- /**
- * Fetch the conversation for posts
- *
- * @param string $conversation The link to the conversation
- * @param string $conversation_uri The conversation in "uri" format
- * @return void
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
- private static function fetchConversation($conversation, $conversation_uri)
- {
- // Ensure that we only store a conversation once in a process
- if (isset(self::$conv_list[$conversation])) {
- return;
- }
-
- self::$conv_list[$conversation] = true;
-
- $curlResult = DI::httpClient()->get($conversation, [HTTPClientOptions::ACCEPT_CONTENT => ['application/atom+xml', 'text/html']]);
-
- if (!$curlResult->isSuccess() || empty($curlResult->getBody())) {
- return;
- }
-
- $xml = '';
-
- if ($curlResult->inHeader('Content-Type') &&
- in_array('application/atom+xml', $curlResult->getHeader('Content-Type'))) {
- $xml = $curlResult->getBody();
- }
-
- if ($xml == '') {
- $doc = new DOMDocument();
- if (!@$doc->loadHTML($curlResult->getBody())) {
- return;
- }
- $xpath = new DOMXPath($doc);
-
- $links = $xpath->query('//link');
- if ($links) {
- $file = '';
- foreach ($links as $link) {
- $attribute = self::readAttributes($link);
- if (($attribute['rel'] == 'alternate') && ($attribute['type'] == 'application/atom+xml')) {
- $file = $attribute['href'];
- }
- }
- if ($file != '') {
- $conversation_atom = DI::httpClient()->get($attribute['href']);
-
- if ($conversation_atom->isSuccess()) {
- $xml = $conversation_atom->getBody();
- }
- }
- }
- }
-
- if ($xml == '') {
- return;
- }
-
- self::storeConversation($xml, $conversation, $conversation_uri);
- }
-
- /**
- * Store a feed in several conversation entries
- *
- * @param string $xml The feed
- * @param string $conversation conversation
- * @param string $conversation_uri conversation uri
- * @return void
- * @throws \Exception
- */
- private static function storeConversation($xml, $conversation = '', $conversation_uri = '')
- {
- $doc = new DOMDocument();
- @$doc->loadXML($xml);
-
- $xpath = new DOMXPath($doc);
- $xpath->registerNamespace('atom', ActivityNamespace::ATOM1);
- $xpath->registerNamespace('thr', ActivityNamespace::THREAD);
- $xpath->registerNamespace('ostatus', ActivityNamespace::OSTATUS);
-
- $entries = $xpath->query('/atom:feed/atom:entry');
-
- // Now store the entries
- foreach ($entries as $entry) {
- $doc2 = new DOMDocument();
- $doc2->preserveWhiteSpace = false;
- $doc2->formatOutput = true;
-
- $conv_data = [];
-
- $conv_data['protocol'] = Conversation::PARCEL_SPLIT_CONVERSATION;
- $conv_data['direction'] = Conversation::PULL;
- $conv_data['network'] = Protocol::OSTATUS;
- $conv_data['uri'] = XML::getFirstNodeValue($xpath, 'atom:id/text()', $entry);
-
- $inreplyto = $xpath->query('thr:in-reply-to', $entry);
- if (is_object($inreplyto->item(0))) {
- foreach ($inreplyto->item(0)->attributes as $attributes) {
- if ($attributes->name == "ref") {
- $conv_data['reply-to-uri'] = $attributes->textContent;
- }
- }
- }
-
- $conv_data['conversation-uri'] = XML::getFirstNodeValue($xpath, 'ostatus:conversation/text()', $entry);
-
- $conv = $xpath->query('ostatus:conversation', $entry);
- if (is_object($conv->item(0))) {
- foreach ($conv->item(0)->attributes as $attributes) {
- if ($attributes->name == "ref") {
- $conv_data['conversation-uri'] = $attributes->textContent;
- }
- if ($attributes->name == "href") {
- $conv_data['conversation-href'] = $attributes->textContent;
- }
- }
- }
-
- if ($conversation != '') {
- $conv_data['conversation-uri'] = $conversation;
- }
-
- if ($conversation_uri != '') {
- $conv_data['conversation-uri'] = $conversation_uri;
- }
-
- $entry = $doc2->importNode($entry, true);
-
- $doc2->appendChild($entry);
-
- $conv_data['source'] = $doc2->saveXML();
-
- Logger::info('Store conversation data for uri '.$conv_data['uri']);
- Conversation::insert($conv_data);
- }
- }
-
- /**
- * Fetch the own post so that it can be stored later
- *
- * We want to store the original data for later processing.
- * This function is meant for cases where we process a feed with multiple entries.
- * In that case we need to fetch the single posts here.
- *
- * @param string $self The link to the self item
- * @param array $item The item array
- * @return void
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
- private static function fetchSelf($self, array &$item)
- {
- $condition = ['item-uri' => $self, 'protocol' => [Conversation::PARCEL_DFRN,
- Conversation::PARCEL_DIASPORA_DFRN, Conversation::PARCEL_LEGACY_DFRN,
- Conversation::PARCEL_LOCAL_DFRN, Conversation::PARCEL_DIRECT, Conversation::PARCEL_SALMON]];
- if (DBA::exists('conversation', $condition)) {
- Logger::info('Conversation '.$item['uri'].' is already stored.');
- return;
- }
-
- $curlResult = DI::httpClient()->get($self);
-
- if (!$curlResult->isSuccess()) {
- return;
- }
-
- // We reformat the XML to make it better readable
- $doc = new DOMDocument();
- $doc->loadXML($curlResult->getBody());
- $doc->preserveWhiteSpace = false;
- $doc->formatOutput = true;
- $xml = $doc->saveXML();
-
- $item["protocol"] = Conversation::PARCEL_SALMON;
- $item["source"] = $xml;
- $item["direction"] = Conversation::PULL;
-
- Logger::info('Conversation '.$item['uri'].' is now fetched.');
- }
-