Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2294 lines
76 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
2 years ago
2 years ago
4 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
2 years ago
2 years ago
2 years ago
  1. <?php
  2. /**
  3. * @file src/Protocol/OStatus.php
  4. */
  5. namespace Friendica\Protocol;
  6. use DOMDocument;
  7. use DOMXPath;
  8. use Friendica\Content\Text\BBCode;
  9. use Friendica\Content\Text\HTML;
  10. use Friendica\Core\Cache\Cache;
  11. use Friendica\Core\Config;
  12. use Friendica\Core\L10n;
  13. use Friendica\Core\Logger;
  14. use Friendica\Core\Protocol;
  15. use Friendica\Database\DBA;
  16. use Friendica\DI;
  17. use Friendica\Model\APContact;
  18. use Friendica\Model\Contact;
  19. use Friendica\Model\Conversation;
  20. use Friendica\Model\GContact;
  21. use Friendica\Model\Item;
  22. use Friendica\Model\User;
  23. use Friendica\Network\Probe;
  24. use Friendica\Util\DateTimeFormat;
  25. use Friendica\Util\Images;
  26. use Friendica\Util\Network;
  27. use Friendica\Util\Proxy as ProxyUtils;
  28. use Friendica\Util\Strings;
  29. use Friendica\Util\XML;
  30. require_once 'mod/share.php';
  31. require_once 'include/api.php';
  32. /**
  33. * @brief This class contain functions for the OStatus protocol
  34. */
  35. class OStatus
  36. {
  37. private static $itemlist;
  38. private static $conv_list = [];
  39. /**
  40. * @brief Fetches author data
  41. *
  42. * @param DOMXPath $xpath The xpath object
  43. * @param object $context The xml context of the author details
  44. * @param array $importer user record of the importing user
  45. * @param array $contact Called by reference, will contain the fetched contact
  46. * @param bool $onlyfetch Only fetch the header without updating the contact entries
  47. *
  48. * @return array Array of author related entries for the item
  49. * @throws \Friendica\Network\HTTPException\InternalServerErrorException
  50. * @throws \ImagickException
  51. */
  52. private static function fetchAuthor(DOMXPath $xpath, $context, array $importer, array &$contact = null, $onlyfetch)
  53. {
  54. $author = [];
  55. $author["author-link"] = XML::getFirstNodeValue($xpath, 'atom:author/atom:uri/text()', $context);
  56. $author["author-name"] = XML::getFirstNodeValue($xpath, 'atom:author/atom:name/text()', $context);
  57. $addr = XML::getFirstNodeValue($xpath, 'atom:author/atom:email/text()', $context);
  58. $aliaslink = $author["author-link"];
  59. $alternate_item = $xpath->query("atom:author/atom:link[@rel='alternate']", $context)->item(0);
  60. if (is_object($alternate_item)) {
  61. foreach ($alternate_item->attributes as $attributes) {
  62. if (($attributes->name == "href") && ($attributes->textContent != "")) {
  63. $author["author-link"] = $attributes->textContent;
  64. }
  65. }
  66. }
  67. $author["author-id"] = Contact::getIdForURL($author["author-link"]);
  68. $author['contact-id'] = ($contact['id'] ?? 0) ?: $author['author-id'];
  69. $contact = [];
  70. /*
  71. This here would be better, but we would get problems with contacts from the statusnet addon
  72. This is kept here as a reminder for the future
  73. $cid = Contact::getIdForURL($author["author-link"], $importer["uid"]);
  74. if ($cid) {
  75. $contact = DBA::selectFirst('contact', [], ['id' => $cid]);
  76. }
  77. */
  78. if ($aliaslink != '') {
  79. $condition = ["`uid` = ? AND `alias` = ? AND `network` != ? AND `rel` IN (?, ?)",
  80. $importer["uid"], $aliaslink, Protocol::STATUSNET,
  81. Contact::SHARING, Contact::FRIEND];
  82. $contact = DBA::selectFirst('contact', [], $condition);
  83. }
  84. if (!DBA::isResult($contact) && $author["author-link"] != '') {
  85. if ($aliaslink == "") {
  86. $aliaslink = $author["author-link"];
  87. }
  88. $condition = ["`uid` = ? AND `nurl` IN (?, ?) AND `network` != ? AND `rel` IN (?, ?)",
  89. $importer["uid"], Strings::normaliseLink($author["author-link"]), Strings::normaliseLink($aliaslink),
  90. Protocol::STATUSNET, Contact::SHARING, Contact::FRIEND];
  91. $contact = DBA::selectFirst('contact', [], $condition);
  92. }
  93. if (!DBA::isResult($contact) && ($addr != '')) {
  94. $condition = ["`uid` = ? AND `addr` = ? AND `network` != ? AND `rel` IN (?, ?)",
  95. $importer["uid"], $addr, Protocol::STATUSNET,
  96. Contact::SHARING, Contact::FRIEND];
  97. $contact = DBA::selectFirst('contact', [], $condition);
  98. }
  99. if (DBA::isResult($contact)) {
  100. if ($contact['blocked']) {
  101. $contact['id'] = -1;
  102. } elseif (!empty(APContact::getByURL($contact['url'], false))) {
  103. ActivityPub\Receiver::switchContact($contact['id'], $importer['uid'], $contact['url']);
  104. }
  105. $author["contact-id"] = $contact["id"];
  106. }
  107. $avatarlist = [];
  108. $avatars = $xpath->query("atom:author/atom:link[@rel='avatar']", $context);
  109. foreach ($avatars as $avatar) {
  110. $href = "";
  111. $width = 0;
  112. foreach ($avatar->attributes as $attributes) {
  113. if ($attributes->name == "href") {
  114. $href = $attributes->textContent;
  115. }
  116. if ($attributes->name == "width") {
  117. $width = $attributes->textContent;
  118. }
  119. }
  120. if ($href != "") {
  121. $avatarlist[$width] = $href;
  122. }
  123. }
  124. if (count($avatarlist) > 0) {
  125. krsort($avatarlist);
  126. $author["author-avatar"] = Probe::fixAvatar(current($avatarlist), $author["author-link"]);
  127. }
  128. $displayname = XML::getFirstNodeValue($xpath, 'atom:author/poco:displayName/text()', $context);
  129. if ($displayname != "") {
  130. $author["author-name"] = $displayname;
  131. }
  132. $author["owner-id"] = $author["author-id"];
  133. // Only update the contacts if it is an OStatus contact
  134. if (DBA::isResult($contact) && ($contact['id'