Merge branch '1.0.x' into schema-x
Conflicts: plugins/OStatus/classes/Ostatus_profile.php
This commit is contained in:
@@ -146,9 +146,11 @@ class Ostatus_profile extends Managed_DataObject
|
||||
} else if ($this->group_id && !$this->profile_id) {
|
||||
return true;
|
||||
} else if ($this->group_id && $this->profile_id) {
|
||||
throw new ServerException("Invalid ostatus_profile state: both group and profile IDs set for $this->uri");
|
||||
// TRANS: Server exception.
|
||||
throw new ServerException(sprintf(_m('Invalid ostatus_profile state: both group and profile IDs set for %s.'),$this->uri));
|
||||
} else {
|
||||
throw new ServerException("Invalid ostatus_profile state: both group and profile IDs empty for $this->uri");
|
||||
// TRANS: Server exception.
|
||||
throw new ServerException(sprintf(_m('Invalid ostatus_profile state: both group and profile IDs empty for %s.'),$this->uri));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +238,9 @@ class Ostatus_profile extends Managed_DataObject
|
||||
if ($type == 'object') {
|
||||
$type = get_class($actor);
|
||||
}
|
||||
throw new ServerException("Invalid actor passed to " . __METHOD__ . ": " . $type);
|
||||
// TRANS: Server exception.
|
||||
// TRANS: %1$s is the method name the exception occured in, %2$s is the actor type.
|
||||
throw new ServerException(sprintf(_m('Invalid actor passed to %1$s: %2$s.'),__METHOD__,$type));
|
||||
}
|
||||
if ($object == null) {
|
||||
$object = $this;
|
||||
@@ -328,7 +332,8 @@ class Ostatus_profile extends Managed_DataObject
|
||||
} else if ($entry instanceof Notice) {
|
||||
return $preamble . $entry->asAtomEntry(true, true);
|
||||
} else {
|
||||
throw new ServerException("Invalid type passed to Ostatus_profile::notify; must be XML string or Activity entry");
|
||||
// TRANS: Server exception.
|
||||
throw new ServerException(_m('Invalid type passed to Ostatus_profile::notify. It must be XML string or Activity entry.'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,7 +363,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
} else if ($feed->localName == 'rss') { // @fixme check namespace
|
||||
$this->processRssFeed($feed, $source);
|
||||
} else {
|
||||
throw new Exception("Unknown feed format.");
|
||||
throw new Exception(_m('Unknown feed format.'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,7 +386,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
$channels = $rss->getElementsByTagName('channel');
|
||||
|
||||
if ($channels->length == 0) {
|
||||
throw new Exception("RSS feed without a channel.");
|
||||
throw new Exception(_m('RSS feed without a channel.'));
|
||||
} else if ($channels->length > 1) {
|
||||
common_log(LOG_WARNING, __METHOD__ . ": more than one channel in an RSS feed");
|
||||
}
|
||||
@@ -403,26 +408,33 @@ class Ostatus_profile extends Managed_DataObject
|
||||
* @param DOMElement $feed for context
|
||||
* @param string $source identifier ("push" or "salmon")
|
||||
*/
|
||||
|
||||
public function processEntry($entry, $feed, $source)
|
||||
{
|
||||
$activity = new Activity($entry, $feed);
|
||||
|
||||
// @todo process all activity objects
|
||||
switch ($activity->objects[0]->type) {
|
||||
case ActivityObject::ARTICLE:
|
||||
case ActivityObject::BLOGENTRY:
|
||||
case ActivityObject::NOTE:
|
||||
case ActivityObject::STATUS:
|
||||
case ActivityObject::COMMENT:
|
||||
break;
|
||||
default:
|
||||
throw new ClientException("Can't handle that kind of post.");
|
||||
}
|
||||
if (Event::handle('StartHandleFeedEntry', array($activity))) {
|
||||
|
||||
if ($activity->verb == ActivityVerb::POST) {
|
||||
$this->processPost($activity, $source);
|
||||
} else {
|
||||
common_log(LOG_INFO, "Ignoring activity with unrecognized verb $activity->verb");
|
||||
// @todo process all activity objects
|
||||
switch ($activity->objects[0]->type) {
|
||||
case ActivityObject::ARTICLE:
|
||||
case ActivityObject::BLOGENTRY:
|
||||
case ActivityObject::NOTE:
|
||||
case ActivityObject::STATUS:
|
||||
case ActivityObject::COMMENT:
|
||||
case null:
|
||||
if ($activity->verb == ActivityVerb::POST) {
|
||||
$this->processPost($activity, $source);
|
||||
} else {
|
||||
common_log(LOG_INFO, "Ignoring activity with unrecognized verb $activity->verb");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// TRANS: Client exception.
|
||||
throw new ClientException(_m('Can\'t handle that kind of post.'));
|
||||
}
|
||||
|
||||
Event::handle('EndHandleFeedEntry', array($activity));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,8 +466,11 @@ class Ostatus_profile extends Managed_DataObject
|
||||
} else if ($actor->id) {
|
||||
// We have an ActivityStreams actor with an explicit ID that doesn't match the feed owner.
|
||||
// This isn't what we expect from mainline OStatus person feeds!
|
||||
// Group feeds go down another path, with different validation.
|
||||
throw new Exception("Got an actor '{$actor->title}' ({$actor->id}) on single-user feed for {$this->uri}");
|
||||
// Group feeds go down another path, with different validation...
|
||||
// Most likely this is a plain ol' blog feed of some kind which
|
||||
// doesn't match our expectations. We'll take the entry, but ignore
|
||||
// the <author> info.
|
||||
common_log(LOG_WARNING, "Got an actor '{$actor->title}' ({$actor->id}) on single-user feed for {$this->uri}");
|
||||
} else {
|
||||
// Plain <author> without ActivityStreams actor info.
|
||||
// We'll just ignore this info for now and save the update under the feed's identity.
|
||||
@@ -498,13 +513,14 @@ class Ostatus_profile extends Managed_DataObject
|
||||
$sourceContent = $note->title;
|
||||
} else {
|
||||
// @fixme fetch from $sourceUrl?
|
||||
throw new ClientException("No content for notice {$sourceUri}");
|
||||
// TRANS: Client exception. %s is a source URL.
|
||||
throw new ClientException(sprintf(_m('No content for notice %s.'),$sourceUri));
|
||||
}
|
||||
|
||||
// Get (safe!) HTML and text versions of the content
|
||||
|
||||
$rendered = $this->purify($sourceContent);
|
||||
$content = html_entity_decode(strip_tags($rendered));
|
||||
$content = html_entity_decode(strip_tags($rendered), ENT_QUOTES, 'UTF-8');
|
||||
|
||||
$shortened = common_shorten_links($content);
|
||||
|
||||
@@ -515,7 +531,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
|
||||
if (Notice::contentTooLong($shortened)) {
|
||||
$attachment = $this->saveHTMLFile($note->title, $rendered);
|
||||
$summary = html_entity_decode(strip_tags($note->summary));
|
||||
$summary = html_entity_decode(strip_tags($note->summary), ENT_QUOTES, 'UTF-8');
|
||||
if (empty($summary)) {
|
||||
$summary = $content;
|
||||
}
|
||||
@@ -529,12 +545,15 @@ class Ostatus_profile extends Managed_DataObject
|
||||
|
||||
// We mark up the attachment link specially for the HTML output
|
||||
// so we can fold-out the full version inline.
|
||||
|
||||
// TRANS: Shown when a notice is longer than supported and/or when attachments are present.
|
||||
$showMoreText = _m('Show more');
|
||||
$attachUrl = common_local_url('attachment',
|
||||
array('attachment' => $attachment->id));
|
||||
$rendered = common_render_text($shortSummary) .
|
||||
'<a href="' . htmlspecialchars($attachUrl) .'"'.
|
||||
' class="attachment more"' .
|
||||
' title="'. htmlspecialchars(_m('Show more')) . '">' .
|
||||
' title="'. htmlspecialchars($showMoreText) . '">' .
|
||||
'…' .
|
||||
'</a>';
|
||||
}
|
||||
@@ -648,21 +667,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
continue;
|
||||
}
|
||||
|
||||
// Is the recipient a remote group?
|
||||
$oprofile = Ostatus_profile::staticGet('uri', $recipient);
|
||||
if ($oprofile) {
|
||||
if ($oprofile->isGroup()) {
|
||||
// Deliver to local members of this remote group.
|
||||
// @fixme sender verification?
|
||||
$groups[] = $oprofile->group_id;
|
||||
} else {
|
||||
common_log(LOG_DEBUG, "Skipping reply to remote profile $recipient");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Is the recipient a local group?
|
||||
// @fixme uri on user_group isn't reliable yet
|
||||
// $group = User_group::staticGet('uri', $recipient);
|
||||
$id = OStatusPlugin::localGroupFromUrl($recipient);
|
||||
if ($id) {
|
||||
@@ -681,7 +686,22 @@ class Ostatus_profile extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
common_log(LOG_DEBUG, "Skipping reply to unrecognized profile $recipient");
|
||||
// Is the recipient a remote user or group?
|
||||
try {
|
||||
$oprofile = Ostatus_profile::ensureProfileURI($recipient);
|
||||
if ($oprofile->isGroup()) {
|
||||
// Deliver to local members of this remote group.
|
||||
// @fixme sender verification?
|
||||
$groups[] = $oprofile->group_id;
|
||||
} else {
|
||||
// may be canonicalized or something
|
||||
$replies[] = $oprofile->uri;
|
||||
}
|
||||
continue;
|
||||
} catch (Exception $e) {
|
||||
// Neither a recognizable local nor remote user!
|
||||
common_log(LOG_DEBUG, "Skipping reply to unrecognized profile $recipient: " . $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
$attention_uris = $replies;
|
||||
@@ -719,7 +739,8 @@ class Ostatus_profile extends Managed_DataObject
|
||||
$response = $client->get($profile_url);
|
||||
|
||||
if (!$response->isOk()) {
|
||||
throw new Exception("Could not reach profile page: " . $profile_url);
|
||||
// TRANS: Exception. %s is a profile URL.
|
||||
throw new Exception(sprintf(_m('Could not reach profile page %s.'),$profile_url));
|
||||
}
|
||||
|
||||
// Check if we have a non-canonical URL
|
||||
@@ -776,7 +797,8 @@ class Ostatus_profile extends Managed_DataObject
|
||||
return self::ensureFeedURL($feedurl, $hints);
|
||||
}
|
||||
|
||||
throw new Exception("Could not find a feed URL for profile page " . $finalUrl);
|
||||
// TRANS: Exception.
|
||||
throw new Exception(sprintf(_m('Could not find a feed URL for profile page %s.'),$finalUrl));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -808,6 +830,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
$user = User::staticGet('id', $profile->id);
|
||||
|
||||
if (!empty($user)) {
|
||||
// @todo i18n FIXME: use sprintf and add i18n (?)
|
||||
throw new OStatusShadowException($profile, "'$profile_url' is the profile for local user '{$user->nickname}'.");
|
||||
}
|
||||
|
||||
@@ -912,8 +935,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
}
|
||||
|
||||
// XXX: make some educated guesses here
|
||||
|
||||
throw new FeedSubException("Can't find enough profile information to make a feed.");
|
||||
throw new FeedSubException(_m('Can\'t find enough profile information to make a feed.'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -972,7 +994,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
return;
|
||||
}
|
||||
if (!common_valid_http_url($url)) {
|
||||
throw new ServerException(sprintf(_m("Invalid avatar URL %s"), $url));
|
||||
throw new ServerException(sprintf(_m("Invalid avatar URL %s."), $url));
|
||||
}
|
||||
|
||||
if ($this->isGroup()) {
|
||||
@@ -982,7 +1004,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
}
|
||||
if (!$self) {
|
||||
throw new ServerException(sprintf(
|
||||
_m("Tried to update avatar for unsaved remote profile %s"),
|
||||
_m("Tried to update avatar for unsaved remote profile %s."),
|
||||
$this->uri));
|
||||
}
|
||||
|
||||
@@ -990,7 +1012,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
// ripped from oauthstore.php (for old OMB client)
|
||||
$temp_filename = tempnam(sys_get_temp_dir(), 'listener_avatar');
|
||||
if (!copy($url, $temp_filename)) {
|
||||
throw new ServerException(sprintf(_m("Unable to fetch avatar from %s"), $url));
|
||||
throw new ServerException(sprintf(_m("Unable to fetch avatar from %s."), $url));
|
||||
}
|
||||
|
||||
if ($this->isGroup()) {
|
||||
@@ -1005,6 +1027,14 @@ class Ostatus_profile extends Managed_DataObject
|
||||
null,
|
||||
common_timestamp());
|
||||
rename($temp_filename, Avatar::path($filename));
|
||||
// @fixme hardcoded chmod is lame, but seems to be necessary to
|
||||
// keep from accidentally saving images from command-line (queues)
|
||||
// that can't be read from web server, which causes hard-to-notice
|
||||
// problems later on:
|
||||
//
|
||||
// http://status.net/open-source/issues/2663
|
||||
chmod(Avatar::path($filename), 0644);
|
||||
|
||||
$self->setOriginal($filename);
|
||||
|
||||
$orig = clone($this);
|
||||
@@ -1020,7 +1050,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
* @return mixed URL string or false
|
||||
*/
|
||||
|
||||
protected static function getActivityObjectAvatar($object, $hints=array())
|
||||
public static function getActivityObjectAvatar($object, $hints=array())
|
||||
{
|
||||
if ($object->avatarLinks) {
|
||||
$best = false;
|
||||
@@ -1173,7 +1203,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
if ($object->link && common_valid_http_url($object->link)) {
|
||||
return $object->link;
|
||||
}
|
||||
throw new ServerException("No author ID URI found");
|
||||
throw new ServerException("No author ID URI found.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1203,11 +1233,13 @@ class Ostatus_profile extends Managed_DataObject
|
||||
|
||||
$user = User::staticGet('uri', $homeuri);
|
||||
if ($user) {
|
||||
throw new Exception("Local user can't be referenced as remote.");
|
||||
// TRANS: Exception.
|
||||
throw new Exception(_m('Local user can\'t be referenced as remote.'));
|
||||
}
|
||||
|
||||
if (OStatusPlugin::localGroupFromUrl($homeuri)) {
|
||||
throw new Exception("Local group can't be referenced as remote.");
|
||||
// TRANS: Exception.
|
||||
throw new Exception(_m('Local group can\'t be referenced as remote.'));
|
||||
}
|
||||
|
||||
if (array_key_exists('feedurl', $hints)) {
|
||||
@@ -1258,7 +1290,8 @@ class Ostatus_profile extends Managed_DataObject
|
||||
|
||||
$oprofile->profile_id = $profile->insert();
|
||||
if (!$oprofile->profile_id) {
|
||||
throw new ServerException("Can't save local profile");
|
||||
// TRANS: Exception.
|
||||
throw new ServerException(_m('Can\'t save local profile.'));
|
||||
}
|
||||
} else {
|
||||
$group = new User_group();
|
||||
@@ -1268,14 +1301,16 @@ class Ostatus_profile extends Managed_DataObject
|
||||
|
||||
$oprofile->group_id = $group->insert();
|
||||
if (!$oprofile->group_id) {
|
||||
throw new ServerException("Can't save local profile");
|
||||
// TRANS: Exception.
|
||||
throw new ServerException(_m('Can\'t save local profile.'));
|
||||
}
|
||||
}
|
||||
|
||||
$ok = $oprofile->insert();
|
||||
|
||||
if (!$ok) {
|
||||
throw new ServerException("Can't save OStatus profile");
|
||||
// TRANS: Exception.
|
||||
throw new ServerException(_m('Can\'t save OStatus profile.'));
|
||||
}
|
||||
|
||||
$avatar = self::getActivityObjectAvatar($object, $hints);
|
||||
@@ -1317,7 +1352,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
|
||||
protected static function updateProfile($profile, $object, $hints=array())
|
||||
public static function updateProfile($profile, $object, $hints=array())
|
||||
{
|
||||
$orig = clone($profile);
|
||||
|
||||
@@ -1445,7 +1480,7 @@ class Ostatus_profile extends Managed_DataObject
|
||||
return $bio;
|
||||
}
|
||||
|
||||
protected static function getActivityObjectNickname($object, $hints=array())
|
||||
public static function getActivityObjectNickname($object, $hints=array())
|
||||
{
|
||||
if ($object->poco) {
|
||||
if (!empty($object->poco->preferredUsername)) {
|
||||
@@ -1533,7 +1568,8 @@ class Ostatus_profile extends Managed_DataObject
|
||||
if ($uri !== false) {
|
||||
if (is_null($uri)) {
|
||||
// Negative cache entry
|
||||
throw new Exception('Not a valid webfinger address.');
|
||||
// TRANS: Exception.
|
||||
throw new Exception(_m('Not a valid webfinger address.'));
|
||||
}
|
||||
$oprofile = Ostatus_profile::staticGet('uri', $uri);
|
||||
if (!empty($oprofile)) {
|
||||
@@ -1560,7 +1596,8 @@ class Ostatus_profile extends Managed_DataObject
|
||||
// Save negative cache entry so we don't waste time looking it up again.
|
||||
// @fixme distinguish temporary failures?
|
||||
self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), null);
|
||||
throw new Exception('Not a valid webfinger address.');
|
||||
// TRANS: Exception.
|
||||
throw new Exception(_m('Not a valid webfinger address.'));
|
||||
}
|
||||
|
||||
$hints = array('webfinger' => $addr);
|
||||
@@ -1641,7 +1678,8 @@ class Ostatus_profile extends Managed_DataObject
|
||||
|
||||
if (!$profile_id) {
|
||||
common_log_db_error($profile, 'INSERT', __FILE__);
|
||||
throw new Exception("Couldn't save profile for '$addr'");
|
||||
// TRANS: Exception. %s is a webfinger address.
|
||||
throw new Exception(sprintf(_m('Couldn\'t save profile for "%s".'),$addr));
|
||||
}
|
||||
|
||||
$oprofile = new Ostatus_profile();
|
||||
@@ -1659,14 +1697,16 @@ class Ostatus_profile extends Managed_DataObject
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($oprofile, 'INSERT', __FILE__);
|
||||
throw new Exception("Couldn't save ostatus_profile for '$addr'");
|
||||
// TRANS: Exception. %s is a webfinger address.
|
||||
throw new Exception(sprintf(_m('Couldn\'t save ostatus_profile for "%s".'),$addr));
|
||||
}
|
||||
|
||||
self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri);
|
||||
return $oprofile;
|
||||
}
|
||||
|
||||
throw new Exception("Couldn't find a valid profile for '$addr'");
|
||||
// TRANS: Exception. %s is a webfinger address.
|
||||
throw new Exception(sprintf(_m('Couldn\'t find a valid profile for "%s".'),$addr));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1708,11 +1748,42 @@ class Ostatus_profile extends Managed_DataObject
|
||||
|
||||
if ($file_id === false) {
|
||||
common_log_db_error($file, "INSERT", __FILE__);
|
||||
throw new ServerException(_('Could not store HTML content of long post as file.'));
|
||||
throw new ServerException(_m('Could not store HTML content of long post as file.'));
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
static function ensureProfileURI($uri)
|
||||
{
|
||||
$oprofile = null;
|
||||
|
||||
// First, try to query it
|
||||
|
||||
$oprofile = Ostatus_profile::staticGet('uri', $uri);
|
||||
|
||||
// If unfound, do discovery stuff
|
||||
|
||||
if (empty($oprofile)) {
|
||||
if (preg_match("/^(\w+)\:(.*)/", $uri, $match)) {
|
||||
$protocol = $match[1];
|
||||
switch ($protocol) {
|
||||
case 'http':
|
||||
case 'https':
|
||||
$oprofile = Ostatus_profile::ensureProfileURL($uri);
|
||||
break;
|
||||
case 'acct':
|
||||
case 'mailto':
|
||||
$rest = $match[2];
|
||||
$oprofile = Ostatus_profile::ensureWebfinger($rest);
|
||||
default:
|
||||
common_log("Unrecognized URI protocol for profile: $protocol ($uri)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $oprofile;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1734,4 +1805,3 @@ class OStatusShadowException extends Exception
|
||||
parent::__construct($message);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user