. * * @category Plugin * @package GNUsocial * @author Diogo Cordeiro * @author Daniel Supernault * @copyright 2018 Free Software Foundation http://fsf.org * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link https://www.gnu.org/software/social/ */ if (!defined('GNUSOCIAL')) { exit(1); } $valid_object_types = array("Note"); // Validate data if (!isset($data->object->id)) { ActivityPubReturn::error("Object ID not specified."); } elseif (!filter_var($data->object->id, FILTER_VALIDATE_URL)) { ActivityPubReturn::error("Invalid Object ID."); } if (!(isset($data->object->type) && in_array($data->object->type, $valid_object_types))) { ActivityPubReturn::error("Invalid Object type."); } if (!isset($data->object->content)) { ActivityPubReturn::error("Object content was not specified."); } if (!isset($data->object->url)) { ActivityPubReturn::error("Object url was not specified."); } elseif (!filter_var($data->object->url, FILTER_VALIDATE_URL)) { ActivityPubReturn::error("Invalid Object URL."); } if (!isset($data->object->to)) { ActivityPubReturn::error("Object To was not specified."); } $content = $data->object->content; $act = new Activity(); $act->verb = ActivityVerb::POST; $act->time = time(); $act->actor = $actor_profile->asActivityObject(); $act->context = new ActivityContext(); // Is this a reply? if (isset($data->object->inReplyTo)) { try { $inReplyTo = ActivityPubPlugin::get_local_notice_from_url($data->object->inReplyTo); } catch (Exception $e) { ActivityPubReturn::error("Invalid Object inReplyTo value."); } $act->context->replyToID = $inReplyTo->getUri(); $act->context->replyToUrl = $inReplyTo->getUrl(); } else { $inReplyTo = null; } $act->context->attention = common_get_attentions($content, $actor_profile, $inReplyTo); $discovery = new Activitypub_explorer; if ($to_profiles == "https://www.w3.org/ns/activitystreams#Public") { $to_profiles = array(); } // Generate To objects if (is_array($data->object->to)) { // Remove duplicates from To actors set array_unique($data->object->to); foreach ($data->object->to as $to_url) { try { $to_profiles = array_merge($to_profiles, $discovery->lookup($to_url)); } catch (Exception $e) { // Invalid actor found, just let it go. } } } elseif (empty($data->object->to) || in_array($data->object->to, $public_to)) { // No need to do anything else at this point, let's just break out the if } else { try { $to_profiles = array_merge($to_profiles, $discovery->lookup($data->object->to)); } catch (Exception $e) { // Invalid actor found, just let it go. } } // Generate Cc objects if (isset($data->object->cc) && is_array($data->object->cc)) { // Remove duplicates from Cc actors set array_unique($data->object->to); foreach ($data->object->cc as $cc_url) { try { $to_profiles = array_merge($to_profiles, $discovery->lookup($cc_url)); } catch (Exception $e) { // Invalid actor found, just let it go. } } } elseif (empty($data->object->cc) || in_array($data->object->cc, $public_to)) { // No need to do anything else at this point, let's just break out the if } else { try { $to_profiles = array_merge($to_profiles, $discovery->lookup($data->object->cc)); } catch (Exception $e) { // Invalid actor found, just let it go. } } unset($discovery); foreach ($to_profiles as $tp) { $act->context->attention[ActivityPubPlugin::actor_uri($tp)] = "http://activitystrea.ms/schema/1.0/person"; } // Add location if that is set if (isset($data->object->latitude, $data->object->longitude)) { $act->context->location = Location::fromLatLon($data->object->latitude, $data->object->longitude); } // Reject notice if it is too long (without the HTML) // This is done after MediaFile::fromUpload etc. just to act the same as the ApiStatusesUpdateAction if (Notice::contentTooLong($content)) { ActivityPubReturn::error("That's too long. Maximum notice size is %d character."); } $options = array('source' => 'ActivityPub', 'uri' => isset($data->id) ? $data->id : $data->object->url, 'url' => $data->object->url); // $options gets filled with possible scoping settings ToSelector::fillActivity($this, $act, $options); $actobj = new ActivityObject(); $actobj->type = ActivityObject::NOTE; $actobj->content = common_render_content($content, $actor_profile, $inReplyTo); // Finally add the activity object to our activity $act->objects[] = $actobj; try { $res = Activitypub_create::create_to_array( $data->id, $data->actor, Activitypub_notice::notice_to_array(Notice::saveActivity($act, $actor_profile, $options)) ); ActivityPubReturn::answer($res); } catch (Exception $e) { ActivityPubReturn::error($e->getMessage()); }