diff --git a/classes/Conversation.php b/classes/Conversation.php index 1dba2c1f4a..d18321deba 100644 --- a/classes/Conversation.php +++ b/classes/Conversation.php @@ -36,6 +36,7 @@ class Conversation extends Managed_DataObject public $__table = 'conversation'; // table name public $id; // int(4) primary_key not_null auto_increment public $uri; // varchar(191) unique_key not 255 because utf8mb4 takes more space + public $url; // varchar(191) unique_key not 255 because utf8mb4 takes more space public $created; // datetime not_null public $modified; // timestamp not_null default_CURRENT_TIMESTAMP @@ -45,6 +46,7 @@ class Conversation extends Managed_DataObject 'fields' => array( 'id' => array('type' => 'serial', 'not null' => true, 'description' => 'Unique identifier, (again) unrelated to notice id since 2016-01-06'), 'uri' => array('type' => 'varchar', 'not null'=>true, 'length' => 191, 'description' => 'URI of the conversation'), + 'url' => array('type' => 'varchar', 'length' => 191, 'description' => 'Resolvable URL, preferrably remote (local can be generated on the fly)'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'), ), @@ -89,15 +91,21 @@ class Conversation extends Managed_DataObject * * @return Conversation the new conversation DO */ - static function create($uri=null, $created=null) + static function create(ActivityContext $ctx=null, $created=null) { // Be aware that the Notice does not have an id yet since it's not inserted! $conv = new Conversation(); $conv->created = $created ?: common_sql_now(); - $conv->uri = $uri ?: sprintf('%s%s=%s:%s=%s', + if ($ctx instanceof ActivityContext) { + $conv->uri = $ctx->conversation; + $conv->url = $ctx->conversation_url; + } else { + $conv->uri = sprintf('%s%s=%s:%s=%s', TagURI::mint(), 'objectType', 'thread', 'nonce', common_random_hexstr(8)); + $conv->url = null; // locally generated Conversation objects don't get static URLs stored + } // This insert throws exceptions on failure $conv->insert(); diff --git a/classes/Notice.php b/classes/Notice.php index d5a0e5f6d2..bfe9f1c7f6 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -624,8 +624,13 @@ class Notice extends Managed_DataObject } else { // Conversation entry with specified URI was not found, so we must create it. common_debug('Conversation URI not found, so we will create it with the URI given in the options to Notice::saveNew: '.$options['conversation']); + $convctx = new ActivityContext(); + $convctx->conversation = $options['conversation']; + if (array_key_exists('conversation_url', $options)) { + $convctx->conversation_url = $options['conversation_url']; + } // The insert in Conversation::create throws exception on failure - $conv = Conversation::create($options['conversation'], $notice->created); + $conv = Conversation::create($convctx, $notice->created); } $notice->conversation = $conv->getID(); unset($conv); @@ -921,7 +926,7 @@ class Notice extends Managed_DataObject // Conversation entry with specified URI was not found, so we must create it. common_debug('Conversation URI not found, so we will create it with the URI given in the context of the activity: '.$act->context->conversation); // The insert in Conversation::create throws exception on failure - $conv = Conversation::create($act->context->conversation, $stored->created); + $conv = Conversation::create($act->context, $stored->created); } $stored->conversation = $conv->getID(); unset($conv); @@ -2008,6 +2013,7 @@ class Notice extends Managed_DataObject $conv = Conversation::getKV('id', $this->conversation); if ($conv instanceof Conversation) { $ctx->conversation = $conv->uri; + $ctx->conversation_url = $conv->url; } } diff --git a/lib/activitycontext.php b/lib/activitycontext.php index 32f15c1e9f..68ee08a8fb 100644 --- a/lib/activitycontext.php +++ b/lib/activitycontext.php @@ -39,6 +39,7 @@ class ActivityContext public $location; public $attention = array(); // 'uri' => 'type' public $conversation; + public $conversation_url; public $scope; const THR = 'http://purl.org/syndication/thread/1.0'; @@ -51,7 +52,7 @@ class ActivityContext // OStatus element names with prefixes const OBJECTTYPE = 'ostatus:object-type'; // FIXME: Undocumented! - const CONVERSATION = 'ostatus:conversation'; + const CONVERSATION = 'conversation'; const POINT = 'point'; @@ -74,13 +75,22 @@ class ActivityContext $this->location = $this->getLocation($element); - $convs = $element->getElementsByTagNameNS(self::OSTATUS, self::CONVERSATION); - foreach ($convs as $conv) { - $this->conversation = $conv->textContent; + foreach ($element->getElementsByTagNameNS(self::OSTATUS, self::CONVERSATION) as $conv) { + if ($conv->hasAttribute('ref')) { + $this->conversation = $conv->getAttribute('ref'); + if ($conv->hasAttribute('href')) { + $this->conversation_url = $conv->getAttribute('href'); + } + } else { + $this->conversation = $conv->textContent; + } + if (!empty($this->conversation)) { + break; + } } if (empty($this->conversation)) { // fallback to the atom:link rel="ostatus:conversation" element - $this->conversation = ActivityUtils::getLink($element, self::CONVERSATION); + $this->conversation = ActivityUtils::getLink($element, 'ostatus:'.self::CONVERSATION); } // Multiple attention links allowed @@ -148,6 +158,7 @@ class ActivityContext $context['inReplyTo'] = $this->getInReplyToArray(); $context['conversation'] = $this->conversation; + $context['conversation_url'] = $this->conversation_url; return array_filter($context); }