+ 'toot' => (object)['@id' => 'http://joinmastodon.org/ns#', '@type' => '@id'],
+ 'litepub' => (object)['@id' => 'http://litepub.social/ns#', '@type' => '@id'],
+ 'sc' => (object)['@id' => 'http://schema.org#', '@type' => '@id'],
+ 'pt' => (object)['@id' => 'https://joinpeertube.org/ns#', '@type' => '@id'],
+ 'mobilizon' => (object)['@id' => 'https://joinmobilizon.org/ns#', '@type' => '@id'],
+ 'fedibird' => (object)['@id' => 'http://fedibird.com/ns#', '@type' => '@id'],
+ 'misskey' => (object)['@id' => 'https://misskey-hub.net/ns#', '@type' => '@id'],
+ ];
+
+ $orig_json = $json;
+
+ // Preparation for adding possibly missing content to the context
+ if (!empty($json['@context']) && is_string($json['@context'])) {
+ $json['@context'] = [$json['@context']];
+ }
+
+ if (!empty($json['@context']) && is_array($json['@context'])) {
+ // Remove empty entries from the context (a problem with WriteFreely)
+ $json['@context'] = array_filter($json['@context']);
+
+ // Workaround for servers with missing context
+ // See issue https://github.com/nextcloud/social/issues/330
+ if (!in_array('https://w3id.org/security/v1', $json['@context'])) {
+ $json['@context'][] = 'https://w3id.org/security/v1';
+ }
+
+ // Issue 12419: Workaround for GoToSocial
+ $pos = array_search('http://joinmastodon.org/ns', $json['@context']);
+ if (is_int($pos)) {
+ $json['@context'][$pos] = ['toot' => 'http://joinmastodon.org/ns#'];
+ }
+ }
+
+ // Bookwyrm transmits "id" fields with "null", which isn't allowed.
+ array_walk_recursive($json, function (&$value, $key) {
+ if ($key == 'id' && is_null($value)) {
+ $value = '';
+ }
+ });