From c2e889cfaeaa1b35333750cd6beda4090ee99f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 14:59:29 +0200 Subject: [PATCH 01/37] Added more type-hints --- src/Model/APContact.php | 2 +- src/Protocol/Activity.php | 4 +- src/Protocol/ActivityPub.php | 12 ++-- src/Protocol/ActivityPub/Processor.php | 36 +++++------ src/Protocol/ActivityPub/Receiver.php | 51 ++++++++-------- src/Protocol/ActivityPub/Transmitter.php | 4 +- src/Protocol/DFRN.php | 78 +++++++++++++----------- 7 files changed, 96 insertions(+), 91 deletions(-) diff --git a/src/Model/APContact.php b/src/Model/APContact.php index 9c972efaf2..a934848612 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -117,7 +117,7 @@ class APContact * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function getByURL($url, $update = null) + public static function getByURL(string $url, $update = null) { if (empty($url) || Network::isUrlBlocked($url)) { Logger::info('Domain is blocked', ['url' => $url]); diff --git a/src/Protocol/Activity.php b/src/Protocol/Activity.php index e75b1cf507..0f15e851c3 100644 --- a/src/Protocol/Activity.php +++ b/src/Protocol/Activity.php @@ -212,7 +212,7 @@ final class Activity * * @return bool True, if the activity is hidden */ - public function isHidden(string $activity) + public function isHidden(string $activity): bool { foreach (self::HIDDEN_ACTIVITIES as $hiddenActivity) { if ($this->match($activity, $hiddenActivity)) { @@ -231,7 +231,7 @@ final class Activity * * @return boolean */ - public function match(string $haystack, string $needle) + public function match(string $haystack, string $needle): bool { return (($haystack === $needle) || ((basename($needle) === $haystack) && diff --git a/src/Protocol/ActivityPub.php b/src/Protocol/ActivityPub.php index 78496e2433..b9ab3931bd 100644 --- a/src/Protocol/ActivityPub.php +++ b/src/Protocol/ActivityPub.php @@ -104,12 +104,12 @@ class ActivityPub * @return array * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function fetchContent(string $url, int $uid = 0) + public static function fetchContent(string $url, int $uid = 0): array { return HTTPSignature::fetch($url, $uid); } - private static function getAccountType($apcontact) + private static function getAccountType(array $apcontact): int { $accounttype = -1; @@ -146,7 +146,7 @@ class ActivityPub * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function probeProfile($url, $update = true) + public static function probeProfile(string $url, bool $update = true): array { $apcontact = APContact::getByURL($url, $update); if (empty($apcontact)) { @@ -204,7 +204,7 @@ class ActivityPub * @param integer $uid User ID * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function fetchOutbox($url, $uid) + public static function fetchOutbox(string $url, int $uid) { $data = self::fetchContent($url, $uid); if (empty($data)) { @@ -235,7 +235,7 @@ class ActivityPub * @param integer $uid Optional user id * @return array Endpoint items */ - public static function fetchItems(string $url, int $uid = 0) + public static function fetchItems(string $url, int $uid = 0): array { $data = self::fetchContent($url, $uid); if (empty($data)) { @@ -268,7 +268,7 @@ class ActivityPub * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function isSupportedByContactUrl($url, $update = null) + public static function isSupportedByContactUrl(string $url, $update = null) { return !empty(APContact::getByURL($url, $update)); } diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 2288427b47..c2333004f5 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -94,7 +94,7 @@ class Processor * * @return string with replaced emojis */ - private static function replaceEmojis(int $uri_id, string $body, array $emojis) + private static function replaceEmojis(int $uri_id, string $body, array $emojis): string { $body = strtr($body, array_combine( @@ -690,7 +690,7 @@ class Processor * @param string $url message URL * @return string with GUID */ - private static function getGUIDByURL(string $url) + private static function getGUIDByURL(string $url): string { $parsed = parse_url($url); @@ -711,7 +711,7 @@ class Processor * @param array $item * @return boolean Is the message wanted? */ - private static function isSolicitedMessage(array $activity, array $item) + private static function isSolicitedMessage(array $activity, array $item): bool { // The checks are split to improve the support when searching why a message was accepted. if (count($activity['receiver']) != 1) { @@ -972,7 +972,7 @@ class Processor * @return int|bool New mail table row id or false on error * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function postMail($activity, $item) + private static function postMail(array $activity, array $item) { if (($item['gravity'] != GRAVITY_PARENT) && !DBA::exists('mail', ['uri' => $item['thr-parent'], 'uid' => $item['uid']])) { Logger::info('Parent not found, mail will be discarded.', ['uid' => $item['uid'], 'uri' => $item['thr-parent']]); @@ -1113,7 +1113,7 @@ class Processor * @return string fetched message URL * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function fetchMissingActivity(string $url, array $child = [], string $relay_actor = '', int $completion = Receiver::COMPLETION_MANUAL) + public static function fetchMissingActivity(string $url, array $child = [], string $relay_actor = '', int $completion = Receiver::COMPLETION_MANUAL): string { if (!empty($child['receiver'])) { $uid = ActivityPub\Receiver::getFirstUserFromReceivers($child['receiver']); @@ -1208,7 +1208,7 @@ class Processor * @param string $id object ID * @return boolean true if message is accepted */ - private static function acceptIncomingMessage(array $activity, string $id) + private static function acceptIncomingMessage(array $activity, string $id): bool { if (empty($activity['as:object'])) { Logger::info('No object field in activity - accepted', ['id' => $id]); @@ -1248,7 +1248,7 @@ class Processor * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function followUser($activity) + public static function followUser(array $activity) { $uid = User::getIdForURL($activity['object_id']); if (empty($uid)) { @@ -1326,7 +1326,7 @@ class Processor * @param array $activity * @throws \Exception */ - public static function updatePerson($activity) + public static function updatePerson(array $activity) { if (empty($activity['object_id'])) { return; @@ -1342,7 +1342,7 @@ class Processor * @param array $activity * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function deletePerson($activity) + public static function deletePerson(array $activity) { if (empty($activity['object_id']) || empty($activity['actor'])) { Logger::info('Empty object id or actor.'); @@ -1369,7 +1369,7 @@ class Processor * @param array $activity * @throws \Exception */ - public static function blockAccount($activity) + public static function blockAccount(array $activity) { $cid = Contact::getIdForURL($activity['actor']); if (empty($cid)) { @@ -1392,7 +1392,7 @@ class Processor * @param array $activity * @throws \Exception */ - public static function unblockAccount($activity) + public static function unblockAccount(array $activity) { $cid = Contact::getIdForURL($activity['actor']); if (empty($cid)) { @@ -1416,7 +1416,7 @@ class Processor * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function acceptFollowUser($activity) + public static function acceptFollowUser(array $activity) { $uid = User::getIdForURL($activity['object_actor']); if (empty($uid)) { @@ -1450,7 +1450,7 @@ class Processor * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function rejectFollowUser($activity) + public static function rejectFollowUser(array $activity) { $uid = User::getIdForURL($activity['object_actor']); if (empty($uid)) { @@ -1483,7 +1483,7 @@ class Processor * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function undoActivity($activity) + public static function undoActivity(array $activity) { if (empty($activity['object_id'])) { return; @@ -1508,7 +1508,7 @@ class Processor * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function undoFollowUser($activity) + public static function undoFollowUser(array $activity) { $uid = User::getIdForURL($activity['object_object']); if (empty($uid)) { @@ -1543,7 +1543,7 @@ class Processor * @param integer $cid Contact ID * @throws \Exception */ - private static function switchContact($cid) + private static function switchContact(int $cid) { $contact = DBA::selectFirst('contact', ['network', 'url'], ['id' => $cid]); if (!DBA::isResult($contact) || in_array($contact['network'], [Protocol::ACTIVITYPUB, Protocol::DFRN]) || Contact::isLocal($contact['url'])) { @@ -1563,7 +1563,7 @@ class Processor * @return array * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function getImplicitMentionList(array $parent) + private static function getImplicitMentionList(array $parent): array { $parent_terms = Tag::getByURIId($parent['uri-id'], [Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION]); @@ -1601,7 +1601,7 @@ class Processor * @param array $parent * @return string */ - private static function removeImplicitMentionsFromBody(string $body, array $parent) + private static function removeImplicitMentionsFromBody(string $body, array $parent): string { if (DI::config()->get('system', 'disable_implicit_mentions')) { return $body; diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index 4a13872983..05c40222b1 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -84,8 +84,9 @@ class Receiver * @param $header * @param integer $uid User ID * @throws \Exception + * @todo Find type for $body/$header */ - public static function processInbox($body, $header, $uid) + public static function processInbox($body, $header, int $uid) { $activity = json_decode($body, true); if (empty($activity)) { @@ -220,11 +221,11 @@ class Receiver * @param string $object_id Object ID of the the provided object * @param integer $uid User ID * - * @return string with object type + * @return string with object type or NULL * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function fetchObjectType($activity, $object_id, $uid = 0) + private static function fetchObjectType(array $activity, string $object_id, int $uid = 0) { if (!empty($activity['as:object'])) { $object_type = JsonLD::fetchElement($activity['as:object'], '@type'); @@ -268,7 +269,7 @@ class Receiver * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function prepareObjectData($activity, $uid, $push, &$trust_source) + public static function prepareObjectData(array $activity, int $uid, bool $push, bool &$trust_source): array { $id = JsonLD::fetchElement($activity, '@id'); if (!empty($id) && !$trust_source) { @@ -458,7 +459,7 @@ class Receiver * @param array $receivers Array with receivers * @return integer user id; */ - public static function getFirstUserFromReceivers($receivers) + public static function getFirstUserFromReceivers(array $receivers): int { foreach ($receivers as $receiver) { if (!empty($receiver)) { @@ -479,7 +480,7 @@ class Receiver * @param array $signer The signer of the post * @throws \Exception */ - public static function processActivity($activity, string $body = '', int $uid = null, bool $trust_source = false, bool $push = false, array $signer = []) + public static function processActivity(array $activity, string $body = '', int $uid = null, bool $trust_source = false, bool $push = false, array $signer = []) { $type = JsonLD::fetchElement($activity, '@type'); if (!$type) { @@ -818,7 +819,7 @@ class Receiver * * @return int user id */ - public static function getBestUserForActivity(array $activity) + public static function getBestUserForActivity(array $activity): int { $uid = 0; $actor = JsonLD::fetchElement($activity, 'as:actor', '@id') ?? ''; @@ -844,7 +845,8 @@ class Receiver return $uid; } - public static function getReceiverURL($activity) + // @TODO Missing documentation + public static function getReceiverURL(array $activity): array { $urls = []; @@ -876,7 +878,7 @@ class Receiver * @return array with receivers (user id) * @throws \Exception */ - private static function getReceivers($activity, $actor, $tags = [], $fetch_unlisted = false) + private static function getReceivers(array $activity, string $actor, array $tags = [], bool $fetch_unlisted = false): array { $reply = $receivers = []; @@ -1005,7 +1007,7 @@ class Receiver * @return array with receivers (user id) * @throws \Exception */ - private static function getReceiverForActor($actor, $tags, $receivers, $target_type, $profile) + private static function getReceiverForActor(string $actor, array $tags, array $receivers, int $target_type, array $profile): array { $basecondition = ['rel' => [Contact::SHARING, Contact::FRIEND, Contact::FOLLOWER], 'network' => Protocol::FEDERATED, 'archive' => false, 'pending' => false]; @@ -1047,13 +1049,12 @@ class Receiver * Tests if the contact is a valid receiver for this actor * * @param array $contact - * @param string $actor * @param array $tags * * @return bool with receivers (user id) * @throws \Exception */ - private static function isValidReceiverForActor($contact, $tags) + private static function isValidReceiverForActor(array $contact, string $tags): bool { // Are we following the contact? Then this is a valid receiver if (in_array($contact['rel'], [Contact::SHARING, Contact::FRIEND])) { @@ -1089,7 +1090,7 @@ class Receiver * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function switchContact($cid, $uid, $url) + public static function switchContact(int $cid, int $uid, string $url) { if (DBA::exists('contact', ['id' => $cid, 'network' => Protocol::ACTIVITYPUB])) { Logger::info('Contact is already ActivityPub', ['id' => $cid, 'uid' => $uid, 'url' => $url]); @@ -1108,7 +1109,7 @@ class Receiver } /** - * + * @TODO Fix documentation and type-hints * * @param $receivers * @param $actor @@ -1135,14 +1136,14 @@ class Receiver } /** - * + * @TODO Fix documentation and type-hints * * @param $object_data * @param array $activity * * @return mixed */ - private static function addActivityFields($object_data, $activity) + private static function addActivityFields($object_data, array $activity) { if (!empty($activity['published']) && empty($object_data['published'])) { $object_data['published'] = JsonLD::fetchElement($activity, 'as:published', '@value'); @@ -1262,7 +1263,7 @@ class Receiver * @param array $languages * @return array Languages */ - public static function processLanguages(array $languages) + public static function processLanguages(array $languages): array { if (empty($languages)) { return []; @@ -1285,7 +1286,7 @@ class Receiver * * @return array with tags in a simplified format */ - public static function processTags(array $tags) + public static function processTags(array $tags): array { $taglist = []; @@ -1317,7 +1318,7 @@ class Receiver * @param array $emojis * @return array with emojis in a simplified format */ - private static function processEmojis(array $emojis) + private static function processEmojis(array $emojis): array { $emojilist = []; @@ -1343,7 +1344,7 @@ class Receiver * * @return array Attachments in a simplified format */ - private static function processAttachments(array $attachments) + private static function processAttachments(array $attachments): array { $attachlist = []; @@ -1460,7 +1461,7 @@ class Receiver * * @return array Questions in a simplified format */ - private static function processQuestion(array $object) + private static function processQuestion(array $object): array { $question = []; @@ -1518,10 +1519,10 @@ class Receiver * @param array $object * @param array $object_data * - * @return array + * @return array Object data (?) * @throws \Exception */ - private static function getSource($object, $object_data) + private static function getSource(array $object, array $object_data): array { $object_data['source'] = JsonLD::fetchElement($object, 'as:source', 'as:content', 'as:mediaType', 'text/bbcode'); $object_data['source'] = JsonLD::fetchElement($object_data, 'source', '@value'); @@ -1650,10 +1651,10 @@ class Receiver * * @param array $object * - * @return array + * @return array|bool Object data or FALSE if $object does not contain @id element * @throws \Exception */ - private static function processObject($object) + private static function processObject(array $object) { if (!JsonLD::fetchElement($object, '@id')) { return false; diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index 023bd5c83c..8483d5d1dd 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -68,7 +68,7 @@ class Transmitter * @param array $inboxes * @return array inboxes with added relay servers */ - public static function addRelayServerInboxes(array $inboxes = []) + public static function addRelayServerInboxes(array $inboxes = []): array { foreach (Relay::getList(['inbox']) as $contact) { $inboxes[$contact['inbox']] = $contact['inbox']; @@ -83,7 +83,7 @@ class Transmitter * @param array $inboxes * @return array inboxes with added relay servers */ - public static function addRelayServerInboxesForItem(int $item_id, array $inboxes = []) + public static function addRelayServerInboxesForItem(int $item_id, array $inboxes = []): array { $item = Post::selectFirst(['uid'], ['id' => $item_id]); if (empty($item)) { diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index 0fb7394579..fc72f7e371 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -72,7 +72,7 @@ class DFRN * @return array importer * @throws \Exception */ - public static function getImporter($cid, $uid = 0) + public static function getImporter(int $cid, int $uid = 0): array { $condition = ['id' => $cid, 'blocked' => false, 'pending' => false]; $contact = DBA::selectFirst('contact', [], $condition); @@ -115,7 +115,7 @@ class DFRN * @throws \ImagickException * @todo Find proper type-hints */ - public static function entries($items, $owner) + public static function entries(array $items, array $owner): string { $doc = new DOMDocument('1.0', 'utf-8'); $doc->formatOutput = true; @@ -152,7 +152,7 @@ class DFRN * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function itemFeed(int $uri_id, int $uid, bool $conversation = false) + public static function itemFeed(int $uri_id, int $uid, bool $conversation = false): string { if ($conversation) { $condition = ['parent-uri-id' => $uri_id]; @@ -222,7 +222,7 @@ class DFRN * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @todo Find proper type-hints */ - public static function mail(array $mail, array $owner) + public static function mail(array $mail, array $owner): string { $doc = new DOMDocument('1.0', 'utf-8'); $doc->formatOutput = true; @@ -259,7 +259,7 @@ class DFRN * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @todo Find proper type-hints */ - public static function fsuggest($item, $owner) + public static function fsuggest(array $item, array $owner): string { $doc = new DOMDocument('1.0', 'utf-8'); $doc->formatOutput = true; @@ -289,7 +289,7 @@ class DFRN * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @todo Find proper type-hints */ - public static function relocate($owner, $uid) + public static function relocate(array $owner, int $uid): string { /* get site pubkey. this could be a new installation with no site keys*/ @@ -346,9 +346,9 @@ class DFRN * * @return object XML root object * @throws \Friendica\Network\HTTPException\InternalServerErrorException - * @todo Find proper type-hints + * @todo Find proper type-hint for returned type */ - private static function addHeader(DOMDocument $doc, $owner, $authorelement, $alternatelink = "", $public = false) + private static function addHeader(DOMDocument $doc, array $owner, string $authorelement, string $alternatelink = "", bool $public = false) { if ($alternatelink == "") { @@ -428,8 +428,12 @@ class DFRN * viewer's timezone also, but first we are going to convert it from the birthday * person's timezone to GMT - so the viewer may find the birthday starting at * 6:00PM the day before, but that will correspond to midnight to the birthday person. + * + * @param int $uid User id + * @param string $tz Time zone string, like UTC + * @return string Formatted birthday string */ - private static function determineNextBirthday($uid, $tz) + private static function determineNextBirthday(int $uid, string $tz): string { $birthday = ''; @@ -467,7 +471,7 @@ class DFRN * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @todo Find proper type-hints */ - private static function addAuthor(DOMDocument $doc, array $owner, $authorelement, $public) + private static function addAuthor(DOMDocument $doc, array $owner, string $authorelement, bool $public) { // Should the profile be "unsearchable" in the net? Then add the "hide" element $hide = DBA::exists('profile', ['uid' => $owner['uid'], 'net-publish' => false]); @@ -592,7 +596,7 @@ class DFRN * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @todo Find proper type-hints */ - private static function addEntryAuthor(DOMDocument $doc, $element, $contact_url, $item) + private static function addEntryAuthor(DOMDocument $doc, string $element, string $contact_url, array $item) { $author = $doc->createElement($element); @@ -637,7 +641,7 @@ class DFRN * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @todo Find proper type-hints */ - private static function createActivity(DOMDocument $doc, $element, $activity, $uriid) + private static function createActivity(DOMDocument $doc, string $element, string $activity, int $uriid) { if ($activity) { $entry = $doc->createElement($element); @@ -703,7 +707,7 @@ class DFRN * @return void XML attachment object * @todo Find proper type-hints */ - private static function getAttachment($doc, $root, $item) + private static function getAttachment($doc, $root, array $item) { foreach (Post\Media::getByURIId($item['uri-id'], [Post\Media::DOCUMENT, Post\Media::TORRENT, Post\Media::UNKNOWN]) as $attachment) { $attributes = ['rel' => 'enclosure', @@ -737,7 +741,7 @@ class DFRN * @throws \ImagickException * @todo Find proper type-hints */ - private static function entry(DOMDocument $doc, $type, array $item, array $owner, $comment = false, $cid = 0, $single = false) + private static function entry(DOMDocument $doc, string $type, array $item, array $owner, bool $comment = false, int $cid = 0, bool $single = false) { $mentioned = []; @@ -961,13 +965,12 @@ class DFRN * @param array $owner Owner record * @param array $contact Contact record of the receiver * @param string $atom Content that will be transmitted - * * @param bool $public_batch * @return int Deliver status. Negative values mean an error. * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function transmit($owner, $contact, $atom, $public_batch = false) + public static function transmit(array $owner, array $contact, string $atom, bool $public_batch = false) { if (!$public_batch) { if (empty($contact['addr'])) { @@ -1060,7 +1063,7 @@ class DFRN * @throws \ImagickException * @todo Find good type-hints for all parameter */ - private static function fetchauthor(\DOMXPath $xpath, \DOMNode $context, $importer, $element, $onlyfetch, $xml = "") + private static function fetchauthor(\DOMXPath $xpath, \DOMNode $context, array $importer, string $element, bool $onlyfetch, string $xml = ""): array { $author = []; $author["name"] = XML::getFirstNodeValue($xpath, $element."/atom:name/text()", $context); @@ -1280,7 +1283,7 @@ class DFRN * @return string XML string * @todo Find good type-hints for all parameter */ - private static function transformActivity($xpath, $activity, $element) + private static function transformActivity($xpath, $activity, string $element): string { if (!is_object($activity)) { return ""; @@ -1335,7 +1338,7 @@ class DFRN * @throws \Exception * @todo Find good type-hints for all parameter */ - private static function processMail($xpath, $mail, $importer) + private static function processMail($xpath, $mail, array $importer) { Logger::notice("Processing mails"); @@ -1364,7 +1367,7 @@ class DFRN * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @todo Find good type-hints for all parameter */ - private static function processSuggestion($xpath, $suggestion, $importer) + private static function processSuggestion($xpath, $suggestion, array $importer) { Logger::notice('Processing suggestions'); @@ -1383,7 +1386,7 @@ class DFRN * @param integer $from_cid * @return bool Was the adding successful? */ - private static function addSuggestion(int $uid, int $cid, int $from_cid, string $note = '') + private static function addSuggestion(int $uid, int $cid, int $from_cid, string $note = ''): bool { $owner = User::getOwnerDataById($uid); $contact = Contact::getById($cid); @@ -1440,7 +1443,7 @@ class DFRN * @throws \ImagickException * @todo Find good type-hints for all parameter */ - private static function processRelocation($xpath, $relocation, $importer) + private static function processRelocation($xpath, $relocation, array $importer): bool { Logger::notice("Processing relocations"); @@ -1510,7 +1513,7 @@ class DFRN * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @todo set proper type-hints (array?) */ - private static function updateContent($current, $item, $importer, $entrytype) + private static function updateContent(array $current, array $item, array $importer, int $entrytype) { $changed = false; @@ -1542,7 +1545,7 @@ class DFRN * @throws \Exception * @todo set proper type-hints (array?) */ - private static function getEntryType($importer, $item) + private static function getEntryType(array $importer, array $item): int { if ($item["thr-parent"] != $item["uri"]) { $community = false; @@ -1638,7 +1641,7 @@ class DFRN * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @todo set proper type-hints (array?) */ - private static function processVerbs($entrytype, $importer, &$item, &$is_like) + private static function processVerbs(int $entrytype, array $importer, array &$item, bool &$is_like) { Logger::info("Process verb ".$item["verb"]." and object-type ".$item["object-type"]." for entrytype ".$entrytype); @@ -1734,7 +1737,7 @@ class DFRN * @return void * @todo set proper type-hints */ - private static function parseLinks($links, &$item) + private static function parseLinks($links, array &$item) { $rel = ""; $href = ""; @@ -1772,7 +1775,7 @@ class DFRN * @param array $imporer * @return boolean Is the message wanted? */ - private static function isSolicitedMessage(array $item, array $importer) + private static function isSolicitedMessage(array $item, array $importer): bool { if (DBA::exists('contact', ["`nurl` = ? AND `uid` != ? AND `rel` IN (?, ?)", Strings::normaliseLink($item["author-link"]), 0, Contact::FRIEND, Contact::SHARING])) { @@ -1807,12 +1810,13 @@ class DFRN * @param object $entry entry elements * @param array $importer Record of the importer user mixed with contact of the content * @param string $xml xml + * @param int $protocol Protocol * @return void * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException * @todo Add type-hints */ - private static function processEntry($header, $xpath, $entry, $importer, $xml, $protocol) + private static function processEntry(array $header, $xpath, $entry, array $importer, string $xml, int $protocol) { Logger::notice("Processing entries"); @@ -2163,7 +2167,7 @@ class DFRN * @throws \Exception * @todo set proper type-hints */ - private static function processDeletion($xpath, $deletion, $importer) + private static function processDeletion($xpath, $deletion, array $importer) { Logger::notice("Processing deletions"); $uri = null; @@ -2224,9 +2228,8 @@ class DFRN * @return integer Import status * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException - * @todo set proper type-hints */ - public static function import($xml, $importer, $protocol, $direction) + public static function import(string $xml, array $importer, int $protocol, int $direction): int { if ($xml == "") { return 400; @@ -2365,7 +2368,7 @@ class DFRN * * @return string activity verb */ - private static function constructVerb(array $item) + private static function constructVerb(array $item): string { if ($item['verb']) { return $item['verb']; @@ -2373,7 +2376,8 @@ class DFRN return Activity::POST; } - private static function tgroupCheck($uid, $item) + // @TODO Documentation missing + private static function tgroupCheck(int $uid, array $item): bool { $mention = false; @@ -2421,12 +2425,12 @@ class DFRN * item is assumed to be up-to-date. If the timestamps are equal it * assumes the update has been seen before and should be ignored. * - * @param $existing - * @param $update + * @param array $existing + * @param array $update * @return bool * @throws \Exception */ - private static function isEditedTimestampNewer($existing, $update) + private static function isEditedTimestampNewer(array $existing, array $update): bool { if (empty($existing['edited'])) { return true; @@ -2449,7 +2453,7 @@ class DFRN * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function isSupportedByContactUrl($url) + public static function isSupportedByContactUrl(string $url): bool { $probe = Probe::uri($url, Protocol::DFRN); return $probe['network'] == Protocol::DFRN; From 97e27cb523048508e2732f1551116f15c4cda001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 16:25:30 +0200 Subject: [PATCH 02/37] Added more type-hints --- src/App.php | 58 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/src/App.php b/src/App.php index 6fa79c5014..2d635951be 100644 --- a/src/App.php +++ b/src/App.php @@ -145,7 +145,7 @@ class App $this->nickname = $nickname; } - public function isLoggedIn() + public function isLoggedIn(): bool { return local_user() && $this->user_id && ($this->user_id == local_user()); } @@ -155,7 +155,7 @@ class App * * @return bool true if user is an admin */ - public function isSiteAdmin() + public function isSiteAdmin(): bool { $admin_email = $this->config->get('config', 'admin_email'); @@ -166,18 +166,18 @@ class App /** * Fetch the user id - * @return int + * @return int User id */ - public function getLoggedInUserId() + public function getLoggedInUserId(): int { return $this->user_id; } /** * Fetch the user nick name - * @return string + * @return string User's nickname */ - public function getLoggedInUserNickname() + public function getLoggedInUserNickname(): string { return $this->nickname; } @@ -198,7 +198,7 @@ class App * * @return int */ - public function getProfileOwner():int + public function getProfileOwner(): int { return $this->profile_owner; } @@ -219,7 +219,7 @@ class App * * @return int */ - public function getContactId():int + public function getContactId(): int { return $this->contact_id; } @@ -241,7 +241,7 @@ class App * * @return int */ - public function getTimeZone():string + public function getTimeZone(): string { return $this->timezone; } @@ -260,9 +260,9 @@ class App /** * Fetch workerqueue information * - * @return array + * @return array Worker queue */ - public function getQueue() + public function getQueue(): array { return $this->queue ?? []; } @@ -270,8 +270,8 @@ class App /** * Fetch a specific workerqueue field * - * @param string $index - * @return mixed + * @param string $index Work queue record to fetch + * @return mixed Work queue item or NULL if not found */ public function getQueueValue(string $index) { @@ -306,9 +306,9 @@ class App /** * The basepath of this app * - * @return string + * @return string Base path from configuration */ - public function getBasePath() + public function getBasePath(): string { // Don't use the basepath of the config table for basepath (it should always be the config-file one) return $this->config->getCache()->get('system', 'basepath'); @@ -396,10 +396,10 @@ class App /** * Returns the current theme name. May be overriden by the mobile theme name. * - * @return string + * @return string Current theme name or empty string in installation phase * @throws Exception */ - public function getCurrentTheme() + public function getCurrentTheme(): string { if ($this->mode->isInstall()) { return ''; @@ -425,10 +425,10 @@ class App /** * Returns the current mobile theme name. * - * @return string + * @return string Mobile theme name or empty string if installer * @throws Exception */ - public function getCurrentMobileTheme() + public function getCurrentMobileTheme(): string { if ($this->mode->isInstall()) { return ''; @@ -441,12 +441,22 @@ class App return $this->currentMobileTheme; } - public function setCurrentTheme($theme) + /** + * Setter for current theme name + * + * @param string $theme Name of current theme + */ + public function setCurrentTheme(string $theme) { $this->currentTheme = $theme; } - public function setCurrentMobileTheme($theme) + /** + * Setter for current mobile theme name + * + * @param string $theme Name of current mobile theme + */ + public function setCurrentMobileTheme(string $theme) { $this->currentMobileTheme = $theme; } @@ -525,10 +535,10 @@ class App /** * Provide a sane default if nothing is chosen or the specified theme does not exist. * - * @return string + * @return string Current theme's stylsheet path * @throws Exception */ - public function getCurrentThemeStylesheetPath() + public function getCurrentThemeStylesheetPath(): string { return Core\Theme::getStylesheetPath($this->getCurrentTheme()); } @@ -730,7 +740,7 @@ class App * * @throws HTTPException\InternalServerErrorException */ - public function redirect($toUrl) + public function redirect(string $toUrl) { if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) { Core\System::externalRedirect($toUrl); From aa5f0d5ec1c1c810a4d49dab4a7b60ec8b7e36aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 16:35:39 +0200 Subject: [PATCH 03/37] Added more type-hints and documented a few methods --- src/BaseCollection.php | 12 +++++++----- src/BaseEntity.php | 6 +++--- src/BaseModel.php | 4 ++-- src/BaseModule.php | 17 ++++++++++++----- src/LegacyModule.php | 4 ++-- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/BaseCollection.php b/src/BaseCollection.php index 0bf46f0dcb..f6fa9bbd4d 100644 --- a/src/BaseCollection.php +++ b/src/BaseCollection.php @@ -70,9 +70,11 @@ class BaseCollection extends \ArrayIterator } /** - * @return int + * Getter for total count + * + * @return int Total count */ - public function getTotalCount() + public function getTotalCount(): int { return $this->totalCount; } @@ -85,7 +87,7 @@ class BaseCollection extends \ArrayIterator * @return array * @see array_column() */ - public function column($column, $index_key = null) + public function column(string $column, $index_key = null): array { return array_column($this->getArrayCopy(true), $column, $index_key); } @@ -97,7 +99,7 @@ class BaseCollection extends \ArrayIterator * @return BaseCollection * @see array_map() */ - public function map(callable $callback) + public function map(callable $callback): BaseCollection { return new static(array_map($callback, $this->getArrayCopy()), $this->getTotalCount()); } @@ -110,7 +112,7 @@ class BaseCollection extends \ArrayIterator * @return BaseCollection * @see array_filter() */ - public function filter(callable $callback = null, int $flag = 0) + public function filter(callable $callback = null, int $flag = 0): BaseCollection { return new static(array_filter($this->getArrayCopy(), $callback, $flag)); } diff --git a/src/BaseEntity.php b/src/BaseEntity.php index 8e8938febc..065d100fa3 100644 --- a/src/BaseEntity.php +++ b/src/BaseEntity.php @@ -55,14 +55,14 @@ abstract class BaseEntity extends BaseDataTransferObject } /** - * @param $name + * @param mixed $name * @return bool * @throws HTTPException\InternalServerErrorException */ - public function __isset($name) + public function __isset($name): bool { if (!property_exists($this, $name)) { - throw new HTTPException\InternalServerErrorException('Unknown property ' . $name . ' in Entity ' . static::class); + throw new HTTPException\InternalServerErrorException('Unknown property ' . $name . ' of type ' . gettype($name) . ' in Entity ' . static::class); } return !empty($this->$name); diff --git a/src/BaseModel.php b/src/BaseModel.php index 768e9e9e53..06a61c505a 100644 --- a/src/BaseModel.php +++ b/src/BaseModel.php @@ -110,11 +110,11 @@ abstract class BaseModel extends BaseDataTransferObject * - $model->field (outside of class) * - $this->field (inside of class) * - * @param $name + * @param string $name Name of data to fetch * @return mixed * @throws HTTPException\InternalServerErrorException */ - public function __get($name) + public function __get(string $name) { $this->checkValid(); diff --git a/src/BaseModule.php b/src/BaseModule.php index c03a77e29e..f70662a62f 100644 --- a/src/BaseModule.php +++ b/src/BaseModule.php @@ -331,7 +331,7 @@ abstract class BaseModule implements ICanHandleRequests * Actually, important actions should not be triggered by Links / GET-Requests at all, but sometimes they still are, * so this mechanism brings in some damage control (the attacker would be able to forge a request to a form of this type, but not to forms of other types). */ - public static function getFormSecurityToken($typename = '') + public static function getFormSecurityToken(string $typename = '') { $user = User::getById(DI::app()->getLoggedInUserId(), ['guid', 'prvkey']); $timestamp = time(); @@ -340,7 +340,14 @@ abstract class BaseModule implements ICanHandleRequests return $timestamp . '.' . $sec_hash; } - public static function checkFormSecurityToken($typename = '', $formname = 'form_security_token') + /** + * Checks if form's security (CSRF) token is valid. + * + * @param string $typename ??? + * @param string $formname Name of form/field (???) + * @return bool Whether it is valid + */ + public static function checkFormSecurityToken(string $typename = '', string $formname = 'form_security_token'): bool { $hash = null; @@ -372,12 +379,12 @@ abstract class BaseModule implements ICanHandleRequests return ($sec_hash == $x[1]); } - public static function getFormSecurityStandardErrorMessage() + public static function getFormSecurityStandardErrorMessage(): string { return DI::l10n()->t("The form security token was not correct. This probably happened because the form has been opened for too long \x28>3 hours\x29 before submitting it.") . EOL; } - public static function checkFormSecurityTokenRedirectOnError($err_redirect, $typename = '', $formname = 'form_security_token') + public static function checkFormSecurityTokenRedirectOnError(string $err_redirect, string $typename = '', string $formname = 'form_security_token') { if (!self::checkFormSecurityToken($typename, $formname)) { Logger::notice('checkFormSecurityToken failed: user ' . DI::app()->getLoggedInUserNickname() . ' - form element ' . $typename); @@ -387,7 +394,7 @@ abstract class BaseModule implements ICanHandleRequests } } - public static function checkFormSecurityTokenForbiddenOnError($typename = '', $formname = 'form_security_token') + public static function checkFormSecurityTokenForbiddenOnError(string $typename = '', string $formname = 'form_security_token') { if (!self::checkFormSecurityToken($typename, $formname)) { Logger::notice('checkFormSecurityToken failed: user ' . DI::app()->getLoggedInUserNickname() . ' - form element ' . $typename); diff --git a/src/LegacyModule.php b/src/LegacyModule.php index 22d393ef9e..7d9cf20283 100644 --- a/src/LegacyModule.php +++ b/src/LegacyModule.php @@ -57,7 +57,7 @@ class LegacyModule extends BaseModule * @param string $file_path * @throws \Exception */ - private function setModuleFile($file_path) + private function setModuleFile(string $file_path) { if (!is_readable($file_path)) { throw new \Exception(DI::l10n()->t('Legacy module file not found: %s', $file_path)); @@ -87,7 +87,7 @@ class LegacyModule extends BaseModule * @return string * @throws \Exception */ - private function runModuleFunction(string $function_suffix) + private function runModuleFunction(string $function_suffix): string { $function_name = $this->moduleName . '_' . $function_suffix; From 42b04f397b4b288d1685f9f7b89458b79817c6c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 16:38:58 +0200 Subject: [PATCH 04/37] Added more type-hints --- src/Worker/Delivery.php | 6 +++--- src/Worker/Directory.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php index c09181d3e6..2f78bed6b8 100644 --- a/src/Worker/Delivery.php +++ b/src/Worker/Delivery.php @@ -269,7 +269,7 @@ class Delivery * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function deliverDFRN($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup, $server_protocol) + private static function deliverDFRN(string $cmd, array $contact, array $owner, array $items, array $target_item, bool $public_message, bool $top_level, bool $followup, int $server_protocol) { // Transmit Diaspora reshares via Diaspora if the Friendica contact support Diaspora if (Diaspora::isReshare($target_item['body'] ?? '') && !empty(FContact::getByURL($contact['addr'], false))) { @@ -384,7 +384,7 @@ class Delivery * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function deliverDiaspora($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup) + private static function deliverDiaspora(string $cmd, array $contact, array $owner, array $items, array $target_item, bool $public_message, bool $top_level, bool $followup) { // We don't treat Forum posts as "wall-to-wall" to be able to post them via Diaspora $walltowall = $top_level && ($owner['id'] != $items[0]['contact-id']) & ($owner['account-type'] != Model\User::ACCOUNT_TYPE_COMMUNITY); @@ -478,7 +478,7 @@ class Delivery * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function deliverMail($cmd, $contact, $owner, $target_item, $thr_parent) + private static function deliverMail(string $cmd, array $contact, array $owner, array $target_item, array $thr_parent) { if (DI::config()->get('system','imap_disabled')) { return; diff --git a/src/Worker/Directory.php b/src/Worker/Directory.php index d6294d0498..bb8041a225 100644 --- a/src/Worker/Directory.php +++ b/src/Worker/Directory.php @@ -34,7 +34,7 @@ use Friendica\Network\HTTPClient\Client\HttpClientAccept; */ class Directory { - public static function execute($url = '') + public static function execute(string $url = '') { $dir = Search::getGlobalDirectory(); From 1edc6b3c3b507914b6707c4cb3eca8fda15ea2b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 16:49:43 +0200 Subject: [PATCH 05/37] Added more type-hints for "App" classes --- src/App/Arguments.php | 12 ++++++------ src/App/BaseURL.php | 25 +++++++++++++------------ src/App/Mode.php | 22 +++++++++++----------- src/App/Page.php | 4 ++-- src/App/Router.php | 13 ++++++++++--- 5 files changed, 42 insertions(+), 34 deletions(-) diff --git a/src/App/Arguments.php b/src/App/Arguments.php index 4d386fc255..6dfdcb560f 100644 --- a/src/App/Arguments.php +++ b/src/App/Arguments.php @@ -78,7 +78,7 @@ class Arguments /** * @return string The whole command of this call */ - public function getCommand() + public function getCommand(): string { return $this->command; } @@ -94,7 +94,7 @@ class Arguments /** * @return array All arguments of this call */ - public function getArgv() + public function getArgv(): array { return $this->argv; } @@ -102,7 +102,7 @@ class Arguments /** * @return string The used HTTP method */ - public function getMethod() + public function getMethod(): string { return $this->method; } @@ -110,7 +110,7 @@ class Arguments /** * @return int The count of arguments of this call */ - public function getArgc() + public function getArgc(): int { return $this->argc; } @@ -145,7 +145,7 @@ class Arguments * * @return bool if the argument position exists */ - public function has(int $position) + public function has(int $position): bool { return array_key_exists($position, $this->argv); } @@ -158,7 +158,7 @@ class Arguments * * @return Arguments The determined arguments */ - public function determine(array $server, array $get) + public function determine(array $server, array $get): Arguments { // removing leading / - maybe a nginx problem $server['QUERY_STRING'] = ltrim($server['QUERY_STRING'] ?? '', '/'); diff --git a/src/App/BaseURL.php b/src/App/BaseURL.php index 9a8348510d..f02a5f1fe7 100644 --- a/src/App/BaseURL.php +++ b/src/App/BaseURL.php @@ -107,7 +107,7 @@ class BaseURL * * @return string */ - public function getHostname() + public function getHostname(): string { return $this->hostname; } @@ -117,7 +117,7 @@ class BaseURL * * @return string */ - public function getScheme() + public function getScheme(): string { return $this->scheme; } @@ -127,7 +127,7 @@ class BaseURL * * @return int */ - public function getSSLPolicy() + public function getSSLPolicy(): int { return $this->sslPolicy; } @@ -137,7 +137,7 @@ class BaseURL * * @return string */ - public function getUrlPath() + public function getUrlPath(): string { return $this->urlPath; } @@ -151,7 +151,7 @@ class BaseURL * * @return string */ - public function get($ssl = false) + public function get(bool $ssl = false): string { if ($this->sslPolicy === self::SSL_POLICY_SELFSIGN && $ssl) { return Network::switchScheme($this->url); @@ -168,8 +168,9 @@ class BaseURL * @param string? $urlPath * * @return bool true, if successful + * @TODO Find proper types */ - public function save($hostname = null, $sslPolicy = null, $urlPath = null) + public function save($hostname = null, $sslPolicy = null, $urlPath = null): bool { $currHostname = $this->hostname; $currSSLPolicy = $this->sslPolicy; @@ -224,11 +225,11 @@ class BaseURL /** * Save the current url as base URL * - * @param $url + * @param string $url * * @return bool true, if the save was successful */ - public function saveByURL($url) + public function saveByURL(string $url): bool { $parsed = @parse_url($url); @@ -421,7 +422,7 @@ class BaseURL * * @return string The cleaned url */ - public function remove(string $origURL) + public function remove(string $origURL): string { // Remove the hostname from the url if it is an internal link $nurl = Strings::normaliseLink($origURL); @@ -445,7 +446,7 @@ class BaseURL * * @throws HTTPException\InternalServerErrorException In Case the given URL is not relative to the Friendica node */ - public function redirect($toUrl = '', $ssl = false) + public function redirect(string $toUrl = '', bool $ssl = false) { if (!empty(parse_url($toUrl, PHP_URL_SCHEME))) { throw new HTTPException\InternalServerErrorException("'$toUrl is not a relative path, please use System::externalRedirectTo"); @@ -458,8 +459,8 @@ class BaseURL /** * Returns the base url as string */ - public function __toString() + public function __toString(): string { - return $this->get(); + return (string) $this->get(); } } diff --git a/src/App/Mode.php b/src/App/Mode.php index 3e7b9f0d16..5d6bd759f2 100644 --- a/src/App/Mode.php +++ b/src/App/Mode.php @@ -130,7 +130,7 @@ class Mode * * @throws \Exception */ - public function determine(BasePath $basepath, Database $database, Cache $configCache) + public function determine(BasePath $basepath, Database $database, Cache $configCache): Mode { $mode = 0; @@ -178,7 +178,7 @@ class Mode * * @return Mode returns the determined mode */ - public function determineRunMode(bool $isBackend, array $server, Arguments $args, MobileDetect $mobileDetect) + public function determineRunMode(bool $isBackend, array $server, Arguments $args, MobileDetect $mobileDetect): Mode { foreach (self::BACKEND_CONTENT_TYPES as $type) { if (strpos(strtolower($server['HTTP_ACCEPT'] ?? ''), $type) !== false) { @@ -201,7 +201,7 @@ class Mode * * @return bool returns true, if the mode is set */ - public function has($mode) + public function has(int $mode): bool { return ($this->mode & $mode) > 0; } @@ -227,7 +227,7 @@ class Mode * * @return int Execution Mode */ - public function getExecutor() + public function getExecutor(): int { return $this->executor; } @@ -235,9 +235,9 @@ class Mode /** * Install mode is when the local config file is missing or the DB schema hasn't been installed yet. * - * @return bool + * @return bool Whether installation mode is active (local/database configuration files present or not) */ - public function isInstall() + public function isInstall(): bool { return !$this->has(Mode::LOCALCONFIGPRESENT) || !$this->has(MODE::DBCONFIGAVAILABLE); @@ -248,7 +248,7 @@ class Mode * * @return bool */ - public function isNormal() + public function isNormal(): bool { return $this->has(Mode::LOCALCONFIGPRESENT) && $this->has(Mode::DBAVAILABLE) && @@ -261,7 +261,7 @@ class Mode * * @return bool Is it a backend call */ - public function isBackend() + public function isBackend(): bool { return $this->isBackend; } @@ -271,7 +271,7 @@ class Mode * * @return bool true if it was an AJAX request */ - public function isAjax() + public function isAjax(): bool { return $this->isAjax; } @@ -281,7 +281,7 @@ class Mode * * @return bool true if it was an mobile request */ - public function isMobile() + public function isMobile(): bool { return $this->isMobile; } @@ -291,7 +291,7 @@ class Mode * * @return bool true if it was an tablet request */ - public function isTablet() + public function isTablet(): bool { return $this->isTablet; } diff --git a/src/App/Page.php b/src/App/Page.php index d38757687c..475681054a 100644 --- a/src/App/Page.php +++ b/src/App/Page.php @@ -195,7 +195,7 @@ class Page implements ArrayAccess * @param string $media * @see Page::initHead() */ - public function registerStylesheet($path, string $media = 'screen') + public function registerStylesheet(string $path, string $media = 'screen') { $path = Network::appendQueryParam($path, ['v' => FRIENDICA_VERSION]); @@ -288,7 +288,7 @@ class Page implements ArrayAccess * * Taken from http://webcheatsheet.com/php/get_current_page_url.php */ - private function curPageURL() + private function curPageURL(): string { $pageURL = 'http'; if (!empty($_SERVER["HTTPS"]) && ($_SERVER["HTTPS"] == "on")) { diff --git a/src/App/Router.php b/src/App/Router.php index 6e390a84d9..9906568925 100644 --- a/src/App/Router.php +++ b/src/App/Router.php @@ -152,7 +152,7 @@ class Router * * @throws HTTPException\InternalServerErrorException In case of invalid configs */ - public function loadRoutes(array $routes) + public function loadRoutes(array $routes): Router { $routeCollector = ($this->routeCollector ?? new RouteCollector(new Std(), new GroupCountBased())); @@ -166,6 +166,13 @@ class Router return $this; } + /** + * Adds multiple routes to a route collector + * + * @param RouteCollector $routeCollector Route collector instance + * @param array $routes Multiple routes to be added + * @throws HTTPException\InternalServerErrorException If route was wrong (somehow) + */ private function addRoutes(RouteCollector $routeCollector, array $routes) { foreach ($routes as $route => $config) { @@ -221,7 +228,7 @@ class Router * * @return bool */ - private function isRoute(array $config) + private function isRoute(array $config): bool { return // The config array should at least have one entry @@ -253,7 +260,7 @@ class Router * @throws HTTPException\MethodNotAllowedException If a rule matched but the method didn't * @throws HTTPException\NotFoundException If no rule matched */ - private function getModuleClass() + private function getModuleClass(): string { $cmd = $this->args->getCommand(); $cmd = '/' . ltrim($cmd, '/'); From 40d7f29a11400ff7648a5fe31bbe99e92810fd26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 18:28:38 +0200 Subject: [PATCH 06/37] Continued: - more type-hints - fixed incompatible method declarations --- src/Contact/Avatar.php | 2 +- src/Content/BoundariesPager.php | 4 +-- src/Content/ContactSelector.php | 10 +++--- src/Content/Conversation.php | 36 +++++++++---------- src/Model/Log/ParsedLogIterator.php | 16 ++++----- .../ProfileField/Collection/ProfileFields.php | 4 +-- 6 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/Contact/Avatar.php b/src/Contact/Avatar.php index 60981485e8..f43ed7b8c7 100644 --- a/src/Contact/Avatar.php +++ b/src/Contact/Avatar.php @@ -123,7 +123,7 @@ class Avatar return $fields; } - private static function getFilename(string $url) + private static function getFilename(string $url): string { $guid = Item::guidFromUri($url, parse_url($url, PHP_URL_HOST)); diff --git a/src/Content/BoundariesPager.php b/src/Content/BoundariesPager.php index 358539794c..a8b873f22a 100644 --- a/src/Content/BoundariesPager.php +++ b/src/Content/BoundariesPager.php @@ -49,7 +49,7 @@ class BoundariesPager extends Pager * @param string $last_item_id The id† of the last item in the displayed item list * @param integer $itemsPerPage An optional number of items per page to override the default value */ - public function __construct(L10n $l10n, $queryString, $first_item_id = null, $last_item_id = null, $itemsPerPage = 50) + public function __construct(L10n $l10n, string $queryString, string $first_item_id = null, string $last_item_id = null, int $itemsPerPage = 50) { parent::__construct($l10n, $queryString, $itemsPerPage); @@ -102,7 +102,7 @@ class BoundariesPager extends Pager * @return string HTML string of the pager * @throws \Exception */ - public function renderMinimal(int $itemCount) + public function renderMinimal(int $itemCount): string { $displayedItemCount = max(0, intval($itemCount)); diff --git a/src/Content/ContactSelector.php b/src/Content/ContactSelector.php index 6c7e09945f..fd574889e6 100644 --- a/src/Content/ContactSelector.php +++ b/src/Content/ContactSelector.php @@ -41,7 +41,7 @@ class ContactSelector * @param boolean $disabled optional, default false * @return string */ - public static function pollInterval($current, $disabled = false) + public static function pollInterval(string $current, bool $disabled = false): string { $dis = (($disabled) ? ' disabled="disabled" ' : ''); $o = ''; @@ -84,7 +84,7 @@ class ContactSelector * @return string Server URL * @throws \Exception */ - private static function getServerURLForProfile($profile) + private static function getServerURLForProfile(string $profile): string { if (!empty(self::$server_url[$profile])) { return self::$server_url[$profile]; @@ -114,10 +114,11 @@ class ContactSelector * @param string $network network of the contact * @param string $profile optional, default empty * @param string $protocol (Optional) Protocol that is used for the transmission + * @param int $gsid ??? (@TODO) * @return string * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function networkToName($network, $profile = '', $protocol = '', $gsid = 0) + public static function networkToName(string $network, string $profile = '', string $protocol = '', int $gsid = 0): string { $nets = [ Protocol::DFRN => DI::l10n()->t('DFRN'), @@ -181,10 +182,11 @@ class ContactSelector /** * @param string $network network * @param string $profile optional, default empty + * @param int $gsid ??? (@TODO) * @return string * @throws \Exception */ - public static function networkToIcon($network, $profile = "", $gsid = 0) + public static function networkToIcon(string $network, string $profile = "", int $gsid = 0): string { $nets = [ Protocol::DFRN => 'friendica', diff --git a/src/Content/Conversation.php b/src/Content/Conversation.php index 952b80e768..1088497983 100644 --- a/src/Content/Conversation.php +++ b/src/Content/Conversation.php @@ -189,7 +189,7 @@ class Conversation * @return string formatted text * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public function formatActivity(array $links, $verb, $id) + public function formatActivity(array $links, string $verb, int $id): string { $this->profiler->startRecording('rendering'); $o = ''; @@ -275,7 +275,7 @@ class Conversation return $o; } - public function statusEditor(array $x = [], $notes_cid = 0, $popup = false) + public function statusEditor(array $x = [], int $notes_cid = 0, bool $popup = false): string { $user = User::getById($this->app->getLoggedInUserId(), ['uid', 'nickname', 'allow_location', 'default-location']); if (empty($user['uid'])) { @@ -414,8 +414,8 @@ class Conversation * figures out how to determine page owner and other contextual items * that are based on unique features of the calling module. * @param array $items - * @param $mode - * @param $update + * @param string $mode + * @param $update @TODO Which type? * @param bool $preview * @param string $order * @param int $uid @@ -423,7 +423,7 @@ class Conversation * @throws ImagickException * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public function create(array $items, $mode, $update, $preview = false, $order = 'commented', $uid = 0) + public function create(array $items, string $mode, $update, bool $preview = false, string $order = 'commented', int $uid = 0): string { $this->profiler->startRecording('rendering'); @@ -784,7 +784,7 @@ class Conversation return $o; } - private function getBlocklist() + private function getBlocklist(): array { if (!local_user()) { return []; @@ -816,7 +816,7 @@ class Conversation * * @return array items with parents and comments */ - private function addRowInformation(array $row, array $activity, array $thr_parent) + private function addRowInformation(array $row, array $activity, array $thr_parent): array { $this->profiler->startRecording('rendering'); @@ -911,7 +911,7 @@ class Conversation * @return array items with parents and comments * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private function addChildren(array $parents, bool $block_authors, string $order, int $uid, string $mode) + private function addChildren(array $parents, bool $block_authors, string $order, int $uid, string $mode): array { $this->profiler->startRecording('rendering'); if (count($parents) > 1) { @@ -1005,7 +1005,7 @@ class Conversation * @param bool $recursive * @return array */ - private function getItemChildren(array &$item_list, array $parent, $recursive = true) + private function getItemChildren(array &$item_list, array $parent, bool $recursive = true): array { $this->profiler->startRecording('rendering'); $children = []; @@ -1040,7 +1040,7 @@ class Conversation * @param array $items * @return array */ - private function sortItemChildren(array $items) + private function sortItemChildren(array $items): array { $this->profiler->startRecording('rendering'); $result = $items; @@ -1086,7 +1086,7 @@ class Conversation * @param array $parent A tree-like array of items * @return array */ - private function smartFlattenConversation(array $parent) + private function smartFlattenConversation(array $parent): array { $this->profiler->startRecording('rendering'); if (!isset($parent['children']) || count($parent['children']) == 0) { @@ -1142,7 +1142,7 @@ class Conversation * @return array * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private function convSort(array $item_list, $order) + private function convSort(array $item_list, string $order): array { $this->profiler->startRecording('rendering'); $parents = []; @@ -1222,7 +1222,7 @@ class Conversation * @param array $b * @return int */ - private function sortThrFeaturedReceived(array $a, array $b) + private function sortThrFeaturedReceived(array $a, array $b): int { if ($b['featured'] && !$a['featured']) { return 1; @@ -1240,7 +1240,7 @@ class Conversation * @param array $b * @return int */ - private function sortThrFeaturedCommented(array $a, array $b) + private function sortThrFeaturedCommented(array $a, array $b): int { if ($b['featured'] && !$a['featured']) { return 1; @@ -1258,7 +1258,7 @@ class Conversation * @param array $b * @return int */ - private function sortThrReceived(array $a, array $b) + private function sortThrReceived(array $a, array $b): int { return strcmp($b['received'], $a['received']); } @@ -1270,7 +1270,7 @@ class Conversation * @param array $b * @return int */ - private function sortThrReceivedRev(array $a, array $b) + private function sortThrReceivedRev(array $a, array $b): int { return strcmp($a['received'], $b['received']); } @@ -1282,7 +1282,7 @@ class Conversation * @param array $b * @return int */ - private function sortThrCommented(array $a, array $b) + private function sortThrCommented(array $a, array $b): int { return strcmp($b['commented'], $a['commented']); } @@ -1294,7 +1294,7 @@ class Conversation * @param array $b * @return int */ - private function sortThrCreated(array $a, array $b) + private function sortThrCreated(array $a, array $b): int { return strcmp($b['created'], $a['created']); } diff --git a/src/Model/Log/ParsedLogIterator.php b/src/Model/Log/ParsedLogIterator.php index 711391cb01..d3a5650397 100644 --- a/src/Model/Log/ParsedLogIterator.php +++ b/src/Model/Log/ParsedLogIterator.php @@ -60,7 +60,7 @@ class ParsedLogIterator implements \Iterator * @param string $filename File to open * @return $this */ - public function open(string $filename) + public function open(string $filename): ParsedLogIterator { $this->reader->open($filename); return $this; @@ -70,7 +70,7 @@ class ParsedLogIterator implements \Iterator * @param int $limit Max num of lines to read * @return $this */ - public function withLimit(int $limit) + public function withLimit(int $limit): ParsedLogIterator { $this->limit = $limit; return $this; @@ -80,7 +80,7 @@ class ParsedLogIterator implements \Iterator * @param array $filters filters per column * @return $this */ - public function withFilters(array $filters) + public function withFilters(array $filters): ParsedLogIterator { $this->filters = $filters; return $this; @@ -90,7 +90,7 @@ class ParsedLogIterator implements \Iterator * @param string $search string to search to filter lines * @return $this */ - public function withSearch(string $search) + public function withSearch(string $search): ParsedLogIterator { $this->search = $search; return $this; @@ -100,10 +100,10 @@ class ParsedLogIterator implements \Iterator * Check if parsed log line match filters. * Always match if no filters are set. * - * @param ParsedLogLine $parsedlogline - * @return bool + * @param ParsedLogLine $parsedlogline ParsedLogLine instance + * @return bool Wether the parse log line matches */ - private function filter($parsedlogline) + private function filter(ParsedLogLine $parsedlogline): bool { $match = true; foreach ($this->filters as $filter => $filtervalue) { @@ -126,7 +126,7 @@ class ParsedLogIterator implements \Iterator * @param ParsedLogLine $parsedlogline * @return bool */ - private function search($parsedlogline) + private function search(ParsedLogLine $parsedlogline): bool { if ($this->search != "") { return strstr($parsedlogline->logline, $this->search) !== false; diff --git a/src/Profile/ProfileField/Collection/ProfileFields.php b/src/Profile/ProfileField/Collection/ProfileFields.php index 0520103d76..906b690fa2 100644 --- a/src/Profile/ProfileField/Collection/ProfileFields.php +++ b/src/Profile/ProfileField/Collection/ProfileFields.php @@ -33,9 +33,9 @@ class ProfileFields extends BaseCollection /** * @param callable $callback - * @return ProfileFields + * @return ProfileFields (as an extended form of BaseCollection) */ - public function map(callable $callback): ProfileFields + public function map(callable $callback): BaseCollection { return parent::map($callback); } From 2c5595c3584a13760b7fd2b3331861b317c117bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 18:36:56 +0200 Subject: [PATCH 07/37] Another incompatible method declaration fixed + type-hints added --- src/Content/Widget.php | 12 +++++++----- .../ProfileField/Collection/ProfileFields.php | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Content/Widget.php b/src/Content/Widget.php index 1b2502d2d6..22772d2b2e 100644 --- a/src/Content/Widget.php +++ b/src/Content/Widget.php @@ -45,7 +45,7 @@ class Widget * @return string * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function follow($value = "") + public static function follow(string $value = ""): string { return Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/follow.tpl'), array( '$connect' => DI::l10n()->t('Add New Contact'), @@ -58,8 +58,10 @@ class Widget /** * Return Find People widget + * + * @return string HTML code respresenting "People Widget" */ - public static function findPeople() + public static function findPeople(): string { $global_dir = Search::getGlobalDirectory(); @@ -97,7 +99,7 @@ class Widget * * @return array Unsupported networks */ - public static function unavailableNetworks() + public static function unavailableNetworks(): array { // Always hide content from these networks $networks = [Protocol::PHANTOM, Protocol::FACEBOOK, Protocol::APPNET, Protocol::ZOT]; @@ -154,7 +156,7 @@ class Widget * @return string * @throws \Exception */ - private static function filter($type, $title, $desc, $all, $baseUrl, array $options, $selected = null) + private static function filter(string $type, string $title, string $desc, string $all, string $baseUrl, array $options, string $selected = null): string { $queryString = parse_url($baseUrl, PHP_URL_QUERY); $queryArray = []; @@ -191,7 +193,7 @@ class Widget * @return string * @throws \Exception */ - public static function groups($baseurl, $selected = '') + public static function groups(string $baseurl, string $selected = ''): string { if (!local_user()) { return ''; diff --git a/src/Profile/ProfileField/Collection/ProfileFields.php b/src/Profile/ProfileField/Collection/ProfileFields.php index 906b690fa2..f04aaa65da 100644 --- a/src/Profile/ProfileField/Collection/ProfileFields.php +++ b/src/Profile/ProfileField/Collection/ProfileFields.php @@ -43,9 +43,9 @@ class ProfileFields extends BaseCollection /** * @param callable|null $callback * @param int $flag - * @return ProfileFields + * @return ProfileFields as an extended version of BaseCollection */ - public function filter(callable $callback = null, int $flag = 0): ProfileFields + public function filter(callable $callback = null, int $flag = 0): BaseCollection { return parent::filter($callback, $flag); } From c351099c5a77d22adfb6f2753ae34dcf5f12c209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 19:17:25 +0200 Subject: [PATCH 08/37] Ops, bad type-hint here --- src/Protocol/ActivityPub/Receiver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index 05c40222b1..fe16256f07 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -1054,7 +1054,7 @@ class Receiver * @return bool with receivers (user id) * @throws \Exception */ - private static function isValidReceiverForActor(array $contact, string $tags): bool + private static function isValidReceiverForActor(array $contact, array $tags): bool { // Are we following the contact? Then this is a valid receiver if (in_array($contact['rel'], [Contact::SHARING, Contact::FRIEND])) { From dd54e52575587cede80ec60b6d4328a5eff704b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 19:21:07 +0200 Subject: [PATCH 09/37] MrPetovan brought the right one up: > Since this is depending on remote systems, the log can quickly fill with unactionable messages. --- src/Util/HTTPSignature.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Util/HTTPSignature.php b/src/Util/HTTPSignature.php index 498b356cd6..9f732acb6e 100644 --- a/src/Util/HTTPSignature.php +++ b/src/Util/HTTPSignature.php @@ -708,7 +708,6 @@ class HTTPSignature } } - // @TODO really a notice or more a warning? Logger::notice('Key could not be fetched', ['url' => $url, 'actor' => $actor]); return []; } From a587217f47e8912713cc70ea9e53aaa2cab5462c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 19:39:49 +0200 Subject: [PATCH 10/37] Fixed "Argument 4 passed to Friendica\Protocol\DFRN::processVerbs() must be of the type bool" --- src/Protocol/DFRN.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index fc72f7e371..d06e65c603 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -2074,6 +2074,9 @@ class DFRN } } + // Need to initialize variable, otherwise E_NOTICE will happen + $is_like = false; + if (!self::processVerbs($entrytype, $importer, $item, $is_like)) { Logger::info("Exiting because 'processVerbs' told us so"); return; From 2766c7d9cf6b9f592b4426297b681219538cb810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 20:01:09 +0200 Subject: [PATCH 11/37] Continued: - added more type-hints - added some missing documentation --- src/Factory/Api/Mastodon/Account.php | 4 ++-- src/Factory/Api/Twitter/Status.php | 5 ++++- src/Factory/Api/Twitter/User.php | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Factory/Api/Mastodon/Account.php b/src/Factory/Api/Mastodon/Account.php index d0c654fc21..0a647787a8 100644 --- a/src/Factory/Api/Mastodon/Account.php +++ b/src/Factory/Api/Mastodon/Account.php @@ -57,7 +57,7 @@ class Account extends BaseFactory * @throws HTTPException\InternalServerErrorException * @throws ImagickException|HTTPException\NotFoundException */ - public function createFromContactId(int $contactId, $uid = 0): \Friendica\Object\Api\Mastodon\Account + public function createFromContactId(int $contactId, int $uid = 0): \Friendica\Object\Api\Mastodon\Account { $contact = Contact::getById($contactId, ['uri-id']); if (empty($contact)) { @@ -74,7 +74,7 @@ class Account extends BaseFactory * @throws HTTPException\InternalServerErrorException * @throws ImagickException|HTTPException\NotFoundException */ - public function createFromUriId(int $contactUriId, $uid = 0): \Friendica\Object\Api\Mastodon\Account + public function createFromUriId(int $contactUriId, int $uid = 0): \Friendica\Object\Api\Mastodon\Account { $account = DBA::selectFirst('account-user-view', [], ['uri-id' => $contactUriId, 'uid' => [0, $uid]], ['order' => ['id' => true]]); if (empty($account)) { diff --git a/src/Factory/Api/Twitter/Status.php b/src/Factory/Api/Twitter/Status.php index ed138e2bdb..123fd3dcf0 100644 --- a/src/Factory/Api/Twitter/Status.php +++ b/src/Factory/Api/Twitter/Status.php @@ -70,6 +70,7 @@ class Status extends BaseFactory /** * @param int $uriId Uri-ID of the item * @param int $uid Item user + * @param bool $include_entities Whether to include entities * * @return \Friendica\Object\Api\Twitter\Status * @throws HTTPException\InternalServerErrorException @@ -90,12 +91,13 @@ class Status extends BaseFactory /** * @param int $uriId Uri-ID of the item * @param int $uid Item user + * @param bool $include_entities Whether to include entities * * @return \Friendica\Object\Api\Twitter\Status * @throws HTTPException\InternalServerErrorException * @throws ImagickException|HTTPException\NotFoundException */ - public function createFromUriId(int $uriId, $uid = 0, $include_entities = false): \Friendica\Object\Api\Twitter\Status + public function createFromUriId(int $uriId, int $uid = 0, bool $include_entities = false): \Friendica\Object\Api\Twitter\Status { $fields = ['parent-uri-id', 'uri-id', 'uid', 'author-id', 'author-link', 'author-network', 'owner-id', 'causer-id', 'starred', 'app', 'title', 'body', 'raw-body', 'created', 'network','post-reason', 'language', 'gravity', @@ -110,6 +112,7 @@ class Status extends BaseFactory /** * @param array $item item array * @param int $uid Item user + * @param bool $include_entities Whether to include entities * * @return \Friendica\Object\Api\Twitter\Status * @throws HTTPException\InternalServerErrorException diff --git a/src/Factory/Api/Twitter/User.php b/src/Factory/Api/Twitter/User.php index 6dd19ede3a..f7040cefa9 100644 --- a/src/Factory/Api/Twitter/User.php +++ b/src/Factory/Api/Twitter/User.php @@ -51,7 +51,7 @@ class User extends BaseFactory * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public function createFromContactId(int $contactId, $uid = 0, $skip_status = true, $include_user_entities = true) + public function createFromContactId(int $contactId, int $uid = 0, bool $skip_status = true, bool $include_user_entities = true) { $cdata = Contact::getPublicAndUserContactID($contactId, $uid); if (!empty($cdata)) { @@ -78,7 +78,7 @@ class User extends BaseFactory return new \Friendica\Object\Api\Twitter\User($publicContact, $apcontact, $userContact, $status, $include_user_entities); } - public function createFromUserId(int $uid, $skip_status = true, $include_user_entities = true) + public function createFromUserId(int $uid, bool $skip_status = true, bool $include_user_entities = true) { return $this->createFromContactId(Contact::getPublicIdByUserId($uid), $uid, $skip_status, $include_user_entities); } From 7560dccc088ff15980dcdf7f6db09b38980bd3d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 20:17:04 +0200 Subject: [PATCH 12/37] Added again more type-hints --- src/Model/Contact.php | 61 ++++++++++++++++++++-------------------- src/Module/Directory.php | 2 +- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 3ed2785cfa..aea3faf3cd 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -119,7 +119,7 @@ class Contact * @return array * @throws \Exception */ - public static function selectToArray(array $fields = [], array $condition = [], array $params = []) + public static function selectToArray(array $fields = [], array $condition = [], array $params = []): array { return DBA::selectToArray('contact', $fields, $condition, $params); } @@ -131,7 +131,7 @@ class Contact * @return array * @throws \Exception */ - public static function selectFirst(array $fields = [], array $condition = [], array $params = []) + public static function selectFirst(array $fields = [], array $condition = [], array $params = []): array { $contact = DBA::selectFirst('contact', $fields, $condition, $params); @@ -148,7 +148,7 @@ class Contact * @return int id of the created contact * @throws \Exception */ - public static function insert(array $fields, int $duplicate_mode = Database::INSERT_DEFAULT) + public static function insert(array $fields, int $duplicate_mode = Database::INSERT_DEFAULT): int { if (!empty($fields['baseurl']) && empty($fields['gsid'])) { $fields['gsid'] = GServer::getID($fields['baseurl'], true); @@ -187,6 +187,7 @@ class Contact * * @return boolean was the update successfull? * @throws \Exception + * @todo Let's get rid of boolean type of $old_fields */ public static function update(array $fields, array $condition, $old_fields = []) { @@ -204,7 +205,7 @@ class Contact * @return array|boolean Contact record if it exists, false otherwise * @throws \Exception */ - public static function getById($id, $fields = []) + public static function getById(int $id, array $fields = []) { return DBA::selectFirst('contact', $fields, ['id' => $id]); } @@ -217,7 +218,7 @@ class Contact * @return array|boolean Contact record if it exists, false otherwise * @throws \Exception */ - public static function getByUriId($uri_id, $fields = []) + public static function getByUriId(int $uri_id, array $fields = []) { return DBA::selectFirst('contact', $fields, ['uri-id' => $uri_id], ['order' => ['uid']]); } @@ -231,7 +232,7 @@ class Contact * @param integer $uid User ID of the contact * @return array contact array */ - public static function getByURL(string $url, $update = null, array $fields = [], int $uid = 0) + public static function getByURL(string $url, $update = null, array $fields = [], int $uid = 0): array { if ($update || is_null($update)) { $cid = self::getIdForURL($url, $uid, $update); @@ -302,7 +303,7 @@ class Contact * @param array $fields Field list * @return array contact array */ - public static function getByURLForUser(string $url, int $uid = 0, $update = false, array $fields = []) + public static function getByURLForUser(string $url, int $uid = 0, $update = false, array $fields = []): array { if ($uid != 0) { $contact = self::getByURL($url, $update, $fields, $uid); @@ -333,7 +334,7 @@ class Contact * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function isFollower($cid, $uid) + public static function isFollower(int $cid, int $uid): bool { if (Contact\User::isBlocked($cid, $uid)) { return false; @@ -358,7 +359,7 @@ class Contact * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function isFollowerByURL($url, $uid) + public static function isFollowerByURL(string $url, uid $uid): bool { $cid = self::getIdForURL($url, $uid); @@ -370,16 +371,16 @@ class Contact } /** - * Tests if the given user follow the given contact + * Tests if the given user shares with the given contact * * @param int $cid Either public contact id or user's contact id * @param int $uid User ID * - * @return boolean is the contact url being followed? + * @return boolean is the contact sharing with given user? * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function isSharing($cid, $uid) + public static function isSharing(int $cid, int $uid): bool { if (Contact\User::isBlocked($cid, $uid)) { return false; @@ -404,7 +405,7 @@ class Contact * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function isSharingByURL($url, $uid) + public static function isSharingByURL(string $url, int $uid): bool { $cid = self::getIdForURL($url, $uid); @@ -425,7 +426,7 @@ class Contact * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function getBasepath($url, $dont_update = false) + public static function getBasepath(string $url, bool $dont_update = false): string { $contact = DBA::selectFirst('contact', ['id', 'baseurl'], ['uid' => 0, 'nurl' => Strings::normaliseLink($url)]); if (!DBA::isResult($contact)) { @@ -459,7 +460,7 @@ class Contact * * @return boolean Is it the same server? */ - public static function isLocal($url) + public static function isLocal(string $url): bool { if (!parse_url($url, PHP_URL_SCHEME)) { $addr_parts = explode('@', $url); @@ -476,7 +477,7 @@ class Contact * * @return boolean Is it the same server? */ - public static function isLocalById(int $cid) + public static function isLocalById(int $cid): bool { $contact = DBA::selectFirst('contact', ['url', 'baseurl'], ['id' => $cid]); if (!DBA::isResult($contact)) { @@ -500,7 +501,7 @@ class Contact * @return integer|boolean Public contact id for given user id * @throws \Exception */ - public static function getPublicIdByUserId($uid) + public static function getPublicIdByUserId(int $uid) { $self = DBA::selectFirst('contact', ['url'], ['self' => true, 'uid' => $uid]); if (!DBA::isResult($self)) { @@ -519,7 +520,7 @@ class Contact * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function getPublicAndUserContactID($cid, $uid) + public static function getPublicAndUserContactID(int $cid, int $uid): array { // We have to use the legacy function as long as the post update hasn't finished if (DI::config()->get('system', 'post_update_version') < 1427) { @@ -560,7 +561,7 @@ class Contact * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function legacyGetPublicAndUserContactID($cid, $uid) + private static function legacyGetPublicAndUserContactID(int $cid, int $uid): array { if (empty($uid) || empty($cid)) { return []; @@ -2614,7 +2615,7 @@ class Contact * @throws HTTPException\NotFoundException * @throws \ImagickException */ - public static function createFromProbeForUser(int $uid, $url, $network = '') + public static function createFromProbeForUser(int $uid, string $url, string $network = ''): array { $result = ['cid' => -1, 'success' => false, 'message' => '']; @@ -2803,7 +2804,7 @@ class Contact * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function addRelationship(array $importer, array $contact, array $datarray, $sharing = false, $note = '') + public static function addRelationship(array $importer, array $contact, array $datarray, bool $sharing = false, string $note = '') { // Should always be set if (empty($datarray['author-id'])) { @@ -3030,7 +3031,7 @@ class Contact * @return array * @throws \Exception */ - public static function pruneUnavailable(array $contact_ids) + public static function pruneUnavailable(array $contact_ids): array { if (empty($contact_ids)) { return []; @@ -3058,7 +3059,7 @@ class Contact * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function magicLink($contact_url, $url = '') + public static function magicLink(string $contact_url, string $url = ''): string { if (!Session::isAuthenticated()) { return $url ?: $contact_url; // Equivalent to: ($url != '') ? $url : $contact_url; @@ -3085,7 +3086,7 @@ class Contact * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function magicLinkById($cid, $url = '') + public static function magicLinkById(int $cid, string $url = ''): string { $contact = DBA::selectFirst('contact', ['id', 'network', 'url', 'uid'], ['id' => $cid]); @@ -3102,7 +3103,7 @@ class Contact * @throws HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function magicLinkByContact($contact, $url = '') + public static function magicLinkByContact(array $contact, string $url = ''): string { $destination = $url ?: $contact['url']; // Equivalent to ($url != '') ? $url : $contact['url']; @@ -3143,7 +3144,7 @@ class Contact * * @return boolean "true" if it is a forum */ - public static function isForum($contactid) + public static function isForum(int $contactid): bool { $fields = ['contact-type']; $condition = ['id' => $contactid]; @@ -3162,7 +3163,7 @@ class Contact * @param array $contact * @return bool */ - public static function canReceivePrivateMessages(array $contact) + public static function canReceivePrivateMessages(array $contact): bool { $protocol = $contact['network'] ?? $contact['protocol'] ?? Protocol::PHANTOM; $self = $contact['self'] ?? false; @@ -3180,7 +3181,7 @@ class Contact * @return array with search results * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function searchByName(string $search, string $mode = '', int $uid = 0) + public static function searchByName(string $search, string $mode = '', int $uid = 0): array { if (empty($search)) { return []; @@ -3223,7 +3224,7 @@ class Contact * @param array $urls * @return array result "count", "added" and "updated" */ - public static function addByUrls(array $urls) + public static function addByUrls(array $urls): array { $added = 0; $updated = 0; @@ -3256,7 +3257,7 @@ class Contact * @return array The profile array * @throws Exception */ - public static function getRandomContact() + public static function getRandomContact(): array { $contact = DBA::selectFirst('contact', ['id', 'network', 'url', 'uid'], [ "`uid` = ? AND `network` = ? AND NOT `failed` AND `last-item` > ?", diff --git a/src/Module/Directory.php b/src/Module/Directory.php index b79e7b1495..d9cad8d623 100644 --- a/src/Module/Directory.php +++ b/src/Module/Directory.php @@ -112,7 +112,7 @@ class Directory extends BaseModule * * @throws \Exception */ - public static function formatEntry(array $contact, $photo_size = 'photo') + public static function formatEntry(array $contact, string $photo_size = 'photo'): array { $itemurl = (($contact['addr'] != "") ? $contact['addr'] : $contact['url']); From 4e53666c704cd4cb31004d9efc442a9e76d2a827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 20:33:10 +0200 Subject: [PATCH 13/37] Added more type-hints --- src/Database/DBA.php | 14 +++++++------- src/Database/Database.php | 16 ++++++++-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Database/DBA.php b/src/Database/DBA.php index a0eb1c3ece..2cafc4e0a6 100644 --- a/src/Database/DBA.php +++ b/src/Database/DBA.php @@ -512,7 +512,7 @@ class DBA * $count = DBA::count($table, $condition); * @throws \Exception */ - public static function count($table, array $condition = [], array $params = []) + public static function count($table, array $condition = [], array $params = []): int { return DI::dba()->count($table, $condition, $params); } @@ -771,7 +771,7 @@ class DBA * * @return array Data array */ - public static function toArray($stmt, $do_close = true, int $count = 0) + public static function toArray($stmt, $do_close = true, int $count = 0): array { return DI::dba()->toArray($stmt, $do_close, $count); } @@ -783,7 +783,7 @@ class DBA * @param array $fields * @return array casted fields */ - public static function castFields(string $table, array $fields) + public static function castFields(string $table, array $fields): array { return DI::dba()->castFields($table, $fields); } @@ -793,7 +793,7 @@ class DBA * * @return string Error number (0 if no error) */ - public static function errorNo() + public static function errorNo(): int { return DI::dba()->errorNo(); } @@ -803,7 +803,7 @@ class DBA * * @return string Error message ('' if no error) */ - public static function errorMessage() + public static function errorMessage(): string { return DI::dba()->errorMessage(); } @@ -814,7 +814,7 @@ class DBA * @param object $stmt statement object * @return boolean was the close successful? */ - public static function close($stmt) + public static function close($stmt): bool { return DI::dba()->close($stmt); } @@ -827,7 +827,7 @@ class DBA * 'amount' => Number of concurrent database processes * @throws \Exception */ - public static function processlist() + public static function processlist(): array { return DI::dba()->processlist(); } diff --git a/src/Database/Database.php b/src/Database/Database.php index 671425f9d1..7edbdf2a2c 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -541,7 +541,7 @@ class Database if (!$retval = $this->connection->query($this->replaceParameters($sql, $args))) { $errorInfo = $this->connection->errorInfo(); $this->error = $errorInfo[2]; - $this->errorno = $errorInfo[1]; + $this->errorno = (int) $errorInfo[1]; $retval = false; $is_error = true; break; @@ -554,7 +554,7 @@ class Database if (!$stmt = $this->connection->prepare($sql)) { $errorInfo = $this->connection->errorInfo(); $this->error = $errorInfo[2]; - $this->errorno = $errorInfo[1]; + $this->errorno = (int) $errorInfo[1]; $retval = false; $is_error = true; break; @@ -574,7 +574,7 @@ class Database if (!$stmt->execute()) { $errorInfo = $stmt->errorInfo(); $this->error = $errorInfo[2]; - $this->errorno = $errorInfo[1]; + $this->errorno = (int) $errorInfo[1]; $retval = false; $is_error = true; } else { @@ -709,7 +709,7 @@ class Database } $this->error = $error; - $this->errorno = $errorno; + $this->errorno = (int) $errorno; } $this->profiler->stopRecording(); @@ -1541,7 +1541,7 @@ class Database * * @return array Data array */ - public function toArray($stmt, $do_close = true, int $count = 0) + public function toArray($stmt, bool $do_close = true, int $count = 0): array { if (is_bool($stmt)) { return []; @@ -1632,7 +1632,7 @@ class Database * * @return string Error number (0 if no error) */ - public function errorNo() + public function errorNo(): int { return $this->errorno; } @@ -1654,7 +1654,7 @@ class Database * * @return boolean was the close successful? */ - public function close($stmt) + public function close($stmt): bool { $this->profiler->startRecording('database'); @@ -1696,7 +1696,7 @@ class Database * 'amount' => Number of concurrent database processes * @throws \Exception */ - public function processlist() + public function processlist(): array { $ret = $this->p("SHOW PROCESSLIST"); $data = $this->toArray($ret); From 33768ea1c6b9b37859334e9364ddc5ea9c9a14ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 20:42:40 +0200 Subject: [PATCH 14/37] Some fixes: - $gsid's default value cannot sadly be 0, it now must be null to allow some code work - added some more type-hints - documented a bit more --- src/Content/ContactSelector.php | 14 +++++++++----- src/Database/DBA.php | 4 ++-- src/Model/Attach.php | 2 +- src/Model/Contact.php | 4 ++-- src/Model/GServer.php | 2 +- src/Model/Photo.php | 2 +- src/Network/Probe.php | 2 +- src/Util/Strings.php | 6 ++++-- 8 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/Content/ContactSelector.php b/src/Content/ContactSelector.php index fd574889e6..db7ad80ca6 100644 --- a/src/Content/ContactSelector.php +++ b/src/Content/ContactSelector.php @@ -111,14 +111,16 @@ class ContactSelector } /** + * Determines network name + * * @param string $network network of the contact * @param string $profile optional, default empty * @param string $protocol (Optional) Protocol that is used for the transmission - * @param int $gsid ??? (@TODO) + * @param int $gsid Server id * @return string * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function networkToName(string $network, string $profile = '', string $protocol = '', int $gsid = 0): string + public static function networkToName(string $network, string $profile = '', string $protocol = '', int $gsid = null): string { $nets = [ Protocol::DFRN => DI::l10n()->t('DFRN'), @@ -180,13 +182,15 @@ class ContactSelector } /** + * Determines network's icon name + * * @param string $network network * @param string $profile optional, default empty - * @param int $gsid ??? (@TODO) - * @return string + * @param int $gsid Server id + * @return string Name for network icon * @throws \Exception */ - public static function networkToIcon(string $network, string $profile = "", int $gsid = 0): string + public static function networkToIcon(string $network, string $profile = "", int $gsid = null): string { $nets = [ Protocol::DFRN => 'friendica', diff --git a/src/Database/DBA.php b/src/Database/DBA.php index 2cafc4e0a6..d62edf6ce1 100644 --- a/src/Database/DBA.php +++ b/src/Database/DBA.php @@ -427,7 +427,7 @@ class DBA * @return boolean was the update successfull? * @throws \Exception */ - public static function update($table, $fields, $condition, $old_fields = [], $params = []) + public static function update($table, array $fields, array $condition, $old_fields = [], array $params = []) { return DI::dba()->update($table, $fields, $condition, $old_fields, $params); } @@ -443,7 +443,7 @@ class DBA * @throws \Exception * @see self::select */ - public static function selectFirst($table, array $fields = [], array $condition = [], $params = []) + public static function selectFirst($table, array $fields = [], array $condition = [], array $params = []) { return DI::dba()->selectFirst($table, $fields, $condition, $params); } diff --git a/src/Model/Attach.php b/src/Model/Attach.php index 9009126868..91970bfc62 100644 --- a/src/Model/Attach.php +++ b/src/Model/Attach.php @@ -102,7 +102,7 @@ class Attach * @return boolean * @throws \Exception */ - public static function exists(array $conditions) + public static function exists(array $conditions): bool { return DBA::exists('attach', $conditions); } diff --git a/src/Model/Contact.php b/src/Model/Contact.php index aea3faf3cd..949db50352 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -128,10 +128,10 @@ class Contact * @param array $fields Array of selected fields, empty for all * @param array $condition Array of fields for condition * @param array $params Array of several parameters - * @return array + * @return array|bool * @throws \Exception */ - public static function selectFirst(array $fields = [], array $condition = [], array $params = []): array + public static function selectFirst(array $fields = [], array $condition = [], array $params = []) { $contact = DBA::selectFirst('contact', $fields, $condition, $params); diff --git a/src/Model/GServer.php b/src/Model/GServer.php index c0e4899923..ff22730e4e 100644 --- a/src/Model/GServer.php +++ b/src/Model/GServer.php @@ -2054,7 +2054,7 @@ class GServer * @return int * @throws Exception */ - public static function getProtocol(int $gsid) + public static function getProtocol(int $gsid): int { if (empty($gsid)) { return null; diff --git a/src/Model/Photo.php b/src/Model/Photo.php index d9e6f7cade..fd387e56e8 100644 --- a/src/Model/Photo.php +++ b/src/Model/Photo.php @@ -110,7 +110,7 @@ class Photo * @throws \Exception * @see \Friendica\Database\DBA::select */ - public static function getPhotosForUser($uid, $resourceid, array $conditions = [], array $params = []) + public static function getPhotosForUser(int $uid, string $resourceid, array $conditions = [], array $params = []) { $conditions["resource-id"] = $resourceid; $conditions["uid"] = $uid; diff --git a/src/Network/Probe.php b/src/Network/Probe.php index c5ecf96ed3..d8a1593313 100644 --- a/src/Network/Probe.php +++ b/src/Network/Probe.php @@ -1445,7 +1445,7 @@ class Probe * @return array|bool OStatus data or "false" on error or "true" on short mode * @throws HTTPException\InternalServerErrorException */ - private static function ostatus($webfinger, $short = false) + private static function ostatus(array $webfinger, bool $short = false) { $data = []; diff --git a/src/Util/Strings.php b/src/Util/Strings.php index 8666d30c18..d2555132a0 100644 --- a/src/Util/Strings.php +++ b/src/Util/Strings.php @@ -165,7 +165,7 @@ class Strings * @return string Formatted network name * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function formatNetworkName($network, $url = '') + public static function formatNetworkName(string $network, string $url = ''): string { if ($network != '') { if ($url != '') { @@ -176,6 +176,8 @@ class Strings return $network_name; } + + return ''; } /** @@ -187,7 +189,7 @@ class Strings * * @return string Transformed string. */ - public static function deindent($text, $chr = "[\t ]", $count = NULL) + public static function deindent(string $text, string $chr = "[\t ]", int $count = null) { $lines = explode("\n", $text); From 5c9ce790bfb0da7dcfe7a8332613b63f6eb7fac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 20:47:59 +0200 Subject: [PATCH 15/37] Fixed: - $object_data['actor'] can be null, but Receiver::getReceivers()'s 2nd parameter expect it to be string --- src/Protocol/ActivityPub/Receiver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index fe16256f07..e8c9ac8f7b 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -1768,7 +1768,7 @@ class Receiver $object_data['question'] = self::processQuestion($object); } - $receiverdata = self::getReceivers($object, $object_data['actor'], $object_data['tags'], true); + $receiverdata = self::getReceivers($object, $object_data['actor'] ?? '', $object_data['tags'], true); $receivers = $reception_types = []; foreach ($receiverdata as $key => $data) { $receivers[$key] = $data['uid']; From 45b5f67bcae597bf79d999f4c8b2c08b46a76ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 20:58:24 +0200 Subject: [PATCH 16/37] Fix for non-existing record system.mobile_theme in config table --- src/Model/Profile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/Profile.php b/src/Model/Profile.php index aa027a860b..7a65727702 100644 --- a/src/Model/Profile.php +++ b/src/Model/Profile.php @@ -237,7 +237,7 @@ class Profile if (!local_user()) { $a->setCurrentTheme($profile['theme']); - $a->setCurrentMobileTheme(DI::pConfig()->get($a->getProfileOwner(), 'system', 'mobile_theme')); + $a->setCurrentMobileTheme(DI::pConfig()->get($a->getProfileOwner(), 'system', 'mobile_theme') ?? ''); } /* From e484b6d6dc97b802a2641d1e9974a9a40f3fdcd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 21:57:02 +0200 Subject: [PATCH 17/37] Continued: - added more type-hints - added some documentation - Contact::getAccountType() should only process string, not null --- src/Model/Contact.php | 2 +- src/Model/User.php | 68 ++++++++++++++++++++-------------------- src/Module/Directory.php | 2 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 949db50352..51e5cf1510 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1527,7 +1527,7 @@ class Contact * @param int $type type of contact or account * @return string */ - public static function getAccountType(int $type) + public static function getAccountType(int $type): string { switch ($type) { case self::TYPE_ORGANISATION: diff --git a/src/Model/User.php b/src/Model/User.php index 71e2c8a812..9701a57d72 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -134,7 +134,7 @@ class User * * @return array system account */ - public static function getSystemAccount() + public static function getSystemAccount(): array { $system = Contact::selectFirst([], ['self' => true, 'uid' => 0]); if (!DBA::isResult($system)) { @@ -244,7 +244,7 @@ class User * * @return string actor account name */ - public static function getActorName() + public static function getActorName(): string { $system_actor_name = DI::config()->get('system', 'actor_name'); if (!empty($system_actor_name)) { @@ -278,7 +278,7 @@ class User * @return boolean * @throws Exception */ - public static function exists($uid) + public static function exists(int $uid): bool { return DBA::exists('user', ['uid' => $uid]); } @@ -289,7 +289,7 @@ class User * @return array|boolean User record if it exists, false otherwise * @throws Exception */ - public static function getById($uid, array $fields = []) + public static function getById(int $uid, array $fields = []) { return !empty($uid) ? DBA::selectFirst('user', $fields, ['uid' => $uid]) : []; } @@ -321,7 +321,7 @@ class User * @return array|boolean User record if it exists, false otherwise * @throws Exception */ - public static function getByNickname($nickname, array $fields = []) + public static function getByNickname(string $nickname, array $fields = []) { return DBA::selectFirst('user', $fields, ['nickname' => $nickname]); } @@ -334,7 +334,7 @@ class User * @return integer user id * @throws Exception */ - public static function getIdForURL(string $url) + public static function getIdForURL(string $url): int { // Avoid database queries when the local node hostname isn't even part of the url. if (!Contact::isLocal($url)) { @@ -380,7 +380,7 @@ class User * @param array $fields * @return array user */ - public static function getFirstAdmin(array $fields = []) + public static function getFirstAdmin(array $fields = []) : array { if (!empty(DI::config()->get('config', 'admin_nickname'))) { return self::getByNickname(DI::config()->get('config', 'admin_nickname'), $fields); @@ -469,7 +469,7 @@ class User * @return boolean|array * @throws Exception */ - public static function getOwnerDataByNick($nick) + public static function getOwnerDataByNick(int $nick) { $user = DBA::selectFirst('user', ['uid'], ['nickname' => $nick]); @@ -488,7 +488,7 @@ class User * @return int group id * @throws Exception */ - public static function getDefaultGroup($uid) + public static function getDefaultGroup(int $uid): int { $user = DBA::selectFirst('user', ['def_gid'], ['uid' => $uid]); if (DBA::isResult($user)) { @@ -512,7 +512,7 @@ class User * @throws HTTPException\ForbiddenException * @throws HTTPException\NotFoundException */ - public static function getIdFromPasswordAuthentication($user_info, $password, $third_party = false) + public static function getIdFromPasswordAuthentication($user_info, string $password, bool $third_party = false) { // Addons registered with the "authenticate" hook may create the user on the // fly. `getAuthenticationInfo` will fail if the user doesn't exist yet. If @@ -580,7 +580,7 @@ class User * @return int User Id if authentication is successful * @throws HTTPException\ForbiddenException */ - public static function getIdFromAuthenticateHooks($username, $password) + public static function getIdFromAuthenticateHooks(string $username, string $password): int { $addon_auth = [ 'username' => $username, @@ -613,7 +613,7 @@ class User * - User array with at least the uid and the hashed password * * @param mixed $user_info - * @return array + * @return array|null Null if not found/determined * @throws HTTPException\NotFoundException */ public static function getAuthenticationInfo($user_info) @@ -671,7 +671,7 @@ class User * @return string * @throws Exception */ - public static function generateNewPassword() + public static function generateNewPassword(): string { return ucfirst(Strings::getRandomName(8)) . random_int(1000, 9999); } @@ -683,7 +683,7 @@ class User * @return bool * @throws Exception */ - public static function isPasswordExposed($password) + public static function isPasswordExposed(string $password): bool { $cache = new CacheItemPool(); $cache->changeConfig([ @@ -712,7 +712,7 @@ class User * @param string $password * @return string */ - private static function hashPasswordLegacy($password) + private static function hashPasswordLegacy(string $password): string { return hash('whirlpool', $password); } @@ -724,7 +724,7 @@ class User * @return string * @throws Exception */ - public static function hashPassword($password) + public static function hashPassword(string $password): string { if (!trim($password)) { throw new Exception(DI::l10n()->t('Password can\'t be empty')); @@ -741,7 +741,7 @@ class User * @return bool * @throws Exception */ - public static function updatePassword($uid, $password) + public static function updatePassword(int $uid, string $password): bool { $password = trim($password); @@ -771,7 +771,7 @@ class User * @return bool * @throws Exception */ - private static function updatePasswordHashed($uid, $pasword_hashed) + private static function updatePasswordHashed(int $uid, string $pasword_hashed): bool { $fields = [ 'password' => $pasword_hashed, @@ -792,7 +792,7 @@ class User * @param string $nickname The nickname that should be checked * @return boolean True is the nickname is blocked on the node */ - public static function isNicknameBlocked($nickname) + public static function isNicknameBlocked(string $nickname): bool { $forbidden_nicknames = DI::config()->get('system', 'forbidden_nicknames', ''); if (!empty($forbidden_nicknames)) { @@ -829,7 +829,7 @@ class User * @return string avatar link * @throws Exception */ - public static function getAvatarUrl(array $user, string $size = ''):string + public static function getAvatarUrl(array $user, string $size = ''): string { if (empty($user['nickname'])) { DI::logger()->warning('Missing user nickname key', ['trace' => System::callstack(20)]); @@ -871,7 +871,7 @@ class User * @return string banner link * @throws Exception */ - public static function getBannerUrl(array $user):string + public static function getBannerUrl(array $user): string { if (empty($user['nickname'])) { DI::logger()->warning('Missing user nickname key', ['trace' => System::callstack(20)]); @@ -913,7 +913,7 @@ class User * @throws ImagickException * @throws Exception */ - public static function create(array $data) + public static function create(array $data): array { $return = ['user' => null, 'password' => '']; @@ -1255,7 +1255,7 @@ class User * @throws Exception */ - public static function block(int $uid, bool $block = true) + public static function block(int $uid, bool $block = true): bool { return DBA::update('user', ['blocked' => $block], ['uid' => $uid]); } @@ -1270,7 +1270,7 @@ class User * @throws HTTPException\InternalServerErrorException * @throws Exception */ - public static function allow(string $hash) + public static function allow(string $hash): bool { $register = Register::getByHash($hash); if (!DBA::isResult($register)) { @@ -1316,7 +1316,7 @@ class User * @return bool True, if the deny was successfull * @throws Exception */ - public static function deny(string $hash) + public static function deny(string $hash): bool { $register = Register::getByHash($hash); if (!DBA::isResult($register)) { @@ -1348,7 +1348,7 @@ class User * @throws ErrorException * @throws ImagickException */ - public static function createMinimal(string $name, string $email, string $nick, string $lang = L10n::DEFAULT) + public static function createMinimal(string $name, string $email, string $nick, string $lang = L10n::DEFAULT): bool { if (empty($name) || empty($email) || @@ -1418,7 +1418,7 @@ class User * @return NULL|boolean from notification() and email() inherited * @throws HTTPException\InternalServerErrorException */ - public static function sendRegisterPendingEmail($user, $sitename, $siteurl, $password) + public static function sendRegisterPendingEmail(array $user, string $sitename, string $siteurl, string $password) { $body = Strings::deindent(DI::l10n()->t( ' @@ -1461,7 +1461,7 @@ class User * @return NULL|boolean from notification() and email() inherited * @throws HTTPException\InternalServerErrorException */ - public static function sendRegisterOpenEmail(L10n $l10n, $user, $sitename, $siteurl, $password) + public static function sendRegisterOpenEmail(L10n $l10n, array $user, string $sitename, string $siteurl, string $password) { $preamble = Strings::deindent($l10n->t( ' @@ -1520,7 +1520,7 @@ class User * @return bool * @throws HTTPException\InternalServerErrorException */ - public static function remove(int $uid) + public static function remove(int $uid): bool { if (empty($uid)) { return false; @@ -1574,7 +1574,7 @@ class User * ] * @throws Exception */ - public static function identities($uid) + public static function identities(int $uid): array { if (empty($uid)) { return []; @@ -1646,7 +1646,7 @@ class User * @param int $uid * @return bool */ - public static function hasIdentities(int $uid):bool + public static function hasIdentities(int $uid): bool { if (empty($uid)) { return false; @@ -1679,7 +1679,7 @@ class User * * @throws Exception */ - public static function getStatistics() + public static function getStatistics(): array { $statistics = [ 'total_users' => 0, @@ -1732,10 +1732,10 @@ class User * @param string $order Order of the user list (Default is 'contact.name') * @param bool $descending Order direction (Default is ascending) * - * @return array The list of the users + * @return array|bool The list of the users * @throws Exception */ - public static function getList($start = 0, $count = Pager::ITEMS_PER_PAGE, $type = 'all', $order = 'name', bool $descending = false) + public static function getList(int $start = 0, int $count = Pager::ITEMS_PER_PAGE, string $type = 'all', string $order = 'name', bool $descending = false) { $param = ['limit' => [$start, $count], 'order' => [$order => $descending]]; $condition = []; diff --git a/src/Module/Directory.php b/src/Module/Directory.php index d9cad8d623..db88bf9fcd 100644 --- a/src/Module/Directory.php +++ b/src/Module/Directory.php @@ -166,7 +166,7 @@ class Directory extends BaseModule 'img_hover' => $contact['name'], 'name' => $contact['name'], 'details' => $details, - 'account_type' => Model\Contact::getAccountType($contact['contact-type']), + 'account_type' => (!empty($contact['contact-type']) ? Model\Contact::getAccountType($contact['contact-type']) : ''), 'profile' => $profile, 'location' => $location_e, 'tags' => $contact['pub_keywords'], From f7c1eaa85872291a4cd7614e1a191edab5346507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 22:12:38 +0200 Subject: [PATCH 18/37] Continued: - added type-hints - removed out-dated documentation - added some missing documentation --- src/Core/Worker.php | 49 +++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/Core/Worker.php b/src/Core/Worker.php index bc52843e69..726dade8cf 100644 --- a/src/Core/Worker.php +++ b/src/Core/Worker.php @@ -60,7 +60,7 @@ class Worker * @return void * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function processQueue($run_cron, Process $process) + public static function processQueue(bool $run_cron, Process $process) { self::$up_start = microtime(true); @@ -169,7 +169,7 @@ class Worker * * @return boolean */ - public static function isReady() + public static function isReady(): bool { // Count active workers and compare them with a maximum value that depends on the load if (self::tooMuchWorkers()) { @@ -204,7 +204,7 @@ class Worker * @return boolean Returns "true" if tasks are existing * @throws \Exception */ - public static function entriesExists() + public static function entriesExists(): bool { $stamp = (float)microtime(true); $exists = DBA::exists('workerqueue', ["NOT `done` AND `pid` = 0 AND `next_try` < ?", DateTimeFormat::utcNow()]); @@ -218,7 +218,7 @@ class Worker * @return integer Number of deferred entries in the worker queue * @throws \Exception */ - private static function deferredEntries() + private static function deferredEntries(): int { $stamp = (float)microtime(true); $count = DBA::count('workerqueue', ["NOT `done` AND `pid` = 0 AND `retrial` > ?", 0]); @@ -233,7 +233,7 @@ class Worker * @return integer Number of non executed entries in the worker queue * @throws \Exception */ - private static function totalEntries() + private static function totalEntries(): int { $stamp = (float)microtime(true); $count = DBA::count('workerqueue', ['done' => false, 'pid' => 0]); @@ -248,7 +248,7 @@ class Worker * @return integer Number of active worker processes * @throws \Exception */ - private static function highestPriority() + private static function highestPriority(): int { $stamp = (float)microtime(true); $condition = ["`pid` = 0 AND NOT `done` AND `next_try` < ?", DateTimeFormat::utcNow()]; @@ -269,7 +269,7 @@ class Worker * @return integer Is there a process running with that priority? * @throws \Exception */ - private static function processWithPriorityActive($priority) + private static function processWithPriorityActive(int $priority): int { $condition = ["`priority` <= ? AND `pid` != 0 AND NOT `done`", $priority]; return DBA::exists('workerqueue', $condition); @@ -281,7 +281,7 @@ class Worker * @param mixed $file * @return bool */ - private static function validateInclude(&$file) + private static function validateInclude(&$file): bool { $orig_file = $file; @@ -321,7 +321,7 @@ class Worker * @return boolean "true" if further processing should be stopped * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function execute($queue) + public static function execute(array $queue): bool { $mypid = getmypid(); @@ -454,7 +454,7 @@ class Worker * @return void * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function execFunction($queue, $funcname, $argv, $method_call) + private static function execFunction(array $queue, string $funcname, array $argv, bool $method_call) { $a = DI::app(); @@ -543,7 +543,7 @@ class Worker * @return bool Are more than 3/4 of the maximum connections used? * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function maxConnectionsReached() + private static function maxConnectionsReached(): bool { // Fetch the max value from the config. This is needed when the system cannot detect the correct value by itself. $max = DI::config()->get("system", "max_connections"); @@ -627,7 +627,7 @@ class Worker * @return bool Are there too much workers running? * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function tooMuchWorkers() + private static function tooMuchWorkers(): bool { $queues = DI::config()->get("system", "worker_queues", 10); @@ -751,7 +751,7 @@ class Worker * @return integer Number of active worker processes * @throws \Exception */ - private static function activeWorkers() + private static function activeWorkers(): int { $stamp = (float)microtime(true); $count = DI::process()->countCommand('Worker.php'); @@ -766,7 +766,7 @@ class Worker * @return array List of worker process ids * @throws \Exception */ - private static function getWorkerPIDList() + private static function getWorkerPIDList(): array { $ids = []; $stamp = (float)microtime(true); @@ -790,7 +790,7 @@ class Worker * @return array waiting workerqueue jobs * @throws \Exception */ - private static function getWaitingJobForPID() + private static function getWaitingJobForPID(): array { $stamp = (float)microtime(true); $r = DBA::select('workerqueue', [], ['pid' => getmypid(), 'done' => false]); @@ -809,7 +809,7 @@ class Worker * @return array array with next jobs * @throws \Exception */ - private static function nextProcess(int $limit) + private static function nextProcess(int $limit): array { $priority = self::nextPriority(); if (empty($priority)) { @@ -844,7 +844,7 @@ class Worker /** * Returns the priority of the next workerqueue job * - * @return string priority + * @return string|bool priority or FALSE on failure * @throws \Exception */ private static function nextPriority() @@ -915,7 +915,7 @@ class Worker /** * Find and claim the next worker process for us * - * @return boolean Have we found something? + * @return void * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ private static function findWorkerProcesses() @@ -993,7 +993,7 @@ class Worker * @return array worker processes * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function workerProcess() + public static function workerProcess(): array { // There can already be jobs for us in the queue. $waiting = self::getWaitingJobForPID(); @@ -1003,7 +1003,7 @@ class Worker $stamp = (float)microtime(true); if (!DI::lock()->acquire(self::LOCK_PROCESS)) { - return false; + return []; } self::$lock_duration += (microtime(true) - $stamp); @@ -1097,7 +1097,7 @@ class Worker * @return void * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function spawnWorker($do_cron = false) + public static function spawnWorker(bool $do_cron = false) { if (Worker\Daemon::isMode() && DI::config()->get('system', 'worker_fork')) { self::forkProcess($do_cron); @@ -1231,7 +1231,7 @@ class Worker return $added; } - public static function countWorkersByCommand(string $command) + public static function countWorkersByCommand(string $command): int { return DBA::count('workerqueue', ['done' => false, 'pid' => 0, 'command' => $command]); } @@ -1244,7 +1244,7 @@ class Worker * @param integer $max_level maximum retrial level * @return integer the next retrial level value */ - private static function getNextRetrial($queue, $max_level) + private static function getNextRetrial(array $queue, int $max_level): int { $created = strtotime($queue['created']); $retrial_time = time() - $created; @@ -1314,9 +1314,10 @@ class Worker /** * Check if the system is inside the defined maintenance window * + * @param bool $check_last_execution Whether check last execution * @return boolean */ - public static function isInMaintenanceWindow(bool $check_last_execution = false) + public static function isInMaintenanceWindow(bool $check_last_execution = false): bool { // Calculate the seconds of the start end end of the maintenance window $start = strtotime(DI::config()->get('system', 'maintenance_start')) % 86400; From 227bab43a8c6346b263d55b8cf739e21b30dfcf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 22:15:06 +0200 Subject: [PATCH 19/37] Ops, wrong type-hint here, must be string ($nickname can never be an integer). --- src/Model/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/User.php b/src/Model/User.php index 9701a57d72..07f2dfe8de 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -469,7 +469,7 @@ class User * @return boolean|array * @throws Exception */ - public static function getOwnerDataByNick(int $nick) + public static function getOwnerDataByNick(string $nick) { $user = DBA::selectFirst('user', ['uid'], ['nickname' => $nick]); From af8cd5ca86b330796b491bdfa29cdbb0a6bee00b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Thu, 16 Jun 2022 22:17:37 +0200 Subject: [PATCH 20/37] Worker::getWaitingJobForPID() can also return FALSE on failure ... :-( --- src/Core/Worker.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Core/Worker.php b/src/Core/Worker.php index 726dade8cf..bcd12f3294 100644 --- a/src/Core/Worker.php +++ b/src/Core/Worker.php @@ -787,10 +787,10 @@ class Worker /** * Returns waiting jobs for the current process id * - * @return array waiting workerqueue jobs + * @return array|bool waiting workerqueue jobs or FALSE on failture * @throws \Exception */ - private static function getWaitingJobForPID(): array + private static function getWaitingJobForPID() { $stamp = (float)microtime(true); $r = DBA::select('workerqueue', [], ['pid' => getmypid(), 'done' => false]); @@ -1011,7 +1011,7 @@ class Worker DI::lock()->release(self::LOCK_PROCESS); - return self::getWaitingJobForPID(); + return (self::getWaitingJobForPID() ?? []); } /** From 0c9aff8a09c288ce7fe459a32f40bc2f22f2f0e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Fri, 17 Jun 2022 09:51:11 +0200 Subject: [PATCH 21/37] Also need to declare $profile or otherwise an invocation of Receiver::getReceiverForActor() will fail. --- src/Protocol/ActivityPub/Receiver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index e8c9ac8f7b..be1c3b7e7c 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -880,7 +880,7 @@ class Receiver */ private static function getReceivers(array $activity, string $actor, array $tags = [], bool $fetch_unlisted = false): array { - $reply = $receivers = []; + $reply = $receivers = $profile = []; // When it is an answer, we inherite the receivers from the parent $replyto = JsonLD::fetchElement($activity, 'as:inReplyTo', '@id'); From 605e7d55b3bd6f2e229ee21b26e0b82467d88dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Fri, 17 Jun 2022 10:44:13 +0200 Subject: [PATCH 22/37] Continued: - added more type-hints - some methods in Diaspora returned void but integer was documented so I changed it to -1 to have a proper type-hint --- src/Model/APContact.php | 6 +- src/Model/FContact.php | 10 +- src/Protocol/Diaspora.php | 238 +++++++++++++++++++++----------------- 3 files changed, 142 insertions(+), 112 deletions(-) diff --git a/src/Model/APContact.php b/src/Model/APContact.php index a934848612..d6f4877407 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -48,7 +48,7 @@ class APContact * @param string $addr Address * @return array webfinger data */ - private static function fetchWebfingerData(string $addr) + private static function fetchWebfingerData(string $addr): array { $addr_parts = explode('@', $addr); if (count($addr_parts) != 2) { @@ -117,7 +117,7 @@ class APContact * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function getByURL(string $url, $update = null) + public static function getByURL(string $url, $update = null): array { if (empty($url) || Network::isUrlBlocked($url)) { Logger::info('Domain is blocked', ['url' => $url]); @@ -527,7 +527,7 @@ class APContact * @param string $url inbox url * @param boolean $shared Shared Inbox */ - private static function unarchiveInbox($url, $shared) + private static function unarchiveInbox(string $url, bool $shared) { if (empty($url)) { return; diff --git a/src/Model/FContact.php b/src/Model/FContact.php index 6812f5fd09..97b1e98efb 100644 --- a/src/Model/FContact.php +++ b/src/Model/FContact.php @@ -40,7 +40,7 @@ class FContact * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function getByURL($handle, $update = null) + public static function getByURL(string $handle, $update = null): array { $person = DBA::selectFirst('fcontact', [], ['network' => Protocol::DIASPORA, 'addr' => $handle]); if (!DBA::isResult($person)) { @@ -90,7 +90,7 @@ class FContact * @param array $arr The fcontact data * @throws \Exception */ - public static function updateFromProbeArray($arr) + public static function updateFromProbeArray(array $arr) { $uriid = ItemURI::insert(['uri' => $arr['url'], 'guid' => $arr['guid']]); @@ -122,12 +122,12 @@ class FContact * get a url (scheme://domain.tld/u/user) from a given Diaspora* * fcontact guid * - * @param mixed $fcontact_guid Hexadecimal string guid + * @param string $fcontact_guid Hexadecimal string guid * - * @return string the contact url or null + * @return string|null the contact url or null * @throws \Exception */ - public static function getUrlByGuid($fcontact_guid) + public static function getUrlByGuid(string $fcontact_guid) { Logger::info('fcontact', ['guid' => $fcontact_guid]); diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 70fd0f1f8d..36f511a6ac 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -74,7 +74,7 @@ class Diaspora * @return array of relay servers * @throws \Exception */ - public static function participantsForThread(array $item, array $contacts) + public static function participantsForThread(array $item, array $contacts): array { if (!in_array($item['private'], [Item::PUBLIC, Item::UNLISTED]) || in_array($item["verb"], [Activity::FOLLOW, Activity::TAG])) { Logger::info('Item is private or a participation request. It will not be relayed', ['guid' => $item['guid'], 'private' => $item['private'], 'verb' => $item['verb']]); @@ -114,11 +114,11 @@ class Diaspora * * @param string $envelope The magic envelope * - * @return string verified data + * @return string|bool verified data or false on error * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function verifyMagicEnvelope($envelope) + private static function verifyMagicEnvelope(string $envelope) { $basedom = XML::parseString($envelope, true); @@ -183,7 +183,7 @@ class Diaspora * * @return string encrypted data */ - private static function aesEncrypt($key, $iv, $data) + private static function aesEncrypt(string $key, string $iv, string $data): string { return openssl_encrypt($data, 'aes-256-cbc', str_pad($key, 32, "\0"), OPENSSL_RAW_DATA, str_pad($iv, 16, "\0")); } @@ -197,7 +197,7 @@ class Diaspora * * @return string decrypted data */ - private static function aesDecrypt($key, $iv, $encrypted) + private static function aesDecrypt(string $key, string $iv, string $encrypted): string { return openssl_decrypt($encrypted, 'aes-256-cbc', str_pad($key, 32, "\0"), OPENSSL_RAW_DATA, str_pad($iv, 16, "\0")); } @@ -216,7 +216,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function decodeRaw(string $raw, string $privKey = '', bool $no_exit = false) + public static function decodeRaw(string $raw, string $privKey = '', bool $no_exit = false): array { $data = json_decode($raw); @@ -232,7 +232,7 @@ class Diaspora if (!is_object($j_outer_key_bundle)) { Logger::notice('Outer Salmon did not verify. Discarding.'); if ($no_exit) { - return false; + return []; } else { throw new \Friendica\Network\HTTPException\BadRequestException(); } @@ -251,7 +251,7 @@ class Diaspora if (!is_object($basedom)) { Logger::notice('Received data does not seem to be an XML. Discarding. '.$xml); if ($no_exit) { - return false; + return []; } else { throw new \Friendica\Network\HTTPException\BadRequestException(); } @@ -277,7 +277,7 @@ class Diaspora if ($author_addr == '') { Logger::notice('No author could be decoded. Discarding. Message: ' . $xml); if ($no_exit) { - return false; + return []; } else { throw new \Friendica\Network\HTTPException\BadRequestException(); } @@ -287,7 +287,7 @@ class Diaspora if ($key == '') { Logger::notice("Couldn't get a key for handle " . $author_addr . ". Discarding."); if ($no_exit) { - return false; + return []; } else { throw new \Friendica\Network\HTTPException\BadRequestException(); } @@ -321,14 +321,14 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function decode(string $xml, string $privKey = '') + public static function decode(string $xml, string $privKey = ''): array { $public = false; $basedom = XML::parseString($xml); if (!is_object($basedom)) { Logger::notice('XML is not parseable.'); - return false; + return []; } $children = $basedom->children('https://joindiaspora.com/protocol'); @@ -342,7 +342,7 @@ class Diaspora // This happens with posts from a relais if (empty($privKey)) { Logger::info('This is no private post in the old format'); - return false; + return []; } $encrypted_header = json_decode(base64_decode($children->encrypted_header)); @@ -457,11 +457,11 @@ class Diaspora * @param array $msg The post that will be dispatched * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * - * @return int The message id of the generated message, "true" or "false" if there was an error + * @return int|bool The message id of the generated message, "true" or "false" if there was an error * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function dispatchPublic($msg, int $direction) + public static function dispatchPublic(array $msg, int $direction) { $enabled = intval(DI::config()->get("system", "diaspora_enabled")); if (!$enabled) { @@ -488,11 +488,11 @@ class Diaspora * @param SimpleXMLElement $fields SimpleXML object that contains the message * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * - * @return int The message id of the generated message, "true" or "false" if there was an error + * @return int|bool The message id of the generated message, "true" or "false" if there was an error * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function dispatch(array $importer, $msg, SimpleXMLElement $fields = null, int $direction = self::PUSHED) + public static function dispatch(array $importer, array $msg, SimpleXMLElement $fields = null, int $direction = self::PUSHED) { // The sender is the handle of the contact that sent the message. // This will often be different with relayed messages (for example "like" and "comment") @@ -598,7 +598,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function validPosting($msg) + private static function validPosting(array $msg) { $data = XML::parseString($msg["message"]); @@ -748,15 +748,15 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function key($handle) + private static function key(string $handle): string { $handle = strval($handle); Logger::notice("Fetching diaspora key for: ".$handle); - $r = FContact::getByURL($handle); - if ($r) { - return $r["pubkey"]; + $fcontact = FContact::getByURL($handle); + if ($fcontact) { + return $fcontact["pubkey"]; } return ""; @@ -771,7 +771,7 @@ class Diaspora * @return string the handle * @throws \Exception */ - private static function handleFromContact($contact_id, $pcontact_id = 0) + private static function handleFromContact(int $contact_id, int $pcontact_id = 0): string { $handle = ''; @@ -804,7 +804,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function contactByHandle($uid, $handle) + private static function contactByHandle(int $uid, string $handle): array { return Contact::getByURL($handle, null, [], $uid); } @@ -818,7 +818,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function isSupportedByContactUrl($url, $update = null) + public static function isSupportedByContactUrl(string $url, $update = null) { return !empty(FContact::getByURL($url, $update)); } @@ -832,7 +832,7 @@ class Diaspora * * @return bool is the contact allowed to post? */ - private static function postAllow(array $importer, array $contact, $is_comment = false) + private static function postAllow(array $importer, array $contact, bool $is_comment = false): bool { /* * Perhaps we were already sharing with this person. Now they're sharing with us. @@ -878,10 +878,10 @@ class Diaspora * @param string $handle The checked handle in the format user@domain.tld * @param bool $is_comment Is the check for a comment? * - * @return array The contact data + * @return array|bool The contact data or false on error * @throws \Exception */ - private static function allowedContactByHandle(array $importer, $handle, $is_comment = false) + private static function allowedContactByHandle(array $importer, string $handle, bool $is_comment = false) { $contact = self::contactByHandle($importer["uid"], $handle); if (!$contact) { @@ -912,7 +912,7 @@ class Diaspora * @return int|bool message id if the message already was stored into the system - or false. * @throws \Exception */ - private static function messageExists($uid, $guid) + private static function messageExists(int $uid, string $guid) { $item = Post::selectFirst(['id'], ['uid' => $uid, 'guid' => $guid]); if (DBA::isResult($item)) { @@ -958,7 +958,7 @@ class Diaspora * * @return string the replaced string */ - public static function replacePeopleGuid($body, $author_link) + public static function replacePeopleGuid(string $body, string $author_link): string { $return = preg_replace_callback( "&\[url=/people/([^\[\]]*)\](.*)\[\/url\]&Usi", @@ -994,7 +994,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function fetchGuidSub($match, $item) + private static function fetchGuidSub(array $match, array $item) { if (!self::storeByGuid($match[1], $item["author-link"], true)) { self::storeByGuid($match[1], $item["owner-link"], true); @@ -1008,11 +1008,11 @@ class Diaspora * @param string $server The server address * @param bool $force Forced fetch * - * @return int the message id of the stored message or false + * @return int|bool the message id of the stored message or false * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function storeByGuid($guid, $server, $force) + private static function storeByGuid(string $guid, string $server, bool $force) { $serverparts = parse_url($server); @@ -1049,7 +1049,7 @@ class Diaspora * 'key' => The public key of the author * @throws \Exception */ - public static function message($guid, $server, $level = 0) + public static function message(string $guid, string $server, int $level = 0) { if ($level > 5) { return false; @@ -1119,12 +1119,13 @@ class Diaspora * Fetches an item with a given URL * * @param string $url the message url + * @param int $uid User id * - * @return int the message id of the stored message or false + * @return int|bool the message id of the stored message or false * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function fetchByURL($url, $uid = 0) + public static function fetchByURL(string $url, int $uid = 0) { // Check for Diaspora (and Friendica) typical paths if (!preg_match("=(https?://.+)/(?:posts|display|objects)/([a-zA-Z0-9-_@.:%]+[a-zA-Z0-9])=i", $url, $matches)) { @@ -1162,10 +1163,10 @@ class Diaspora * @param string $author The handle of the item * @param array $contact The contact of the item owner * - * @return array the item record + * @return array|bool the item record or false on failure * @throws \Exception */ - private static function parentItem($uid, $guid, $author, array $contact) + private static function parentItem(int $uid, string $guid, string $author, array $contact) { $fields = ['id', 'parent', 'body', 'wall', 'uri', 'guid', 'private', 'origin', 'author-name', 'author-link', 'author-avatar', 'gravity', @@ -1210,7 +1211,7 @@ class Diaspora * 'network' => network type * @throws \Exception */ - private static function authorContactByUrl($def_contact, $person, $uid) + private static function authorContactByUrl(array $def_contact, array $person, int $uid): array { $condition = ['nurl' => Strings::normaliseLink($person["url"]), 'uid' => $uid]; $contact = DBA::selectFirst('contact', ['id', 'network'], $condition); @@ -1232,9 +1233,9 @@ class Diaspora * * @return bool is it a hubzilla server? */ - private static function isHubzilla($url) + private static function isHubzilla(string $url): bool { - return(strstr($url, '/channel/')); + return strstr($url, '/channel/'); } /** @@ -1248,7 +1249,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function plink(string $addr, string $guid, string $parent_guid = '') + private static function plink(string $addr, string $guid, string $parent_guid = ''): string { $contact = Contact::getByURL($addr); if (empty($contact)) { @@ -1312,8 +1313,10 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveAccountMigration(array $importer, $data) + private static function receiveAccountMigration(array $importer, $data): bool { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data)); $old_handle = XML::unescape($data->author); $new_handle = XML::unescape($data->profile->author); $signature = XML::unescape($data->signature); @@ -1365,8 +1368,10 @@ class Diaspora * @return bool Success * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function receiveAccountDeletion($data) + private static function receiveAccountDeletion($data): bool { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $contacts = DBA::select('contact', ['id'], ['addr' => $author]); @@ -1387,11 +1392,11 @@ class Diaspora * @param string $guid Message guid * @param boolean $onlyfound Only return uri when found in the database * - * @return string The constructed uri or the one from our database + * @return string The constructed uri or the one from our database or empty string on if $onlyfound is true * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function getUriFromGuid($author, $guid, $onlyfound = false) + private static function getUriFromGuid(string $author, string $guid, bool $onlyfound = false): string { $item = Post::selectFirst(['uri'], ['guid' => $guid]); if (DBA::isResult($item)) { @@ -1456,8 +1461,10 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveComment(array $importer, $sender, $data, $xml, int $direction) + private static function receiveComment(array $importer, string $sender, $data, string $xml, int $direction): bool { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); $parent_guid = XML::unescape($data->parent_guid); @@ -1593,8 +1600,10 @@ class Diaspora * @return bool "true" if it was successful * @throws \Exception */ - private static function receiveConversationMessage(array $importer, array $contact, $data, $msg, $mesg, $conversation) + private static function receiveConversationMessage(array $importer, array $contact, $data, array $msg, $mesg, array $conversation): bool { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data).',mesg='.get_class($mesg)); $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); $subject = XML::unescape($data->subject); @@ -1650,8 +1659,10 @@ class Diaspora * @return bool Success * @throws \Exception */ - private static function receiveConversation(array $importer, $msg, $data) + private static function receiveConversation(array $importer, array $msg, $data) { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); $subject = XML::unescape($data->subject); @@ -1708,12 +1719,14 @@ class Diaspora * @param object $data The message object * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * - * @return int The message id of the generated like or "false" if there was an error + * @return bool Success or failure * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveLike(array $importer, $sender, $data, int $direction) + private static function receiveLike(array $importer, string $sender, $data, int $direction): bool { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); $parent_guid = XML::unescape($data->parent_guid); @@ -1832,8 +1845,10 @@ class Diaspora * @return bool Success? * @throws \Exception */ - private static function receiveMessage(array $importer, $data) + private static function receiveMessage(array $importer, $data): bool { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); $conversation_guid = XML::unescape($data->conversation_guid); @@ -1899,8 +1914,10 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveParticipation(array $importer, $data, int $direction) + private static function receiveParticipation(array $importer, $data, int $direction): bool { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data)); $author = strtolower(XML::unescape($data->author)); $guid = XML::unescape($data->guid); $parent_guid = XML::unescape($data->parent_guid); @@ -2044,8 +2061,10 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveProfile(array $importer, $data) + private static function receiveProfile(array $importer, $data): bool { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data)); $author = strtolower(XML::unescape($data->author)); $contact = self::contactByHandle($importer["uid"], $author); @@ -2145,8 +2164,10 @@ class Diaspora * @return bool Success * @throws \Exception */ - private static function receiveContactRequest(array $importer, $data) + private static function receiveContactRequest(array $importer, $data): bool { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $recipient = XML::unescape($data->recipient); @@ -2233,7 +2254,7 @@ class Diaspora $contact_record = self::contactByHandle($importer['uid'], $author); if (!$contact_record) { Logger::info('unable to locate newly created contact record.'); - return; + return false; } $user = DBA::selectFirst('user', [], ['uid' => $importer['uid']]); @@ -2253,11 +2274,11 @@ class Diaspora * * @param string $guid message guid * @param string $orig_author handle of the original post - * @return array The fetched item + * @return array|bool The fetched item or false on failure * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function originalItem($guid, $orig_author) + public static function originalItem(string $guid, string $orig_author) { if (empty($guid)) { Logger::notice('Empty guid. Quitting.'); @@ -2333,7 +2354,7 @@ class Diaspora * @param string $guid GUID string of reshare action * @param string $author Author handle */ - private static function addReshareActivity($item, $parent_message_id, $guid, $author) + private static function addReshareActivity(array $item, int $parent_message_id, string $guid, string $author) { $parent = Post::selectFirst(['uri', 'guid'], ['id' => $parent_message_id]); @@ -2388,12 +2409,14 @@ class Diaspora * @param string $xml The original XML of the message * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * - * @return int the message id + * @return bool Success or failure * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveReshare(array $importer, $data, $xml, int $direction) + private static function receiveReshare(array $importer, $data, string $xml, int $direction): bool { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); $created_at = DateTimeFormat::utc(XML::unescape($data->created_at)); @@ -2512,8 +2535,10 @@ class Diaspora * @return bool success * @throws \Exception */ - private static function itemRetraction(array $importer, array $contact, $data) + private static function itemRetraction(array $importer, array $contact, $data): bool { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $target_guid = XML::unescape($data->target_guid); $target_type = XML::unescape($data->target_type); @@ -2578,8 +2603,10 @@ class Diaspora * @return bool Success * @throws \Exception */ - private static function receiveRetraction(array $importer, $sender, $data) + private static function receiveRetraction(array $importer, string $sender, $data) { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('data='.get_class($data)); $target_type = XML::unescape($data->target_type); $contact = self::contactByHandle($importer["uid"], $sender); @@ -2624,7 +2651,7 @@ class Diaspora * * @return boolean Is the message wanted? */ - private static function isSolicitedMessage(array $item, string $author, string $body, int $direction) + private static function isSolicitedMessage(array $item, string $author, string $body, int $direction): bool { $contact = Contact::getByURL($author); if (DBA::exists('contact', ["`nurl` = ? AND `uid` != ? AND `rel` IN (?, ?)", @@ -2656,6 +2683,8 @@ class Diaspora */ private static function storePhotoAsMedia(int $uriid, $photo) { + // @TODO Need to find object type, roland@f.haeder.net + Logger::debug('photo='.get_class($photo)); $data = []; $data['uri-id'] = $uriid; $data['type'] = Post\Media::IMAGE; @@ -2675,11 +2704,11 @@ class Diaspora * @param string $xml The original XML of the message * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * - * @return int The message id of the newly created item + * @return int|bool The message id of the newly created item or false on error * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveStatusMessage(array $importer, SimpleXMLElement $data, $xml, int $direction) + private static function receiveStatusMessage(array $importer, SimpleXMLElement $data, string $xml, int $direction) { $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); @@ -2826,7 +2855,7 @@ class Diaspora * @return string the handle in the format user@domain.tld * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function myHandle(array $contact) + private static function myHandle(array $contact): string { if (!empty($contact["addr"])) { return $contact["addr"]; @@ -2856,7 +2885,7 @@ class Diaspora * @return string The encrypted data * @throws \Exception */ - public static function encodePrivateData($msg, array $user, array $contact, $prvkey, $pubkey) + public static function encodePrivateData(string $msg, array $user, array $contact, string $prvkey, string $pubkey): string { Logger::debug("Message: ".$msg); @@ -2897,7 +2926,7 @@ class Diaspora * @return string The envelope * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function buildMagicEnvelope($msg, array $user) + public static function buildMagicEnvelope(string $msg, array $user): string { $b64url_data = Strings::base64UrlEncode($msg); $data = str_replace(["\n", "\r", " ", "\t"], ["", "", "", ""], $b64url_data); @@ -2941,7 +2970,7 @@ class Diaspora * @return string The message that will be transmitted to other servers * @throws \Exception */ - public static function buildMessage($msg, array $user, array $contact, $prvkey, $pubkey, $public = false) + public static function buildMessage(string $msg, array $user, array $contact, string $prvkey, string $pubkey, bool $public = false): string { // The message is put into an envelope with the sender's signature $envelope = self::buildMagicEnvelope($msg, $user); @@ -2962,7 +2991,7 @@ class Diaspora * * @return string The signature */ - private static function signature($owner, $message) + private static function signature(array $owner, array $message): string { $sigmsg = $message; unset($sigmsg["author_signature"]); @@ -2986,7 +3015,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function transmit(array $owner, array $contact, $envelope, $public_batch, $guid = "") + private static function transmit(array $owner, array $contact, string $envelope, bool $public_batch, string $guid = ""): int { $enabled = intval(DI::config()->get("system", "diaspora_enabled")); if (!$enabled) { @@ -3039,7 +3068,7 @@ class Diaspora * * @return string The post XML */ - public static function buildPostXml($type, $message) + public static function buildPostXml(string $type, array $message): array { $data = [$type => $message]; @@ -3060,7 +3089,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function buildAndTransmit(array $owner, array $contact, $type, $message, $public_batch = false, $guid = "") + private static function buildAndTransmit(array $owner, array $contact, string $type, array $message, bool $public_batch = false, string $guid = "") { $msg = self::buildPostXml($type, $message); @@ -3103,18 +3132,18 @@ class Diaspora * @return int The result of the transmission * @throws \Exception */ - private static function sendParticipation(array $contact, array $item) + private static function sendParticipation(array $contact, array $item): int { // Don't send notifications for private postings if ($item['private'] == Item::PRIVATE) { - return; + return -1; } $cachekey = "diaspora:sendParticipation:".$item['guid']; $result = DI::cache()->get($cachekey); if (!is_null($result)) { - return; + return -1; } // Fetch some user id to have a valid handle to transmit the participation. @@ -3156,7 +3185,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function sendAccountMigration(array $owner, array $contact, $uid) + public static function sendAccountMigration(array $owner, array $contact, int $uid): int { $old_handle = DI::pConfig()->get($uid, 'system', 'previous_addr'); $profile = self::createProfileData($uid); @@ -3182,7 +3211,7 @@ class Diaspora * @return int The result of the transmission * @throws \Exception */ - public static function sendShare(array $owner, array $contact) + public static function sendShare(array $owner, array $contact): int { /** * @todo support the different possible combinations of "following" and "sharing" @@ -3226,7 +3255,7 @@ class Diaspora * @return int The result of the transmission * @throws \Exception */ - public static function sendUnshare(array $owner, array $contact) + public static function sendUnshare(array $owner, array $contact): int { $message = ["author" => self::myHandle($owner), "recipient" => $contact["addr"], @@ -3248,7 +3277,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function isReshare($body, $complete = true) + public static function isReshare(string $body, bool $complete = true) { $body = trim($body); @@ -3304,7 +3333,7 @@ class Diaspora * @return array with event data * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function buildEvent($event_id) + private static function buildEvent(string $event_id): array { $event = DBA::selectFirst('event', [], ['id' => $event_id]); if (!DBA::isResult($event)) { @@ -3484,7 +3513,7 @@ class Diaspora return $msg; } - private static function prependParentAuthorMention($body, $profile_url) + private static function prependParentAuthorMention(string $body, string $profile_url): string { $profile = Contact::getByURL($profile_url, false, ['addr', 'name']); if (!empty($profile['addr']) @@ -3509,7 +3538,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function sendStatus(array $item, array $owner, array $contact, $public_batch = false) + public static function sendStatus(array $item, array $owner, array $contact, bool $public_batch = false): int { $status = self::buildStatus($item, $owner); @@ -3522,7 +3551,7 @@ class Diaspora * @param array $item The item that will be exported * @param array $owner the array of the item owner * - * @return array The data for a "like" + * @return array|bool The data for a "like" or false on error * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ private static function constructLike(array $item, array $owner) @@ -3540,12 +3569,12 @@ class Diaspora $positive = "false"; } - return(["author" => self::myHandle($owner), + return ["author" => self::myHandle($owner), "guid" => $item["guid"], "parent_guid" => $parent["guid"], "parent_type" => $target_type, "positive" => $positive, - "author_signature" => ""]); + "author_signature" => ""]; } /** @@ -3554,7 +3583,7 @@ class Diaspora * @param array $item The item that will be exported * @param array $owner the array of the item owner * - * @return array The data for an "EventParticipation" + * @return array|bool The data for an "EventParticipation" or false on error * @throws \Exception */ private static function constructAttend(array $item, array $owner) @@ -3579,11 +3608,11 @@ class Diaspora return false; } - return(["author" => self::myHandle($owner), + return ["author" => self::myHandle($owner), "guid" => $item["guid"], "parent_guid" => $parent["guid"], "status" => $attend_answer, - "author_signature" => ""]); + "author_signature" => ""]; } /** @@ -3651,7 +3680,7 @@ class Diaspora DI::cache()->set($cachekey, $comment, Duration::QUARTER_HOUR); - return($comment); + return $comment; } /** @@ -3666,7 +3695,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function sendFollowup(array $item, array $owner, array $contact, $public_batch = false) + public static function sendFollowup(array $item, array $owner, array $contact, bool $public_batch = false): int { if (in_array($item['verb'], [Activity::ATTEND, Activity::ATTENDNO, Activity::ATTENDMAYBE])) { $message = self::constructAttend($item, $owner); @@ -3680,7 +3709,7 @@ class Diaspora } if (empty($message)) { - return false; + return -1; } $message["author_signature"] = self::signature($owner, $message); @@ -3699,7 +3728,7 @@ class Diaspora * @return int The result of the transmission * @throws \Exception */ - public static function sendRelay(array $item, array $owner, array $contact, $public_batch = false) + public static function sendRelay(array $item, array $owner, array $contact, bool $public_batch = false): int { if ($item["deleted"]) { return self::sendRetraction($item, $owner, $contact, $public_batch, true); @@ -3750,7 +3779,7 @@ class Diaspora * @return int The result of the transmission * @throws \Exception */ - public static function sendRetraction(array $item, array $owner, array $contact, $public_batch = false, $relay = false) + public static function sendRetraction(array $item, array $owner, array $contact, bool $public_batch = false, bool $relay = false): int { $itemaddr = self::handleFromContact($item["contact-id"], $item["author-id"]); @@ -3784,14 +3813,14 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function sendMail(array $item, array $owner, array $contact) + public static function sendMail(array $item, array $owner, array $contact): int { $myaddr = self::myHandle($owner); $cnv = DBA::selectFirst('conv', [], ['id' => $item["convid"], 'uid' => $item["uid"]]); if (!DBA::isResult($cnv)) { Logger::notice("conversation not found."); - return; + return -1; } $body = BBCode::toMarkdown($item["body"]); @@ -3831,7 +3860,8 @@ class Diaspora * * @return array The array with "first" and "last" */ - public static function splitName($name) { + public static function splitName(string $name): array + { $name = trim($name); // Is the name longer than 64 characters? Then cut the rest of it. @@ -3888,7 +3918,7 @@ class Diaspora * @return array The profile data * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function createProfileData($uid) + private static function createProfileData(int $uid): array { $profile = DBA::selectFirst('owner-view', ['uid', 'addr', 'name', 'location', 'net-publish', 'dob', 'about', 'pub_keywords'], ['uid' => $uid]); if (!DBA::isResult($profile)) { @@ -3962,7 +3992,7 @@ class Diaspora * @return void * @throws \Exception */ - public static function sendProfile($uid, $recips = false) + public static function sendProfile(int $uid, bool $recips = false) { if (!$uid) { return; @@ -3996,10 +4026,10 @@ class Diaspora * @param integer $uid The user of that comment * @param array $item Item array * - * @return array Signed content + * @return array|bool Signed content or false on error * @throws \Exception */ - public static function createLikeSignature($uid, array $item) + public static function createLikeSignature(int $uid, array $item) { $owner = User::getOwnerDataById($uid); if (empty($owner)) { @@ -4026,7 +4056,7 @@ class Diaspora * * @param array $item Item array * - * @return array Signed content + * @return array|bool Signed content or false on error * @throws \Exception */ public static function createCommentSignature(array $item) @@ -4069,7 +4099,7 @@ class Diaspora return $message; } - public static function performReshare(int $UriId, int $uid) + public static function performReshare(int $UriId, int $uid): int { $fields = ['uri-id', 'body', 'title', 'author-name', 'author-link', 'author-avatar', 'guid', 'created', 'plink']; $item = Post::selectFirst($fields, ['uri-id' => $UriId, 'uid' => [$uid, 0], 'private' => [Item::PUBLIC, Item::UNLISTED]]); From fdd237a090e76745486250de39f1d8b127322fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Fri, 17 Jun 2022 10:53:45 +0200 Subject: [PATCH 23/37] Fix for "Uncaught Exception TypeError: "Argument 1 passed to Friendica\Model\APContact::unarchiveInbox() must be of the type string, null given" error message --- src/Model/APContact.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model/APContact.php b/src/Model/APContact.php index d6f4877407..48e48ab1d7 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -220,14 +220,14 @@ class APContact $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['inbox'] = (JsonLD::fetchElement($compacted, 'ldp:inbox', '@id') ?? ''); self::unarchiveInbox($apcontact['inbox'], false); $apcontact['outbox'] = JsonLD::fetchElement($compacted, 'as:outbox', '@id'); $apcontact['sharedinbox'] = ''; if (!empty($compacted['as:endpoints'])) { - $apcontact['sharedinbox'] = JsonLD::fetchElement($compacted['as:endpoints'], 'as:sharedInbox', '@id'); + $apcontact['sharedinbox'] = (JsonLD::fetchElement($compacted['as:endpoints'], 'as:sharedInbox', '@id') ?? ''); self::unarchiveInbox($apcontact['sharedinbox'], true); } From 10bb7d562571bd2976e6e07fa821ed7e62d23ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Fri, 17 Jun 2022 10:57:17 +0200 Subject: [PATCH 24/37] Possible fix for Uncaught Exception TypeError: "Return value of Friendica\Model\APContact::getByURL() must be of the type array, bool returned" --- src/Model/APContact.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/APContact.php b/src/Model/APContact.php index 48e48ab1d7..9442db00cd 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -206,7 +206,7 @@ class APContact if ($failed) { self::markForArchival($fetched_contact ?: []); - return $fetched_contact; + return $fetched_contact ?? []; } } From 4f3321cc9f76a53aabaa044feb021fccd5687f0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Fri, 17 Jun 2022 11:04:47 +0200 Subject: [PATCH 25/37] Nore fixes --- src/Model/APContact.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model/APContact.php b/src/Model/APContact.php index 9442db00cd..fba0c24f4c 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -275,7 +275,7 @@ class APContact // Quit if none of the basic values are set if (empty($apcontact['url']) || empty($apcontact['type']) || (($apcontact['type'] != 'Tombstone') && empty($apcontact['inbox']))) { - return $fetched_contact; + return $fetched_contact ?? []; } elseif ($apcontact['type'] == 'Tombstone') { // The "inbox" field must have a content $apcontact['inbox'] = ''; @@ -283,7 +283,7 @@ class APContact // Quit if this doesn't seem to be an account at all if (!in_array($apcontact['type'], ActivityPub::ACCOUNT_TYPES)) { - return $fetched_contact; + return $fetched_contact ?? []; } $parts = parse_url($apcontact['url']); From c467bff79fcbed3d953eea051b89d4be20be506a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Fri, 17 Jun 2022 11:17:53 +0200 Subject: [PATCH 26/37] Some more type-hints added --- src/Model/Attach.php | 28 ++++++++++---------- src/Model/Conversation.php | 4 +-- src/Model/Event.php | 54 +++++++++++++++++++------------------- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/Model/Attach.php b/src/Model/Attach.php index 91970bfc62..e4d58c4b07 100644 --- a/src/Model/Attach.php +++ b/src/Model/Attach.php @@ -59,7 +59,7 @@ class Attach * @param array $conditions Array of fields for conditions * @param array $params Array of several parameters * - * @return array + * @return array|bool * * @throws \Exception * @see \Friendica\Database\DBA::selectToArray @@ -117,7 +117,7 @@ class Attach * @throws \Exception * @see \Friendica\Database\DBA::select */ - public static function getById($id) + public static function getById(int $id) { return self::selectFirst([], ['id' => $id]); } @@ -132,7 +132,7 @@ class Attach * @throws \Exception * @see \Friendica\Database\DBA::select */ - public static function getByIdWithPermission($id) + public static function getByIdWithPermission(int $id) { $r = self::selectFirst(['uid'], ['id' => $id]); if ($r === false) { @@ -156,10 +156,10 @@ class Attach * * @param array $item Attachment data. Needs at least 'id', 'backend-class', 'backend-ref' * - * @return string file data + * @return string|null file data or null on failure * @throws \Exception */ - public static function getData($item) + public static function getData(array $item) { if (!empty($item['data'])) { return $item['data']; @@ -195,10 +195,10 @@ class Attach * @param string $deny_cid Permissions, denied contacts.optional, default = '' * @param string $deny_gid Permissions, denied greoup.optional, default = '' * - * @return boolean/integer Row id on success, False on errors + * @return boolean|integer Row id on success, False on errors * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function store($data, $uid, $filename, $filetype = '' , $filesize = null, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') + public static function store(string $data, int $uid, string $filename, string $filetype = '' , int $filesize = null, string $allow_cid = '', string $allow_gid = '', string $deny_cid = '', string $deny_gid = '') { if ($filetype === '') { $filetype = Mimetype::getContentType($filename); @@ -241,17 +241,17 @@ class Attach /** * Store new file metadata in db and binary in default backend from existing file * - * @param $src - * @param $uid - * @param string $filename + * @param string $src Source file name + * @param int $uid User id + * @param string $filename Optional file name * @param string $allow_cid * @param string $allow_gid * @param string $deny_cid * @param string $deny_gid - * @return boolean True on success + * @return boolean|int Insert id or false on failure * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function storeFile($src, $uid, $filename = '', $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') + public static function storeFile(string $src, int $uid, string $filename = '', string $allow_cid = '', string $allow_gid = '', string $deny_cid = '', string $deny_gid = '') { if ($filename === '') { $filename = basename($src); @@ -276,7 +276,7 @@ class Attach * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @see \Friendica\Database\DBA::update */ - public static function update($fields, $conditions, Image $img = null, array $old_fields = []) + public static function update(array $fields, array $conditions, Image $img = null, array $old_fields = []): bool { if (!is_null($img)) { // get items to update @@ -311,7 +311,7 @@ class Attach * @throws \Exception * @see \Friendica\Database\DBA::delete */ - public static function delete(array $conditions, array $options = []) + public static function delete(array $conditions, array $options = []): bool { // get items to delete data info $items = self::selectToArray(['backend-class','backend-ref'], $conditions); diff --git a/src/Model/Conversation.php b/src/Model/Conversation.php index 1403b30be2..7d8b8058f1 100644 --- a/src/Model/Conversation.php +++ b/src/Model/Conversation.php @@ -62,7 +62,7 @@ class Conversation */ const RELAY = 3; - public static function getByItemUri($item_uri) + public static function getByItemUri(string $item_uri) { return DBA::selectFirst('conversation', [], ['item-uri' => $item_uri]); } @@ -74,7 +74,7 @@ class Conversation * @return array Item array with removed conversation data * @throws \Exception */ - public static function insert(array $arr) + public static function insert(array $arr): array { if (in_array(($arr['network'] ?? '') ?: Protocol::PHANTOM, [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, Protocol::TWITTER]) && !empty($arr['uri'])) { diff --git a/src/Model/Event.php b/src/Model/Event.php index dac00ceceb..f63ec3d559 100644 --- a/src/Model/Event.php +++ b/src/Model/Event.php @@ -41,7 +41,7 @@ use Friendica\Util\XML; class Event { - public static function getHTML(array $event, $simple = false, $uriid = 0) + public static function getHTML(array $event, bool $simple = false, int $uriid = 0): string { if (empty($event)) { return ''; @@ -127,7 +127,7 @@ class Event * @param array $event Array which contains the event data. * @return string The event as a bbcode formatted string. */ - private static function getBBCode(array $event) + private static function getBBCode(array $event): string { $o = ''; @@ -157,11 +157,10 @@ class Event /** * Extract bbcode formatted event data from a string. * - * @params: string $s The string which should be parsed for event data. - * @param $text + * @param string $text The string which should be parsed for event data. * @return array The array with the event information. */ - public static function fromBBCode($text) + public static function fromBBCode(string $text): array { $ev = []; @@ -195,13 +194,13 @@ class Event return $ev; } - public static function sortByDate($event_list) + public static function sortByDate(array $event_list): array { usort($event_list, ['self', 'compareDatesCallback']); return $event_list; } - private static function compareDatesCallback($event_a, $event_b) + private static function compareDatesCallback(array $event_a, array $event_b) { $date_a = DateTimeFormat::local($event_a['start']); $date_b = DateTimeFormat::local($event_b['start']); @@ -223,7 +222,7 @@ class Event * @return void * @throws \Exception */ - public static function delete($event_id) + public static function delete(int $event_id) { if ($event_id == 0) { return; @@ -242,7 +241,7 @@ class Event * @return int The new event id. * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function store($arr) + public static function store(array $arr): int { $event = []; $event['id'] = intval($arr['id'] ?? 0); @@ -317,7 +316,7 @@ class Event return $event['id']; } - public static function getItemArrayForId(int $event_id, array $item = []):array + public static function getItemArrayForId(int $event_id, array $item = []): array { if (empty($event_id)) { return $item; @@ -374,7 +373,7 @@ class Event return $item; } - public static function getItemArrayForImportedId(int $event_id, array $item = []):array + public static function getItemArrayForImportedId(int $event_id, array $item = []): array { if (empty($event_id)) { return $item; @@ -404,7 +403,7 @@ class Event * @return array Array with translations strings. * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function getStrings() + public static function getStrings(): array { // First day of the week (0 = Sunday). $firstDay = DI::pConfig()->get(local_user(), 'system', 'first_day_of_week', 0); @@ -477,7 +476,7 @@ class Event * * @todo We should replace this with a separate update function if there is some time left. */ - private static function removeDuplicates(array $dates) + private static function removeDuplicates(array $dates): array { $dates2 = []; @@ -500,7 +499,7 @@ class Event * @return array Query result * @throws \Exception */ - public static function getListById($owner_uid, $event_id, $sql_extra = '') + public static function getListById(int $owner_uid, int $event_id, string $sql_extra = ''): array { $return = []; @@ -536,7 +535,7 @@ class Event * @return array Query results. * @throws \Exception */ - public static function getListByDate($owner_uid, $event_params, $sql_extra = '') + public static function getListByDate(int $owner_uid, array $event_params, string $sql_extra = ''): array { $return = []; @@ -570,7 +569,7 @@ class Event * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function prepareListForTemplate(array $event_result) + public static function prepareListForTemplate(array $event_result): array { $event_list = []; @@ -651,12 +650,12 @@ class Event * @param array $events Query result for events. * @param string $format The output format (ical/csv). * - * @param $timezone + * @param string $timezone Timezone (missing parameter!) * @return string Content according to selected export format. * * @todo Implement timezone support */ - private static function formatListForExport(array $events, $format) + private static function formatListForExport(array $events, string $format): string { $o = ''; @@ -757,7 +756,7 @@ class Event * @return array Query results. * @throws \Exception */ - private static function getListByUserId($uid = 0) + private static function getListByUserId(int $uid = 0): array { $return = []; @@ -797,7 +796,7 @@ class Event * @throws \Exception * @todo Respect authenticated users with events_by_uid(). */ - public static function exportListByUserId($uid, $format = 'ical') + public static function exportListByUserId(int $uid, string $format = 'ical'): array { $process = false; @@ -845,7 +844,8 @@ class Event * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function getItemHTML(array $item) { + public static function getItemHTML(array $item): string + { $same_date = false; $finish = false; @@ -933,10 +933,11 @@ class Event * @return array The array with the location data. * 'name' => The name of the location,
* 'address' => The address of the location,
- * 'coordinates' => Latitude‎ and longitude‎ (e.g. '48.864716,2.349014').
+ * 'coordinates' => Latitude and longitude (e.g. '48.864716,2.349014').
* @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function locationToArray($s = '') { + private static function locationToArray(string $s = ''): array + { if ($s == '') { return []; } @@ -981,7 +982,7 @@ class Event * @return bool * @throws \Exception */ - public static function createBirthday($contact, $birthday) + public static function createBirthday(array $contact, string $birthday): bool { // Check for duplicates $condition = [ @@ -1011,8 +1012,7 @@ class Event 'type' => 'birthday', ]; - self::store($values); - - return true; + // Check if self::store() was success + return (self::store($values) > 0); } } From 36d56a4041aa03f38d621f771bc613c4ada58a88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Fri, 17 Jun 2022 11:48:52 +0200 Subject: [PATCH 27/37] Continued: - changed back to 'return false;' as other methods heavily rely on false instead of an empty array as pointed out by @heluecht@pirati.ca - $fetched_contact should be initialized as an empty array, let's not make this code more crazier than it already is (see APContact::getByURL()) --- src/Model/APContact.php | 8 ++++---- src/Module/DFRN/Notify.php | 11 ++++++----- src/Protocol/Diaspora.php | 14 +++++++------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/Model/APContact.php b/src/Model/APContact.php index fba0c24f4c..2fff36ed49 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -124,7 +124,7 @@ class APContact return []; } - $fetched_contact = false; + $fetched_contact = []; if (empty($update)) { if (is_null($update)) { @@ -206,7 +206,7 @@ class APContact if ($failed) { self::markForArchival($fetched_contact ?: []); - return $fetched_contact ?? []; + return $fetched_contact; } } @@ -275,7 +275,7 @@ class APContact // Quit if none of the basic values are set if (empty($apcontact['url']) || empty($apcontact['type']) || (($apcontact['type'] != 'Tombstone') && empty($apcontact['inbox']))) { - return $fetched_contact ?? []; + return $fetched_contact; } elseif ($apcontact['type'] == 'Tombstone') { // The "inbox" field must have a content $apcontact['inbox'] = ''; @@ -283,7 +283,7 @@ class APContact // Quit if this doesn't seem to be an account at all if (!in_array($apcontact['type'], ActivityPub::ACCOUNT_TYPES)) { - return $fetched_contact ?? []; + return $fetched_contact; } $parts = parse_url($apcontact['url']); diff --git a/src/Module/DFRN/Notify.php b/src/Module/DFRN/Notify.php index 09fe7ec144..259aa14587 100644 --- a/src/Module/DFRN/Notify.php +++ b/src/Module/DFRN/Notify.php @@ -59,12 +59,13 @@ class Notify extends BaseModule } } - private static function dispatchPublic($postdata) + private static function dispatchPublic(array $postdata) { $msg = Diaspora::decodeRaw($postdata, '', true); - if (!$msg) { + if (!is_array($msg)) { // We have to fail silently to be able to hand it over to the salmon parser - return false; + Logger::warning('Diaspora::decodeRaw() has failed for some reason.'); + return; } // Fetch the corresponding public contact @@ -88,10 +89,10 @@ class Notify extends BaseModule System::xmlExit($ret, 'Done'); } - private static function dispatchPrivate($user, $postdata) + private static function dispatchPrivate(array $user, array $postdata) { $msg = Diaspora::decodeRaw($postdata, $user['prvkey'] ?? ''); - if (!$msg) { + if (!is_array($msg)) { System::xmlExit(4, 'Unable to parse message'); } diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 36f511a6ac..866f3c0163 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -203,20 +203,20 @@ class Diaspora } /** - * Decodes incoming Diaspora message in the new format + * Decodes incoming Diaspora message in the new format. This method returns false on an error. * * @param string $raw raw post message * @param string $privKey The private key of the importer * @param boolean $no_exit Don't do an http exit on error * - * @return array + * @return bool|array * 'message' -> decoded Diaspora XML message * 'author' -> author diaspora handle * 'key' -> author public key (converted to pkcs#8) * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function decodeRaw(string $raw, string $privKey = '', bool $no_exit = false): array + public static function decodeRaw(string $raw, string $privKey = '', bool $no_exit = false) { $data = json_decode($raw); @@ -232,7 +232,7 @@ class Diaspora if (!is_object($j_outer_key_bundle)) { Logger::notice('Outer Salmon did not verify. Discarding.'); if ($no_exit) { - return []; + return false; } else { throw new \Friendica\Network\HTTPException\BadRequestException(); } @@ -251,7 +251,7 @@ class Diaspora if (!is_object($basedom)) { Logger::notice('Received data does not seem to be an XML. Discarding. '.$xml); if ($no_exit) { - return []; + return false; } else { throw new \Friendica\Network\HTTPException\BadRequestException(); } @@ -277,7 +277,7 @@ class Diaspora if ($author_addr == '') { Logger::notice('No author could be decoded. Discarding. Message: ' . $xml); if ($no_exit) { - return []; + return false; } else { throw new \Friendica\Network\HTTPException\BadRequestException(); } @@ -287,7 +287,7 @@ class Diaspora if ($key == '') { Logger::notice("Couldn't get a key for handle " . $author_addr . ". Discarding."); if ($no_exit) { - return []; + return false; } else { throw new \Friendica\Network\HTTPException\BadRequestException(); } From a770634b9568931da0d480642038ed6b55916bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Fri, 17 Jun 2022 12:22:40 +0200 Subject: [PATCH 28/37] Ops, wrong type --- src/Protocol/Diaspora.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 866f3c0163..1eb2cce908 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -3068,7 +3068,7 @@ class Diaspora * * @return string The post XML */ - public static function buildPostXml(string $type, array $message): array + public static function buildPostXml(string $type, array $message): string { $data = [$type => $message]; From 88c40f3336b5553c80d9573ed931802e4fbf92df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Fri, 17 Jun 2022 13:02:43 +0200 Subject: [PATCH 29/37] Ops, wrong type again --- src/Module/DFRN/Notify.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Module/DFRN/Notify.php b/src/Module/DFRN/Notify.php index 259aa14587..2dae0da0ad 100644 --- a/src/Module/DFRN/Notify.php +++ b/src/Module/DFRN/Notify.php @@ -89,7 +89,7 @@ class Notify extends BaseModule System::xmlExit($ret, 'Done'); } - private static function dispatchPrivate(array $user, array $postdata) + private static function dispatchPrivate(array $user, string $postdata) { $msg = Diaspora::decodeRaw($postdata, $user['prvkey'] ?? ''); if (!is_array($msg)) { From 51f43278d6c1e63ebdabff7d02167b7b9be42879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Fri, 17 Jun 2022 18:00:06 +0200 Subject: [PATCH 30/37] Fixed incompatible types --- tests/Util/AppDouble.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Util/AppDouble.php b/tests/Util/AppDouble.php index 1288ec68be..28689425a2 100644 --- a/tests/Util/AppDouble.php +++ b/tests/Util/AppDouble.php @@ -43,7 +43,7 @@ class AppDouble extends App $this->isLoggedIn = $isLoggedIn; } - public function isLoggedIn() + public function isLoggedIn(): bool { return $this->isLoggedIn; } From adb4aea6ad76b959a3b88fc649607fa241f6e1c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Sat, 18 Jun 2022 05:01:51 +0200 Subject: [PATCH 31/37] Changes: - added some type-hints - replaced most double-quotes (only Diaspora.php, later more) with single - added some documentation - normalized indenting in Diaspora.php (I hope I got all?) --- src/Content/Widget.php | 2 +- src/Model/Contact.php | 29 +- src/Module/Directory.php | 2 +- src/Protocol/DFRN.php | 4 +- src/Protocol/Diaspora.php | 1132 +++++++++++++++++++------------------ 5 files changed, 604 insertions(+), 565 deletions(-) diff --git a/src/Content/Widget.php b/src/Content/Widget.php index 22772d2b2e..a2a3b3257b 100644 --- a/src/Content/Widget.php +++ b/src/Content/Widget.php @@ -45,7 +45,7 @@ class Widget * @return string * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function follow(string $value = ""): string + public static function follow(string $value = ''): string { return Renderer::replaceMacros(Renderer::getMarkupTemplate('widget/follow.tpl'), array( '$connect' => DI::l10n()->t('Add New Contact'), diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 51e5cf1510..d6b2780ef3 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1553,11 +1553,11 @@ class Contact /** * Blocks a contact * - * @param int $cid - * @return bool - * @throws \Exception + * @param int $cid Contact id to block + * @param string $reason Block reason + * @return bool Whether it was successful */ - public static function block($cid, $reason = null) + public static function block(int $cid, string $reason = null): bool { $return = self::update(['blocked' => true, 'block_reason' => $reason], ['id' => $cid]); @@ -1567,11 +1567,10 @@ class Contact /** * Unblocks a contact * - * @param int $cid - * @return bool - * @throws \Exception + * @param int $cid Contact id to unblock + * @return bool Whether it was successfull */ - public static function unblock($cid) + public static function unblock(int $cid): bool { $return = self::update(['blocked' => false, 'block_reason' => null], ['id' => $cid]); @@ -1581,7 +1580,7 @@ class Contact /** * Ensure that cached avatar exist * - * @param integer $cid + * @param integer $cid Contact id */ public static function checkAvatarCache(int $cid) { @@ -1621,7 +1620,7 @@ class Contact * @param bool $no_update Don't perfom an update if no cached avatar was found * @return string photo path */ - private static function getAvatarPath(array $contact, string $size, $no_update = false) + private static function getAvatarPath(array $contact, string $size, bool $no_update = false): string { $contact = self::checkAvatarCacheByArray($contact, $no_update); @@ -1655,7 +1654,7 @@ class Contact * @param bool $no_update Don't perfom an update if no cached avatar was found * @return string photo path */ - public static function getPhoto(array $contact, bool $no_update = false) + public static function getPhoto(array $contact, bool $no_update = false): string { return self::getAvatarPath($contact, Proxy::SIZE_SMALL, $no_update); } @@ -1667,7 +1666,7 @@ class Contact * @param bool $no_update Don't perfom an update if no cached avatar was found * @return string photo path */ - public static function getThumb(array $contact, bool $no_update = false) + public static function getThumb(array $contact, bool $no_update = false): string { return self::getAvatarPath($contact, Proxy::SIZE_THUMB, $no_update); } @@ -1679,7 +1678,7 @@ class Contact * @param bool $no_update Don't perfom an update if no cached avatar was found * @return string photo path */ - public static function getMicro(array $contact, bool $no_update = false) + public static function getMicro(array $contact, bool $no_update = false): string { return self::getAvatarPath($contact, Proxy::SIZE_MICRO, $no_update); } @@ -1691,7 +1690,7 @@ class Contact * @param bool $no_update Don't perfom an update if no cached avatar was found * @return array contact array with avatar cache fields */ - private static function checkAvatarCacheByArray(array $contact, bool $no_update = false) + private static function checkAvatarCacheByArray(array $contact, bool $no_update = false): array { $update = false; $contact_fields = []; @@ -1797,7 +1796,7 @@ class Contact * @param string $size Size of the avatar picture * @return string avatar URL */ - public static function getDefaultAvatar(array $contact, string $size) + public static function getDefaultAvatar(array $contact, string $size): string { switch ($size) { case Proxy::SIZE_MICRO: diff --git a/src/Module/Directory.php b/src/Module/Directory.php index db88bf9fcd..5705f33e13 100644 --- a/src/Module/Directory.php +++ b/src/Module/Directory.php @@ -166,7 +166,7 @@ class Directory extends BaseModule 'img_hover' => $contact['name'], 'name' => $contact['name'], 'details' => $details, - 'account_type' => (!empty($contact['contact-type']) ? Model\Contact::getAccountType($contact['contact-type']) : ''), + 'account_type' => Model\Contact::getAccountType($contact['contact-type'] ?? ''), 'profile' => $profile, 'location' => $location_e, 'tags' => $contact['pub_keywords'], diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index d06e65c603..878b1570b4 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -348,7 +348,7 @@ class DFRN * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @todo Find proper type-hint for returned type */ - private static function addHeader(DOMDocument $doc, array $owner, string $authorelement, string $alternatelink = "", bool $public = false) + private static function addHeader(DOMDocument $doc, array $owner, string $authorelement, string $alternatelink = '', bool $public = false) { if ($alternatelink == "") { @@ -1063,7 +1063,7 @@ class DFRN * @throws \ImagickException * @todo Find good type-hints for all parameter */ - private static function fetchauthor(\DOMXPath $xpath, \DOMNode $context, array $importer, string $element, bool $onlyfetch, string $xml = ""): array + private static function fetchauthor(\DOMXPath $xpath, \DOMNode $context, array $importer, string $element, bool $onlyfetch, string $xml = ''): array { $author = []; $author["name"] = XML::getFirstNodeValue($xpath, $element."/atom:name/text()", $context); diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 1eb2cce908..7c1c674a43 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -76,7 +76,7 @@ class Diaspora */ public static function participantsForThread(array $item, array $contacts): array { - if (!in_array($item['private'], [Item::PUBLIC, Item::UNLISTED]) || in_array($item["verb"], [Activity::FOLLOW, Activity::TAG])) { + if (!in_array($item['private'], [Item::PUBLIC, Item::UNLISTED]) || in_array($item['verb'], [Activity::FOLLOW, Activity::TAG])) { Logger::info('Item is private or a participation request. It will not be relayed', ['guid' => $item['guid'], 'private' => $item['private'], 'verb' => $item['verb']]); return $contacts; } @@ -145,14 +145,14 @@ class Diaspora $sig = Strings::base64UrlDecode($children->sig); $key_id = $children->sig->attributes()->key_id[0]; - if ($key_id != "") { + if ($key_id != '') { $handle = Strings::base64UrlDecode($key_id); } $b64url_data = Strings::base64UrlEncode($data); - $msg = str_replace(["\n", "\r", " ", "\t"], ["", "", "", ""], $b64url_data); + $msg = str_replace(["\n", "\r", " ", "\t"], ['', '', '', ''], $b64url_data); - $signable_data = $msg.".".Strings::base64UrlEncode($type).".".Strings::base64UrlEncode($encoding).".".Strings::base64UrlEncode($alg); + $signable_data = $msg . '.' . Strings::base64UrlEncode($type) . '.' . Strings::base64UrlEncode($encoding) . '.' . Strings::base64UrlEncode($alg); if ($handle == '') { Logger::notice('No author could be decoded. Discarding. Message: ' . $envelope); @@ -260,13 +260,13 @@ class Diaspora $base = $basedom->children(ActivityNamespace::SALMON_ME); // Not sure if this cleaning is needed - $data = str_replace([" ", "\t", "\r", "\n"], ["", "", "", ""], $base->data); + $data = str_replace([" ", "\t", "\r", "\n"], ['', '', '', ''], $base->data); // Build the signed data $type = $base->data[0]->attributes()->type[0]; $encoding = $base->encoding; $alg = $base->alg; - $signed_data = $data.'.'.Strings::base64UrlEncode($type).'.'.Strings::base64UrlEncode($encoding).'.'.Strings::base64UrlEncode($alg); + $signed_data = $data . '.' . Strings::base64UrlEncode($type) . '.' . Strings::base64UrlEncode($encoding) . '.' . Strings::base64UrlEncode($alg); // This is the signature $signature = Strings::base64UrlDecode($base->sig); @@ -394,7 +394,7 @@ class Diaspora // unpack the data // strip whitespace so our data element will return to one big base64 blob - $data = str_replace([" ", "\t", "\r", "\n"], ["", "", "", ""], $base->data); + $data = str_replace([" ", "\t", "\r", "\n"], ['', '', '', ''], $base->data); // stash away some other stuff for later @@ -474,7 +474,10 @@ class Diaspora return false; } - $importer = ["uid" => 0, "page-flags" => User::PAGE_FLAGS_FREELOVE]; + $importer = [ + 'uid' => 0, + 'page-flags' => User::PAGE_FLAGS_FREELOVE + ]; $success = self::dispatch($importer, $msg, $fields, $direction); return $success; @@ -496,7 +499,7 @@ class Diaspora { // The sender is the handle of the contact that sent the message. // This will often be different with relayed messages (for example "like" and "comment") - $sender = $msg["author"]; + $sender = $msg['author']; // This is only needed for private postings since this is already done for public ones before if (is_null($fields)) { @@ -511,77 +514,77 @@ class Diaspora $type = $fields->getName(); - Logger::info('Received message', ['type' => $type, 'sender' => $sender, 'user' => $importer["uid"]]); + Logger::info('Received message', ['type' => $type, 'sender' => $sender, 'user' => $importer['uid']]); switch ($type) { - case "account_migration": + case 'account_migration': if (!$private) { Logger::notice('Message with type ' . $type . ' is not private, quitting.'); return false; } return self::receiveAccountMigration($importer, $fields); - case "account_deletion": + case 'account_deletion': return self::receiveAccountDeletion($fields); - case "comment": - return self::receiveComment($importer, $sender, $fields, $msg["message"], $direction); + case 'comment': + return self::receiveComment($importer, $sender, $fields, $msg['message'], $direction); - case "contact": + case 'contact': if (!$private) { Logger::notice('Message with type ' . $type . ' is not private, quitting.'); return false; } return self::receiveContactRequest($importer, $fields); - case "conversation": + case 'conversation': if (!$private) { Logger::notice('Message with type ' . $type . ' is not private, quitting.'); return false; } return self::receiveConversation($importer, $msg, $fields); - case "like": + case 'like': return self::receiveLike($importer, $sender, $fields, $direction); - case "message": + case 'message': if (!$private) { Logger::notice('Message with type ' . $type . ' is not private, quitting.'); return false; } return self::receiveMessage($importer, $fields); - case "participation": + case 'participation': if (!$private) { Logger::notice('Message with type ' . $type . ' is not private, quitting.'); return false; } return self::receiveParticipation($importer, $fields, $direction); - case "photo": // Not implemented + case 'photo': // Not implemented return self::receivePhoto($importer, $fields); - case "poll_participation": // Not implemented + case 'poll_participation': // Not implemented return self::receivePollParticipation($importer, $fields); - case "profile": + case 'profile': if (!$private) { Logger::notice('Message with type ' . $type . ' is not private, quitting.'); return false; } return self::receiveProfile($importer, $fields); - case "reshare": - return self::receiveReshare($importer, $fields, $msg["message"], $direction); + case 'reshare': + return self::receiveReshare($importer, $fields, $msg['message'], $direction); - case "retraction": + case 'retraction': return self::receiveRetraction($importer, $sender, $fields); - case "status_message": - return self::receiveStatusMessage($importer, $fields, $msg["message"], $direction); + case 'status_message': + return self::receiveStatusMessage($importer, $fields, $msg['message'], $direction); default: - Logger::notice("Unknown message type ".$type); + Logger::notice("Unknown message type " . $type); return false; } } @@ -600,7 +603,7 @@ class Diaspora */ private static function validPosting(array $msg) { - $data = XML::parseString($msg["message"]); + $data = XML::parseString($msg['message']); if (!is_object($data)) { Logger::info('No valid XML', ['message' => $msg['message']]); @@ -608,7 +611,7 @@ class Diaspora } // Is this the new or the old version? - if ($data->getName() == "XML") { + if ($data->getName() == 'XML') { $oldXML = true; foreach ($data->post->children() as $child) { $element = $child; @@ -621,106 +624,106 @@ class Diaspora $type = $element->getName(); $orig_type = $type; - Logger::debug("Got message type ".$type.": ".$msg["message"]); + Logger::debug("Got message type " . $type . ": " . $msg['message']); // All retractions are handled identically from now on. // In the new version there will only be "retraction". - if (in_array($type, ["signed_retraction", "relayable_retraction"])) - $type = "retraction"; + if (in_array($type, ['signed_retraction', 'relayable_retraction'])) + $type = 'retraction'; - if ($type == "request") { - $type = "contact"; + if ($type == 'request') { + $type = 'contact'; } - $fields = new SimpleXMLElement("<".$type."/>"); + $fields = new SimpleXMLElement('<' . $type . '/>'); - $signed_data = ""; + $signed_data = ''; $author_signature = null; $parent_author_signature = null; foreach ($element->children() as $fieldname => $entry) { if ($oldXML) { // Translation for the old XML structure - if ($fieldname == "diaspora_handle") { - $fieldname = "author"; + if ($fieldname == 'diaspora_handle') { + $fieldname = 'author'; } - if ($fieldname == "participant_handles") { - $fieldname = "participants"; + if ($fieldname == 'participant_handles') { + $fieldname = 'participants'; } - if (in_array($type, ["like", "participation"])) { - if ($fieldname == "target_type") { - $fieldname = "parent_type"; + if (in_array($type, ['like', 'participation'])) { + if ($fieldname == 'target_type') { + $fieldname = 'parent_type'; } } - if ($fieldname == "sender_handle") { - $fieldname = "author"; + if ($fieldname == 'sender_handle') { + $fieldname = 'author'; } - if ($fieldname == "recipient_handle") { - $fieldname = "recipient"; + if ($fieldname == 'recipient_handle') { + $fieldname = 'recipient'; } - if ($fieldname == "root_diaspora_id") { - $fieldname = "root_author"; + if ($fieldname == 'root_diaspora_id') { + $fieldname = 'root_author'; } - if ($type == "status_message") { - if ($fieldname == "raw_message") { - $fieldname = "text"; + if ($type == 'status_message') { + if ($fieldname == 'raw_message') { + $fieldname = 'text'; } } - if ($type == "retraction") { - if ($fieldname == "post_guid") { - $fieldname = "target_guid"; + if ($type == 'retraction') { + if ($fieldname == 'post_guid') { + $fieldname = 'target_guid'; } - if ($fieldname == "type") { - $fieldname = "target_type"; + if ($fieldname == 'type') { + $fieldname = 'target_type'; } } } - if (($fieldname == "author_signature") && ($entry != "")) { + if (($fieldname == 'author_signature') && ($entry != '')) { $author_signature = base64_decode($entry); - } elseif (($fieldname == "parent_author_signature") && ($entry != "")) { + } elseif (($fieldname == 'parent_author_signature') && ($entry != '')) { $parent_author_signature = base64_decode($entry); - } elseif (!in_array($fieldname, ["author_signature", "parent_author_signature", "target_author_signature"])) { - if ($signed_data != "") { - $signed_data .= ";"; + } elseif (!in_array($fieldname, ['author_signature', 'parent_author_signature', 'target_author_signature'])) { + if ($signed_data != '') { + $signed_data .= ';'; } $signed_data .= $entry; } - if (!in_array($fieldname, ["parent_author_signature", "target_author_signature"]) - || ($orig_type == "relayable_retraction") + if (!in_array($fieldname, ['parent_author_signature', 'target_author_signature']) + || ($orig_type == 'relayable_retraction') ) { XML::copy($entry, $fields, $fieldname); } } // This is something that shouldn't happen at all. - if (in_array($type, ["status_message", "reshare", "profile"])) { - if ($msg["author"] != $fields->author) { + if (in_array($type, ['status_message', 'reshare', 'profile'])) { + if ($msg['author'] != $fields->author) { Logger::notice("Message handle is not the same as envelope sender. Quitting this message."); return false; } } // Only some message types have signatures. So we quit here for the other types. - if (!in_array($type, ["comment", "like"])) { + if (!in_array($type, ['comment', 'like'])) { return $fields; } // No author_signature? This is a must, so we quit. if (!isset($author_signature)) { - Logger::info("No author signature for type ".$type." - Message: ".$msg["message"]); + Logger::info("No author signature for type " . $type . " - Message: " . $msg['message']); return false; } if (isset($parent_author_signature)) { - $key = self::key($msg["author"]); + $key = self::key($msg['author']); if (empty($key)) { - Logger::info('No key found for parent', ['author' => $msg["author"]]); + Logger::info('No key found for parent', ['author' => $msg['author']]); return false; } - if (!Crypto::rsaVerify($signed_data, $parent_author_signature, $key, "sha256")) { - Logger::info("No valid parent author signature for parent author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$parent_author_signature); + if (!Crypto::rsaVerify($signed_data, $parent_author_signature, $key, 'sha256')) { + Logger::info("No valid parent author signature for parent author " . $msg['author'] . " in type " . $type . " - signed data: " . $signed_data . " - Message: " . $msg['message'] . " - Signature " . $parent_author_signature); return false; } } @@ -731,8 +734,8 @@ class Diaspora return false; } - if (!Crypto::rsaVerify($signed_data, $author_signature, $key, "sha256")) { - Logger::info("No valid author signature for author ".$fields->author. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$author_signature); + if (!Crypto::rsaVerify($signed_data, $author_signature, $key, 'sha256')) { + Logger::info("No valid author signature for author " . $fields->author . " in type " . $type . " - signed data: " . $signed_data . " - Message: " . $msg['message'] . " - Signature " . $author_signature); return false; } else { return $fields; @@ -752,14 +755,14 @@ class Diaspora { $handle = strval($handle); - Logger::notice("Fetching diaspora key for: ".$handle); + Logger::notice("Fetching diaspora key for: " . $handle); $fcontact = FContact::getByURL($handle); if ($fcontact) { - return $fcontact["pubkey"]; + return $fcontact['pubkey']; } - return ""; + return ''; } /** @@ -855,15 +858,15 @@ class Diaspora if (Network::isUrlBlocked($contact['url'])) { return false; // We don't seem to like that person - } elseif ($contact["blocked"]) { + } elseif ($contact['blocked']) { // Maybe blocked, don't accept. return false; // We are following this person? - } elseif (($contact["rel"] == Contact::SHARING) || ($contact["rel"] == Contact::FRIEND)) { + } elseif (($contact['rel'] == Contact::SHARING) || ($contact['rel'] == Contact::FRIEND)) { // Yes, then it is fine. return true; // Is the message a global user or a comment? - } elseif (($importer["uid"] == 0) || $is_comment) { + } elseif (($importer['uid'] == 0) || $is_comment) { // Messages for the global users and comments are always accepted return true; } @@ -883,11 +886,11 @@ class Diaspora */ private static function allowedContactByHandle(array $importer, string $handle, bool $is_comment = false) { - $contact = self::contactByHandle($importer["uid"], $handle); + $contact = self::contactByHandle($importer['uid'], $handle); if (!$contact) { - Logger::notice("A Contact for handle ".$handle." and user ".$importer["uid"]." was not found"); + Logger::notice("A Contact for handle " . $handle . " and user " . $importer['uid'] . " was not found"); // If a contact isn't found, we accept it anyway if it is a comment - if ($is_comment && ($importer["uid"] != 0)) { + if ($is_comment && ($importer['uid'] != 0)) { return self::contactByHandle(0, $handle); } elseif ($is_comment) { return $importer; @@ -897,7 +900,7 @@ class Diaspora } if (!self::postAllow($importer, $contact, $is_comment)) { - Logger::notice("The handle: ".$handle." is not allowed to post to user ".$importer["uid"]); + Logger::notice("The handle: " . $handle . " is not allowed to post to user " . $importer['uid']); return false; } return $contact; @@ -916,8 +919,8 @@ class Diaspora { $item = Post::selectFirst(['id'], ['uid' => $uid, 'guid' => $guid]); if (DBA::isResult($item)) { - Logger::notice("message ".$guid." already exists for user ".$uid); - return $item["id"]; + Logger::notice("message " . $guid . " already exists for user " . $uid); + return $item['id']; } return false; @@ -931,13 +934,12 @@ class Diaspora */ private static function fetchGuid(array $item) { - $expression = "=diaspora://.*?/post/([0-9A-Za-z\-_@.:]{15,254}[0-9A-Za-z])=ism"; preg_replace_callback( - $expression, + "=diaspora://.*?/post/([0-9A-Za-z\-_@.:]{15,254}[0-9A-Za-z])=ism", function ($match) use ($item) { self::fetchGuidSub($match, $item); }, - $item["body"] + $item['body'] ); preg_replace_callback( @@ -945,7 +947,7 @@ class Diaspora function ($match) use ($item) { self::fetchGuidSub($match, $item); }, - $item["body"] + $item['body'] ); } @@ -970,11 +972,11 @@ class Diaspora $handle = FContact::getUrlByGuid($match[1]); if ($handle) { - $return = '@[url='.$handle.']'.$match[2].'[/url]'; + $return = '@[url=' . $handle . ']' . $match[2] . '[/url]'; } else { // No local match, restoring absolute remote URL from author scheme and host $author_url = parse_url($author_link); - $return = '[url='.$author_url['scheme'].'://'.$author_url['host'].'/people/'.$match[1].']'.$match[2].'[/url]'; + $return = '[url=' . $author_url['scheme'] . '://' . $author_url['host'] . '/people/' . $match[1] . ']' . $match[2] . '[/url]'; } return $return; @@ -996,8 +998,8 @@ class Diaspora */ private static function fetchGuidSub(array $match, array $item) { - if (!self::storeByGuid($match[1], $item["author-link"], true)) { - self::storeByGuid($match[1], $item["owner-link"], true); + if (!self::storeByGuid($match[1], $item['author-link'], true)) { + self::storeByGuid($match[1], $item['owner-link'], true); } } @@ -1016,13 +1018,13 @@ class Diaspora { $serverparts = parse_url($server); - if (empty($serverparts["host"]) || empty($serverparts["scheme"])) { + if (empty($serverparts['host']) || empty($serverparts['scheme'])) { return false; } - $server = $serverparts["scheme"]."://".$serverparts["host"]; + $server = $serverparts['scheme'] . '://' . $serverparts['host']; - Logger::info("Trying to fetch item ".$guid." from ".$server); + Logger::info("Trying to fetch item " . $guid . " from " . $server); $msg = self::message($guid, $server); @@ -1030,7 +1032,7 @@ class Diaspora return false; } - Logger::info("Successfully fetched item ".$guid." from ".$server); + Logger::info("Successfully fetched item " . $guid . " from " . $server); // Now call the dispatcher return self::dispatchPublic($msg, $force ? self::FORCED_FETCH : self::FETCHED); @@ -1056,9 +1058,9 @@ class Diaspora } // This will work for new Diaspora servers and Friendica servers from 3.5 - $source_url = $server."/fetch/post/".urlencode($guid); + $source_url = $server . '/fetch/post/' . urlencode($guid); - Logger::info("Fetch post from ".$source_url); + Logger::info("Fetch post from " . $source_url); $envelope = DI::httpClient()->fetch($source_url, HttpClientAccept::MAGIC); if ($envelope) { @@ -1098,7 +1100,7 @@ class Diaspora // Fetch the author - for the old and the new Diaspora version if ($source_xml->post->status_message && $source_xml->post->status_message->diaspora_handle) { $author = (string)$source_xml->post->status_message->diaspora_handle; - } elseif ($source_xml->author && ($source_xml->getName() == "status_message")) { + } elseif ($source_xml->author && ($source_xml->getName() == 'status_message')) { $author = (string)$source_xml->author; } @@ -1108,11 +1110,11 @@ class Diaspora return false; } - $msg = ["message" => $x, "author" => $author]; - - $msg["key"] = self::key($msg["author"]); - - return $msg; + return [ + 'message' => $x, + 'author' => $author, + 'key' => self::key($author) + ]; } /** @@ -1128,7 +1130,7 @@ class Diaspora public static function fetchByURL(string $url, int $uid = 0) { // Check for Diaspora (and Friendica) typical paths - if (!preg_match("=(https?://.+)/(?:posts|display|objects)/([a-zA-Z0-9-_@.:%]+[a-zA-Z0-9])=i", $url, $matches)) { + if (!preg_match('=(https?://.+)/(?:posts|display|objects)/([a-zA-Z0-9-_@.:%]+[a-zA-Z0-9])=i', $url, $matches)) { Logger::info('Invalid url', ['url' => $url]); return false; } @@ -1176,25 +1178,25 @@ class Diaspora if (!DBA::isResult($item)) { $person = FContact::getByURL($author); - $result = self::storeByGuid($guid, $person["url"], false); + $result = self::storeByGuid($guid, $person['url'], false); // We don't have an url for items that arrived at the public dispatcher - if (!$result && !empty($contact["url"])) { - $result = self::storeByGuid($guid, $contact["url"], false); + if (!$result && !empty($contact['url'])) { + $result = self::storeByGuid($guid, $contact['url'], false); } if ($result) { - Logger::info("Fetched missing item ".$guid." - result: ".$result); + Logger::info("Fetched missing item " . $guid . " - result: " . $result); $item = Post::selectFirst($fields, $condition); } } if (!DBA::isResult($item)) { - Logger::notice("parent item not found: parent: ".$guid." - user: ".$uid); + Logger::notice("parent item not found: parent: " . $guid . " - user: " . $uid); return false; } else { - Logger::notice("parent item found: parent: ".$guid." - user: ".$uid); + Logger::notice("parent item found: parent: " . $guid . " - user: " . $uid); return $item; } } @@ -1213,17 +1215,20 @@ class Diaspora */ private static function authorContactByUrl(array $def_contact, array $person, int $uid): array { - $condition = ['nurl' => Strings::normaliseLink($person["url"]), 'uid' => $uid]; + $condition = ['nurl' => Strings::normaliseLink($person['url']), 'uid' => $uid]; $contact = DBA::selectFirst('contact', ['id', 'network'], $condition); if (DBA::isResult($contact)) { - $cid = $contact["id"]; - $network = $contact["network"]; + $cid = $contact['id']; + $network = $contact['network']; } else { - $cid = $def_contact["id"]; + $cid = $def_contact['id']; $network = Protocol::DIASPORA; } - return ["cid" => $cid, "network" => $network]; + return [ + 'cid' => $cid, + 'network' => $network + ]; } /** @@ -1316,23 +1321,23 @@ class Diaspora private static function receiveAccountMigration(array $importer, $data): bool { // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data)); + Logger::debug('data=' . get_class($data)); $old_handle = XML::unescape($data->author); $new_handle = XML::unescape($data->profile->author); $signature = XML::unescape($data->signature); - $contact = self::contactByHandle($importer["uid"], $old_handle); + $contact = self::contactByHandle($importer['uid'], $old_handle); if (!$contact) { - Logger::notice("cannot find contact for sender: ".$old_handle." and user ".$importer["uid"]); + Logger::notice("cannot find contact for sender: " . $old_handle . " and user " . $importer['uid']); return false; } - Logger::notice("Got migration for ".$old_handle.", to ".$new_handle." with user ".$importer["uid"]); + Logger::notice("Got migration for " . $old_handle . ", to " . $new_handle . " with user " . $importer['uid']); // Check signature - $signed_text = 'AccountMigration:'.$old_handle.':'.$new_handle; + $signed_text = 'AccountMigration:' . $old_handle . ':' . $new_handle; $key = self::key($old_handle); - if (!Crypto::rsaVerify($signed_text, $signature, $key, "sha256")) { + if (!Crypto::rsaVerify($signed_text, $signature, $key, 'sha256')) { Logger::notice('No valid signature for migration.'); return false; } @@ -1343,15 +1348,21 @@ class Diaspora // change the technical stuff in contact $data = Probe::uri($new_handle); if ($data['network'] == Protocol::PHANTOM) { - Logger::notice('Account for '.$new_handle." couldn't be probed."); + Logger::notice("Account for " . $new_handle . " couldn't be probed."); return false; } - $fields = ['url' => $data['url'], 'nurl' => Strings::normaliseLink($data['url']), - 'name' => $data['name'], 'nick' => $data['nick'], - 'addr' => $data['addr'], 'batch' => $data['batch'], - 'notify' => $data['notify'], 'poll' => $data['poll'], - 'network' => $data['network']]; + $fields = [ + 'url' => $data['url'], + 'nurl' => Strings::normaliseLink($data['url']), + 'name' => $data['name'], + 'nick' => $data['nick'], + 'addr' => $data['addr'], + 'batch' => $data['batch'], + 'notify' => $data['notify'], + 'poll' => $data['poll'], + 'network' => $data['network'] + ]; Contact::update($fields, ['addr' => $old_handle]); @@ -1376,7 +1387,7 @@ class Diaspora $contacts = DBA::select('contact', ['id'], ['addr' => $author]); while ($contact = DBA::fetch($contacts)) { - Contact::remove($contact["id"]); + Contact::remove($contact['id']); } DBA::close($contacts); @@ -1400,7 +1411,7 @@ class Diaspora { $item = Post::selectFirst(['uri'], ['guid' => $guid]); if (DBA::isResult($item)) { - return $item["uri"]; + return $item['uri']; } elseif (!$onlyfound) { $person = FContact::getByURL($author); @@ -1411,7 +1422,7 @@ class Diaspora return $host_url . '/objects/' . $guid; } - return ""; + return ''; } /** @@ -1478,9 +1489,9 @@ class Diaspora if (isset($data->thread_parent_guid)) { $thread_parent_guid = XML::unescape($data->thread_parent_guid); - $thr_parent = self::getUriFromGuid("", $thread_parent_guid, true); + $thr_parent = self::getUriFromGuid('', $thread_parent_guid, true); } else { - $thr_parent = ""; + $thr_parent = ''; } $contact = self::allowedContactByHandle($importer, $sender, true); @@ -1492,12 +1503,12 @@ class Diaspora GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); } - $message_id = self::messageExists($importer["uid"], $guid); + $message_id = self::messageExists($importer['uid'], $guid); if ($message_id) { return true; } - $toplevel_parent_item = self::parentItem($importer["uid"], $parent_guid, $author, $contact); + $toplevel_parent_item = self::parentItem($importer['uid'], $parent_guid, $author, $contact); if (!$toplevel_parent_item) { return false; } @@ -1509,60 +1520,60 @@ class Diaspora } // Fetch the contact id - if we know this contact - $author_contact = self::authorContactByUrl($contact, $person, $importer["uid"]); + $author_contact = self::authorContactByUrl($contact, $person, $importer['uid']); $datarray = []; - $datarray["uid"] = $importer["uid"]; - $datarray["contact-id"] = $author_contact["cid"]; - $datarray["network"] = $author_contact["network"]; + $datarray['uid'] = $importer['uid']; + $datarray['contact-id'] = $author_contact['cid']; + $datarray['network'] = $author_contact['network']; - $datarray["author-link"] = $person["url"]; - $datarray["author-id"] = Contact::getIdForURL($person["url"], 0); + $datarray['author-link'] = $person['url']; + $datarray['author-id'] = Contact::getIdForURL($person['url'], 0); - $datarray["owner-link"] = $contact["url"]; - $datarray["owner-id"] = Contact::getIdForURL($contact["url"], 0); + $datarray['owner-link'] = $contact['url']; + $datarray['owner-id'] = Contact::getIdForURL($contact['url'], 0); // Will be overwritten for sharing accounts in Item::insert if (in_array($direction, [self::FETCHED, self::FORCED_FETCH])) { - $datarray["post-reason"] = Item::PR_FETCHED; - } elseif ($datarray["uid"] == 0) { - $datarray["post-reason"] = Item::PR_GLOBAL; + $datarray['post-reason'] = Item::PR_FETCHED; + } elseif ($datarray['uid'] == 0) { + $datarray['post-reason'] = Item::PR_GLOBAL; } else { - $datarray["post-reason"] = Item::PR_COMMENT; + $datarray['post-reason'] = Item::PR_COMMENT; } - $datarray["guid"] = $guid; - $datarray["uri"] = self::getUriFromGuid($author, $guid); + $datarray['guid'] = $guid; + $datarray['uri'] = self::getUriFromGuid($author, $guid); $datarray['uri-id'] = ItemURI::insert(['uri' => $datarray['uri'], 'guid' => $datarray['guid']]); - $datarray["verb"] = Activity::POST; - $datarray["gravity"] = GRAVITY_COMMENT; + $datarray['verb'] = Activity::POST; + $datarray['gravity'] = GRAVITY_COMMENT; $datarray['thr-parent'] = $thr_parent ?: $toplevel_parent_item['uri']; - $datarray["object-type"] = Activity\ObjectType::COMMENT; - $datarray["post-type"] = Item::PT_NOTE; + $datarray['object-type'] = Activity\ObjectType::COMMENT; + $datarray['post-type'] = Item::PT_NOTE; - $datarray["protocol"] = Conversation::PARCEL_DIASPORA; - $datarray["source"] = $xml; - $datarray["direction"] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; + $datarray['protocol'] = Conversation::PARCEL_DIASPORA; + $datarray['source'] = $xml; + $datarray['direction'] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; - $datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at; + $datarray['changed'] = $datarray['created'] = $datarray['edited'] = $created_at; - $datarray["plink"] = self::plink($author, $guid, $toplevel_parent_item['guid']); + $datarray['plink'] = self::plink($author, $guid, $toplevel_parent_item['guid']); $body = Markdown::toBBCode($text); - $datarray["body"] = self::replacePeopleGuid($body, $person["url"]); + $datarray['body'] = self::replacePeopleGuid($body, $person['url']); self::storeMentions($datarray['uri-id'], $text); - Tag::storeRawTagsFromBody($datarray['uri-id'], $datarray["body"]); + Tag::storeRawTagsFromBody($datarray['uri-id'], $datarray['body']); self::fetchGuid($datarray); // If we are the origin of the parent we store the original data. // We notify our followers during the item storage. - if ($toplevel_parent_item["origin"]) { + if ($toplevel_parent_item['origin']) { $datarray['diaspora_signed_text'] = json_encode($data); } @@ -1578,7 +1589,7 @@ class Diaspora } if ($message_id) { - Logger::info("Stored comment ".$datarray["guid"]." with message id ".$message_id); + Logger::info("Stored comment " . $datarray['guid'] . " with message id " . $message_id); if ($datarray['uid'] == 0) { Item::distribute($message_id, json_encode($data)); } @@ -1676,7 +1687,7 @@ class Diaspora return false; } - $contact = self::allowedContactByHandle($importer, $msg["author"], true); + $contact = self::allowedContactByHandle($importer, $msg['author'], true); if (!$contact) { return false; } @@ -1685,7 +1696,7 @@ class Diaspora GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); } - $conversation = DBA::selectFirst('conv', [], ['uid' => $importer["uid"], 'guid' => $guid]); + $conversation = DBA::selectFirst('conv', [], ['uid' => $importer['uid'], 'guid' => $guid]); if (!DBA::isResult($conversation)) { $r = DBA::insert('conv', [ 'uid' => $importer['uid'], @@ -1696,7 +1707,7 @@ class Diaspora 'subject' => $subject, 'recips' => $participants]); if ($r) { - $conversation = DBA::selectFirst('conv', [], ['uid' => $importer["uid"], 'guid' => $guid]); + $conversation = DBA::selectFirst('conv', [], ['uid' => $importer['uid'], 'guid' => $guid]); } } if (!$conversation) { @@ -1735,7 +1746,7 @@ class Diaspora // likes on comments aren't supported by Diaspora - only on posts // But maybe this will be supported in the future, so we will accept it. - if (!in_array($parent_type, ["Post", "Comment"])) { + if (!in_array($parent_type, ['Post', 'Comment'])) { return false; } @@ -1748,12 +1759,12 @@ class Diaspora GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); } - $message_id = self::messageExists($importer["uid"], $guid); + $message_id = self::messageExists($importer['uid'], $guid); if ($message_id) { return true; } - $toplevel_parent_item = self::parentItem($importer["uid"], $parent_guid, $author, $contact); + $toplevel_parent_item = self::parentItem($importer['uid'], $parent_guid, $author, $contact); if (!$toplevel_parent_item) { return false; } @@ -1765,11 +1776,11 @@ class Diaspora } // Fetch the contact id - if we know this contact - $author_contact = self::authorContactByUrl($contact, $person, $importer["uid"]); + $author_contact = self::authorContactByUrl($contact, $person, $importer['uid']); // "positive" = "false" would be a Dislike - wich isn't currently supported by Diaspora // We would accept this anyhow. - if ($positive == "true") { + if ($positive == 'true') { $verb = Activity::LIKE; } else { $verb = Activity::DISLIKE; @@ -1777,36 +1788,36 @@ class Diaspora $datarray = []; - $datarray["protocol"] = Conversation::PARCEL_DIASPORA; - $datarray["direction"] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; + $datarray['protocol'] = Conversation::PARCEL_DIASPORA; + $datarray['direction'] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; - $datarray["uid"] = $importer["uid"]; - $datarray["contact-id"] = $author_contact["cid"]; - $datarray["network"] = $author_contact["network"]; + $datarray['uid'] = $importer['uid']; + $datarray['contact-id'] = $author_contact['cid']; + $datarray['network'] = $author_contact['network']; - $datarray["owner-link"] = $datarray["author-link"] = $person["url"]; - $datarray["owner-id"] = $datarray["author-id"] = Contact::getIdForURL($person["url"], 0); + $datarray['owner-link'] = $datarray['author-link'] = $person['url']; + $datarray['owner-id'] = $datarray['author-id'] = Contact::getIdForURL($person['url'], 0); - $datarray["guid"] = $guid; - $datarray["uri"] = self::getUriFromGuid($author, $guid); + $datarray['guid'] = $guid; + $datarray['uri'] = self::getUriFromGuid($author, $guid); - $datarray["verb"] = $verb; - $datarray["gravity"] = GRAVITY_ACTIVITY; + $datarray['verb'] = $verb; + $datarray['gravity'] = GRAVITY_ACTIVITY; $datarray['thr-parent'] = $toplevel_parent_item['uri']; - $datarray["object-type"] = Activity\ObjectType::NOTE; + $datarray['object-type'] = Activity\ObjectType::NOTE; - $datarray["body"] = $verb; + $datarray['body'] = $verb; // Diaspora doesn't provide a date for likes - $datarray["changed"] = $datarray["created"] = $datarray["edited"] = DateTimeFormat::utcNow(); + $datarray['changed'] = $datarray['created'] = $datarray['edited'] = DateTimeFormat::utcNow(); // like on comments have the comment as parent. So we need to fetch the toplevel parent if ($toplevel_parent_item['gravity'] != GRAVITY_PARENT) { $toplevel = Post::selectFirst(['origin'], ['id' => $toplevel_parent_item['parent']]); - $origin = $toplevel["origin"]; + $origin = $toplevel['origin']; } else { - $origin = $toplevel_parent_item["origin"]; + $origin = $toplevel_parent_item['origin']; } // If we are the origin of the parent we store the original data. @@ -1827,7 +1838,7 @@ class Diaspora } if ($message_id) { - Logger::info("Stored like ".$datarray["guid"]." with message id ".$message_id); + Logger::info("Stored like " . $datarray['guid'] . " with message id " . $message_id); if ($datarray['uid'] == 0) { Item::distribute($message_id, json_encode($data)); } @@ -1866,7 +1877,7 @@ class Diaspora $conversation = null; - $condition = ['uid' => $importer["uid"], 'guid' => $conversation_guid]; + $condition = ['uid' => $importer['uid'], 'guid' => $conversation_guid]; $conversation = DBA::selectFirst('conv', [], $condition); if (!DBA::isResult($conversation)) { @@ -1874,7 +1885,7 @@ class Diaspora return false; } - $message_uri = $author.":".$guid; + $message_uri = $author . ':' . $guid; $person = FContact::getByURL($author); if (!$person) { @@ -1931,11 +1942,11 @@ class Diaspora GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); } - if (self::messageExists($importer["uid"], $guid)) { + if (self::messageExists($importer['uid'], $guid)) { return true; } - $toplevel_parent_item = self::parentItem($importer["uid"], $parent_guid, $author, $contact); + $toplevel_parent_item = self::parentItem($importer['uid'], $parent_guid, $author, $contact); if (!$toplevel_parent_item) { return false; } @@ -1951,38 +1962,38 @@ class Diaspora $person = FContact::getByURL($author); if (!is_array($person)) { - Logger::notice("Person not found: ".$author); + Logger::notice("Person not found: " . $author); return false; } - $author_contact = self::authorContactByUrl($contact, $person, $importer["uid"]); + $author_contact = self::authorContactByUrl($contact, $person, $importer['uid']); // Store participation $datarray = []; - $datarray["protocol"] = Conversation::PARCEL_DIASPORA; - $datarray["direction"] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; + $datarray['protocol'] = Conversation::PARCEL_DIASPORA; + $datarray['direction'] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; - $datarray["uid"] = $importer["uid"]; - $datarray["contact-id"] = $author_contact["cid"]; - $datarray["network"] = $author_contact["network"]; + $datarray['uid'] = $importer['uid']; + $datarray['contact-id'] = $author_contact['cid']; + $datarray['network'] = $author_contact['network']; - $datarray["owner-link"] = $datarray["author-link"] = $person["url"]; - $datarray["owner-id"] = $datarray["author-id"] = Contact::getIdForURL($person["url"], 0); + $datarray['owner-link'] = $datarray['author-link'] = $person['url']; + $datarray['owner-id'] = $datarray['author-id'] = Contact::getIdForURL($person['url'], 0); - $datarray["guid"] = $guid; - $datarray["uri"] = self::getUriFromGuid($author, $guid); + $datarray['guid'] = $guid; + $datarray['uri'] = self::getUriFromGuid($author, $guid); - $datarray["verb"] = Activity::FOLLOW; - $datarray["gravity"] = GRAVITY_ACTIVITY; + $datarray['verb'] = Activity::FOLLOW; + $datarray['gravity'] = GRAVITY_ACTIVITY; $datarray['thr-parent'] = $toplevel_parent_item['uri']; - $datarray["object-type"] = Activity\ObjectType::NOTE; + $datarray['object-type'] = Activity\ObjectType::NOTE; - $datarray["body"] = Activity::FOLLOW; + $datarray['body'] = Activity::FOLLOW; // Diaspora doesn't provide a date for a participation - $datarray["changed"] = $datarray["created"] = $datarray["edited"] = DateTimeFormat::utcNow(); + $datarray['changed'] = $datarray['created'] = $datarray['edited'] = DateTimeFormat::utcNow(); if (Item::isTooOld($datarray)) { Logger::info('Participation is too old', ['created' => $datarray['created'], 'uid' => $datarray['uid'], 'guid' => $datarray['guid']]); @@ -2012,8 +2023,8 @@ class Diaspora continue; } - Logger::info('Deliver participation', ['item' => $comment['id'], 'contact' => $author_contact["cid"]]); - if (Worker::add(PRIORITY_HIGH, 'Delivery', Delivery::POST, $comment['id'], $author_contact["cid"])) { + Logger::info('Deliver participation', ['item' => $comment['id'], 'contact' => $author_contact['cid']]); + if (Worker::add(PRIORITY_HIGH, 'Delivery', Delivery::POST, $comment['id'], $author_contact['cid'])) { Post\DeliveryData::incrementQueueCount($comment['uri-id'], 1); } } @@ -2067,58 +2078,59 @@ class Diaspora Logger::debug('data='.get_class($data)); $author = strtolower(XML::unescape($data->author)); - $contact = self::contactByHandle($importer["uid"], $author); + $contact = self::contactByHandle($importer['uid'], $author); if (!$contact) { return false; } - $name = XML::unescape($data->first_name).((strlen($data->last_name)) ? " ".XML::unescape($data->last_name) : ""); + $name = XML::unescape($data->first_name).((strlen($data->last_name)) ? ' ' . XML::unescape($data->last_name) : ''); $image_url = XML::unescape($data->image_url); $birthday = XML::unescape($data->birthday); $about = Markdown::toBBCode(XML::unescape($data->bio)); $location = Markdown::toBBCode(XML::unescape($data->location)); - $searchable = (XML::unescape($data->searchable) == "true"); - $nsfw = (XML::unescape($data->nsfw) == "true"); + $searchable = (XML::unescape($data->searchable) == 'true'); + $nsfw = (XML::unescape($data->nsfw) == 'true'); $tags = XML::unescape($data->tag_string); - $tags = explode("#", $tags); + $tags = explode('#', $tags); $keywords = []; foreach ($tags as $tag) { $tag = trim(strtolower($tag)); - if ($tag != "") { + if ($tag != '') { $keywords[] = $tag; } } - $keywords = implode(", ", $keywords); + $keywords = implode(', ', $keywords); - $handle_parts = explode("@", $author); + $handle_parts = explode('@', $author); $nick = $handle_parts[0]; - if ($name === "") { + if ($name === '') { $name = $handle_parts[0]; } - if (preg_match("|^https?://|", $image_url) === 0) { - $image_url = "http://".$handle_parts[1].$image_url; + if (preg_match('|^https?://|', $image_url) === 0) { + // @TODO No HTTPS here? + $image_url = 'http://' . $handle_parts[1] . $image_url; } - Contact::updateAvatar($contact["id"], $image_url); + Contact::updateAvatar($contact['id'], $image_url); // Generic birthday. We don't know the timezone. The year is irrelevant. - $birthday = str_replace("1000", "1901", $birthday); + $birthday = str_replace('1000', '1901', $birthday); - if ($birthday != "") { - $birthday = DateTimeFormat::utc($birthday, "Y-m-d"); + if ($birthday != '') { + $birthday = DateTimeFormat::utc($birthday, 'Y-m-d'); } // this is to prevent multiple birthday notifications in a single year // if we already have a stored birthday and the 'm-d' part hasn't changed, preserve the entry, which will preserve the notify year - if (substr($birthday, 5) === substr($contact["bd"], 5)) { - $birthday = $contact["bd"]; + if (substr($birthday, 5) === substr($contact['bd'], 5)) { + $birthday = $contact['bd']; } $fields = ['name' => $name, 'location' => $location, @@ -2132,7 +2144,7 @@ class Diaspora Contact::update($fields, ['id' => $contact['id']]); - Logger::info("Profile of contact ".$contact["id"]." stored for user ".$importer["uid"]); + Logger::info("Profile of contact " . $contact['id'] . " stored for user " . $importer['uid']); return true; } @@ -2147,10 +2159,10 @@ class Diaspora */ private static function receiveRequestMakeFriend(array $importer, array $contact) { - if ($contact["rel"] == Contact::SHARING) { + if ($contact['rel'] == Contact::SHARING) { Contact::update( ['rel' => Contact::FRIEND, 'writable' => true], - ['id' => $contact["id"], 'uid' => $importer["uid"]] + ['id' => $contact['id'], 'uid' => $importer['uid']] ); } } @@ -2178,64 +2190,64 @@ class Diaspora // the current protocol version doesn't know these fields // That means that we will assume their existance if (isset($data->following)) { - $following = (XML::unescape($data->following) == "true"); + $following = (XML::unescape($data->following) == 'true'); } else { $following = true; } if (isset($data->sharing)) { - $sharing = (XML::unescape($data->sharing) == "true"); + $sharing = (XML::unescape($data->sharing) == 'true'); } else { $sharing = true; } - $contact = self::contactByHandle($importer["uid"], $author); + $contact = self::contactByHandle($importer['uid'], $author); // perhaps we were already sharing with this person. Now they're sharing with us. // That makes us friends. if ($contact) { if ($following) { - Logger::info("Author ".$author." (Contact ".$contact["id"].") wants to follow us."); + Logger::info("Author " . $author . " (Contact " . $contact['id'] . ") wants to follow us."); self::receiveRequestMakeFriend($importer, $contact); // refetch the contact array - $contact = self::contactByHandle($importer["uid"], $author); + $contact = self::contactByHandle($importer['uid'], $author); // If we are now friends, we are sending a share message. // Normally we needn't to do so, but the first message could have been vanished. - if (in_array($contact["rel"], [Contact::FRIEND])) { - $user = DBA::selectFirst('user', [], ['uid' => $importer["uid"]]); + if (in_array($contact['rel'], [Contact::FRIEND])) { + $user = DBA::selectFirst('user', [], ['uid' => $importer['uid']]); if (DBA::isResult($user)) { - Logger::info("Sending share message to author ".$author." - Contact: ".$contact["id"]." - User: ".$importer["uid"]); + Logger::info("Sending share message to author " . $author . " - Contact: " . $contact['id'] . " - User: " . $importer['uid']); self::sendShare($user, $contact); } } return true; } else { - Logger::info("Author ".$author." doesn't want to follow us anymore."); + Logger::info("Author " . $author . " doesn't want to follow us anymore."); Contact::removeFollower($contact); return true; } } - if (!$following && $sharing && in_array($importer["page-flags"], [User::PAGE_FLAGS_SOAPBOX, User::PAGE_FLAGS_NORMAL])) { - Logger::info("Author ".$author." wants to share with us - but doesn't want to listen. Request is ignored."); + if (!$following && $sharing && in_array($importer['page-flags'], [User::PAGE_FLAGS_SOAPBOX, User::PAGE_FLAGS_NORMAL])) { + Logger::info("Author " . $author . " wants to share with us - but doesn't want to listen. Request is ignored."); return false; } elseif (!$following && !$sharing) { - Logger::info("Author ".$author." doesn't want anything - and we don't know the author. Request is ignored."); + Logger::info("Author " . $author . " doesn't want anything - and we don't know the author. Request is ignored."); return false; } elseif (!$following && $sharing) { - Logger::info("Author ".$author." wants to share with us."); + Logger::info("Author " . $author . " wants to share with us."); } elseif ($following && $sharing) { - Logger::info("Author ".$author." wants to have a bidirectional conection."); + Logger::info("Author " . $author . " wants to have a bidirectional conection."); } elseif ($following && !$sharing) { - Logger::info("Author ".$author." wants to listen to us."); + Logger::info("Author " . $author . " wants to listen to us."); } $ret = FContact::getByURL($author); - if (!$ret || ($ret["network"] != Protocol::DIASPORA)) { - Logger::notice("Cannot resolve diaspora handle ".$author." for ".$recipient); + if (!$ret || ($ret['network'] != Protocol::DIASPORA)) { + Logger::notice("Cannot resolve diaspora handle " . $author . " for ".$recipient); return false; } @@ -2292,17 +2304,17 @@ class Diaspora $item = Post::selectFirst($fields, $condition); if (DBA::isResult($item)) { - Logger::notice("reshared message ".$guid." already exists on system."); + Logger::notice("reshared message " . $guid . " already exists on system."); // Maybe it is already a reshared item? // Then refetch the content, if it is a reshare from a reshare. // If it is a reshared post from another network then reformat to avoid display problems with two share elements - if (self::isReshare($item["body"], true)) { + if (self::isReshare($item['body'], true)) { $item = []; - } elseif (self::isReshare($item["body"], false) || strstr($item["body"], "[share")) { - $item["body"] = Markdown::toBBCode(BBCode::toMarkdown($item["body"])); + } elseif (self::isReshare($item['body'], false) || strstr($item['body'], '[share')) { + $item['body'] = Markdown::toBBCode(BBCode::toMarkdown($item['body'])); - $item["body"] = self::replacePeopleGuid($item["body"], $item["author-link"]); + $item['body'] = self::replacePeopleGuid($item['body'], $item['author-link']); return $item; } else { @@ -2316,13 +2328,13 @@ class Diaspora return false; } - $server = "https://".substr($orig_author, strpos($orig_author, "@") + 1); - Logger::notice("1st try: reshared message ".$guid." will be fetched via SSL from the server ".$server); + $server = 'https://' . substr($orig_author, strpos($orig_author, '@') + 1); + Logger::notice("1st try: reshared message " . $guid . " will be fetched via SSL from the server " . $server); $stored = self::storeByGuid($guid, $server, true); if (!$stored) { - $server = "http://".substr($orig_author, strpos($orig_author, "@") + 1); - Logger::notice("2nd try: reshared message ".$guid." will be fetched without SSL from the server ".$server); + $server = 'http://' . substr($orig_author, strpos($orig_author, '@') + 1); + Logger::notice("2nd try: reshared message " . $guid . " will be fetched without SSL from the server " . $server); $stored = self::storeByGuid($guid, $server, true); } @@ -2334,9 +2346,9 @@ class Diaspora if (DBA::isResult($item)) { // If it is a reshared post from another network then reformat to avoid display problems with two share elements - if (self::isReshare($item["body"], false)) { - $item["body"] = Markdown::toBBCode(BBCode::toMarkdown($item["body"])); - $item["body"] = self::replacePeopleGuid($item["body"], $item["author-link"]); + if (self::isReshare($item['body'], false)) { + $item['body'] = Markdown::toBBCode(BBCode::toMarkdown($item['body'])); + $item['body'] = self::replacePeopleGuid($item['body'], $item['author-link']); } return $item; @@ -2434,7 +2446,7 @@ class Diaspora GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); } - $message_id = self::messageExists($importer["uid"], $guid); + $message_id = self::messageExists($importer['uid'], $guid); if ($message_id) { return true; } @@ -2450,53 +2462,53 @@ class Diaspora $datarray = []; - $datarray["uid"] = $importer["uid"]; - $datarray["contact-id"] = $contact["id"]; - $datarray["network"] = Protocol::DIASPORA; + $datarray['uid'] = $importer['uid']; + $datarray['contact-id'] = $contact['id']; + $datarray['network'] = Protocol::DIASPORA; - $datarray["author-link"] = $contact["url"]; - $datarray["author-id"] = Contact::getIdForURL($contact["url"], 0); + $datarray['author-link'] = $contact['url']; + $datarray['author-id'] = Contact::getIdForURL($contact['url'], 0); - $datarray["owner-link"] = $datarray["author-link"]; - $datarray["owner-id"] = $datarray["author-id"]; + $datarray['owner-link'] = $datarray['author-link']; + $datarray['owner-id'] = $datarray['author-id']; - $datarray["guid"] = $guid; - $datarray["uri"] = $datarray["thr-parent"] = self::getUriFromGuid($author, $guid); + $datarray['guid'] = $guid; + $datarray['uri'] = $datarray['thr-parent'] = self::getUriFromGuid($author, $guid); $datarray['uri-id'] = ItemURI::insert(['uri' => $datarray['uri'], 'guid' => $datarray['guid']]); - $datarray["verb"] = Activity::POST; - $datarray["gravity"] = GRAVITY_PARENT; + $datarray['verb'] = Activity::POST; + $datarray['gravity'] = GRAVITY_PARENT; - $datarray["protocol"] = Conversation::PARCEL_DIASPORA; - $datarray["source"] = $xml; - $datarray["direction"] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; + $datarray['protocol'] = Conversation::PARCEL_DIASPORA; + $datarray['source'] = $xml; + $datarray['direction'] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; /// @todo Copy tag data from original post $prefix = BBCode::getShareOpeningTag( - $original_item["author-name"], - $original_item["author-link"], - $original_item["author-avatar"], - $original_item["plink"], - $original_item["created"], - $original_item["guid"] + $original_item['author-name'], + $original_item['author-link'], + $original_item['author-avatar'], + $original_item['plink'], + $original_item['created'], + $original_item['guid'] ); if (!empty($original_item['title'])) { $prefix .= '[h3]' . $original_item['title'] . "[/h3]\n"; } - $datarray["body"] = $prefix.$original_item["body"]."[/share]"; + $datarray['body'] = $prefix.$original_item['body'] . '[/share]'; - Tag::storeFromBody($datarray['uri-id'], $datarray["body"]); + Tag::storeFromBody($datarray['uri-id'], $datarray['body']); - $datarray["app"] = $original_item["app"]; + $datarray['app'] = $original_item['app']; - $datarray["plink"] = self::plink($author, $guid); - $datarray["private"] = (($public == "false") ? Item::PRIVATE : Item::PUBLIC); - $datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at; + $datarray['plink'] = self::plink($author, $guid); + $datarray['private'] = (($public == 'false') ? Item::PRIVATE : Item::PUBLIC); + $datarray['changed'] = $datarray['created'] = $datarray['edited'] = $created_at; - $datarray["object-type"] = $original_item["object-type"]; + $datarray['object-type'] = $original_item['object-type']; self::fetchGuid($datarray); @@ -2509,13 +2521,13 @@ class Diaspora self::sendParticipation($contact, $datarray); - $root_message_id = self::messageExists($importer["uid"], $root_guid); + $root_message_id = self::messageExists($importer['uid'], $root_guid); if ($root_message_id) { self::addReshareActivity($datarray, $root_message_id, $guid, $author); } if ($message_id) { - Logger::info("Stored reshare ".$datarray["guid"]." with message id ".$message_id); + Logger::info("Stored reshare " . $datarray['guid'] . " with message id " . $message_id); if ($datarray['uid'] == 0) { Item::distribute($message_id); } @@ -2545,12 +2557,12 @@ class Diaspora $person = FContact::getByURL($author); if (!is_array($person)) { - Logger::notice("unable to find author detail for ".$author); + Logger::notice("unable to find author detail for " . $author); return false; } - if (empty($contact["url"])) { - $contact["url"] = $person["url"]; + if (empty($contact['url'])) { + $contact['url'] = $person['url']; } // Fetch items that are about to be deleted @@ -2565,7 +2577,7 @@ class Diaspora $r = Post::select($fields, $condition); if (!DBA::isResult($r)) { - Logger::notice("Target guid ".$target_guid." was not found on this system for user ".$importer['uid']."."); + Logger::notice("Target guid " . $target_guid . " was not found on this system for user " . $importer['uid'] . "."); return false; } @@ -2579,14 +2591,14 @@ class Diaspora $parent = Post::selectFirst(['author-link'], ['id' => $item['parent']]); // Only delete it if the parent author really fits - if (!Strings::compareLink($parent["author-link"], $contact["url"]) && !Strings::compareLink($item["author-link"], $contact["url"])) { - Logger::info("Thread author ".$parent["author-link"]." and item author ".$item["author-link"]." don't fit to expected contact ".$contact["url"]); + if (!Strings::compareLink($parent['author-link'], $contact['url']) && !Strings::compareLink($item['author-link'], $contact['url'])) { + Logger::info("Thread author " . $parent['author-link'] . " and item author " . $item['author-link'] . " don't fit to expected contact " . $contact['url']); continue; } Item::markForDeletion(['id' => $item['id']]); - Logger::info("Deleted target ".$target_guid." (".$item["id"].") from user ".$item["uid"]." parent: ".$item['parent']); + Logger::info("Deleted target " . $target_guid . " (" . $item['id'] . ") from user " . $item['uid'] . " parent: " . $item['parent']); } DBA::close($r); @@ -2609,9 +2621,9 @@ class Diaspora Logger::debug('data='.get_class($data)); $target_type = XML::unescape($data->target_type); - $contact = self::contactByHandle($importer["uid"], $sender); - if (!$contact && (in_array($target_type, ["Contact", "Person"]))) { - Logger::notice("cannot find contact for sender: ".$sender." and user ".$importer["uid"]); + $contact = self::contactByHandle($importer['uid'], $sender); + if (!$contact && (in_array($target_type, ['Contact', 'Person']))) { + Logger::notice("cannot find contact for sender: " . $sender . " and user " . $importer['uid']); return false; } @@ -2619,23 +2631,23 @@ class Diaspora $contact = []; } - Logger::info("Got retraction for ".$target_type.", sender ".$sender." and user ".$importer["uid"]); + Logger::info("Got retraction for " . $target_type . ", sender " . $sender . " and user " . $importer['uid']); switch ($target_type) { - case "Comment": - case "Like": - case "Post": - case "Reshare": - case "StatusMessage": + case 'Comment': + case 'Like': + case 'Post': + case 'Reshare': + case 'StatusMessage': return self::itemRetraction($importer, $contact, $data); - case "PollParticipation": - case "Photo": + case 'PollParticipation': + case 'Photo': // Currently unsupported break; default: - Logger::notice("Unknown target type ".$target_type); + Logger::notice("Unknown target type " . $target_type); return false; } return true; @@ -2654,8 +2666,7 @@ class Diaspora private static function isSolicitedMessage(array $item, string $author, string $body, int $direction): bool { $contact = Contact::getByURL($author); - if (DBA::exists('contact', ["`nurl` = ? AND `uid` != ? AND `rel` IN (?, ?)", - $contact['nurl'], 0, Contact::FRIEND, Contact::SHARING])) { + if (DBA::exists('contact', ['`nurl` = ? AND `uid` != ? AND `rel` IN (?, ?)', $contact['nurl'], 0, Contact::FRIEND, Contact::SHARING])) { Logger::debug('Author has got followers - accepted', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri'], 'author' => $author]); return true; } @@ -2726,7 +2737,7 @@ class Diaspora GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); } - $message_id = self::messageExists($importer["uid"], $guid); + $message_id = self::messageExists($importer['uid'], $guid); if ($message_id) { return true; } @@ -2742,8 +2753,8 @@ class Diaspora $datarray = []; - $datarray["guid"] = $guid; - $datarray["uri"] = $datarray["thr-parent"] = self::getUriFromGuid($author, $guid); + $datarray['guid'] = $guid; + $datarray['uri'] = $datarray['thr-parent'] = self::getUriFromGuid($author, $guid); $datarray['uri-id'] = ItemURI::insert(['uri' => $datarray['uri'], 'guid' => $datarray['guid']]); // Attach embedded pictures to the body @@ -2752,14 +2763,14 @@ class Diaspora self::storePhotoAsMedia($datarray['uri-id'], $photo); } - $datarray["object-type"] = Activity\ObjectType::IMAGE; - $datarray["post-type"] = Item::PT_IMAGE; + $datarray['object-type'] = Activity\ObjectType::IMAGE; + $datarray['post-type'] = Item::PT_IMAGE; } elseif ($data->poll) { - $datarray["object-type"] = Activity\ObjectType::NOTE; - $datarray["post-type"] = Item::PT_POLL; + $datarray['object-type'] = Activity\ObjectType::NOTE; + $datarray['post-type'] = Item::PT_POLL; } else { - $datarray["object-type"] = Activity\ObjectType::NOTE; - $datarray["post-type"] = Item::PT_NOTE; + $datarray['object-type'] = Activity\ObjectType::NOTE; + $datarray['post-type'] = Item::PT_NOTE; } /// @todo enable support for polls @@ -2771,54 +2782,54 @@ class Diaspora /// @todo enable support for events - $datarray["uid"] = $importer["uid"]; - $datarray["contact-id"] = $contact["id"]; - $datarray["network"] = Protocol::DIASPORA; + $datarray['uid'] = $importer['uid']; + $datarray['contact-id'] = $contact['id']; + $datarray['network'] = Protocol::DIASPORA; - $datarray["author-link"] = $contact["url"]; - $datarray["author-id"] = Contact::getIdForURL($contact["url"], 0); + $datarray['author-link'] = $contact['url']; + $datarray['author-id'] = Contact::getIdForURL($contact['url'], 0); - $datarray["owner-link"] = $datarray["author-link"]; - $datarray["owner-id"] = $datarray["author-id"]; + $datarray['owner-link'] = $datarray['author-link']; + $datarray['owner-id'] = $datarray['author-id']; - $datarray["verb"] = Activity::POST; - $datarray["gravity"] = GRAVITY_PARENT; + $datarray['verb'] = Activity::POST; + $datarray['gravity'] = GRAVITY_PARENT; - $datarray["protocol"] = Conversation::PARCEL_DIASPORA; - $datarray["source"] = $xml; - $datarray["direction"] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; + $datarray['protocol'] = Conversation::PARCEL_DIASPORA; + $datarray['source'] = $xml; + $datarray['direction'] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; if (in_array($direction, [self::FETCHED, self::FORCED_FETCH])) { - $datarray["post-reason"] = Item::PR_FETCHED; - } elseif ($datarray["uid"] == 0) { - $datarray["post-reason"] = Item::PR_GLOBAL; + $datarray['post-reason'] = Item::PR_FETCHED; + } elseif ($datarray['uid'] == 0) { + $datarray['post-reason'] = Item::PR_GLOBAL; } - $datarray["body"] = self::replacePeopleGuid($body, $contact["url"]); - $datarray["raw-body"] = self::replacePeopleGuid($raw_body, $contact["url"]); + $datarray['body'] = self::replacePeopleGuid($body, $contact['url']); + $datarray['raw-body'] = self::replacePeopleGuid($raw_body, $contact['url']); self::storeMentions($datarray['uri-id'], $text); - Tag::storeRawTagsFromBody($datarray['uri-id'], $datarray["body"]); + Tag::storeRawTagsFromBody($datarray['uri-id'], $datarray['body']); if (!self::isSolicitedMessage($datarray, $author, $body, $direction)) { DBA::delete('item-uri', ['uri' => $datarray['uri']]); return false; } - if ($provider_display_name != "") { - $datarray["app"] = $provider_display_name; + if ($provider_display_name != '') { + $datarray['app'] = $provider_display_name; } - $datarray["plink"] = self::plink($author, $guid); - $datarray["private"] = (($public == "false") ? Item::PRIVATE : Item::PUBLIC); - $datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at; + $datarray['plink'] = self::plink($author, $guid); + $datarray['private'] = (($public == 'false') ? Item::PRIVATE : Item::PUBLIC); + $datarray['changed'] = $datarray['created'] = $datarray['edited'] = $created_at; - if (isset($address["address"])) { - $datarray["location"] = $address["address"]; + if (isset($address['address'])) { + $datarray['location'] = $address['address']; } - if (isset($address["lat"]) && isset($address["lng"])) { - $datarray["coord"] = $address["lat"]." ".$address["lng"]; + if (isset($address['lat']) && isset($address['lng'])) { + $datarray['coord'] = $address['lat'] . " " . $address['lng']; } self::fetchGuid($datarray); @@ -2833,7 +2844,7 @@ class Diaspora self::sendParticipation($contact, $datarray); if ($message_id) { - Logger::info("Stored item ".$datarray["guid"]." with message id ".$message_id); + Logger::info("Stored item " . $datarray['guid'] . " with message id " . $message_id); if ($datarray['uid'] == 0) { Item::distribute($message_id); } @@ -2857,19 +2868,19 @@ class Diaspora */ private static function myHandle(array $contact): string { - if (!empty($contact["addr"])) { - return $contact["addr"]; + if (!empty($contact['addr'])) { + return $contact['addr']; } // Normally we should have a filled "addr" field - but in the past this wasn't the case // So - just in case - we build the the address here. - if ($contact["nickname"] != "") { - $nick = $contact["nickname"]; + if ($contact['nickname'] != '') { + $nick = $contact['nickname']; } else { - $nick = $contact["nick"]; + $nick = $contact['nick']; } - return $nick . "@" . substr(DI::baseUrl(), strpos(DI::baseUrl(), "://") + 3); + return $nick . '@' . substr(DI::baseUrl(), strpos(DI::baseUrl(), '://') + 3); } @@ -2902,16 +2913,18 @@ class Diaspora $ciphertext = self::aesEncrypt($aes_key, $iv, $msg); - $json = json_encode(["iv" => $b_iv, "key" => $b_aes_key]); + $json = json_encode(['iv' => $b_iv, 'key' => $b_aes_key]); - $encrypted_key_bundle = ""; + $encrypted_key_bundle = ''; if (!@openssl_public_encrypt($json, $encrypted_key_bundle, $pubkey)) { return false; } $json_object = json_encode( - ["aes_key" => base64_encode($encrypted_key_bundle), - "encrypted_magic_envelope" => base64_encode($ciphertext)] + [ + 'aes_key' => base64_encode($encrypted_key_bundle), + 'encrypted_magic_envelope' => base64_encode($ciphertext) + ] ); return $json_object; @@ -2929,30 +2942,34 @@ class Diaspora public static function buildMagicEnvelope(string $msg, array $user): string { $b64url_data = Strings::base64UrlEncode($msg); - $data = str_replace(["\n", "\r", " ", "\t"], ["", "", "", ""], $b64url_data); + $data = str_replace(["\n", "\r", " ", "\t"], ['', '', '', ''], $b64url_data); $key_id = Strings::base64UrlEncode(self::myHandle($user)); - $type = "application/xml"; - $encoding = "base64url"; - $alg = "RSA-SHA256"; - $signable_data = $data.".".Strings::base64UrlEncode($type).".".Strings::base64UrlEncode($encoding).".".Strings::base64UrlEncode($alg); + $type = 'application/xml'; + $encoding = 'base64url'; + $alg = 'RSA-SHA256'; + $signable_data = $data . '.' . Strings::base64UrlEncode($type) . '.' . Strings::base64UrlEncode($encoding) . '.' . Strings::base64UrlEncode($alg); // Fallback if the private key wasn't transmitted in the expected field - if ($user['uprvkey'] == "") { + if ($user['uprvkey'] == '') { $user['uprvkey'] = $user['prvkey']; } - $signature = Crypto::rsaSign($signable_data, $user["uprvkey"]); + $signature = Crypto::rsaSign($signable_data, $user['uprvkey']); $sig = Strings::base64UrlEncode($signature); - $xmldata = ["me:env" => ["me:data" => $data, - "@attributes" => ["type" => $type], - "me:encoding" => $encoding, - "me:alg" => $alg, - "me:sig" => $sig, - "@attributes2" => ["key_id" => $key_id]]]; + $xmldata = [ + 'me:env' => [ + 'me:data' => $data, + '@attributes' => ['type' => $type], + 'me:encoding' => $encoding, + 'me:alg' => $alg, + 'me:sig' => $sig, + '@attributes2' => ['key_id' => $key_id] + ] + ]; - $namespaces = ["me" => "http://salmon-protocol.org/ns/magic-env"]; + $namespaces = ['me' => 'http://salmon-protocol.org/ns/magic-env']; return XML::fromArray($xmldata, $xml, false, $namespaces); } @@ -2994,12 +3011,12 @@ class Diaspora private static function signature(array $owner, array $message): string { $sigmsg = $message; - unset($sigmsg["author_signature"]); - unset($sigmsg["parent_author_signature"]); + unset($sigmsg['author_signature']); + unset($sigmsg['parent_author_signature']); - $signed_text = implode(";", $sigmsg); + $signed_text = implode(';', $sigmsg); - return base64_encode(Crypto::rsaSign($signed_text, $owner["uprvkey"], "sha256")); + return base64_encode(Crypto::rsaSign($signed_text, $owner['uprvkey'], 'sha256')); } /** @@ -3015,9 +3032,9 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function transmit(array $owner, array $contact, string $envelope, bool $public_batch, string $guid = ""): int + private static function transmit(array $owner, array $contact, string $envelope, bool $public_batch, string $guid = ''): int { - $enabled = intval(DI::config()->get("system", "diaspora_enabled")); + $enabled = intval(DI::config()->get('system', 'diaspora_enabled')); if (!$enabled) { return 200; } @@ -3029,32 +3046,32 @@ class Diaspora if (!empty($contact['addr'])) { $fcontact = FContact::getByURL($contact['addr']); if (!empty($fcontact)) { - $dest_url = ($public_batch ? $fcontact["batch"] : $fcontact["notify"]); + $dest_url = ($public_batch ? $fcontact['batch'] : $fcontact['notify']); } } if (empty($dest_url)) { - $dest_url = ($public_batch ? $contact["batch"] : $contact["notify"]); + $dest_url = ($public_batch ? $contact['batch'] : $contact['notify']); } if (!$dest_url) { - Logger::notice("no url for contact: ".$contact["id"]." batch mode =".$public_batch); + Logger::notice("no url for contact: " . $contact['id'] . " batch mode =" . $public_batch); return 0; } - Logger::notice("transmit: ".$logid."-".$guid." ".$dest_url); + Logger::notice("transmit: " . $logid . "-" . $guid . " " . $dest_url); - if (!intval(DI::config()->get("system", "diaspora_test"))) { - $content_type = (($public_batch) ? "application/magic-envelope+xml" : "application/json"); + if (!intval(DI::config()->get('system', 'diaspora_test'))) { + $content_type = (($public_batch) ? 'application/magic-envelope+xml' : 'application/json'); - $postResult = DI::httpClient()->post($dest_url . "/", $envelope, ['Content-Type' => $content_type]); + $postResult = DI::httpClient()->post($dest_url . '/', $envelope, ['Content-Type' => $content_type]); $return_code = $postResult->getReturnCode(); } else { - Logger::notice("test_mode"); + Logger::notice('test_mode'); return 200; } - Logger::notice("transmit: ".$logid."-".$guid." to ".$dest_url." returns: ".$return_code); + Logger::notice("transmit: " . $logid . "-" . $guid . " to " . $dest_url . " returns: " . $return_code); return $return_code ? $return_code : -1; } @@ -3089,7 +3106,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function buildAndTransmit(array $owner, array $contact, string $type, array $message, bool $public_batch = false, string $guid = "") + private static function buildAndTransmit(array $owner, array $contact, string $type, array $message, bool $public_batch = false, string $guid = '') { $msg = self::buildPostXml($type, $message); @@ -3136,10 +3153,10 @@ class Diaspora { // Don't send notifications for private postings if ($item['private'] == Item::PRIVATE) { - return -1; + return 0; } - $cachekey = "diaspora:sendParticipation:".$item['guid']; + $cachekey = 'diaspora:sendParticipation:' . $item['guid']; $result = DI::cache()->get($cachekey); if (!is_null($result)) { @@ -3161,17 +3178,19 @@ class Diaspora $author = self::myHandle($owner); - $message = ["author" => $author, - "guid" => System::createUUID(), - "parent_type" => "Post", - "parent_guid" => $item["guid"]]; + $message = [ + 'author' => $author, + 'guid' => System::createUUID(), + 'parent_type' => 'Post', + 'parent_guid' => $item['guid'] + ]; - Logger::info("Send participation for ".$item["guid"]." by ".$author); + Logger::info("Send participation for " . $item['guid'] . " by " . $author); // It doesn't matter what we store, we only want to avoid sending repeated notifications for the same item - DI::cache()->set($cachekey, $item["guid"], Duration::QUARTER_HOUR); + DI::cache()->set($cachekey, $item['guid'], Duration::QUARTER_HOUR); - return self::buildAndTransmit($owner, $contact, "participation", $message); + return self::buildAndTransmit($owner, $contact, 'participation', $message); } /** @@ -3191,15 +3210,17 @@ class Diaspora $profile = self::createProfileData($uid); $signed_text = 'AccountMigration:'.$old_handle.':'.$profile['author']; - $signature = base64_encode(Crypto::rsaSign($signed_text, $owner["uprvkey"], "sha256")); + $signature = base64_encode(Crypto::rsaSign($signed_text, $owner['uprvkey'], 'sha256')); - $message = ["author" => $old_handle, - "profile" => $profile, - "signature" => $signature]; + $message = [ + 'author' => $old_handle, + 'profile' => $profile, + 'signature' => $signature + ]; Logger::info('Send account migration', ['msg' => $message]); - return self::buildAndTransmit($owner, $contact, "account_migration", $message); + return self::buildAndTransmit($owner, $contact, 'account_migration', $message); } /** @@ -3236,14 +3257,16 @@ class Diaspora } */ - $message = ["author" => self::myHandle($owner), - "recipient" => $contact["addr"], - "following" => "true", - "sharing" => "true"]; + $message = [ + 'author' => self::myHandle($owner), + 'recipient' => $contact['addr'], + 'following' => 'true', + 'sharing' => 'true' + ]; Logger::info('Send share', ['msg' => $message]); - return self::buildAndTransmit($owner, $contact, "contact", $message); + return self::buildAndTransmit($owner, $contact, 'contact', $message); } /** @@ -3257,14 +3280,16 @@ class Diaspora */ public static function sendUnshare(array $owner, array $contact): int { - $message = ["author" => self::myHandle($owner), - "recipient" => $contact["addr"], - "following" => "false", - "sharing" => "false"]; + $message = [ + 'author' => self::myHandle($owner), + 'recipient' => $contact['addr'], + 'following' => 'false', + 'sharing' => 'false' + ]; Logger::info('Send unshare', ['msg' => $message]); - return self::buildAndTransmit($owner, $contact, "contact", $message); + return self::buildAndTransmit($owner, $contact, 'contact', $message); } /** @@ -3297,8 +3322,8 @@ class Diaspora $item = Post::selectFirst(['contact-id'], $condition); if (DBA::isResult($item)) { $ret = []; - $ret["root_handle"] = self::handleFromContact($item["contact-id"]); - $ret["root_guid"] = $reshared['guid']; + $ret['root_handle'] = self::handleFromContact($item['contact-id']); + $ret['root_guid'] = $reshared['guid']; return $ret; } elseif ($complete) { // We are resharing something that isn't a DFRN or Diaspora post. @@ -3356,7 +3381,7 @@ class Diaspora $mask = DateTimeFormat::ATOM; /// @todo - establish "all day" events in Friendica - $eventdata["all_day"] = "false"; + $eventdata['all_day'] = 'false'; $eventdata['timezone'] = 'UTC'; @@ -3377,13 +3402,13 @@ class Diaspora $coord = Map::getCoordinates($event['location']); $location = []; - $location["address"] = html_entity_decode(BBCode::toMarkdown($event['location'])); + $location['address'] = html_entity_decode(BBCode::toMarkdown($event['location'])); if (!empty($coord['lat']) && !empty($coord['lon'])) { - $location["lat"] = $coord['lat']; - $location["lng"] = $coord['lon']; + $location['lat'] = $coord['lat']; + $location['lng'] = $coord['lon']; } else { - $location["lat"] = 0; - $location["lng"] = 0; + $location['lat'] = 0; + $location['lng'] = 0; } $eventdata['location'] = $location; } @@ -3405,7 +3430,7 @@ class Diaspora */ public static function buildStatus(array $item, array $owner) { - $cachekey = "diaspora:buildStatus:".$item['guid']; + $cachekey = 'diaspora:buildStatus:' . $item['guid']; $result = DI::cache()->get($cachekey); if (!is_null($result)) { @@ -3414,27 +3439,29 @@ class Diaspora $myaddr = self::myHandle($owner); - $public = ($item["private"] == Item::PRIVATE ? "false" : "true"); + $public = ($item['private'] == Item::PRIVATE ? 'false' : 'true'); $created = DateTimeFormat::utc($item['received'], DateTimeFormat::ATOM); - $edited = DateTimeFormat::utc($item["edited"] ?? $item["created"], DateTimeFormat::ATOM); + $edited = DateTimeFormat::utc($item['edited'] ?? $item['created'], DateTimeFormat::ATOM); // Detect a share element and do a reshare - if (($item['private'] != Item::PRIVATE) && ($ret = self::isReshare($item["body"]))) { - $message = ["author" => $myaddr, - "guid" => $item["guid"], - "created_at" => $created, - "root_author" => $ret["root_handle"], - "root_guid" => $ret["root_guid"], - "provider_display_name" => $item["app"], - "public" => $public]; + if (($item['private'] != Item::PRIVATE) && ($ret = self::isReshare($item['body']))) { + $message = [ + 'author' => $myaddr, + 'guid' => $item['guid'], + 'created_at' => $created, + 'root_author' => $ret['root_handle'], + 'root_guid' => $ret['root_guid'], + 'provider_display_name' => $item['app'], + 'public' => $public + ]; - $type = "reshare"; + $type = 'reshare'; } else { - $title = $item["title"]; + $title = $item['title']; $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']); // Fetch the title from an attached link - if there is one - if (empty($item["title"]) && DI::pConfig()->get($owner['uid'], 'system', 'attach_link_title')) { + if (empty($item['title']) && DI::pConfig()->get($owner['uid'], 'system', 'attach_link_title')) { $page_data = BBCode::getAttachmentData($item['body']); if (!empty($page_data['type']) && !empty($page_data['title']) && ($page_data['type'] == 'link')) { $title = $page_data['title']; @@ -3451,7 +3478,7 @@ class Diaspora // Adding the title if (strlen($title)) { - $body = "### ".html_entity_decode($title)."\n\n".$body; + $body = '### ' . html_entity_decode($title) . "\n\n" . $body; } $attachments = Post\Media::getByURIId($item['uri-id'], [Post\Media::DOCUMENT, Post\Media::TORRENT, Post\Media::UNKNOWN]); @@ -3464,27 +3491,29 @@ class Diaspora $location = []; - if ($item["location"] != "") - $location["address"] = $item["location"]; + if ($item['location'] != '') + $location['address'] = $item['location']; - if ($item["coord"] != "") { - $coord = explode(" ", $item["coord"]); - $location["lat"] = $coord[0]; - $location["lng"] = $coord[1]; + if ($item['coord'] != '') { + $coord = explode(' ', $item['coord']); + $location['lat'] = $coord[0]; + $location['lng'] = $coord[1]; } - $message = ["author" => $myaddr, - "guid" => $item["guid"], - "created_at" => $created, - "edited_at" => $edited, - "public" => $public, - "text" => $body, - "provider_display_name" => $item["app"], - "location" => $location]; + $message = [ + 'author' => $myaddr, + 'guid' => $item['guid'], + 'created_at' => $created, + 'edited_at' => $edited, + 'public' => $public, + 'text' => $body, + 'provider_display_name' => $item['app'], + 'location' => $location + ]; // Diaspora rejects messages when they contain a location without "lat" or "lng" - if (!isset($location["lat"]) || !isset($location["lng"])) { - unset($message["location"]); + if (!isset($location['lat']) || !isset($location['lng'])) { + unset($message['location']); } if ($item['event-id'] > 0) { @@ -3503,10 +3532,13 @@ class Diaspora } } - $type = "status_message"; + $type = 'status_message'; } - $msg = ["type" => $type, "message" => $message]; + $msg = [ + 'type' => $type, + 'message' => $message + ]; DI::cache()->set($cachekey, $msg, Duration::QUARTER_HOUR); @@ -3542,7 +3574,7 @@ class Diaspora { $status = self::buildStatus($item, $owner); - return self::buildAndTransmit($owner, $contact, $status["type"], $status["message"], $public_batch, $item["guid"]); + return self::buildAndTransmit($owner, $contact, $status['type'], $status['message'], $public_batch, $item['guid']); } /** @@ -3556,25 +3588,27 @@ class Diaspora */ private static function constructLike(array $item, array $owner) { - $parent = Post::selectFirst(['guid', 'uri', 'thr-parent'], ['uri' => $item["thr-parent"]]); + $parent = Post::selectFirst(['guid', 'uri', 'thr-parent'], ['uri' => $item['thr-parent']]); if (!DBA::isResult($parent)) { return false; } - $target_type = ($parent["uri"] === $parent["thr-parent"] ? "Post" : "Comment"); + $target_type = ($parent['uri'] === $parent['thr-parent'] ? 'Post' : 'Comment'); $positive = null; if ($item['verb'] === Activity::LIKE) { - $positive = "true"; + $positive = 'true'; } elseif ($item['verb'] === Activity::DISLIKE) { - $positive = "false"; + $positive = 'false'; } - return ["author" => self::myHandle($owner), - "guid" => $item["guid"], - "parent_guid" => $parent["guid"], - "parent_type" => $target_type, - "positive" => $positive, - "author_signature" => ""]; + return [ + 'author' => self::myHandle($owner), + 'guid' => $item['guid'], + 'parent_guid' => $parent['guid'], + 'parent_type' => $target_type, + 'positive' => $positive, + 'author_signature' => '' + ]; } /** @@ -3608,11 +3642,13 @@ class Diaspora return false; } - return ["author" => self::myHandle($owner), - "guid" => $item["guid"], - "parent_guid" => $parent["guid"], - "status" => $attend_answer, - "author_signature" => ""]; + return [ + 'author' => self::myHandle($owner), + 'guid' => $item['guid'], + 'parent_guid' => $parent['guid'], + 'status' => $attend_answer, + 'author_signature' => '' + ]; } /** @@ -3626,7 +3662,7 @@ class Diaspora */ private static function constructComment(array $item, array $owner) { - $cachekey = "diaspora:constructComment:".$item['guid']; + $cachekey = 'diaspora:constructComment:' . $item['guid']; $result = DI::cache()->get($cachekey); if (!is_null($result)) { @@ -3660,17 +3696,17 @@ class Diaspora } $text = html_entity_decode(BBCode::toMarkdown($body)); - $created = DateTimeFormat::utc($item["created"], DateTimeFormat::ATOM); - $edited = DateTimeFormat::utc($item["edited"], DateTimeFormat::ATOM); + $created = DateTimeFormat::utc($item['created'], DateTimeFormat::ATOM); + $edited = DateTimeFormat::utc($item['edited'], DateTimeFormat::ATOM); $comment = [ - "author" => self::myHandle($owner), - "guid" => $item["guid"], - "created_at" => $created, - "edited_at" => $edited, - "parent_guid" => $toplevel_item["guid"], - "text" => $text, - "author_signature" => "" + 'author' => self::myHandle($owner), + 'guid' => $item['guid'], + 'created_at' => $created, + 'edited_at' => $edited, + 'parent_guid' => $toplevel_item['guid'], + 'text' => $text, + 'author_signature' => '' ]; // Send the thread parent guid only if it is a threaded comment @@ -3699,22 +3735,22 @@ class Diaspora { if (in_array($item['verb'], [Activity::ATTEND, Activity::ATTENDNO, Activity::ATTENDMAYBE])) { $message = self::constructAttend($item, $owner); - $type = "event_participation"; - } elseif (in_array($item["verb"], [Activity::LIKE, Activity::DISLIKE])) { + $type = 'event_participation'; + } elseif (in_array($item['verb'], [Activity::LIKE, Activity::DISLIKE])) { $message = self::constructLike($item, $owner); - $type = "like"; - } elseif (!in_array($item["verb"], [Activity::FOLLOW, Activity::TAG])) { + $type = 'like'; + } elseif (!in_array($item['verb'], [Activity::FOLLOW, Activity::TAG])) { $message = self::constructComment($item, $owner); - $type = "comment"; + $type = 'comment'; } if (empty($message)) { return -1; } - $message["author_signature"] = self::signature($owner, $message); + $message['author_signature'] = self::signature($owner, $message); - return self::buildAndTransmit($owner, $contact, $type, $message, $public_batch, $item["guid"]); + return self::buildAndTransmit($owner, $contact, $type, $message, $public_batch, $item['guid']); } /** @@ -3730,41 +3766,41 @@ class Diaspora */ public static function sendRelay(array $item, array $owner, array $contact, bool $public_batch = false): int { - if ($item["deleted"]) { + if ($item['deleted']) { return self::sendRetraction($item, $owner, $contact, $public_batch, true); - } elseif (in_array($item["verb"], [Activity::LIKE, Activity::DISLIKE])) { - $type = "like"; + } elseif (in_array($item['verb'], [Activity::LIKE, Activity::DISLIKE])) { + $type = 'like'; } else { - $type = "comment"; + $type = 'comment'; } - Logger::info("Got relayable data ".$type." for item ".$item["guid"]." (".$item["id"].")"); + Logger::info("Got relayable data " . $type . " for item " . $item['guid'] . " (" . $item['id'] . ")"); $msg = json_decode($item['signed_text'], true); $message = []; if (is_array($msg)) { foreach ($msg as $field => $data) { - if (!$item["deleted"]) { - if ($field == "diaspora_handle") { - $field = "author"; + if (!$item['deleted']) { + if ($field == 'diaspora_handle') { + $field = 'author'; } - if ($field == "target_type") { - $field = "parent_type"; + if ($field == 'target_type') { + $field = 'parent_type'; } } $message[$field] = $data; } } else { - Logger::info("Signature text for item ".$item["guid"]." (".$item["id"].") couldn't be extracted: ".$item['signed_text']); + Logger::info("Signature text for item " . $item["guid"] . " (" . $item["id"] . ") couldn't be extracted: " . $item['signed_text']); } - $message["parent_author_signature"] = self::signature($owner, $message); + $message['parent_author_signature'] = self::signature($owner, $message); Logger::info('Relayed data', ['msg' => $message]); - return self::buildAndTransmit($owner, $contact, $type, $message, $public_batch, $item["guid"]); + return self::buildAndTransmit($owner, $contact, $type, $message, $public_batch, $item['guid']); } /** @@ -3781,25 +3817,27 @@ class Diaspora */ public static function sendRetraction(array $item, array $owner, array $contact, bool $public_batch = false, bool $relay = false): int { - $itemaddr = self::handleFromContact($item["contact-id"], $item["author-id"]); + $itemaddr = self::handleFromContact($item['contact-id'], $item['author-id']); - $msg_type = "retraction"; + $msg_type = 'retraction'; if ($item['gravity'] == GRAVITY_PARENT) { - $target_type = "Post"; - } elseif (in_array($item["verb"], [Activity::LIKE, Activity::DISLIKE])) { - $target_type = "Like"; + $target_type = 'Post'; + } elseif (in_array($item['verb'], [Activity::LIKE, Activity::DISLIKE])) { + $target_type = 'Like'; } else { - $target_type = "Comment"; + $target_type = 'Comment'; } - $message = ["author" => $itemaddr, - "target_guid" => $item['guid'], - "target_type" => $target_type]; + $message = [ + 'author' => $itemaddr, + 'target_guid' => $item['guid'], + 'target_type' => $target_type + ]; Logger::info('Got message', ['msg' => $message]); - return self::buildAndTransmit($owner, $contact, $msg_type, $message, $public_batch, $item["guid"]); + return self::buildAndTransmit($owner, $contact, $msg_type, $message, $public_batch, $item['guid']); } /** @@ -3817,40 +3855,40 @@ class Diaspora { $myaddr = self::myHandle($owner); - $cnv = DBA::selectFirst('conv', [], ['id' => $item["convid"], 'uid' => $item["uid"]]); + $cnv = DBA::selectFirst('conv', [], ['id' => $item['convid'], 'uid' => $item['uid']]); if (!DBA::isResult($cnv)) { Logger::notice("conversation not found."); return -1; } - $body = BBCode::toMarkdown($item["body"]); - $created = DateTimeFormat::utc($item["created"], DateTimeFormat::ATOM); + $body = BBCode::toMarkdown($item['body']); + $created = DateTimeFormat::utc($item['created'], DateTimeFormat::ATOM); $msg = [ - "author" => $myaddr, - "guid" => $item["guid"], - "conversation_guid" => $cnv["guid"], - "text" => $body, - "created_at" => $created, + 'author' => $myaddr, + 'guid' => $item['guid'], + 'conversation_guid' => $cnv['guid'], + 'text' => $body, + 'created_at' => $created, ]; - if ($item["reply"]) { + if ($item['reply']) { $message = $msg; - $type = "message"; + $type = 'message'; } else { $message = [ - "author" => $cnv["creator"], - "guid" => $cnv["guid"], - "subject" => $cnv["subject"], - "created_at" => DateTimeFormat::utc($cnv['created'], DateTimeFormat::ATOM), - "participants" => $cnv["recips"], - "message" => $msg + 'author' => $cnv['creator'], + 'guid' => $cnv['guid'], + 'subject' => $cnv['subject'], + 'created_at' => DateTimeFormat::utc($cnv['created'], DateTimeFormat::ATOM), + 'participants' => $cnv['recips'], + 'message' => $msg ]; - $type = "conversation"; + $type = 'conversation'; } - return self::buildAndTransmit($owner, $contact, $type, $message, false, $item["guid"]); + return self::buildAndTransmit($owner, $contact, $type, $message, false, $item['guid']); } /** @@ -3925,7 +3963,7 @@ class Diaspora return []; } - $handle = $profile["addr"]; + $handle = $profile['addr']; $split_name = self::splitName($profile['name']); $first = $split_name['first']; @@ -3970,18 +4008,20 @@ class Diaspora $tags = trim($tags); } - return ["author" => $handle, - "first_name" => $first, - "last_name" => $last, - "image_url" => $large, - "image_url_medium" => $medium, - "image_url_small" => $small, - "birthday" => $dob, - "bio" => $about, - "location" => $location, - "searchable" => $searchable, - "nsfw" => "false", - "tag_string" => $tags]; + return [ + 'author' => $handle, + 'first_name' => $first, + 'last_name' => $last, + 'image_url' => $large, + 'image_url_medium' => $medium, + 'image_url_small' => $small, + 'birthday' => $dob, + 'bio' => $about, + 'location' => $location, + 'searchable' => $searchable, + 'nsfw' => 'false', + 'tag_string' => $tags + ]; } /** @@ -4015,8 +4055,8 @@ class Diaspora // @ToDo Split this into single worker jobs foreach ($recips as $recip) { - Logger::info("Send updated profile data for user ".$uid." to contact ".$recip["id"]); - self::buildAndTransmit($owner, $recip, "profile", $message); + Logger::info("Send updated profile data for user " . $uid . " to contact " . $recip['id']); + self::buildAndTransmit($owner, $recip, 'profile', $message); } } @@ -4037,7 +4077,7 @@ class Diaspora return false; } - if (!in_array($item["verb"], [Activity::LIKE, Activity::DISLIKE])) { + if (!in_array($item['verb'], [Activity::LIKE, Activity::DISLIKE])) { return false; } @@ -4046,7 +4086,7 @@ class Diaspora return false; } - $message["author_signature"] = self::signature($owner, $message); + $message['author_signature'] = self::signature($owner, $message); return $message; } @@ -4094,7 +4134,7 @@ class Diaspora return false; } - $message["author_signature"] = self::signature($owner, $message); + $message['author_signature'] = self::signature($owner, $message); return $message; } From aaf5c323b6fdf81fc057b0688786992a6319eb41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Sat, 18 Jun 2022 05:04:04 +0200 Subject: [PATCH 32/37] Fixed indenting --- src/Protocol/Diaspora.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 7c1c674a43..c0a338344b 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -303,9 +303,11 @@ class Diaspora } } - return ['message' => (string)Strings::base64UrlDecode($base->data), - 'author' => XML::unescape($author_addr), - 'key' => (string)$key]; + return [ + 'message' => (string)Strings::base64UrlDecode($base->data), + 'author' => XML::unescape($author_addr), + 'key' => (string)$key + ]; } /** @@ -445,9 +447,11 @@ class Diaspora Logger::notice('Message verified.'); - return ['message' => (string)$inner_decrypted, - 'author' => XML::unescape($author_link), - 'key' => (string)$key]; + return [ + 'message' => (string)$inner_decrypted, + 'author' => XML::unescape($author_link), + 'key' => (string)$key + ]; } From 89302d0843308c8fa7cc0537cb10943e8defc8ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Sat, 18 Jun 2022 05:06:00 +0200 Subject: [PATCH 33/37] Some outside code relies on returned "false" --- src/Protocol/Diaspora.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index c0a338344b..c71745a426 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -323,14 +323,14 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function decode(string $xml, string $privKey = ''): array + public static function decode(string $xml, string $privKey = '') { $public = false; $basedom = XML::parseString($xml); if (!is_object($basedom)) { Logger::notice('XML is not parseable.'); - return []; + return false; } $children = $basedom->children('https://joindiaspora.com/protocol'); @@ -344,7 +344,7 @@ class Diaspora // This happens with posts from a relais if (empty($privKey)) { Logger::info('This is no private post in the old format'); - return []; + return false; } $encrypted_header = json_decode(base64_decode($children->encrypted_header)); From 7cbb818c93423378bc26ead0aa38a97792ee3758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Sat, 18 Jun 2022 05:18:38 +0200 Subject: [PATCH 34/37] Set type-hint for parameter $data to SimpleXMLElement as $fields in dispatch() is the same and being handled over. --- src/Protocol/Diaspora.php | 81 ++++++++++++++------------------------- 1 file changed, 28 insertions(+), 53 deletions(-) diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index c71745a426..838d405505 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -1316,16 +1316,14 @@ class Diaspora * Receives account migration * * @param array $importer Array of the importer user - * @param object $data The message object + * @param SimpleXMLElement $data The message object * * @return bool Success * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveAccountMigration(array $importer, $data): bool + private static function receiveAccountMigration(array $importer, SimpleXMLElement $data): bool { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data=' . get_class($data)); $old_handle = XML::unescape($data->author); $new_handle = XML::unescape($data->profile->author); $signature = XML::unescape($data->signature); @@ -1378,15 +1376,13 @@ class Diaspora /** * Processes an account deletion * - * @param object $data The message object + * @param SimpleXMLElement $data The message object * * @return bool Success * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - private static function receiveAccountDeletion($data): bool + private static function receiveAccountDeletion(SimpleXMLElement $data): bool { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $contacts = DBA::select('contact', ['id'], ['addr' => $author]); @@ -1468,7 +1464,7 @@ class Diaspora * * @param array $importer Array of the importer user * @param string $sender The sender of the message - * @param object $data The message object + * @param SimpleXMLElement $data The message object * @param string $xml The original XML of the message * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * @@ -1476,10 +1472,8 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveComment(array $importer, string $sender, $data, string $xml, int $direction): bool + private static function receiveComment(array $importer, string $sender, SimpleXMLElement $data, string $xml, int $direction): bool { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); $parent_guid = XML::unescape($data->parent_guid); @@ -1607,18 +1601,17 @@ class Diaspora * * @param array $importer Array of the importer user * @param array $contact The contact of the message - * @param object $data The message object + * @param SimpleXMLElement $data The message object * @param array $msg Array of the processed message, author handle and key * @param object $mesg The private message * @param array $conversation The conversation record to which this message belongs * * @return bool "true" if it was successful * @throws \Exception + * @todo Find type-hint for $mesg and update documentation */ - private static function receiveConversationMessage(array $importer, array $contact, $data, array $msg, $mesg, array $conversation): bool + private static function receiveConversationMessage(array $importer, array $contact, SimpleXMLElement $data, array $msg, $mesg, array $conversation): bool { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data).',mesg='.get_class($mesg)); $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); $subject = XML::unescape($data->subject); @@ -1669,15 +1662,13 @@ class Diaspora * * @param array $importer Array of the importer user * @param array $msg Array of the processed message, author handle and key - * @param object $data The message object + * @param SimpleXMLElement $data The message object * * @return bool Success * @throws \Exception */ - private static function receiveConversation(array $importer, array $msg, $data) + private static function receiveConversation(array $importer, array $msg, SimpleXMLElement $data) { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); $subject = XML::unescape($data->subject); @@ -1731,17 +1722,15 @@ class Diaspora * * @param array $importer Array of the importer user * @param string $sender The sender of the message - * @param object $data The message object + * @param SimpleXMLElement $data The message object * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * * @return bool Success or failure * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveLike(array $importer, string $sender, $data, int $direction): bool + private static function receiveLike(array $importer, string $sender, SimpleXMLElement $data, int $direction): bool { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); $parent_guid = XML::unescape($data->parent_guid); @@ -1855,15 +1844,13 @@ class Diaspora * Processes private messages * * @param array $importer Array of the importer user - * @param object $data The message object + * @param SimpleXMLElement $data The message object * * @return bool Success? * @throws \Exception */ - private static function receiveMessage(array $importer, $data): bool + private static function receiveMessage(array $importer, SimpleXMLElement $data): bool { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); $conversation_guid = XML::unescape($data->conversation_guid); @@ -1922,17 +1909,15 @@ class Diaspora * Processes participations - unsupported by now * * @param array $importer Array of the importer user - * @param object $data The message object + * @param SimpleXMLElement $data The message object * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * * @return bool success * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveParticipation(array $importer, $data, int $direction): bool + private static function receiveParticipation(array $importer, SimpleXMLElement $data, int $direction): bool { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data)); $author = strtolower(XML::unescape($data->author)); $guid = XML::unescape($data->guid); $parent_guid = XML::unescape($data->parent_guid); @@ -2041,7 +2026,7 @@ class Diaspora * Processes photos - unneeded * * @param array $importer Array of the importer user - * @param object $data The message object + * @param SimpleXMLElement $data The message object * * @return bool always true */ @@ -2070,16 +2055,14 @@ class Diaspora * Processes incoming profile updates * * @param array $importer Array of the importer user - * @param object $data The message object + * @param SimpleXMLElement $data The message object * * @return bool Success * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveProfile(array $importer, $data): bool + private static function receiveProfile(array $importer, SimpleXMLElement $data): bool { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data)); $author = strtolower(XML::unescape($data->author)); $contact = self::contactByHandle($importer['uid'], $author); @@ -2175,15 +2158,13 @@ class Diaspora * Processes incoming sharing notification * * @param array $importer Array of the importer user - * @param object $data The message object + * @param SimpleXMLElement $data The message object * * @return bool Success * @throws \Exception */ - private static function receiveContactRequest(array $importer, $data): bool + private static function receiveContactRequest(array $importer, SimpleXMLElement $data): bool { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $recipient = XML::unescape($data->recipient); @@ -2421,7 +2402,7 @@ class Diaspora * Processes a reshare message * * @param array $importer Array of the importer user - * @param object $data The message object + * @param SimpleXMLElement $data The message object * @param string $xml The original XML of the message * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * @@ -2429,10 +2410,8 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveReshare(array $importer, $data, string $xml, int $direction): bool + private static function receiveReshare(array $importer, SimpleXMLElement $data, string $xml, int $direction): bool { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); $created_at = DateTimeFormat::utc(XML::unescape($data->created_at)); @@ -2546,15 +2525,13 @@ class Diaspora * * @param array $importer Array of the importer user * @param array $contact The contact of the item owner - * @param object $data The message object + * @param SimpleXMLElement $data The message object * * @return bool success * @throws \Exception */ - private static function itemRetraction(array $importer, array $contact, $data): bool + private static function itemRetraction(array $importer, array $contact, SimpleXMLElement $data): bool { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data)); $author = XML::unescape($data->author); $target_guid = XML::unescape($data->target_guid); $target_type = XML::unescape($data->target_type); @@ -2614,15 +2591,13 @@ class Diaspora * * @param array $importer Array of the importer user * @param string $sender The sender of the message - * @param object $data The message object + * @param SimpleXMLElement $data The message object * * @return bool Success * @throws \Exception */ - private static function receiveRetraction(array $importer, string $sender, $data) + private static function receiveRetraction(array $importer, string $sender, SimpleXMLElement $data) { - // @TODO Need to find object type, roland@f.haeder.net - Logger::debug('data='.get_class($data)); $target_type = XML::unescape($data->target_type); $contact = self::contactByHandle($importer['uid'], $sender); From 69cda4f76027786428d9bbec03d5ba0602cae120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Sat, 18 Jun 2022 05:41:19 +0200 Subject: [PATCH 35/37] Fixed TypeError: "Argument 1 passed to Friendica\Core\System::httpExit() must be of the type string, null given, called in /var/www/.../src/Module/DFRN/Poll.php on line 37" --- src/Module/DFRN/Poll.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Module/DFRN/Poll.php b/src/Module/DFRN/Poll.php index 516f863845..65f113b9db 100644 --- a/src/Module/DFRN/Poll.php +++ b/src/Module/DFRN/Poll.php @@ -33,7 +33,6 @@ class Poll extends BaseModule { protected function rawContent(array $request = []) { - $last_update = $request['last_update'] ?? ''; - System::httpExit(OStatus::feed($this->parameters['nickname'], $last_update, 10), Response::TYPE_ATOM); + System::httpExit(OStatus::feed($this->parameters['nickname'], $request['last_update'] ?? '', 10) ?? '', Response::TYPE_ATOM); } } From bd3a7b98775e2983ff0937b2215c892c9ecacd2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Sat, 18 Jun 2022 09:58:44 +0200 Subject: [PATCH 36/37] Ops, needs to be a variable: Error: "Cannot pass parameter 2 by reference" at /var/www/.../src/Module/DFRN/Poll.php line 36 --- src/Module/DFRN/Poll.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Module/DFRN/Poll.php b/src/Module/DFRN/Poll.php index 65f113b9db..e41dafed56 100644 --- a/src/Module/DFRN/Poll.php +++ b/src/Module/DFRN/Poll.php @@ -33,6 +33,7 @@ class Poll extends BaseModule { protected function rawContent(array $request = []) { - System::httpExit(OStatus::feed($this->parameters['nickname'], $request['last_update'] ?? '', 10) ?? '', Response::TYPE_ATOM); + $last_update = $request['last_update'] ?? ''; + System::httpExit(OStatus::feed($this->parameters['nickname'], $last_update, 10) ?? '', Response::TYPE_ATOM); } } From 8756d923160b99a26204ad49bd3cb2e02bf32075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roland=20H=C3=A4der?= Date: Sat, 18 Jun 2022 15:56:58 +0200 Subject: [PATCH 37/37] Continued: - prevents a "Return value of Friendica\Core\Worker::workerProcess() must be of the type array, bool returned" --- src/Core/Worker.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Core/Worker.php b/src/Core/Worker.php index bcd12f3294..62fd321c24 100644 --- a/src/Core/Worker.php +++ b/src/Core/Worker.php @@ -1011,7 +1011,9 @@ class Worker DI::lock()->release(self::LOCK_PROCESS); - return (self::getWaitingJobForPID() ?? []); + // Prevents "Return value of Friendica\Core\Worker::workerProcess() must be of the type array, bool returned" + $process = self::getWaitingJobForPID(); + return (is_array($process) ? $process : []); } /**