Merge pull request #11670 from Quix0r/fixes/more-type-hints-004
Fixes/more type hints 004
This commit is contained in:
commit
b96daeeeef
17 changed files with 1734 additions and 1548 deletions
|
|
@ -102,6 +102,7 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
* e.g. from protocol implementations.
|
||||
*
|
||||
* @param string[] $request The $_REQUEST content
|
||||
* @return void
|
||||
*/
|
||||
protected function rawContent(array $request = [])
|
||||
{
|
||||
|
|
@ -117,6 +118,7 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
* XML feed or a JSON output.
|
||||
*
|
||||
* @param string[] $request The $_REQUEST content
|
||||
* @return string
|
||||
*/
|
||||
protected function content(array $request = []): string
|
||||
{
|
||||
|
|
@ -130,6 +132,7 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
* Doesn't display any content
|
||||
*
|
||||
* @param string[] $request The $_REQUEST content
|
||||
* @return void
|
||||
*/
|
||||
protected function delete(array $request = [])
|
||||
{
|
||||
|
|
@ -142,6 +145,7 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
* Doesn't display any content
|
||||
*
|
||||
* @param string[] $request The $_REQUEST content
|
||||
* @return void
|
||||
*/
|
||||
protected function patch(array $request = [])
|
||||
{
|
||||
|
|
@ -154,7 +158,7 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
* Doesn't display any content
|
||||
*
|
||||
* @param string[] $request The $_REQUEST content
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function post(array $request = [])
|
||||
{
|
||||
|
|
@ -168,6 +172,7 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
* Doesn't display any content
|
||||
*
|
||||
* @param string[] $request The $_REQUEST content
|
||||
* @return void
|
||||
*/
|
||||
protected function put(array $request = [])
|
||||
{
|
||||
|
|
@ -279,12 +284,12 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
/**
|
||||
* Fetch a request value and apply default values and check against minimal and maximal values
|
||||
*
|
||||
* @param array $input
|
||||
* @param string $parameter
|
||||
* @param mixed $default
|
||||
* @param mixed $minimal_value
|
||||
* @param mixed $maximum_value
|
||||
* @return mixed
|
||||
* @param array $input Input fields
|
||||
* @param string $parameter Parameter
|
||||
* @param mixed $default Default
|
||||
* @param mixed $minimal_value Minimal value
|
||||
* @param mixed $maximum_value Maximum value
|
||||
* @return mixed null on error anything else on success (?)
|
||||
*/
|
||||
public function getRequestValue(array $input, string $parameter, $default = null, $minimal_value = null, $maximum_value = null)
|
||||
{
|
||||
|
|
@ -320,7 +325,7 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
return $value;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Functions used to protect against Cross-Site Request Forgery
|
||||
* The security token has to base on at least one value that an attacker can't know - here it's the session ID and the private key.
|
||||
* In this implementation, a security token is reusable (if the user submits a form, goes back and resubmits the form, maybe with small changes;
|
||||
|
|
@ -330,8 +335,11 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
* If the new page contains by any chance external elements, then the used security token is exposed by the referrer.
|
||||
* Actually, important actions should not be triggered by Links / GET-Requests at all, but sometimes they still are,
|
||||
* so this mechanism brings in some damage control (the attacker would be able to forge a request to a form of this type, but not to forms of other types).
|
||||
*
|
||||
* @param string $typename Type name
|
||||
* @return string Security hash with timestamp
|
||||
*/
|
||||
public static function getFormSecurityToken(string $typename = '')
|
||||
public static function getFormSecurityToken(string $typename = ''): string
|
||||
{
|
||||
$user = User::getById(DI::app()->getLoggedInUserId(), ['guid', 'prvkey']);
|
||||
$timestamp = time();
|
||||
|
|
@ -404,7 +412,7 @@ abstract class BaseModule implements ICanHandleRequests
|
|||
}
|
||||
}
|
||||
|
||||
protected static function getContactFilterTabs(string $baseUrl, string $current, bool $displayCommonTab)
|
||||
protected static function getContactFilterTabs(string $baseUrl, string $current, bool $displayCommonTab): array
|
||||
{
|
||||
$tabs = [
|
||||
[
|
||||
|
|
|
|||
|
|
@ -1247,16 +1247,28 @@ class BBCode
|
|||
return $text;
|
||||
}
|
||||
|
||||
private static function expandLinksCallback($match)
|
||||
/**
|
||||
* Callback: Expands links from given $match array
|
||||
*
|
||||
* @param arrat $match Array with link match
|
||||
* @return string BBCode
|
||||
*/
|
||||
private static function expandLinksCallback(array $match): string
|
||||
{
|
||||
if (($match[3] == '') || ($match[2] == $match[3]) || stristr($match[2], $match[3])) {
|
||||
return ($match[1] . "[url]" . $match[2] . "[/url]");
|
||||
return ($match[1] . '[url]' . $match[2] . '[/url]');
|
||||
} else {
|
||||
return ($match[1] . $match[3] . " [url]" . $match[2] . "[/url]");
|
||||
return ($match[1] . $match[3] . ' [url]' . $match[2] . '[/url]');
|
||||
}
|
||||
}
|
||||
|
||||
private static function cleanPictureLinksCallback($match)
|
||||
/**
|
||||
* Callback: Cleans picture links
|
||||
*
|
||||
* @param arrat $match Array with link match
|
||||
* @return string BBCode
|
||||
*/
|
||||
private static function cleanPictureLinksCallback(array $match): string
|
||||
{
|
||||
// When the picture link is the own photo path then we can avoid fetching the link
|
||||
$own_photo_url = preg_quote(Strings::normaliseLink(DI::baseUrl()->get()) . '/photos/');
|
||||
|
|
@ -1325,7 +1337,13 @@ class BBCode
|
|||
return $text;
|
||||
}
|
||||
|
||||
public static function cleanPictureLinks($text)
|
||||
/**
|
||||
* Cleans picture links
|
||||
*
|
||||
* @param string $text HTML/BBCode string
|
||||
* @return string Cleaned HTML/BBCode
|
||||
*/
|
||||
public static function cleanPictureLinks(string $text): string
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$return = preg_replace_callback("&\[url=([^\[\]]*)\]\[img=(.*)\](.*)\[\/img\]\[\/url\]&Usi", 'self::cleanPictureLinksCallback', $text);
|
||||
|
|
@ -1334,7 +1352,13 @@ class BBCode
|
|||
return $return;
|
||||
}
|
||||
|
||||
public static function removeLinks(string $bbcode)
|
||||
/**
|
||||
* Removes links
|
||||
*
|
||||
* @param string $text HTML/BBCode string
|
||||
* @return string Cleaned HTML/BBCode
|
||||
*/
|
||||
public static function removeLinks(string $bbcode): string
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$bbcode = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", ' $1 ', $bbcode);
|
||||
|
|
@ -1350,10 +1374,10 @@ class BBCode
|
|||
/**
|
||||
* Replace names in mentions with nicknames
|
||||
*
|
||||
* @param string $body
|
||||
* @param string $body HTML/BBCode
|
||||
* @return string Body with replaced mentions
|
||||
*/
|
||||
public static function setMentionsToNicknames(string $body):string
|
||||
public static function setMentionsToNicknames(string $body): string
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$regexp = "/([@!])\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
|
||||
|
|
@ -1366,10 +1390,10 @@ class BBCode
|
|||
* Callback function to replace a Friendica style mention in a mention with the nickname
|
||||
*
|
||||
* @param array $match Matching values for the callback
|
||||
* @return string Replaced mention
|
||||
* @return string Replaced mention or empty string
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function mentionCallback($match)
|
||||
private static function mentionCallback(array $match): string
|
||||
{
|
||||
if (empty($match[2])) {
|
||||
return '';
|
||||
|
|
@ -1407,7 +1431,7 @@ class BBCode
|
|||
* @return string
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function convertForUriId(int $uriid = null, string $text = null, int $simple_html = self::INTERNAL)
|
||||
public static function convertForUriId(int $uriid = null, string $text = null, int $simple_html = self::INTERNAL): string
|
||||
{
|
||||
$try_oembed = ($simple_html == self::INTERNAL);
|
||||
|
||||
|
|
@ -1437,10 +1461,10 @@ class BBCode
|
|||
* @param int $simple_html
|
||||
* @param bool $for_plaintext
|
||||
* @param int $uriid
|
||||
* @return string
|
||||
* @return string Converted code or empty string
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function convert(string $text = null, $try_oembed = true, $simple_html = self::INTERNAL, $for_plaintext = false, $uriid = 0)
|
||||
public static function convert(string $text = null, bool $try_oembed = true, int $simple_html = self::INTERNAL, bool $for_plaintext = false, int $uriid = 0): string
|
||||
{
|
||||
// Accounting for null default column values
|
||||
if (is_null($text) || $text === '') {
|
||||
|
|
@ -2142,7 +2166,7 @@ class BBCode
|
|||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function bbCodeMention2DiasporaCallback($match)
|
||||
private static function bbCodeMention2DiasporaCallback(array $match): string
|
||||
{
|
||||
$contact = Contact::getByURL($match[3], false, ['addr']);
|
||||
if (empty($contact['addr'])) {
|
||||
|
|
@ -2164,7 +2188,7 @@ class BBCode
|
|||
* @return string
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function toMarkdown($text, $for_diaspora = true)
|
||||
public static function toMarkdown(string $text, bool $for_diaspora = true): string
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$original_text = $text;
|
||||
|
|
@ -2249,7 +2273,7 @@ class BBCode
|
|||
*
|
||||
* @return array List of tag and person names
|
||||
*/
|
||||
public static function getTags($string)
|
||||
public static function getTags(string $string): array
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$ret = [];
|
||||
|
|
@ -2309,10 +2333,10 @@ class BBCode
|
|||
/**
|
||||
* Expand tags to URLs, checks the tag is at the start of a line or preceded by a non-word character
|
||||
*
|
||||
* @param string $body
|
||||
* @param string $body HTML/BBCode
|
||||
* @return string body with expanded tags
|
||||
*/
|
||||
public static function expandTags(string $body)
|
||||
public static function expandTags(string $body): string
|
||||
{
|
||||
return preg_replace_callback("/(?<=\W|^)([!#@])([^\^ \x0D\x0A,;:?'\"]*[^\^ \x0D\x0A,;:?!'\".])/",
|
||||
function ($match) {
|
||||
|
|
@ -2336,7 +2360,7 @@ class BBCode
|
|||
/**
|
||||
* Perform a custom function on a text after having escaped blocks enclosed in the provided tag list.
|
||||
*
|
||||
* @param string $text
|
||||
* @param string $text HTML/BBCode
|
||||
* @param array $tagList A list of tag names, e.g ['noparse', 'nobb', 'pre']
|
||||
* @param callable $callback
|
||||
* @return string
|
||||
|
|
@ -2352,14 +2376,14 @@ class BBCode
|
|||
/**
|
||||
* Replaces mentions in the provided message body in BBCode links for the provided user and network if any
|
||||
*
|
||||
* @param $body
|
||||
* @param $profile_uid
|
||||
* @param $network
|
||||
* @return string
|
||||
* @param string $body HTML/BBCode
|
||||
* @param int $profile_uid Profile user id
|
||||
* @param string $network Network name
|
||||
* @return string HTML/BBCode with inserted images
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public static function setMentions($body, $profile_uid = 0, $network = '')
|
||||
public static function setMentions(string $body, $profile_uid = 0, $network = '')
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$body = self::performWithEscapedTags($body, ['noparse', 'pre', 'code', 'img'], function ($body) use ($profile_uid, $network) {
|
||||
|
|
@ -2406,7 +2430,7 @@ class BBCode
|
|||
* @return string
|
||||
* @TODO Rewrite to handle over whole record array
|
||||
*/
|
||||
public static function getShareOpeningTag(string $author, string $profile, string $avatar, string $link, string $posted, string $guid = null)
|
||||
public static function getShareOpeningTag(string $author, string $profile, string $avatar, string $link, string $posted, string $guid = null): string
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$header = "[share author='" . str_replace(["'", "[", "]"], ["'", "[", "]"], $author) .
|
||||
|
|
|
|||
|
|
@ -73,11 +73,12 @@ class Tag
|
|||
/**
|
||||
* Store tag/mention elements
|
||||
*
|
||||
* @param integer $uriid
|
||||
* @param integer $type
|
||||
* @param string $name
|
||||
* @param string $url
|
||||
* @param integer $target
|
||||
* @param integer $uriid URI id
|
||||
* @param integer $type Tag type
|
||||
* @param string $name Tag name
|
||||
* @param string $url Contact URL (optional)
|
||||
* @param integer $target Target (default: null)
|
||||
* @return void
|
||||
*/
|
||||
public static function store(int $uriid, int $type, string $name, string $url = '', int $target = null)
|
||||
{
|
||||
|
|
@ -249,13 +250,14 @@ class Tag
|
|||
/**
|
||||
* Store tag/mention elements
|
||||
*
|
||||
* @param integer $uriid
|
||||
* @param string $hash
|
||||
* @param string $name
|
||||
* @param string $url
|
||||
* @param boolean $probing
|
||||
* @param integer $uriid URI id
|
||||
* @param string $hash Hash
|
||||
* @param string $name Name
|
||||
* @param string $url URL
|
||||
* @param boolean $probing Whether probing is active
|
||||
* @return void
|
||||
*/
|
||||
public static function storeByHash(int $uriid, string $hash, string $name, string $url = '', $probing = true)
|
||||
public static function storeByHash(int $uriid, string $hash, string $name, string $url = '', bool $probing = true)
|
||||
{
|
||||
$type = self::getTypeForHash($hash);
|
||||
if ($type == self::UNKNOWN) {
|
||||
|
|
@ -293,8 +295,9 @@ class Tag
|
|||
* @param string $body Body of the post
|
||||
* @param string $tags Accepted tags
|
||||
* @param boolean $probing Perform a probing for contacts, adding them if needed
|
||||
* @return void
|
||||
*/
|
||||
public static function storeFromBody(int $uriid, string $body, string $tags = null, $probing = true)
|
||||
public static function storeFromBody(int $uriid, string $body, string $tags = null, bool $probing = true)
|
||||
{
|
||||
Logger::info('Check for tags', ['uri-id' => $uriid, 'hash' => $tags, 'callstack' => System::callstack()]);
|
||||
|
||||
|
|
@ -330,6 +333,7 @@ class Tag
|
|||
*
|
||||
* @param integer $uriid URI-Id
|
||||
* @param string $body Body of the post
|
||||
* @return void
|
||||
*/
|
||||
public static function storeRawTagsFromBody(int $uriid, string $body)
|
||||
{
|
||||
|
|
@ -364,10 +368,11 @@ class Tag
|
|||
/**
|
||||
* Remove tag/mention
|
||||
*
|
||||
* @param integer $uriid
|
||||
* @param integer $type
|
||||
* @param string $name
|
||||
* @param string $url
|
||||
* @param integer $uriid URI id
|
||||
* @param integer $type Type
|
||||
* @param string $name Name
|
||||
* @param string $url URL
|
||||
* @return void
|
||||
*/
|
||||
public static function remove(int $uriid, int $type, string $name, string $url = '')
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,7 +43,10 @@ require_once 'boot.php';
|
|||
abstract class BaseAdmin extends BaseModule
|
||||
{
|
||||
/**
|
||||
* Checks admin access and throws exceptions if not logged-in administrator
|
||||
*
|
||||
* @param bool $interactive
|
||||
* @return void
|
||||
* @throws HTTPException\ForbiddenException
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ abstract class HTTPException extends Exception
|
|||
protected $httpdesc = '';
|
||||
protected $explanation = '';
|
||||
|
||||
public function __construct($message = '', Exception $previous = null)
|
||||
public function __construct(string $message = '', Exception $previous = null)
|
||||
{
|
||||
parent::__construct($message, $this->code, $previous);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,18 +85,17 @@ class Probe
|
|||
* Rearrange the array so that it always has the same order
|
||||
*
|
||||
* @param array $data Unordered data
|
||||
*
|
||||
* @return array Ordered data
|
||||
*/
|
||||
private static function rearrangeData($data)
|
||||
private static function rearrangeData(array $data): array
|
||||
{
|
||||
$fields = ["name", "nick", "guid", "url", "addr", "alias", "photo", "header",
|
||||
"account-type", "community", "keywords", "location", "about", "xmpp", "matrix",
|
||||
"hide", "batch", "notify", "poll", "request", "confirm", "subscribe", "poco",
|
||||
"following", "followers", "inbox", "outbox", "sharedinbox",
|
||||
"priority", "network", "pubkey", "manually-approve", "baseurl", "gsid"];
|
||||
$fields = ['name', 'nick', 'guid', 'url', 'addr', 'alias', 'photo', 'header',
|
||||
'account-type', 'community', 'keywords', 'location', 'about', 'xmpp', 'matrix',
|
||||
'hide', 'batch', 'notify', 'poll', 'request', 'confirm', 'subscribe', 'poco',
|
||||
'following', 'followers', 'inbox', 'outbox', 'sharedinbox',
|
||||
'priority', 'network', 'pubkey', 'manually-approve', 'baseurl', 'gsid'];
|
||||
|
||||
$numeric_fields = ["gsid", "hide", "account-type", "manually-approve"];
|
||||
$numeric_fields = ['gsid', 'hide', 'account-type', 'manually-approve'];
|
||||
|
||||
$newdata = [];
|
||||
foreach ($fields as $field) {
|
||||
|
|
@ -107,14 +106,14 @@ class Probe
|
|||
$newdata[$field] = $data[$field];
|
||||
}
|
||||
} elseif (!in_array($field, $numeric_fields)) {
|
||||
$newdata[$field] = "";
|
||||
$newdata[$field] = '';
|
||||
} else {
|
||||
$newdata[$field] = null;
|
||||
}
|
||||
}
|
||||
|
||||
// We don't use the "priority" field anymore and replace it with a dummy.
|
||||
$newdata["priority"] = 0;
|
||||
$newdata['priority'] = 0;
|
||||
|
||||
return $newdata;
|
||||
}
|
||||
|
|
@ -123,10 +122,9 @@ class Probe
|
|||
* Check if the hostname belongs to the own server
|
||||
*
|
||||
* @param string $host The hostname that is to be checked
|
||||
*
|
||||
* @return bool Does the testes hostname belongs to the own server?
|
||||
*/
|
||||
private static function ownHost($host)
|
||||
private static function ownHost(string $host): bool
|
||||
{
|
||||
$own_host = DI::baseUrl()->getHostname();
|
||||
|
||||
|
|
@ -149,21 +147,20 @@ class Probe
|
|||
* It seems as if it was dropped from the standard.
|
||||
*
|
||||
* @param string $host The host part of an url
|
||||
*
|
||||
* @return array with template and type of the webfinger template for JSON or XML
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function hostMeta($host)
|
||||
private static function hostMeta(string $host): array
|
||||
{
|
||||
// Reset the static variable
|
||||
self::$baseurl = '';
|
||||
|
||||
// Handles the case when the hostname contains the scheme
|
||||
if (!parse_url($host, PHP_URL_SCHEME)) {
|
||||
$ssl_url = "https://" . $host . "/.well-known/host-meta";
|
||||
$url = "http://" . $host . "/.well-known/host-meta";
|
||||
$ssl_url = 'https://' . $host . '/.well-known/host-meta';
|
||||
$url = 'http://' . $host . '/.well-known/host-meta';
|
||||
} else {
|
||||
$ssl_url = $host . "/.well-known/host-meta";
|
||||
$ssl_url = $host . '/.well-known/host-meta';
|
||||
$url = '';
|
||||
}
|
||||
|
||||
|
|
@ -210,26 +207,26 @@ class Probe
|
|||
}
|
||||
|
||||
$links = XML::elementToArray($xrd);
|
||||
if (!isset($links["xrd"]["link"])) {
|
||||
if (!isset($links['xrd']['link'])) {
|
||||
Logger::info('No xrd data found', ['host' => $host]);
|
||||
return [];
|
||||
}
|
||||
|
||||
$lrdd = [];
|
||||
|
||||
foreach ($links["xrd"]["link"] as $value => $link) {
|
||||
if (!empty($link["@attributes"])) {
|
||||
$attributes = $link["@attributes"];
|
||||
} elseif ($value == "@attributes") {
|
||||
foreach ($links['xrd']['link'] as $value => $link) {
|
||||
if (!empty($link['@attributes'])) {
|
||||
$attributes = $link['@attributes'];
|
||||
} elseif ($value == '@attributes') {
|
||||
$attributes = $link;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($attributes["rel"]) && $attributes["rel"] == "lrdd" && !empty($attributes["template"])) {
|
||||
$type = (empty($attributes["type"]) ? '' : $attributes["type"]);
|
||||
if (!empty($attributes['rel']) && $attributes['rel'] == 'lrdd' && !empty($attributes['template'])) {
|
||||
$type = (empty($attributes['type']) ? '' : $attributes['type']);
|
||||
|
||||
$lrdd[$type] = $attributes["template"];
|
||||
$lrdd[$type] = $attributes['template'];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -249,11 +246,10 @@ class Probe
|
|||
* Check an URI for LRDD data
|
||||
*
|
||||
* @param string $uri Address that should be probed
|
||||
*
|
||||
* @return array uri data
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function lrdd(string $uri)
|
||||
public static function lrdd(string $uri): array
|
||||
{
|
||||
$data = self::getWebfingerArray($uri);
|
||||
if (empty($data)) {
|
||||
|
|
@ -261,22 +257,25 @@ class Probe
|
|||
}
|
||||
$webfinger = $data['webfinger'];
|
||||
|
||||
if (empty($webfinger["links"])) {
|
||||
if (empty($webfinger['links'])) {
|
||||
Logger::info('No webfinger links found', ['uri' => $uri]);
|
||||
return [];
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach ($webfinger["links"] as $link) {
|
||||
$data[] = ["@attributes" => $link];
|
||||
foreach ($webfinger['links'] as $link) {
|
||||
$data[] = ['@attributes' => $link];
|
||||
}
|
||||
|
||||
if (!empty($webfinger["aliases"]) && is_array($webfinger["aliases"])) {
|
||||
foreach ($webfinger["aliases"] as $alias) {
|
||||
$data[] = ["@attributes" =>
|
||||
["rel" => "alias",
|
||||
"href" => $alias]];
|
||||
if (!empty($webfinger['aliases']) && is_array($webfinger['aliases'])) {
|
||||
foreach ($webfinger['aliases'] as $alias) {
|
||||
$data[] = [
|
||||
'@attributes' => [
|
||||
'rel' => 'alias',
|
||||
'href' => $alias,
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -383,10 +382,9 @@ class Probe
|
|||
* Fetches the "hide" status from the profile
|
||||
*
|
||||
* @param string $url URL of the profile
|
||||
*
|
||||
* @return boolean "hide" status
|
||||
*/
|
||||
private static function getHideStatus($url)
|
||||
private static function getHideStatus(string $url): bool
|
||||
{
|
||||
$curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::CONTENT_LENGTH => 1000000]);
|
||||
if (!$curlResult->isSuccess()) {
|
||||
|
|
@ -443,11 +441,11 @@ class Probe
|
|||
/**
|
||||
* Fetch the "subscribe" and add it to the result
|
||||
*
|
||||
* @param array $result
|
||||
* @param array $webfinger
|
||||
* @return array result
|
||||
* @param array $result Result array
|
||||
* @param array $webfinger Webfinger data
|
||||
* @return array result Altered/unaltered result array
|
||||
*/
|
||||
private static function getSubscribeLink(array $result, array $webfinger)
|
||||
private static function getSubscribeLink(array $result, array $webfinger): array
|
||||
{
|
||||
if (empty($webfinger['links'])) {
|
||||
return $result;
|
||||
|
|
@ -465,8 +463,8 @@ class Probe
|
|||
/**
|
||||
* Get webfinger data from a given URI
|
||||
*
|
||||
* @param string $uri
|
||||
* @return array
|
||||
* @param string $uri URI
|
||||
* @return array Webfinger data
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function getWebfingerArray(string $uri): array
|
||||
|
|
@ -583,7 +581,7 @@ class Probe
|
|||
* @param string $addr
|
||||
* @return array webfinger results
|
||||
*/
|
||||
private static function getWebfinger(string $template, string $type, string $uri, string $addr)
|
||||
private static function getWebfinger(string $template, string $type, string $uri, string $addr): array
|
||||
{
|
||||
if (Network::isUrlBlocked($template)) {
|
||||
Logger::info('Domain is blocked', ['url' => $template]);
|
||||
|
|
@ -593,7 +591,7 @@ class Probe
|
|||
// First try the address because this is the primary purpose of webfinger
|
||||
if (!empty($addr)) {
|
||||
$detected = $addr;
|
||||
$path = str_replace('{uri}', urlencode("acct:" . $addr), $template);
|
||||
$path = str_replace('{uri}', urlencode('acct:' . $addr), $template);
|
||||
$webfinger = self::webfinger($path, $type);
|
||||
if (self::$istimeout) {
|
||||
return [];
|
||||
|
|
@ -626,11 +624,10 @@ class Probe
|
|||
* @param string $network Test for this specific network
|
||||
* @param integer $uid User ID for the probe (only used for mails)
|
||||
* @param array $ap_profile Previously probed AP profile
|
||||
*
|
||||
* @return array uri data
|
||||
* @return array URI data
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function detect(string $uri, string $network, int $uid, array $ap_profile)
|
||||
private static function detect(string $uri, string $network, int $uid, array $ap_profile): array
|
||||
{
|
||||
$hookData = [
|
||||
'uri' => $uri,
|
||||
|
|
@ -700,7 +697,7 @@ class Probe
|
|||
if (in_array($network, ['', Protocol::ZOT])) {
|
||||
$result = self::zot($webfinger, $result, $baseurl);
|
||||
}
|
||||
if ((!$result && ($network == "")) || ($network == Protocol::PUMPIO)) {
|
||||
if ((!$result && ($network == '')) || ($network == Protocol::PUMPIO)) {
|
||||
$result = self::pumpio($webfinger, $addr);
|
||||
}
|
||||
if (empty($result['network']) && empty($ap_profile['network']) || ($network == Protocol::FEED)) {
|
||||
|
|
@ -708,30 +705,30 @@ class Probe
|
|||
} else {
|
||||
// We overwrite the detected nick with our try if the previois routines hadn't detected it.
|
||||
// Additionally it is overwritten when the nickname doesn't make sense (contains spaces).
|
||||
if ((empty($result["nick"]) || (strstr($result["nick"], " "))) && ($nick != "")) {
|
||||
$result["nick"] = $nick;
|
||||
if ((empty($result['nick']) || (strstr($result['nick'], ' '))) && ($nick != '')) {
|
||||
$result['nick'] = $nick;
|
||||
}
|
||||
|
||||
if (empty($result["addr"]) && ($addr != "")) {
|
||||
$result["addr"] = $addr;
|
||||
if (empty($result['addr']) && ($addr != '')) {
|
||||
$result['addr'] = $addr;
|
||||
}
|
||||
}
|
||||
|
||||
$result = self::getSubscribeLink($result, $webfinger);
|
||||
|
||||
if (empty($result["network"])) {
|
||||
$result["network"] = Protocol::PHANTOM;
|
||||
if (empty($result['network'])) {
|
||||
$result['network'] = Protocol::PHANTOM;
|
||||
}
|
||||
|
||||
if (empty($result['baseurl']) && !empty($baseurl)) {
|
||||
$result['baseurl'] = $baseurl;
|
||||
}
|
||||
|
||||
if (empty($result["url"])) {
|
||||
$result["url"] = $uri;
|
||||
if (empty($result['url'])) {
|
||||
$result['url'] = $uri;
|
||||
}
|
||||
|
||||
Logger::info('Probing done', ['uri' => $uri, 'network' => $result["network"]]);
|
||||
Logger::info('Probing done', ['uri' => $uri, 'network' => $result['network']]);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
|
@ -739,24 +736,24 @@ class Probe
|
|||
/**
|
||||
* Check for Zot contact
|
||||
*
|
||||
* @param array $webfinger Webfinger data
|
||||
* @param array $data previously probed data
|
||||
*
|
||||
* @param array $webfinger Webfinger data
|
||||
* @param array $data previously probed data
|
||||
* @param string $baseUrl Base URL
|
||||
* @return array Zot data
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function zot($webfinger, $data, $baseurl)
|
||||
private static function zot(array $webfinger, array $data, string $baseurl): array
|
||||
{
|
||||
if (!empty($webfinger["aliases"]) && is_array($webfinger["aliases"])) {
|
||||
foreach ($webfinger["aliases"] as $alias) {
|
||||
if (!empty($webfinger['aliases']) && is_array($webfinger['aliases'])) {
|
||||
foreach ($webfinger['aliases'] as $alias) {
|
||||
if (substr($alias, 0, 5) == 'acct:') {
|
||||
$data["addr"] = substr($alias, 5);
|
||||
$data['addr'] = substr($alias, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($webfinger["subject"]) && (substr($webfinger["subject"], 0, 5) == "acct:")) {
|
||||
$data["addr"] = substr($webfinger["subject"], 5);
|
||||
if (!empty($webfinger['subject']) && (substr($webfinger['subject'], 0, 5) == 'acct:')) {
|
||||
$data['addr'] = substr($webfinger['subject'], 5);
|
||||
}
|
||||
|
||||
$zot_url = '';
|
||||
|
|
@ -882,11 +879,10 @@ class Probe
|
|||
*
|
||||
* @param string $url Address that should be probed
|
||||
* @param string $type type
|
||||
*
|
||||
* @return array webfinger data
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function webfinger($url, $type)
|
||||
public static function webfinger(string $url, string $type): array
|
||||
{
|
||||
$xrd_timeout = DI::config()->get('system', 'xrd_timeout', 20);
|
||||
|
||||
|
|
@ -899,7 +895,7 @@ class Probe
|
|||
|
||||
$webfinger = json_decode($data, true);
|
||||
if (!empty($webfinger)) {
|
||||
if (!isset($webfinger["links"])) {
|
||||
if (!isset($webfinger['links'])) {
|
||||
Logger::info('No json webfinger links', ['url' => $url]);
|
||||
return [];
|
||||
}
|
||||
|
|
@ -914,33 +910,33 @@ class Probe
|
|||
}
|
||||
|
||||
$xrd_arr = XML::elementToArray($xrd);
|
||||
if (!isset($xrd_arr["xrd"]["link"])) {
|
||||
if (!isset($xrd_arr['xrd']['link'])) {
|
||||
Logger::info('No XML webfinger links', ['url' => $url]);
|
||||
return [];
|
||||
}
|
||||
|
||||
$webfinger = [];
|
||||
|
||||
if (!empty($xrd_arr["xrd"]["subject"])) {
|
||||
$webfinger["subject"] = $xrd_arr["xrd"]["subject"];
|
||||
if (!empty($xrd_arr['xrd']['subject'])) {
|
||||
$webfinger['subject'] = $xrd_arr['xrd']['subject'];
|
||||
}
|
||||
|
||||
if (!empty($xrd_arr["xrd"]["alias"])) {
|
||||
$webfinger["aliases"] = $xrd_arr["xrd"]["alias"];
|
||||
if (!empty($xrd_arr['xrd']['alias'])) {
|
||||
$webfinger['aliases'] = $xrd_arr['xrd']['alias'];
|
||||
}
|
||||
|
||||
$webfinger["links"] = [];
|
||||
$webfinger['links'] = [];
|
||||
|
||||
foreach ($xrd_arr["xrd"]["link"] as $value => $data) {
|
||||
if (!empty($data["@attributes"])) {
|
||||
$attributes = $data["@attributes"];
|
||||
} elseif ($value == "@attributes") {
|
||||
foreach ($xrd_arr['xrd']['link'] as $value => $data) {
|
||||
if (!empty($data['@attributes'])) {
|
||||
$attributes = $data['@attributes'];
|
||||
} elseif ($value == '@attributes') {
|
||||
$attributes = $data;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
$webfinger["links"][] = $attributes;
|
||||
$webfinger['links'][] = $attributes;
|
||||
}
|
||||
return $webfinger;
|
||||
}
|
||||
|
|
@ -953,11 +949,10 @@ class Probe
|
|||
*
|
||||
* @param string $noscrape_url Link to the noscrape page
|
||||
* @param array $data The already fetched data
|
||||
*
|
||||
* @return array noscrape data
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function pollNoscrape($noscrape_url, $data)
|
||||
private static function pollNoscrape(string $noscrape_url, array $data): array
|
||||
{
|
||||
$curlResult = DI::httpClient()->get($noscrape_url, HttpClientAccept::JSON);
|
||||
if ($curlResult->isTimeout()) {
|
||||
|
|
@ -976,78 +971,78 @@ class Probe
|
|||
return $data;
|
||||
}
|
||||
|
||||
if (!empty($json["fn"])) {
|
||||
$data["name"] = $json["fn"];
|
||||
if (!empty($json['fn'])) {
|
||||
$data['name'] = $json['fn'];
|
||||
}
|
||||
|
||||
if (!empty($json["addr"])) {
|
||||
$data["addr"] = $json["addr"];
|
||||
if (!empty($json['addr'])) {
|
||||
$data['addr'] = $json['addr'];
|
||||
}
|
||||
|
||||
if (!empty($json["nick"])) {
|
||||
$data["nick"] = $json["nick"];
|
||||
if (!empty($json['nick'])) {
|
||||
$data['nick'] = $json['nick'];
|
||||
}
|
||||
|
||||
if (!empty($json["guid"])) {
|
||||
$data["guid"] = $json["guid"];
|
||||
if (!empty($json['guid'])) {
|
||||
$data['guid'] = $json['guid'];
|
||||
}
|
||||
|
||||
if (!empty($json["comm"])) {
|
||||
$data["community"] = $json["comm"];
|
||||
if (!empty($json['comm'])) {
|
||||
$data['community'] = $json['comm'];
|
||||
}
|
||||
|
||||
if (!empty($json["tags"])) {
|
||||
$keywords = implode(", ", $json["tags"]);
|
||||
if ($keywords != "") {
|
||||
$data["keywords"] = $keywords;
|
||||
if (!empty($json['tags'])) {
|
||||
$keywords = implode(', ', $json['tags']);
|
||||
if ($keywords != '') {
|
||||
$data['keywords'] = $keywords;
|
||||
}
|
||||
}
|
||||
|
||||
$location = Profile::formatLocation($json);
|
||||
if ($location) {
|
||||
$data["location"] = $location;
|
||||
$data['location'] = $location;
|
||||
}
|
||||
|
||||
if (!empty($json["about"])) {
|
||||
$data["about"] = $json["about"];
|
||||
if (!empty($json['about'])) {
|
||||
$data['about'] = $json['about'];
|
||||
}
|
||||
|
||||
if (!empty($json["xmpp"])) {
|
||||
$data["xmpp"] = $json["xmpp"];
|
||||
if (!empty($json['xmpp'])) {
|
||||
$data['xmpp'] = $json['xmpp'];
|
||||
}
|
||||
|
||||
if (!empty($json["matrix"])) {
|
||||
$data["matrix"] = $json["matrix"];
|
||||
if (!empty($json['matrix'])) {
|
||||
$data['matrix'] = $json['matrix'];
|
||||
}
|
||||
|
||||
if (!empty($json["key"])) {
|
||||
$data["pubkey"] = $json["key"];
|
||||
if (!empty($json['key'])) {
|
||||
$data['pubkey'] = $json['key'];
|
||||
}
|
||||
|
||||
if (!empty($json["photo"])) {
|
||||
$data["photo"] = $json["photo"];
|
||||
if (!empty($json['photo'])) {
|
||||
$data['photo'] = $json['photo'];
|
||||
}
|
||||
|
||||
if (!empty($json["dfrn-request"])) {
|
||||
$data["request"] = $json["dfrn-request"];
|
||||
if (!empty($json['dfrn-request'])) {
|
||||
$data['request'] = $json['dfrn-request'];
|
||||
}
|
||||
|
||||
if (!empty($json["dfrn-confirm"])) {
|
||||
$data["confirm"] = $json["dfrn-confirm"];
|
||||
if (!empty($json['dfrn-confirm'])) {
|
||||
$data['confirm'] = $json['dfrn-confirm'];
|
||||
}
|
||||
|
||||
if (!empty($json["dfrn-notify"])) {
|
||||
$data["notify"] = $json["dfrn-notify"];
|
||||
if (!empty($json['dfrn-notify'])) {
|
||||
$data['notify'] = $json['dfrn-notify'];
|
||||
}
|
||||
|
||||
if (!empty($json["dfrn-poll"])) {
|
||||
$data["poll"] = $json["dfrn-poll"];
|
||||
if (!empty($json['dfrn-poll'])) {
|
||||
$data['poll'] = $json['dfrn-poll'];
|
||||
}
|
||||
|
||||
if (isset($json["hide"])) {
|
||||
$data["hide"] = (bool)$json["hide"];
|
||||
if (isset($json['hide'])) {
|
||||
$data['hide'] = (bool)$json['hide'];
|
||||
} else {
|
||||
$data["hide"] = false;
|
||||
$data['hide'] = false;
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
|
@ -1085,48 +1080,47 @@ class Probe
|
|||
* Fetch data from a DFRN profile page and via "noscrape"
|
||||
*
|
||||
* @param string $profile_link Link to the profile page
|
||||
*
|
||||
* @return array profile data
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public static function profile($profile_link)
|
||||
public static function profile(string $profile_link): array
|
||||
{
|
||||
$data = [];
|
||||
|
||||
Logger::info('Check profile', ['link' => $profile_link]);
|
||||
|
||||
// Fetch data via noscrape - this is faster
|
||||
$noscrape_url = str_replace(["/hcard/", "/profile/"], "/noscrape/", $profile_link);
|
||||
$noscrape_url = str_replace(['/hcard/', '/profile/'], '/noscrape/', $profile_link);
|
||||
$data = self::pollNoscrape($noscrape_url, $data);
|
||||
|
||||
if (!isset($data["notify"])
|
||||
|| !isset($data["confirm"])
|
||||
|| !isset($data["request"])
|
||||
|| !isset($data["poll"])
|
||||
|| !isset($data["name"])
|
||||
|| !isset($data["photo"])
|
||||
if (!isset($data['notify'])
|
||||
|| !isset($data['confirm'])
|
||||
|| !isset($data['request'])
|
||||
|| !isset($data['poll'])
|
||||
|| !isset($data['name'])
|
||||
|| !isset($data['photo'])
|
||||
) {
|
||||
$data = self::pollHcard($profile_link, $data, true);
|
||||
}
|
||||
|
||||
$prof_data = [];
|
||||
|
||||
if (empty($data["addr"]) || empty($data["nick"])) {
|
||||
if (empty($data['addr']) || empty($data['nick'])) {
|
||||
$probe_data = self::uri($profile_link);
|
||||
$data["addr"] = ($data["addr"] ?? '') ?: $probe_data["addr"];
|
||||
$data["nick"] = ($data["nick"] ?? '') ?: $probe_data["nick"];
|
||||
$data['addr'] = ($data['addr'] ?? '') ?: $probe_data['addr'];
|
||||
$data['nick'] = ($data['nick'] ?? '') ?: $probe_data['nick'];
|
||||
}
|
||||
|
||||
$prof_data["addr"] = $data["addr"];
|
||||
$prof_data["nick"] = $data["nick"];
|
||||
$prof_data["dfrn-request"] = $data['request'] ?? null;
|
||||
$prof_data["dfrn-confirm"] = $data['confirm'] ?? null;
|
||||
$prof_data["dfrn-notify"] = $data['notify'] ?? null;
|
||||
$prof_data["dfrn-poll"] = $data['poll'] ?? null;
|
||||
$prof_data["photo"] = $data['photo'] ?? null;
|
||||
$prof_data["fn"] = $data['name'] ?? null;
|
||||
$prof_data["key"] = $data['pubkey'] ?? null;
|
||||
$prof_data['addr'] = $data['addr'];
|
||||
$prof_data['nick'] = $data['nick'];
|
||||
$prof_data['dfrn-request'] = $data['request'] ?? null;
|
||||
$prof_data['dfrn-confirm'] = $data['confirm'] ?? null;
|
||||
$prof_data['dfrn-notify'] = $data['notify'] ?? null;
|
||||
$prof_data['dfrn-poll'] = $data['poll'] ?? null;
|
||||
$prof_data['photo'] = $data['photo'] ?? null;
|
||||
$prof_data['fn'] = $data['name'] ?? null;
|
||||
$prof_data['key'] = $data['pubkey'] ?? null;
|
||||
|
||||
Logger::debug('Result', ['link' => $profile_link, 'data' => $prof_data]);
|
||||
|
||||
|
|
@ -1137,73 +1131,71 @@ class Probe
|
|||
* Check for DFRN contact
|
||||
*
|
||||
* @param array $webfinger Webfinger data
|
||||
*
|
||||
* @return array DFRN data
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function dfrn($webfinger)
|
||||
private static function dfrn(array $webfinger): array
|
||||
{
|
||||
$hcard_url = "";
|
||||
$hcard_url = '';
|
||||
$data = [];
|
||||
// The array is reversed to take into account the order of preference for same-rel links
|
||||
// See: https://tools.ietf.org/html/rfc7033#section-4.4.4
|
||||
foreach (array_reverse($webfinger["links"]) as $link) {
|
||||
if (($link["rel"] == ActivityNamespace::DFRN) && !empty($link["href"])) {
|
||||
$data["network"] = Protocol::DFRN;
|
||||
} elseif (($link["rel"] == ActivityNamespace::FEED) && !empty($link["href"])) {
|
||||
$data["poll"] = $link["href"];
|
||||
} elseif (($link["rel"] == "http://webfinger.net/rel/profile-page") && (($link["type"] ?? "") == "text/html") && !empty($link["href"])) {
|
||||
$data["url"] = $link["href"];
|
||||
} elseif (($link["rel"] == "http://microformats.org/profile/hcard") && !empty($link["href"])) {
|
||||
$hcard_url = $link["href"];
|
||||
} elseif (($link["rel"] == ActivityNamespace::POCO) && !empty($link["href"])) {
|
||||
$data["poco"] = $link["href"];
|
||||
} elseif (($link["rel"] == "http://webfinger.net/rel/avatar") && !empty($link["href"])) {
|
||||
$data["photo"] = $link["href"];
|
||||
} elseif (($link["rel"] == "http://joindiaspora.com/seed_location") && !empty($link["href"])) {
|
||||
$data["baseurl"] = trim($link["href"], '/');
|
||||
} elseif (($link["rel"] == "http://joindiaspora.com/guid") && !empty($link["href"])) {
|
||||
$data["guid"] = $link["href"];
|
||||
} elseif (($link["rel"] == "diaspora-public-key") && !empty($link["href"])) {
|
||||
$data["pubkey"] = base64_decode($link["href"]);
|
||||
foreach (array_reverse($webfinger['links']) as $link) {
|
||||
if (($link['rel'] == ActivityNamespace::DFRN) && !empty($link['href'])) {
|
||||
$data['network'] = Protocol::DFRN;
|
||||
} elseif (($link['rel'] == ActivityNamespace::FEED) && !empty($link['href'])) {
|
||||
$data['poll'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'http://webfinger.net/rel/profile-page') && (($link['type'] ?? '') == 'text/html') && !empty($link['href'])) {
|
||||
$data['url'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'http://microformats.org/profile/hcard') && !empty($link['href'])) {
|
||||
$hcard_url = $link['href'];
|
||||
} elseif (($link['rel'] == ActivityNamespace::POCO) && !empty($link['href'])) {
|
||||
$data['poco'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'http://webfinger.net/rel/avatar') && !empty($link['href'])) {
|
||||
$data['photo'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'http://joindiaspora.com/seed_location') && !empty($link['href'])) {
|
||||
$data['baseurl'] = trim($link['href'], '/');
|
||||
} elseif (($link['rel'] == 'http://joindiaspora.com/guid') && !empty($link['href'])) {
|
||||
$data['guid'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'diaspora-public-key') && !empty($link['href'])) {
|
||||
$data['pubkey'] = base64_decode($link['href']);
|
||||
|
||||
//if (strstr($data["pubkey"], 'RSA ') || ($link["type"] == "RSA"))
|
||||
if (strstr($data["pubkey"], 'RSA ')) {
|
||||
$data["pubkey"] = Crypto::rsaToPem($data["pubkey"]);
|
||||
if (strstr($data['pubkey'], 'RSA ')) {
|
||||
$data['pubkey'] = Crypto::rsaToPem($data['pubkey']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($webfinger["aliases"]) && is_array($webfinger["aliases"])) {
|
||||
foreach ($webfinger["aliases"] as $alias) {
|
||||
if (empty($data["url"]) && !strstr($alias, "@")) {
|
||||
$data["url"] = $alias;
|
||||
} elseif (!strstr($alias, "@") && Strings::normaliseLink($alias) != Strings::normaliseLink($data["url"])) {
|
||||
$data["alias"] = $alias;
|
||||
if (!empty($webfinger['aliases']) && is_array($webfinger['aliases'])) {
|
||||
foreach ($webfinger['aliases'] as $alias) {
|
||||
if (empty($data['url']) && !strstr($alias, '@')) {
|
||||
$data['url'] = $alias;
|
||||
} elseif (!strstr($alias, '@') && Strings::normaliseLink($alias) != Strings::normaliseLink($data['url'])) {
|
||||
$data['alias'] = $alias;
|
||||
} elseif (substr($alias, 0, 5) == 'acct:') {
|
||||
$data["addr"] = substr($alias, 5);
|
||||
$data['addr'] = substr($alias, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($webfinger["subject"]) && (substr($webfinger["subject"], 0, 5) == "acct:")) {
|
||||
$data["addr"] = substr($webfinger["subject"], 5);
|
||||
if (!empty($webfinger['subject']) && (substr($webfinger['subject'], 0, 5) == 'acct:')) {
|
||||
$data['addr'] = substr($webfinger['subject'], 5);
|
||||
}
|
||||
|
||||
if (!isset($data["network"]) || ($hcard_url == "")) {
|
||||
if (!isset($data['network']) || ($hcard_url == '')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Fetch data via noscrape - this is faster
|
||||
$noscrape_url = str_replace("/hcard/", "/noscrape/", $hcard_url);
|
||||
$noscrape_url = str_replace('/hcard/', '/noscrape/', $hcard_url);
|
||||
$data = self::pollNoscrape($noscrape_url, $data);
|
||||
|
||||
if (isset($data["notify"])
|
||||
&& isset($data["confirm"])
|
||||
&& isset($data["request"])
|
||||
&& isset($data["poll"])
|
||||
&& isset($data["name"])
|
||||
&& isset($data["photo"])
|
||||
if (isset($data['notify'])
|
||||
&& isset($data['confirm'])
|
||||
&& isset($data['request'])
|
||||
&& isset($data['poll'])
|
||||
&& isset($data['name'])
|
||||
&& isset($data['photo'])
|
||||
) {
|
||||
return $data;
|
||||
}
|
||||
|
|
@ -1219,11 +1211,10 @@ class Probe
|
|||
* @param string $hcard_url Link to the hcard page
|
||||
* @param array $data The already fetched data
|
||||
* @param boolean $dfrn Poll DFRN specific data
|
||||
*
|
||||
* @return array hcard data
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function pollHcard($hcard_url, $data, $dfrn = false)
|
||||
private static function pollHcard(string $hcard_url, array $data, bool $dfrn = false): array
|
||||
{
|
||||
$curlResult = DI::httpClient()->get($hcard_url, HttpClientAccept::HTML);
|
||||
if ($curlResult->isTimeout()) {
|
||||
|
|
@ -1278,15 +1269,15 @@ class Probe
|
|||
|
||||
$search = $xpath->query("//*[contains(concat(' ', @class, ' '), ' key ')]", $vcard); // */
|
||||
if ($search->length > 0) {
|
||||
$data["pubkey"] = $search->item(0)->nodeValue;
|
||||
if (strstr($data["pubkey"], 'RSA ')) {
|
||||
$data["pubkey"] = Crypto::rsaToPem($data["pubkey"]);
|
||||
$data['pubkey'] = $search->item(0)->nodeValue;
|
||||
if (strstr($data['pubkey'], 'RSA ')) {
|
||||
$data['pubkey'] = Crypto::rsaToPem($data['pubkey']);
|
||||
}
|
||||
}
|
||||
|
||||
$search = $xpath->query("//*[@id='pod_location']", $vcard); // */
|
||||
if ($search->length > 0) {
|
||||
$data["baseurl"] = trim($search->item(0)->nodeValue, "/");
|
||||
$data['baseurl'] = trim($search->item(0)->nodeValue, '/');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1299,21 +1290,21 @@ class Probe
|
|||
$attr[$attribute->name] = trim($attribute->value);
|
||||
}
|
||||
|
||||
if (isset($attr["src"]) && isset($attr["width"])) {
|
||||
$avatar[$attr["width"]] = $attr["src"];
|
||||
if (isset($attr['src']) && isset($attr['width'])) {
|
||||
$avatar[$attr['width']] = $attr['src'];
|
||||
}
|
||||
|
||||
// We don't have a width. So we just take everything that we got.
|
||||
// This is a Hubzilla workaround which doesn't send a width.
|
||||
if ((sizeof($avatar) == 0) && !empty($attr["src"])) {
|
||||
$avatar[] = $attr["src"];
|
||||
if ((sizeof($avatar) == 0) && !empty($attr['src'])) {
|
||||
$avatar[] = $attr['src'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sizeof($avatar)) {
|
||||
ksort($avatar);
|
||||
$data["photo"] = self::fixAvatar(array_pop($avatar), $data["baseurl"]);
|
||||
$data['photo'] = self::fixAvatar(array_pop($avatar), $data['baseurl']);
|
||||
}
|
||||
|
||||
if ($dfrn) {
|
||||
|
|
@ -1321,19 +1312,19 @@ class Probe
|
|||
$search = $xpath->query("//link[contains(concat(' ', @rel), ' dfrn-')]");
|
||||
if ($search->length > 0) {
|
||||
foreach ($search as $link) {
|
||||
//$data["request"] = $search->item(0)->nodeValue;
|
||||
//$data['request'] = $search->item(0)->nodeValue;
|
||||
$attr = [];
|
||||
foreach ($link->attributes as $attribute) {
|
||||
$attr[$attribute->name] = trim($attribute->value);
|
||||
}
|
||||
|
||||
$data[substr($attr["rel"], 5)] = $attr["href"];
|
||||
$data[substr($attr['rel'], 5)] = $attr['href'];
|
||||
}
|
||||
}
|
||||
|
||||
// Older Friendica versions had used the "uid" field differently than newer versions
|
||||
if (!empty($data["nick"]) && !empty($data["guid"]) && ($data["nick"] == $data["guid"])) {
|
||||
unset($data["guid"]);
|
||||
if (!empty($data['nick']) && !empty($data['guid']) && ($data['nick'] == $data['guid'])) {
|
||||
unset($data['guid']);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1345,64 +1336,62 @@ class Probe
|
|||
* Check for Diaspora contact
|
||||
*
|
||||
* @param array $webfinger Webfinger data
|
||||
*
|
||||
* @return array Diaspora data
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function diaspora($webfinger)
|
||||
private static function diaspora(array $webfinger): array
|
||||
{
|
||||
$hcard_url = "";
|
||||
$hcard_url = '';
|
||||
$data = [];
|
||||
|
||||
// The array is reversed to take into account the order of preference for same-rel links
|
||||
// See: https://tools.ietf.org/html/rfc7033#section-4.4.4
|
||||
foreach (array_reverse($webfinger["links"]) as $link) {
|
||||
if (($link["rel"] == "http://microformats.org/profile/hcard") && !empty($link["href"])) {
|
||||
$hcard_url = $link["href"];
|
||||
} elseif (($link["rel"] == "http://joindiaspora.com/seed_location") && !empty($link["href"])) {
|
||||
$data["baseurl"] = trim($link["href"], '/');
|
||||
} elseif (($link["rel"] == "http://joindiaspora.com/guid") && !empty($link["href"])) {
|
||||
$data["guid"] = $link["href"];
|
||||
} elseif (($link["rel"] == "http://webfinger.net/rel/profile-page") && (($link["type"] ?? "") == "text/html") && !empty($link["href"])) {
|
||||
$data["url"] = $link["href"];
|
||||
} elseif (($link["rel"] == "http://webfinger.net/rel/profile-page") && empty($link["type"]) && !empty($link["href"])) {
|
||||
$profile_url = $link["href"];
|
||||
} elseif (($link["rel"] == ActivityNamespace::FEED) && !empty($link["href"])) {
|
||||
$data["poll"] = $link["href"];
|
||||
} elseif (($link["rel"] == ActivityNamespace::POCO) && !empty($link["href"])) {
|
||||
$data["poco"] = $link["href"];
|
||||
} elseif (($link["rel"] == "salmon") && !empty($link["href"])) {
|
||||
$data["notify"] = $link["href"];
|
||||
} elseif (($link["rel"] == "diaspora-public-key") && !empty($link["href"])) {
|
||||
$data["pubkey"] = base64_decode($link["href"]);
|
||||
foreach (array_reverse($webfinger['links']) as $link) {
|
||||
if (($link['rel'] == 'http://microformats.org/profile/hcard') && !empty($link['href'])) {
|
||||
$hcard_url = $link['href'];
|
||||
} elseif (($link['rel'] == 'http://joindiaspora.com/seed_location') && !empty($link['href'])) {
|
||||
$data['baseurl'] = trim($link['href'], '/');
|
||||
} elseif (($link['rel'] == 'http://joindiaspora.com/guid') && !empty($link['href'])) {
|
||||
$data['guid'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'http://webfinger.net/rel/profile-page') && (($link['type'] ?? '') == 'text/html') && !empty($link['href'])) {
|
||||
$data['url'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'http://webfinger.net/rel/profile-page') && empty($link['type']) && !empty($link['href'])) {
|
||||
$profile_url = $link['href'];
|
||||
} elseif (($link['rel'] == ActivityNamespace::FEED) && !empty($link['href'])) {
|
||||
$data['poll'] = $link['href'];
|
||||
} elseif (($link['rel'] == ActivityNamespace::POCO) && !empty($link['href'])) {
|
||||
$data['poco'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'salmon') && !empty($link['href'])) {
|
||||
$data['notify'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'diaspora-public-key') && !empty($link['href'])) {
|
||||
$data['pubkey'] = base64_decode($link['href']);
|
||||
|
||||
//if (strstr($data["pubkey"], 'RSA ') || ($link["type"] == "RSA"))
|
||||
if (strstr($data["pubkey"], 'RSA ')) {
|
||||
$data["pubkey"] = Crypto::rsaToPem($data["pubkey"]);
|
||||
if (strstr($data['pubkey'], 'RSA ')) {
|
||||
$data['pubkey'] = Crypto::rsaToPem($data['pubkey']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($data["url"]) && !empty($profile_url)) {
|
||||
$data["url"] = $profile_url;
|
||||
if (empty($data['url']) && !empty($profile_url)) {
|
||||
$data['url'] = $profile_url;
|
||||
}
|
||||
|
||||
if (empty($data["url"]) || empty($hcard_url)) {
|
||||
if (empty($data['url']) || empty($hcard_url)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!empty($webfinger["aliases"]) && is_array($webfinger["aliases"])) {
|
||||
foreach ($webfinger["aliases"] as $alias) {
|
||||
if (Strings::normaliseLink($alias) != Strings::normaliseLink($data["url"]) && ! strstr($alias, "@")) {
|
||||
$data["alias"] = $alias;
|
||||
if (!empty($webfinger['aliases']) && is_array($webfinger['aliases'])) {
|
||||
foreach ($webfinger['aliases'] as $alias) {
|
||||
if (Strings::normaliseLink($alias) != Strings::normaliseLink($data['url']) && ! strstr($alias, '@')) {
|
||||
$data['alias'] = $alias;
|
||||
} elseif (substr($alias, 0, 5) == 'acct:') {
|
||||
$data["addr"] = substr($alias, 5);
|
||||
$data['addr'] = substr($alias, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($webfinger["subject"]) && (substr($webfinger["subject"], 0, 5) == 'acct:')) {
|
||||
$data["addr"] = substr($webfinger["subject"], 5);
|
||||
if (!empty($webfinger['subject']) && (substr($webfinger['subject'], 0, 5) == 'acct:')) {
|
||||
$data['addr'] = substr($webfinger['subject'], 5);
|
||||
}
|
||||
|
||||
// Fetch further information from the hcard
|
||||
|
|
@ -1412,23 +1401,23 @@ class Probe
|
|||
return [];
|
||||
}
|
||||
|
||||
if (!empty($data["url"])
|
||||
&& !empty($data["guid"])
|
||||
&& !empty($data["baseurl"])
|
||||
&& !empty($data["pubkey"])
|
||||
if (!empty($data['url'])
|
||||
&& !empty($data['guid'])
|
||||
&& !empty($data['baseurl'])
|
||||
&& !empty($data['pubkey'])
|
||||
&& !empty($hcard_url)
|
||||
) {
|
||||
$data["network"] = Protocol::DIASPORA;
|
||||
$data["manually-approve"] = false;
|
||||
$data['network'] = Protocol::DIASPORA;
|
||||
$data['manually-approve'] = false;
|
||||
|
||||
// The Diaspora handle must always be lowercase
|
||||
if (!empty($data["addr"])) {
|
||||
$data["addr"] = strtolower($data["addr"]);
|
||||
if (!empty($data['addr'])) {
|
||||
$data['addr'] = strtolower($data['addr']);
|
||||
}
|
||||
|
||||
// We have to overwrite the detected value for "notify" since Hubzilla doesn't send it
|
||||
$data["notify"] = $data["baseurl"] . "/receive/users/" . $data["guid"];
|
||||
$data["batch"] = $data["baseurl"] . "/receive/public";
|
||||
$data['notify'] = $data['baseurl'] . '/receive/users/' . $data['guid'];
|
||||
$data['batch'] = $data['baseurl'] . '/receive/public';
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
|
@ -1441,7 +1430,6 @@ class Probe
|
|||
*
|
||||
* @param array $webfinger Webfinger data
|
||||
* @param bool $short Short detection mode
|
||||
*
|
||||
* @return array|bool OStatus data or "false" on error or "true" on short mode
|
||||
* @throws HTTPException\InternalServerErrorException
|
||||
*/
|
||||
|
|
@ -1449,35 +1437,35 @@ class Probe
|
|||
{
|
||||
$data = [];
|
||||
|
||||
if (!empty($webfinger["aliases"]) && is_array($webfinger["aliases"])) {
|
||||
foreach ($webfinger["aliases"] as $alias) {
|
||||
if (strstr($alias, "@") && !strstr(Strings::normaliseLink($alias), "http://")) {
|
||||
$data["addr"] = str_replace('acct:', '', $alias);
|
||||
if (!empty($webfinger['aliases']) && is_array($webfinger['aliases'])) {
|
||||
foreach ($webfinger['aliases'] as $alias) {
|
||||
if (strstr($alias, '@') && !strstr(Strings::normaliseLink($alias), 'http://')) {
|
||||
$data['addr'] = str_replace('acct:', '', $alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($webfinger["subject"]) && strstr($webfinger["subject"], "@")
|
||||
&& !strstr(Strings::normaliseLink($webfinger["subject"]), "http://")
|
||||
if (!empty($webfinger['subject']) && strstr($webfinger['subject'], '@')
|
||||
&& !strstr(Strings::normaliseLink($webfinger['subject']), 'http://')
|
||||
) {
|
||||
$data["addr"] = str_replace('acct:', '', $webfinger["subject"]);
|
||||
$data['addr'] = str_replace('acct:', '', $webfinger['subject']);
|
||||
}
|
||||
|
||||
if (!empty($webfinger["links"])) {
|
||||
if (!empty($webfinger['links'])) {
|
||||
// The array is reversed to take into account the order of preference for same-rel links
|
||||
// See: https://tools.ietf.org/html/rfc7033#section-4.4.4
|
||||
foreach (array_reverse($webfinger["links"]) as $link) {
|
||||
if (($link["rel"] == "http://webfinger.net/rel/profile-page")
|
||||
&& (($link["type"] ?? "") == "text/html")
|
||||
&& ($link["href"] != "")
|
||||
foreach (array_reverse($webfinger['links']) as $link) {
|
||||
if (($link['rel'] == 'http://webfinger.net/rel/profile-page')
|
||||
&& (($link['type'] ?? '') == 'text/html')
|
||||
&& ($link['href'] != '')
|
||||
) {
|
||||
$data["url"] = $data["alias"] = $link["href"];
|
||||
} elseif (($link["rel"] == "salmon") && !empty($link["href"])) {
|
||||
$data["notify"] = $link["href"];
|
||||
} elseif (($link["rel"] == ActivityNamespace::FEED) && !empty($link["href"])) {
|
||||
$data["poll"] = $link["href"];
|
||||
} elseif (($link["rel"] == "magic-public-key") && !empty($link["href"])) {
|
||||
$pubkey = $link["href"];
|
||||
$data['url'] = $data['alias'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'salmon') && !empty($link['href'])) {
|
||||
$data['notify'] = $link['href'];
|
||||
} elseif (($link['rel'] == ActivityNamespace::FEED) && !empty($link['href'])) {
|
||||
$data['poll'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'magic-public-key') && !empty($link['href'])) {
|
||||
$pubkey = $link['href'];
|
||||
|
||||
if (substr($pubkey, 0, 5) === 'data:') {
|
||||
if (strstr($pubkey, ',')) {
|
||||
|
|
@ -1495,23 +1483,23 @@ class Probe
|
|||
$pubkey = $curlResult->getBody();
|
||||
}
|
||||
|
||||
$key = explode(".", $pubkey);
|
||||
$key = explode('.', $pubkey);
|
||||
|
||||
if (sizeof($key) >= 3) {
|
||||
$m = Strings::base64UrlDecode($key[1]);
|
||||
$e = Strings::base64UrlDecode($key[2]);
|
||||
$data["pubkey"] = Crypto::meToPem($m, $e);
|
||||
$data['pubkey'] = Crypto::meToPem($m, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data["notify"]) && isset($data["pubkey"])
|
||||
&& isset($data["poll"])
|
||||
&& isset($data["url"])
|
||||
if (isset($data['notify']) && isset($data['pubkey'])
|
||||
&& isset($data['poll'])
|
||||
&& isset($data['url'])
|
||||
) {
|
||||
$data["network"] = Protocol::OSTATUS;
|
||||
$data["manually-approve"] = false;
|
||||
$data['network'] = Protocol::OSTATUS;
|
||||
$data['manually-approve'] = false;
|
||||
} else {
|
||||
return $short ? false : [];
|
||||
}
|
||||
|
|
@ -1521,7 +1509,7 @@ class Probe
|
|||
}
|
||||
|
||||
// Fetch all additional data from the feed
|
||||
$curlResult = DI::httpClient()->get($data["poll"], HttpClientAccept::FEED_XML);
|
||||
$curlResult = DI::httpClient()->get($data['poll'], HttpClientAccept::FEED_XML);
|
||||
if ($curlResult->isTimeout()) {
|
||||
self::$istimeout = true;
|
||||
return [];
|
||||
|
|
@ -1532,32 +1520,32 @@ class Probe
|
|||
return [];
|
||||
}
|
||||
|
||||
if (!empty($feed_data["header"]["author-name"])) {
|
||||
$data["name"] = $feed_data["header"]["author-name"];
|
||||
if (!empty($feed_data['header']['author-name'])) {
|
||||
$data['name'] = $feed_data['header']['author-name'];
|
||||
}
|
||||
if (!empty($feed_data["header"]["author-nick"])) {
|
||||
$data["nick"] = $feed_data["header"]["author-nick"];
|
||||
if (!empty($feed_data['header']['author-nick'])) {
|
||||
$data['nick'] = $feed_data['header']['author-nick'];
|
||||
}
|
||||
if (!empty($feed_data["header"]["author-avatar"])) {
|
||||
$data["photo"] = self::fixAvatar($feed_data["header"]["author-avatar"], $data["url"]);
|
||||
if (!empty($feed_data['header']['author-avatar'])) {
|
||||
$data['photo'] = self::fixAvatar($feed_data['header']['author-avatar'], $data['url']);
|
||||
}
|
||||
if (!empty($feed_data["header"]["author-id"])) {
|
||||
$data["alias"] = $feed_data["header"]["author-id"];
|
||||
if (!empty($feed_data['header']['author-id'])) {
|
||||
$data['alias'] = $feed_data['header']['author-id'];
|
||||
}
|
||||
if (!empty($feed_data["header"]["author-location"])) {
|
||||
$data["location"] = $feed_data["header"]["author-location"];
|
||||
if (!empty($feed_data['header']['author-location'])) {
|
||||
$data['location'] = $feed_data['header']['author-location'];
|
||||
}
|
||||
if (!empty($feed_data["header"]["author-about"])) {
|
||||
$data["about"] = $feed_data["header"]["author-about"];
|
||||
if (!empty($feed_data['header']['author-about'])) {
|
||||
$data['about'] = $feed_data['header']['author-about'];
|
||||
}
|
||||
// OStatus has serious issues when the the url doesn't fit (ssl vs. non ssl)
|
||||
// So we take the value that we just fetched, although the other one worked as well
|
||||
if (!empty($feed_data["header"]["author-link"])) {
|
||||
$data["url"] = $feed_data["header"]["author-link"];
|
||||
if (!empty($feed_data['header']['author-link'])) {
|
||||
$data['url'] = $feed_data['header']['author-link'];
|
||||
}
|
||||
|
||||
if ($data["url"] == $data["alias"]) {
|
||||
$data["alias"] = '';
|
||||
if ($data['url'] == $data['alias']) {
|
||||
$data['alias'] = '';
|
||||
}
|
||||
|
||||
/// @todo Fetch location and "about" from the feed as well
|
||||
|
|
@ -1568,10 +1556,9 @@ class Probe
|
|||
* Fetch data from a pump.io profile page
|
||||
*
|
||||
* @param string $profile_link Link to the profile page
|
||||
*
|
||||
* @return array profile data
|
||||
* @return array Profile data
|
||||
*/
|
||||
private static function pumpioProfileData($profile_link)
|
||||
private static function pumpioProfileData(string $profile_link): array
|
||||
{
|
||||
$curlResult = DI::httpClient()->get($profile_link, HttpClientAccept::HTML);
|
||||
if (!$curlResult->isSuccess() || empty($curlResult->getBody())) {
|
||||
|
|
@ -1586,28 +1573,27 @@ class Probe
|
|||
$xpath = new DomXPath($doc);
|
||||
|
||||
$data = [];
|
||||
$data['name'] = $xpath->query("//span[contains(@class, 'p-name')]")->item(0)->nodeValue;
|
||||
|
||||
$data["name"] = $xpath->query("//span[contains(@class, 'p-name')]")->item(0)->nodeValue;
|
||||
|
||||
if ($data["name"] == '') {
|
||||
if ($data['name'] == '') {
|
||||
// This is ugly - but pump.io doesn't seem to know a better way for it
|
||||
$data["name"] = trim($xpath->query("//h1[@class='media-header']")->item(0)->nodeValue);
|
||||
$pos = strpos($data["name"], chr(10));
|
||||
$data['name'] = trim($xpath->query("//h1[@class='media-header']")->item(0)->nodeValue);
|
||||
$pos = strpos($data['name'], chr(10));
|
||||
if ($pos) {
|
||||
$data["name"] = trim(substr($data["name"], 0, $pos));
|
||||
$data['name'] = trim(substr($data['name'], 0, $pos));
|
||||
}
|
||||
}
|
||||
|
||||
$data["location"] = XML::getFirstNodeValue($xpath, "//p[contains(@class, 'p-locality')]");
|
||||
$data['location'] = XML::getFirstNodeValue($xpath, "//p[contains(@class, 'p-locality')]");
|
||||
|
||||
if ($data["location"] == '') {
|
||||
$data["location"] = XML::getFirstNodeValue($xpath, "//p[contains(@class, 'location')]");
|
||||
if ($data['location'] == '') {
|
||||
$data['location'] = XML::getFirstNodeValue($xpath, "//p[contains(@class, 'location')]");
|
||||
}
|
||||
|
||||
$data["about"] = XML::getFirstNodeValue($xpath, "//p[contains(@class, 'p-note')]");
|
||||
$data['about'] = XML::getFirstNodeValue($xpath, "//p[contains(@class, 'p-note')]");
|
||||
|
||||
if ($data["about"] == '') {
|
||||
$data["about"] = XML::getFirstNodeValue($xpath, "//p[contains(@class, 'summary')]");
|
||||
if ($data['about'] == '') {
|
||||
$data['about'] = XML::getFirstNodeValue($xpath, "//p[contains(@class, 'summary')]");
|
||||
}
|
||||
|
||||
$avatar = $xpath->query("//img[contains(@class, 'u-photo')]")->item(0);
|
||||
|
|
@ -1616,8 +1602,8 @@ class Probe
|
|||
}
|
||||
if ($avatar) {
|
||||
foreach ($avatar->attributes as $attribute) {
|
||||
if ($attribute->name == "src") {
|
||||
$data["photo"] = trim($attribute->value);
|
||||
if ($attribute->name == 'src') {
|
||||
$data['photo'] = trim($attribute->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1632,39 +1618,39 @@ class Probe
|
|||
* @param string $addr
|
||||
* @return array pump.io data
|
||||
*/
|
||||
private static function pumpio($webfinger, $addr)
|
||||
private static function pumpio(array $webfinger, string $addr): array
|
||||
{
|
||||
$data = [];
|
||||
// The array is reversed to take into account the order of preference for same-rel links
|
||||
// See: https://tools.ietf.org/html/rfc7033#section-4.4.4
|
||||
foreach (array_reverse($webfinger["links"]) as $link) {
|
||||
if (($link["rel"] == "http://webfinger.net/rel/profile-page")
|
||||
&& (($link["type"] ?? "") == "text/html")
|
||||
&& ($link["href"] != "")
|
||||
foreach (array_reverse($webfinger['links']) as $link) {
|
||||
if (($link['rel'] == 'http://webfinger.net/rel/profile-page')
|
||||
&& (($link['type'] ?? '') == 'text/html')
|
||||
&& ($link['href'] != '')
|
||||
) {
|
||||
$data["url"] = $link["href"];
|
||||
} elseif (($link["rel"] == "activity-inbox") && ($link["href"] != "")) {
|
||||
$data["notify"] = $link["href"];
|
||||
} elseif (($link["rel"] == "activity-outbox") && ($link["href"] != "")) {
|
||||
$data["poll"] = $link["href"];
|
||||
} elseif (($link["rel"] == "dialback") && ($link["href"] != "")) {
|
||||
$data["dialback"] = $link["href"];
|
||||
$data['url'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'activity-inbox') && ($link['href'] != '')) {
|
||||
$data['notify'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'activity-outbox') && ($link['href'] != '')) {
|
||||
$data['poll'] = $link['href'];
|
||||
} elseif (($link['rel'] == 'dialback') && ($link['href'] != '')) {
|
||||
$data['dialback'] = $link['href'];
|
||||
}
|
||||
}
|
||||
if (isset($data["poll"]) && isset($data["notify"])
|
||||
&& isset($data["dialback"])
|
||||
&& isset($data["url"])
|
||||
if (isset($data['poll']) && isset($data['notify'])
|
||||
&& isset($data['dialback'])
|
||||
&& isset($data['url'])
|
||||
) {
|
||||
// by now we use these fields only for the network type detection
|
||||
// So we unset all data that isn't used at the moment
|
||||
unset($data["dialback"]);
|
||||
unset($data['dialback']);
|
||||
|
||||
$data["network"] = Protocol::PUMPIO;
|
||||
$data['network'] = Protocol::PUMPIO;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
||||
$profile_data = self::pumpioProfileData($data["url"]);
|
||||
$profile_data = self::pumpioProfileData($data['url']);
|
||||
|
||||
if (!$profile_data) {
|
||||
return [];
|
||||
|
|
@ -1719,9 +1705,9 @@ class Probe
|
|||
* @param string $href The potential relative href found in the HTML document
|
||||
* @param string $base The HTML document URL
|
||||
* @param DOMXPath $xpath The HTML document XPath
|
||||
* @return string
|
||||
* @return string Absolute URL
|
||||
*/
|
||||
private static function ensureAbsoluteLinkFromHTMLDoc(string $href, string $base, DOMXPath $xpath)
|
||||
private static function ensureAbsoluteLinkFromHTMLDoc(string $href, string $base, DOMXPath $xpath): string
|
||||
{
|
||||
if (filter_var($href, FILTER_VALIDATE_URL)) {
|
||||
return $href;
|
||||
|
|
@ -1808,26 +1794,26 @@ class Probe
|
|||
return self::feed($feed_url, false);
|
||||
}
|
||||
|
||||
if (!empty($feed_data["header"]["author-name"])) {
|
||||
$data["name"] = $feed_data["header"]["author-name"];
|
||||
if (!empty($feed_data['header']['author-name'])) {
|
||||
$data['name'] = $feed_data['header']['author-name'];
|
||||
}
|
||||
|
||||
if (!empty($feed_data["header"]["author-nick"])) {
|
||||
$data["nick"] = $feed_data["header"]["author-nick"];
|
||||
if (!empty($feed_data['header']['author-nick'])) {
|
||||
$data['nick'] = $feed_data['header']['author-nick'];
|
||||
}
|
||||
|
||||
if (!empty($feed_data["header"]["author-avatar"])) {
|
||||
$data["photo"] = $feed_data["header"]["author-avatar"];
|
||||
if (!empty($feed_data['header']['author-avatar'])) {
|
||||
$data['photo'] = $feed_data['header']['author-avatar'];
|
||||
}
|
||||
|
||||
if (!empty($feed_data["header"]["author-id"])) {
|
||||
$data["alias"] = $feed_data["header"]["author-id"];
|
||||
if (!empty($feed_data['header']['author-id'])) {
|
||||
$data['alias'] = $feed_data['header']['author-id'];
|
||||
}
|
||||
|
||||
$data["url"] = $url;
|
||||
$data["poll"] = $url;
|
||||
$data['url'] = $url;
|
||||
$data['poll'] = $url;
|
||||
|
||||
$data["network"] = Protocol::FEED;
|
||||
$data['network'] = Protocol::FEED;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
|
@ -1837,11 +1823,10 @@ class Probe
|
|||
*
|
||||
* @param string $uri Profile link
|
||||
* @param integer $uid User ID
|
||||
*
|
||||
* @return array mail data
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function mail($uri, $uid)
|
||||
private static function mail(string $uri, int $uid): array
|
||||
{
|
||||
if (!Network::isEmailDomainValid($uri)) {
|
||||
return [];
|
||||
|
|
@ -1879,14 +1864,14 @@ class Probe
|
|||
$phost = substr($uri, strpos($uri, '@') + 1);
|
||||
|
||||
$data = [];
|
||||
$data["addr"] = $uri;
|
||||
$data["network"] = Protocol::MAIL;
|
||||
$data["name"] = substr($uri, 0, strpos($uri, '@'));
|
||||
$data["nick"] = $data["name"];
|
||||
$data["photo"] = Network::lookupAvatarByEmail($uri);
|
||||
$data["url"] = 'mailto:'.$uri;
|
||||
$data["notify"] = 'smtp ' . Strings::getRandomHex();
|
||||
$data["poll"] = 'email ' . Strings::getRandomHex();
|
||||
$data['addr'] = $uri;
|
||||
$data['network'] = Protocol::MAIL;
|
||||
$data['name'] = substr($uri, 0, strpos($uri, '@'));
|
||||
$data['nick'] = $data['name'];
|
||||
$data['photo'] = Network::lookupAvatarByEmail($uri);
|
||||
$data['url'] = 'mailto:'.$uri;
|
||||
$data['notify'] = 'smtp ' . Strings::getRandomHex();
|
||||
$data['poll'] = 'email ' . Strings::getRandomHex();
|
||||
|
||||
$x = Email::messageMeta($mbox, $msgs[0]);
|
||||
if (stristr($x[0]->from, $uri)) {
|
||||
|
|
@ -1896,17 +1881,17 @@ class Probe
|
|||
}
|
||||
if (isset($adr)) {
|
||||
foreach ($adr as $feadr) {
|
||||
if ((strcasecmp($feadr->mailbox, $data["name"]) == 0)
|
||||
if ((strcasecmp($feadr->mailbox, $data['name']) == 0)
|
||||
&&(strcasecmp($feadr->host, $phost) == 0)
|
||||
&& (strlen($feadr->personal))
|
||||
) {
|
||||
$personal = imap_mime_header_decode($feadr->personal);
|
||||
$data["name"] = "";
|
||||
$data['name'] = '';
|
||||
foreach ($personal as $perspart) {
|
||||
if ($perspart->charset != "default") {
|
||||
$data["name"] .= iconv($perspart->charset, 'UTF-8//IGNORE', $perspart->text);
|
||||
if ($perspart->charset != 'default') {
|
||||
$data['name'] .= iconv($perspart->charset, 'UTF-8//IGNORE', $perspart->text);
|
||||
} else {
|
||||
$data["name"] .= $perspart->text;
|
||||
$data['name'] .= $perspart->text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1923,11 +1908,10 @@ class Probe
|
|||
*
|
||||
* @param string $avatar Path to the avatar
|
||||
* @param string $base Another path that is hopefully complete
|
||||
*
|
||||
* @return string fixed avatar path
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function fixAvatar($avatar, $base)
|
||||
public static function fixAvatar(string $avatar, string $base): string
|
||||
{
|
||||
$base_parts = parse_url($base);
|
||||
|
||||
|
|
@ -1962,7 +1946,7 @@ class Probe
|
|||
* @param array $data probing result
|
||||
* @return string last activity
|
||||
*/
|
||||
public static function getLastUpdate(array $data)
|
||||
public static function getLastUpdate(array $data): string
|
||||
{
|
||||
$uid = User::getIdForURL($data['url']);
|
||||
if (!empty($uid)) {
|
||||
|
|
@ -1991,9 +1975,7 @@ class Probe
|
|||
* Fetch the last activity date from the "noscrape" endpoint
|
||||
*
|
||||
* @param array $data Probing result
|
||||
* @return string last activity
|
||||
*
|
||||
* @return bool 'true' if update was successful or the server was unreachable
|
||||
* @return string last activity or true if update was successful or the server was unreachable
|
||||
*/
|
||||
private static function updateFromNoScrape(array $data)
|
||||
{
|
||||
|
|
@ -2028,7 +2010,7 @@ class Probe
|
|||
* @return string last activity
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function updateFromOutbox(string $feed, array $data)
|
||||
private static function updateFromOutbox(string $feed, array $data): string
|
||||
{
|
||||
$outbox = ActivityPub::fetchContent($feed);
|
||||
if (empty($outbox)) {
|
||||
|
|
@ -2080,7 +2062,7 @@ class Probe
|
|||
* @param array $data Probing result
|
||||
* @return string last activity
|
||||
*/
|
||||
private static function updateFromFeed(array $data)
|
||||
private static function updateFromFeed(array $data): string
|
||||
{
|
||||
// Search for the newest entry in the feed
|
||||
$curlResult = DI::httpClient()->get($data['poll'], HttpClientAccept::ATOM_XML);
|
||||
|
|
|
|||
|
|
@ -47,12 +47,13 @@ class Image
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
* @param string $data
|
||||
* @param boolean $type optional, default null
|
||||
*
|
||||
* @param string $data Image data
|
||||
* @param string $type optional, default null
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public function __construct($data, $type = null)
|
||||
public function __construct(string $data, string $type = null)
|
||||
{
|
||||
$this->imagick = class_exists('Imagick');
|
||||
$this->types = Images::supportedTypes();
|
||||
|
|
@ -62,12 +63,12 @@ class Image
|
|||
$this->type = $type;
|
||||
|
||||
if ($this->isImagick() && $this->loadData($data)) {
|
||||
return true;
|
||||
return;
|
||||
} else {
|
||||
// Failed to load with Imagick, fallback
|
||||
$this->imagick = false;
|
||||
}
|
||||
return $this->loadData($data);
|
||||
$this->loadData($data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -98,12 +99,14 @@ class Image
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $data data
|
||||
* @return boolean
|
||||
* Loads image data into handler class
|
||||
*
|
||||
* @param string $data Image data
|
||||
* @return boolean Success
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private function loadData($data)
|
||||
private function loadData(string $data): bool
|
||||
{
|
||||
if ($this->isImagick()) {
|
||||
$this->image = new Imagick();
|
||||
|
|
@ -132,7 +135,7 @@ class Image
|
|||
* setup the compression here, so we'll do it only once
|
||||
*/
|
||||
switch ($this->getType()) {
|
||||
case "image/png":
|
||||
case 'image/png':
|
||||
$quality = DI::config()->get('system', 'png_quality');
|
||||
/*
|
||||
* From http://www.imagemagick.org/script/command-line-options.php#quality:
|
||||
|
|
@ -145,7 +148,9 @@ class Image
|
|||
$quality = $quality * 10;
|
||||
$this->image->setCompressionQuality($quality);
|
||||
break;
|
||||
case "image/jpeg":
|
||||
|
||||
case 'image/jpg':
|
||||
case 'image/jpeg':
|
||||
$quality = DI::config()->get('system', 'jpeg_quality');
|
||||
$this->image->setCompressionQuality($quality);
|
||||
}
|
||||
|
|
@ -185,7 +190,7 @@ class Image
|
|||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid()
|
||||
public function isValid(): bool
|
||||
{
|
||||
if ($this->isImagick()) {
|
||||
return ($this->image !== false);
|
||||
|
|
@ -269,10 +274,12 @@ class Image
|
|||
}
|
||||
|
||||
/**
|
||||
* Scales image down
|
||||
*
|
||||
* @param integer $max max dimension
|
||||
* @return mixed
|
||||
*/
|
||||
public function scaleDown($max)
|
||||
public function scaleDown(int $max)
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
return false;
|
||||
|
|
@ -327,10 +334,12 @@ class Image
|
|||
}
|
||||
|
||||
/**
|
||||
* Rotates image
|
||||
*
|
||||
* @param integer $degrees degrees to rotate image
|
||||
* @return mixed
|
||||
*/
|
||||
public function rotate($degrees)
|
||||
public function rotate(int $degrees)
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
return false;
|
||||
|
|
@ -351,11 +360,13 @@ class Image
|
|||
}
|
||||
|
||||
/**
|
||||
* Flips image
|
||||
*
|
||||
* @param boolean $horiz optional, default true
|
||||
* @param boolean $vert optional, default false
|
||||
* @return mixed
|
||||
*/
|
||||
public function flip($horiz = true, $vert = false)
|
||||
public function flip(bool $horiz = true, bool $vert = false)
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
return false;
|
||||
|
|
@ -391,10 +402,12 @@ class Image
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $filename filename
|
||||
* Fixes orientation and maybe returns EXIF data (?)
|
||||
*
|
||||
* @param string $filename Filename
|
||||
* @return mixed
|
||||
*/
|
||||
public function orient($filename)
|
||||
public function orient(string $filename)
|
||||
{
|
||||
if ($this->isImagick()) {
|
||||
// based off comment on http://php.net/manual/en/imagick.getimageorientation.php
|
||||
|
|
@ -470,10 +483,12 @@ class Image
|
|||
}
|
||||
|
||||
/**
|
||||
* @param integer $min minimum dimension
|
||||
* Rescales image to minimum size
|
||||
*
|
||||
* @param integer $min Minimum dimension
|
||||
* @return mixed
|
||||
*/
|
||||
public function scaleUp($min)
|
||||
public function scaleUp(int $min)
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
return false;
|
||||
|
|
@ -513,10 +528,12 @@ class Image
|
|||
}
|
||||
|
||||
/**
|
||||
* @param integer $dim dimension
|
||||
* Scales image to square
|
||||
*
|
||||
* @param integer $dim Dimension
|
||||
* @return mixed
|
||||
*/
|
||||
public function scaleToSquare($dim)
|
||||
public function scaleToSquare(int $dim)
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
return false;
|
||||
|
|
@ -528,11 +545,11 @@ class Image
|
|||
/**
|
||||
* Scale image to target dimensions
|
||||
*
|
||||
* @param int $dest_width
|
||||
* @param int $dest_height
|
||||
* @return boolean
|
||||
* @param int $dest_width Destination width
|
||||
* @param int $dest_height Destination height
|
||||
* @return boolean Success
|
||||
*/
|
||||
private function scale($dest_width, $dest_height)
|
||||
private function scale(int $dest_width, int $dest_height): bool
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
return false;
|
||||
|
|
@ -584,6 +601,8 @@ class Image
|
|||
|
||||
/**
|
||||
* Convert a GIF to a PNG to make it static
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function toStatic()
|
||||
{
|
||||
|
|
@ -598,6 +617,8 @@ class Image
|
|||
}
|
||||
|
||||
/**
|
||||
* Crops image
|
||||
*
|
||||
* @param integer $max maximum
|
||||
* @param integer $x x coordinate
|
||||
* @param integer $y y coordinate
|
||||
|
|
@ -605,7 +626,7 @@ class Image
|
|||
* @param integer $h height
|
||||
* @return mixed
|
||||
*/
|
||||
public function crop($max, $x, $y, $w, $h)
|
||||
public function crop(int $max, int $x, int $y, int $w, int $h)
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
return false;
|
||||
|
|
@ -638,6 +659,9 @@ class Image
|
|||
$this->image = $dest;
|
||||
$this->width = imagesx($this->image);
|
||||
$this->height = imagesy($this->image);
|
||||
|
||||
// All successful
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -650,11 +674,14 @@ class Image
|
|||
* @return string
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public function __toString() {
|
||||
return $this->asString();
|
||||
public function __toString(): string
|
||||
{
|
||||
return (string) $this->asString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns image as string or false on failure
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
|
|
@ -681,13 +708,16 @@ class Image
|
|||
imageinterlace($this->image, true);
|
||||
|
||||
switch ($this->getType()) {
|
||||
case "image/png":
|
||||
case 'image/png':
|
||||
$quality = DI::config()->get('system', 'png_quality');
|
||||
imagepng($this->image, null, $quality);
|
||||
break;
|
||||
case "image/jpeg":
|
||||
|
||||
case 'image/jpeg':
|
||||
case 'image/jpg':
|
||||
$quality = DI::config()->get('system', 'jpeg_quality');
|
||||
imagejpeg($this->image, null, $quality);
|
||||
break;
|
||||
}
|
||||
$string = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
namespace Friendica\Protocol;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMElement;
|
||||
use DOMNode;
|
||||
use DOMXPath;
|
||||
use Friendica\Content\Text\BBCode;
|
||||
use Friendica\Core\Logger;
|
||||
|
|
@ -120,7 +122,7 @@ class DFRN
|
|||
$doc = new DOMDocument('1.0', 'utf-8');
|
||||
$doc->formatOutput = true;
|
||||
|
||||
$root = self::addHeader($doc, $owner, "dfrn:owner", "", false);
|
||||
$root = self::addHeader($doc, $owner, 'dfrn:owner', '', false);
|
||||
|
||||
if (! count($items)) {
|
||||
return trim($doc->saveXML());
|
||||
|
|
@ -129,10 +131,10 @@ class DFRN
|
|||
foreach ($items as $item) {
|
||||
// These values aren't sent when sending from the queue.
|
||||
/// @todo Check if we can set these values from the queue or if they are needed at all.
|
||||
$item["entry:comment-allow"] = ($item["entry:comment-allow"] ?? '') ?: true;
|
||||
$item["entry:cid"] = $item["entry:cid"] ?? 0;
|
||||
$item['entry:comment-allow'] = ($item['entry:comment-allow'] ?? '') ?: true;
|
||||
$item['entry:cid'] = $item['entry:cid'] ?? 0;
|
||||
|
||||
$entry = self::entry($doc, "text", $item, $owner, $item["entry:comment-allow"], $item["entry:cid"]);
|
||||
$entry = self::entry($doc, 'text', $item, $owner, $item['entry:comment-allow'], $item['entry:cid']);
|
||||
if (isset($entry)) {
|
||||
$root->appendChild($entry);
|
||||
}
|
||||
|
|
@ -186,17 +188,15 @@ class DFRN
|
|||
$root = $doc->createElementNS(ActivityNamespace::ATOM1, 'feed');
|
||||
$doc->appendChild($root);
|
||||
|
||||
$root->setAttribute("xmlns:thr", ActivityNamespace::THREAD);
|
||||
$root->setAttribute("xmlns:at", ActivityNamespace::TOMB);
|
||||
$root->setAttribute("xmlns:media", ActivityNamespace::MEDIA);
|
||||
$root->setAttribute("xmlns:dfrn", ActivityNamespace::DFRN);
|
||||
$root->setAttribute("xmlns:activity", ActivityNamespace::ACTIVITY);
|
||||
$root->setAttribute("xmlns:georss", ActivityNamespace::GEORSS);
|
||||
$root->setAttribute("xmlns:poco", ActivityNamespace::POCO);
|
||||
$root->setAttribute("xmlns:ostatus", ActivityNamespace::OSTATUS);
|
||||
$root->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET);
|
||||
|
||||
//$root = self::addHeader($doc, $owner, "dfrn:owner", "", false);
|
||||
$root->setAttribute('xmlns:thr', ActivityNamespace::THREAD);
|
||||
$root->setAttribute('xmlns:at', ActivityNamespace::TOMB);
|
||||
$root->setAttribute('xmlns:media', ActivityNamespace::MEDIA);
|
||||
$root->setAttribute('xmlns:dfrn', ActivityNamespace::DFRN);
|
||||
$root->setAttribute('xmlns:activity', ActivityNamespace::ACTIVITY);
|
||||
$root->setAttribute('xmlns:georss', ActivityNamespace::GEORSS);
|
||||
$root->setAttribute('xmlns:poco', ActivityNamespace::POCO);
|
||||
$root->setAttribute('xmlns:ostatus', ActivityNamespace::OSTATUS);
|
||||
$root->setAttribute('xmlns:statusnet', ActivityNamespace::STATUSNET);
|
||||
|
||||
foreach ($items as $item) {
|
||||
$entry = self::entry($doc, $type, $item, $owner, true, 0);
|
||||
|
|
@ -227,22 +227,22 @@ class DFRN
|
|||
$doc = new DOMDocument('1.0', 'utf-8');
|
||||
$doc->formatOutput = true;
|
||||
|
||||
$root = self::addHeader($doc, $owner, "dfrn:owner", "", false);
|
||||
$root = self::addHeader($doc, $owner, 'dfrn:owner', '', false);
|
||||
|
||||
$mailElement = $doc->createElement("dfrn:mail");
|
||||
$senderElement = $doc->createElement("dfrn:sender");
|
||||
$mailElement = $doc->createElement('dfrn:mail');
|
||||
$senderElement = $doc->createElement('dfrn:sender');
|
||||
|
||||
XML::addElement($doc, $senderElement, "dfrn:name", $owner['name']);
|
||||
XML::addElement($doc, $senderElement, "dfrn:uri", $owner['url']);
|
||||
XML::addElement($doc, $senderElement, "dfrn:avatar", $owner['thumb']);
|
||||
XML::addElement($doc, $senderElement, 'dfrn:name', $owner['name']);
|
||||
XML::addElement($doc, $senderElement, 'dfrn:uri', $owner['url']);
|
||||
XML::addElement($doc, $senderElement, 'dfrn:avatar', $owner['thumb']);
|
||||
|
||||
$mailElement->appendChild($senderElement);
|
||||
|
||||
XML::addElement($doc, $mailElement, "dfrn:id", $mail['uri']);
|
||||
XML::addElement($doc, $mailElement, "dfrn:in-reply-to", $mail['parent-uri']);
|
||||
XML::addElement($doc, $mailElement, "dfrn:sentdate", DateTimeFormat::utc($mail['created'] . '+00:00', DateTimeFormat::ATOM));
|
||||
XML::addElement($doc, $mailElement, "dfrn:subject", $mail['title']);
|
||||
XML::addElement($doc, $mailElement, "dfrn:content", $mail['body']);
|
||||
XML::addElement($doc, $mailElement, 'dfrn:id', $mail['uri']);
|
||||
XML::addElement($doc, $mailElement, 'dfrn:in-reply-to', $mail['parent-uri']);
|
||||
XML::addElement($doc, $mailElement, 'dfrn:sentdate', DateTimeFormat::utc($mail['created'] . '+00:00', DateTimeFormat::ATOM));
|
||||
XML::addElement($doc, $mailElement, 'dfrn:subject', $mail['title']);
|
||||
XML::addElement($doc, $mailElement, 'dfrn:content', $mail['body']);
|
||||
|
||||
$root->appendChild($mailElement);
|
||||
|
||||
|
|
@ -264,15 +264,15 @@ class DFRN
|
|||
$doc = new DOMDocument('1.0', 'utf-8');
|
||||
$doc->formatOutput = true;
|
||||
|
||||
$root = self::addHeader($doc, $owner, "dfrn:owner", "", false);
|
||||
$root = self::addHeader($doc, $owner, 'dfrn:owner', '', false);
|
||||
|
||||
$suggest = $doc->createElement("dfrn:suggest");
|
||||
$suggest = $doc->createElement('dfrn:suggest');
|
||||
|
||||
XML::addElement($doc, $suggest, "dfrn:url", $item['url']);
|
||||
XML::addElement($doc, $suggest, "dfrn:name", $item['name']);
|
||||
XML::addElement($doc, $suggest, "dfrn:photo", $item['photo']);
|
||||
XML::addElement($doc, $suggest, "dfrn:request", $item['request']);
|
||||
XML::addElement($doc, $suggest, "dfrn:note", $item['note']);
|
||||
XML::addElement($doc, $suggest, 'dfrn:url', $item['url']);
|
||||
XML::addElement($doc, $suggest, 'dfrn:name', $item['name']);
|
||||
XML::addElement($doc, $suggest, 'dfrn:photo', $item['photo']);
|
||||
XML::addElement($doc, $suggest, 'dfrn:request', $item['request']);
|
||||
XML::addElement($doc, $suggest, 'dfrn:note', $item['note']);
|
||||
|
||||
$root->appendChild($suggest);
|
||||
|
||||
|
|
@ -313,22 +313,22 @@ class DFRN
|
|||
$doc = new DOMDocument('1.0', 'utf-8');
|
||||
$doc->formatOutput = true;
|
||||
|
||||
$root = self::addHeader($doc, $owner, "dfrn:owner", "", false);
|
||||
$root = self::addHeader($doc, $owner, 'dfrn:owner', '', false);
|
||||
|
||||
$relocate = $doc->createElement("dfrn:relocate");
|
||||
$relocate = $doc->createElement('dfrn:relocate');
|
||||
|
||||
XML::addElement($doc, $relocate, "dfrn:url", $owner['url']);
|
||||
XML::addElement($doc, $relocate, "dfrn:name", $owner['name']);
|
||||
XML::addElement($doc, $relocate, "dfrn:addr", $owner['addr']);
|
||||
XML::addElement($doc, $relocate, "dfrn:avatar", $owner['avatar']);
|
||||
XML::addElement($doc, $relocate, "dfrn:photo", $photos[4]);
|
||||
XML::addElement($doc, $relocate, "dfrn:thumb", $photos[5]);
|
||||
XML::addElement($doc, $relocate, "dfrn:micro", $photos[6]);
|
||||
XML::addElement($doc, $relocate, "dfrn:request", $owner['request']);
|
||||
XML::addElement($doc, $relocate, "dfrn:confirm", $owner['confirm']);
|
||||
XML::addElement($doc, $relocate, "dfrn:notify", $owner['notify']);
|
||||
XML::addElement($doc, $relocate, "dfrn:poll", $owner['poll']);
|
||||
XML::addElement($doc, $relocate, "dfrn:sitepubkey", DI::config()->get('system', 'site_pubkey'));
|
||||
XML::addElement($doc, $relocate, 'dfrn:url', $owner['url']);
|
||||
XML::addElement($doc, $relocate, 'dfrn:name', $owner['name']);
|
||||
XML::addElement($doc, $relocate, 'dfrn:addr', $owner['addr']);
|
||||
XML::addElement($doc, $relocate, 'dfrn:avatar', $owner['avatar']);
|
||||
XML::addElement($doc, $relocate, 'dfrn:photo', $photos[4]);
|
||||
XML::addElement($doc, $relocate, 'dfrn:thumb', $photos[5]);
|
||||
XML::addElement($doc, $relocate, 'dfrn:micro', $photos[6]);
|
||||
XML::addElement($doc, $relocate, 'dfrn:request', $owner['request']);
|
||||
XML::addElement($doc, $relocate, 'dfrn:confirm', $owner['confirm']);
|
||||
XML::addElement($doc, $relocate, 'dfrn:notify', $owner['notify']);
|
||||
XML::addElement($doc, $relocate, 'dfrn:poll', $owner['poll']);
|
||||
XML::addElement($doc, $relocate, 'dfrn:sitepubkey', DI::config()->get('system', 'site_pubkey'));
|
||||
|
||||
$root->appendChild($relocate);
|
||||
|
||||
|
|
@ -343,69 +343,67 @@ class DFRN
|
|||
* @param string $authorelement Element name for the author
|
||||
* @param string $alternatelink link to profile or category
|
||||
* @param bool $public Is it a header for public posts?
|
||||
*
|
||||
* @return object XML root object
|
||||
* @return DOMElement XML root element
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @todo Find proper type-hint for returned type
|
||||
*/
|
||||
private static function addHeader(DOMDocument $doc, array $owner, string $authorelement, string $alternatelink = '', bool $public = false)
|
||||
private static function addHeader(DOMDocument $doc, array $owner, string $authorelement, string $alternatelink = '', bool $public = false): DOMElement
|
||||
{
|
||||
|
||||
if ($alternatelink == "") {
|
||||
if ($alternatelink == '') {
|
||||
$alternatelink = $owner['url'];
|
||||
}
|
||||
|
||||
$root = $doc->createElementNS(ActivityNamespace::ATOM1, 'feed');
|
||||
$doc->appendChild($root);
|
||||
|
||||
$root->setAttribute("xmlns:thr", ActivityNamespace::THREAD);
|
||||
$root->setAttribute("xmlns:at", ActivityNamespace::TOMB);
|
||||
$root->setAttribute("xmlns:media", ActivityNamespace::MEDIA);
|
||||
$root->setAttribute("xmlns:dfrn", ActivityNamespace::DFRN);
|
||||
$root->setAttribute("xmlns:activity", ActivityNamespace::ACTIVITY);
|
||||
$root->setAttribute("xmlns:georss", ActivityNamespace::GEORSS);
|
||||
$root->setAttribute("xmlns:poco", ActivityNamespace::POCO);
|
||||
$root->setAttribute("xmlns:ostatus", ActivityNamespace::OSTATUS);
|
||||
$root->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET);
|
||||
$root->setAttribute('xmlns:thr', ActivityNamespace::THREAD);
|
||||
$root->setAttribute('xmlns:at', ActivityNamespace::TOMB);
|
||||
$root->setAttribute('xmlns:media', ActivityNamespace::MEDIA);
|
||||
$root->setAttribute('xmlns:dfrn', ActivityNamespace::DFRN);
|
||||
$root->setAttribute('xmlns:activity', ActivityNamespace::ACTIVITY);
|
||||
$root->setAttribute('xmlns:georss', ActivityNamespace::GEORSS);
|
||||
$root->setAttribute('xmlns:poco', ActivityNamespace::POCO);
|
||||
$root->setAttribute('xmlns:ostatus', ActivityNamespace::OSTATUS);
|
||||
$root->setAttribute('xmlns:statusnet', ActivityNamespace::STATUSNET);
|
||||
|
||||
XML::addElement($doc, $root, "id", DI::baseUrl()."/profile/".$owner["nick"]);
|
||||
XML::addElement($doc, $root, "title", $owner["name"]);
|
||||
XML::addElement($doc, $root, 'id', DI::baseUrl() . '/profile/' . $owner['nick']);
|
||||
XML::addElement($doc, $root, 'title', $owner['name']);
|
||||
|
||||
$attributes = ["uri" => "https://friendi.ca", "version" => FRIENDICA_VERSION."-".DB_UPDATE_VERSION];
|
||||
XML::addElement($doc, $root, "generator", FRIENDICA_PLATFORM, $attributes);
|
||||
$attributes = ['uri' => 'https://friendi.ca', 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION];
|
||||
XML::addElement($doc, $root, 'generator', FRIENDICA_PLATFORM, $attributes);
|
||||
|
||||
$attributes = ["rel" => "license", "href" => "http://creativecommons.org/licenses/by/3.0/"];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = ['rel' => 'license', 'href' => 'http://creativecommons.org/licenses/by/3.0/'];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
|
||||
$attributes = ["rel" => "alternate", "type" => "text/html", "href" => $alternatelink];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = ['rel' => 'alternate', 'type' => 'text/html', 'href' => $alternatelink];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
|
||||
|
||||
if ($public) {
|
||||
// DFRN itself doesn't uses this. But maybe someone else wants to subscribe to the public feed.
|
||||
OStatus::hublinks($doc, $root, $owner["nick"]);
|
||||
OStatus::addHubLink($doc, $root, $owner['nick']);
|
||||
|
||||
$attributes = ["rel" => "salmon", "href" => DI::baseUrl()."/salmon/".$owner["nick"]];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = ['rel' => 'salmon', 'href' => DI::baseUrl() . '/salmon/' . $owner['nick']];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
|
||||
$attributes = ["rel" => "http://salmon-protocol.org/ns/salmon-replies", "href" => DI::baseUrl()."/salmon/".$owner["nick"]];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = ['rel' => 'http://salmon-protocol.org/ns/salmon-replies', 'href' => DI::baseUrl() . '/salmon/' . $owner['nick']];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
|
||||
$attributes = ["rel" => "http://salmon-protocol.org/ns/salmon-mention", "href" => DI::baseUrl()."/salmon/".$owner["nick"]];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = ['rel' => 'http://salmon-protocol.org/ns/salmon-mention', 'href' => DI::baseUrl() . '/salmon/' . $owner['nick']];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
}
|
||||
|
||||
// For backward compatibility we keep this element
|
||||
if ($owner['page-flags'] == User::PAGE_FLAGS_COMMUNITY) {
|
||||
XML::addElement($doc, $root, "dfrn:community", 1);
|
||||
XML::addElement($doc, $root, 'dfrn:community', 1);
|
||||
}
|
||||
|
||||
// The former element is replaced by this one
|
||||
XML::addElement($doc, $root, "dfrn:account_type", $owner["account-type"]);
|
||||
XML::addElement($doc, $root, 'dfrn:account_type', $owner['account-type']);
|
||||
|
||||
/// @todo We need a way to transmit the different page flags like "User::PAGE_FLAGS_PRVGROUP"
|
||||
|
||||
XML::addElement($doc, $root, "updated", DateTimeFormat::utcNow(DateTimeFormat::ATOM));
|
||||
XML::addElement($doc, $root, 'updated', DateTimeFormat::utcNow(DateTimeFormat::ATOM));
|
||||
|
||||
$author = self::addAuthor($doc, $owner, $authorelement, $public);
|
||||
$root->appendChild($author);
|
||||
|
|
@ -466,12 +464,11 @@ class DFRN
|
|||
* @param array $owner Owner record
|
||||
* @param string $authorelement Element name for the author
|
||||
* @param boolean $public boolean
|
||||
*
|
||||
* @return \DOMElement XML author object
|
||||
* @return DOMElement XML author object
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @todo Find proper type-hints
|
||||
*/
|
||||
private static function addAuthor(DOMDocument $doc, array $owner, string $authorelement, bool $public)
|
||||
private static function addAuthor(DOMDocument $doc, array $owner, string $authorelement, bool $public): DOMElement
|
||||
{
|
||||
// Should the profile be "unsearchable" in the net? Then add the "hide" element
|
||||
$hide = DBA::exists('profile', ['uid' => $owner['uid'], 'net-publish' => false]);
|
||||
|
|
@ -484,28 +481,32 @@ class DFRN
|
|||
$attributes = [];
|
||||
|
||||
if (!$public || !$hide) {
|
||||
$attributes = ["dfrn:updated" => $namdate];
|
||||
$attributes = ['dfrn:updated' => $namdate];
|
||||
}
|
||||
|
||||
XML::addElement($doc, $author, "name", $owner["name"], $attributes);
|
||||
XML::addElement($doc, $author, "uri", DI::baseUrl().'/profile/'.$owner["nickname"], $attributes);
|
||||
XML::addElement($doc, $author, "dfrn:handle", $owner["addr"], $attributes);
|
||||
XML::addElement($doc, $author, 'name', $owner['name'], $attributes);
|
||||
XML::addElement($doc, $author, 'uri', DI::baseUrl().'/profile/' . $owner['nickname'], $attributes);
|
||||
XML::addElement($doc, $author, 'dfrn:handle', $owner['addr'], $attributes);
|
||||
|
||||
$attributes = ["rel" => "photo", "type" => "image/jpeg",
|
||||
"media:width" => Proxy::PIXEL_SMALL, "media:height" => Proxy::PIXEL_SMALL,
|
||||
"href" => User::getAvatarUrl($owner, Proxy::SIZE_SMALL)];
|
||||
$attributes = [
|
||||
'rel' => 'photo',
|
||||
'type' => 'image/jpeg',
|
||||
'media:width' => Proxy::PIXEL_SMALL,
|
||||
'media:height' => Proxy::PIXEL_SMALL,
|
||||
'href' => User::getAvatarUrl($owner, Proxy::SIZE_SMALL),
|
||||
];
|
||||
|
||||
if (!$public || !$hide) {
|
||||
$attributes["dfrn:updated"] = $picdate;
|
||||
$attributes['dfrn:updated'] = $picdate;
|
||||
}
|
||||
|
||||
XML::addElement($doc, $author, "link", "", $attributes);
|
||||
XML::addElement($doc, $author, 'link', '', $attributes);
|
||||
|
||||
$attributes["rel"] = "avatar";
|
||||
XML::addElement($doc, $author, "link", "", $attributes);
|
||||
$attributes['rel'] = 'avatar';
|
||||
XML::addElement($doc, $author, 'link', '', $attributes);
|
||||
|
||||
if ($hide) {
|
||||
XML::addElement($doc, $author, "dfrn:hide", "true");
|
||||
XML::addElement($doc, $author, 'dfrn:hide', 'true');
|
||||
}
|
||||
|
||||
// The following fields will only be generated if the data isn't meant for a public feed
|
||||
|
|
@ -516,7 +517,7 @@ class DFRN
|
|||
$birthday = self::determineNextBirthday($owner['uid'], $owner['timezone']);
|
||||
|
||||
if ($birthday) {
|
||||
XML::addElement($doc, $author, "dfrn:birthday", $birthday);
|
||||
XML::addElement($doc, $author, 'dfrn:birthday', $birthday);
|
||||
}
|
||||
|
||||
// Only show contact details when we are allowed to
|
||||
|
|
@ -524,57 +525,57 @@ class DFRN
|
|||
['about', 'name', 'homepage', 'nickname', 'timezone', 'locality', 'region', 'country-name', 'pub_keywords', 'xmpp', 'dob'],
|
||||
['uid' => $owner['uid'], 'hidewall' => false]);
|
||||
if (DBA::isResult($profile)) {
|
||||
XML::addElement($doc, $author, "poco:displayName", $profile["name"]);
|
||||
XML::addElement($doc, $author, "poco:updated", $namdate);
|
||||
XML::addElement($doc, $author, 'poco:displayName', $profile['name']);
|
||||
XML::addElement($doc, $author, 'poco:updated', $namdate);
|
||||
|
||||
if (trim($profile["dob"]) > DBA::NULL_DATE) {
|
||||
XML::addElement($doc, $author, "poco:birthday", "0000-".date("m-d", strtotime($profile["dob"])));
|
||||
if (trim($profile['dob']) > DBA::NULL_DATE) {
|
||||
XML::addElement($doc, $author, 'poco:birthday', '0000-'.date('m-d', strtotime($profile['dob'])));
|
||||
}
|
||||
|
||||
XML::addElement($doc, $author, "poco:note", $profile["about"]);
|
||||
XML::addElement($doc, $author, "poco:preferredUsername", $profile["nickname"]);
|
||||
XML::addElement($doc, $author, 'poco:note', $profile['about']);
|
||||
XML::addElement($doc, $author, 'poco:preferredUsername', $profile['nickname']);
|
||||
|
||||
XML::addElement($doc, $author, "poco:utcOffset", DateTimeFormat::timezoneNow($profile["timezone"], "P"));
|
||||
XML::addElement($doc, $author, 'poco:utcOffset', DateTimeFormat::timezoneNow($profile['timezone'], 'P'));
|
||||
|
||||
if (trim($profile["homepage"]) != "") {
|
||||
$urls = $doc->createElement("poco:urls");
|
||||
XML::addElement($doc, $urls, "poco:type", "homepage");
|
||||
XML::addElement($doc, $urls, "poco:value", $profile["homepage"]);
|
||||
XML::addElement($doc, $urls, "poco:primary", "true");
|
||||
if (trim($profile['homepage']) != '') {
|
||||
$urls = $doc->createElement('poco:urls');
|
||||
XML::addElement($doc, $urls, 'poco:type', 'homepage');
|
||||
XML::addElement($doc, $urls, 'poco:value', $profile['homepage']);
|
||||
XML::addElement($doc, $urls, 'poco:primary', 'true');
|
||||
$author->appendChild($urls);
|
||||
}
|
||||
|
||||
if (trim($profile["pub_keywords"]) != "") {
|
||||
$keywords = explode(",", $profile["pub_keywords"]);
|
||||
if (trim($profile['pub_keywords']) != '') {
|
||||
$keywords = explode(',', $profile['pub_keywords']);
|
||||
|
||||
foreach ($keywords as $keyword) {
|
||||
XML::addElement($doc, $author, "poco:tags", trim($keyword));
|
||||
XML::addElement($doc, $author, 'poco:tags', trim($keyword));
|
||||
}
|
||||
}
|
||||
|
||||
if (trim($profile["xmpp"]) != "") {
|
||||
$ims = $doc->createElement("poco:ims");
|
||||
XML::addElement($doc, $ims, "poco:type", "xmpp");
|
||||
XML::addElement($doc, $ims, "poco:value", $profile["xmpp"]);
|
||||
XML::addElement($doc, $ims, "poco:primary", "true");
|
||||
if (trim($profile['xmpp']) != '') {
|
||||
$ims = $doc->createElement('poco:ims');
|
||||
XML::addElement($doc, $ims, 'poco:type', 'xmpp');
|
||||
XML::addElement($doc, $ims, 'poco:value', $profile['xmpp']);
|
||||
XML::addElement($doc, $ims, 'poco:primary', 'true');
|
||||
$author->appendChild($ims);
|
||||
}
|
||||
|
||||
if (trim($profile["locality"].$profile["region"].$profile["country-name"]) != "") {
|
||||
$element = $doc->createElement("poco:address");
|
||||
if (trim($profile['locality'] . $profile['region'] . $profile['country-name']) != '') {
|
||||
$element = $doc->createElement('poco:address');
|
||||
|
||||
XML::addElement($doc, $element, "poco:formatted", Profile::formatLocation($profile));
|
||||
XML::addElement($doc, $element, 'poco:formatted', Profile::formatLocation($profile));
|
||||
|
||||
if (trim($profile["locality"]) != "") {
|
||||
XML::addElement($doc, $element, "poco:locality", $profile["locality"]);
|
||||
if (trim($profile['locality']) != '') {
|
||||
XML::addElement($doc, $element, 'poco:locality', $profile['locality']);
|
||||
}
|
||||
|
||||
if (trim($profile["region"]) != "") {
|
||||
XML::addElement($doc, $element, "poco:region", $profile["region"]);
|
||||
if (trim($profile['region']) != '') {
|
||||
XML::addElement($doc, $element, 'poco:region', $profile['region']);
|
||||
}
|
||||
|
||||
if (trim($profile["country-name"]) != "") {
|
||||
XML::addElement($doc, $element, "poco:country", $profile["country-name"]);
|
||||
if (trim($profile['country-name']) != '') {
|
||||
XML::addElement($doc, $element, 'poco:country', $profile['country-name']);
|
||||
}
|
||||
|
||||
$author->appendChild($element);
|
||||
|
|
@ -588,42 +589,43 @@ class DFRN
|
|||
* Adds the author elements in the "entry" elements of the DFRN protocol
|
||||
*
|
||||
* @param DOMDocument $doc XML document
|
||||
* @param string $element Element name for the author
|
||||
* @param string $contact_url Link of the contact
|
||||
* @param array $item Item elements
|
||||
*
|
||||
* @return \DOMElement XML author object
|
||||
* @param string $element Element name for the author
|
||||
* @param string $contact_url Link of the contact
|
||||
* @param array $item Item elements
|
||||
* @return DOMElement XML author object
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @todo Find proper type-hints
|
||||
*/
|
||||
private static function addEntryAuthor(DOMDocument $doc, string $element, string $contact_url, array $item)
|
||||
private static function addEntryAuthor(DOMDocument $doc, string $element, string $contact_url, array $item): DOMElement
|
||||
{
|
||||
$author = $doc->createElement($element);
|
||||
|
||||
$contact = Contact::getByURLForUser($contact_url, $item["uid"], false, ['url', 'name', 'addr', 'photo']);
|
||||
$contact = Contact::getByURLForUser($contact_url, $item['uid'], false, ['url', 'name', 'addr', 'photo']);
|
||||
if (!empty($contact)) {
|
||||
XML::addElement($doc, $author, "name", $contact["name"]);
|
||||
XML::addElement($doc, $author, "uri", $contact["url"]);
|
||||
XML::addElement($doc, $author, "dfrn:handle", $contact["addr"]);
|
||||
XML::addElement($doc, $author, 'name', $contact['name']);
|
||||
XML::addElement($doc, $author, 'uri', $contact['url']);
|
||||
XML::addElement($doc, $author, 'dfrn:handle', $contact['addr']);
|
||||
|
||||
/// @Todo
|
||||
/// - Check real image type and image size
|
||||
/// - Check which of these boths elements we should use
|
||||
$attributes = [
|
||||
"rel" => "photo",
|
||||
"type" => "image/jpeg",
|
||||
"media:width" => 80,
|
||||
"media:height" => 80,
|
||||
"href" => $contact["photo"]];
|
||||
XML::addElement($doc, $author, "link", "", $attributes);
|
||||
'rel' => 'photo',
|
||||
'type' => 'image/jpeg',
|
||||
'media:width' => 80,
|
||||
'media:height' => 80,
|
||||
'href' => $contact['photo'],
|
||||
];
|
||||
XML::addElement($doc, $author, 'link', '', $attributes);
|
||||
|
||||
$attributes = [
|
||||
"rel" => "avatar",
|
||||
"type" => "image/jpeg",
|
||||
"media:width" => 80,
|
||||
"media:height" => 80,
|
||||
"href" => $contact["photo"]];
|
||||
XML::addElement($doc, $author, "link", "", $attributes);
|
||||
'rel' => 'avatar',
|
||||
'type' => 'image/jpeg',
|
||||
'media:width' => 80,
|
||||
'media:height' => 80,
|
||||
'href' => $contact['photo'],
|
||||
];
|
||||
XML::addElement($doc, $author, 'link', '', $attributes);
|
||||
}
|
||||
|
||||
return $author;
|
||||
|
|
@ -636,8 +638,7 @@ class DFRN
|
|||
* @param string $element Element name for the activity
|
||||
* @param string $activity activity value
|
||||
* @param int $uriid Uri-Id of the post
|
||||
*
|
||||
* @return \DOMElement XML activity object
|
||||
* @return DOMElement XML activity object
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @todo Find proper type-hints
|
||||
*/
|
||||
|
|
@ -825,91 +826,95 @@ class DFRN
|
|||
}
|
||||
|
||||
$attributes = [
|
||||
"href" => $conversation_href,
|
||||
"ref" => $conversation_uri];
|
||||
'href' => $conversation_href,
|
||||
'ref' => $conversation_uri,
|
||||
];
|
||||
|
||||
XML::addElement($doc, $entry, "ostatus:conversation", $conversation_uri, $attributes);
|
||||
XML::addElement($doc, $entry, 'ostatus:conversation', $conversation_uri, $attributes);
|
||||
|
||||
XML::addElement($doc, $entry, "id", $item["uri"]);
|
||||
XML::addElement($doc, $entry, "title", $item["title"]);
|
||||
XML::addElement($doc, $entry, 'id', $item['uri']);
|
||||
XML::addElement($doc, $entry, 'title', $item['title']);
|
||||
|
||||
XML::addElement($doc, $entry, "published", DateTimeFormat::utc($item["created"] . "+00:00", DateTimeFormat::ATOM));
|
||||
XML::addElement($doc, $entry, "updated", DateTimeFormat::utc($item["edited"] . "+00:00", DateTimeFormat::ATOM));
|
||||
XML::addElement($doc, $entry, 'published', DateTimeFormat::utc($item['created'] . '+00:00', DateTimeFormat::ATOM));
|
||||
XML::addElement($doc, $entry, 'updated', DateTimeFormat::utc($item['edited'] . '+00:00', DateTimeFormat::ATOM));
|
||||
|
||||
// "dfrn:env" is used to read the content
|
||||
XML::addElement($doc, $entry, "dfrn:env", Strings::base64UrlEncode($body, true));
|
||||
XML::addElement($doc, $entry, 'dfrn:env', Strings::base64UrlEncode($body, true));
|
||||
|
||||
// The "content" field is not read by the receiver. We could remove it when the type is "text"
|
||||
// We keep it at the moment, maybe there is some old version that doesn't read "dfrn:env"
|
||||
XML::addElement($doc, $entry, "content", (($type == 'html') ? $htmlbody : $body), ["type" => $type]);
|
||||
XML::addElement($doc, $entry, 'content', (($type == 'html') ? $htmlbody : $body), ['type' => $type]);
|
||||
|
||||
// We save this value in "plink". Maybe we should read it from there as well?
|
||||
XML::addElement(
|
||||
$doc,
|
||||
$entry,
|
||||
"link",
|
||||
"",
|
||||
["rel" => "alternate", "type" => "text/html",
|
||||
"href" => DI::baseUrl() . "/display/" . $item["guid"]]
|
||||
'link',
|
||||
'',
|
||||
[
|
||||
'rel' => 'alternate',
|
||||
'type' => 'text/html',
|
||||
'href' => DI::baseUrl() . '/display/' . $item['guid']
|
||||
],
|
||||
);
|
||||
|
||||
// "comment-allow" is some old fashioned stuff for old Friendica versions.
|
||||
// It is included in the rewritten code for completeness
|
||||
if ($comment) {
|
||||
XML::addElement($doc, $entry, "dfrn:comment-allow", 1);
|
||||
XML::addElement($doc, $entry, 'dfrn:comment-allow', 1);
|
||||
}
|
||||
|
||||
if ($item['location']) {
|
||||
XML::addElement($doc, $entry, "dfrn:location", $item['location']);
|
||||
XML::addElement($doc, $entry, 'dfrn:location', $item['location']);
|
||||
}
|
||||
|
||||
if ($item['coord']) {
|
||||
XML::addElement($doc, $entry, "georss:point", $item['coord']);
|
||||
XML::addElement($doc, $entry, 'georss:point', $item['coord']);
|
||||
}
|
||||
|
||||
if ($item['private']) {
|
||||
// Friendica versions prior to 2020.3 can't handle "unlisted" properly. So we can only transmit public and private
|
||||
XML::addElement($doc, $entry, "dfrn:private", ($item['private'] == Item::PRIVATE ? Item::PRIVATE : Item::PUBLIC));
|
||||
XML::addElement($doc, $entry, "dfrn:unlisted", $item['private'] == Item::UNLISTED);
|
||||
XML::addElement($doc, $entry, 'dfrn:private', ($item['private'] == Item::PRIVATE ? Item::PRIVATE : Item::PUBLIC));
|
||||
XML::addElement($doc, $entry, 'dfrn:unlisted', $item['private'] == Item::UNLISTED);
|
||||
}
|
||||
|
||||
if ($item['extid']) {
|
||||
XML::addElement($doc, $entry, "dfrn:extid", $item['extid']);
|
||||
XML::addElement($doc, $entry, 'dfrn:extid', $item['extid']);
|
||||
}
|
||||
|
||||
if ($item['post-type'] == Item::PT_PAGE) {
|
||||
XML::addElement($doc, $entry, "dfrn:bookmark", "true");
|
||||
XML::addElement($doc, $entry, 'dfrn:bookmark', 'true');
|
||||
}
|
||||
|
||||
if ($item['app']) {
|
||||
XML::addElement($doc, $entry, "statusnet:notice_info", "", ["local_id" => $item['id'], "source" => $item['app']]);
|
||||
XML::addElement($doc, $entry, 'statusnet:notice_info', '', ['local_id' => $item['id'], 'source' => $item['app']]);
|
||||
}
|
||||
|
||||
XML::addElement($doc, $entry, "dfrn:diaspora_guid", $item["guid"]);
|
||||
XML::addElement($doc, $entry, 'dfrn:diaspora_guid', $item['guid']);
|
||||
|
||||
// The signed text contains the content in Markdown, the sender handle and the signatur for the content
|
||||
// It is needed for relayed comments to Diaspora.
|
||||
if ($item['signed_text']) {
|
||||
$sign = base64_encode(json_encode(['signed_text' => $item['signed_text'],'signature' => '','signer' => '']));
|
||||
XML::addElement($doc, $entry, "dfrn:diaspora_signature", $sign);
|
||||
XML::addElement($doc, $entry, 'dfrn:diaspora_signature', $sign);
|
||||
}
|
||||
|
||||
XML::addElement($doc, $entry, "activity:verb", self::constructVerb($item));
|
||||
XML::addElement($doc, $entry, 'activity:verb', self::constructVerb($item));
|
||||
|
||||
if ($item['object-type'] != "") {
|
||||
XML::addElement($doc, $entry, "activity:object-type", $item['object-type']);
|
||||
if ($item['object-type'] != '') {
|
||||
XML::addElement($doc, $entry, 'activity:object-type', $item['object-type']);
|
||||
} elseif ($item['gravity'] == GRAVITY_PARENT) {
|
||||
XML::addElement($doc, $entry, "activity:object-type", Activity\ObjectType::NOTE);
|
||||
XML::addElement($doc, $entry, 'activity:object-type', Activity\ObjectType::NOTE);
|
||||
} else {
|
||||
XML::addElement($doc, $entry, "activity:object-type", Activity\ObjectType::COMMENT);
|
||||
XML::addElement($doc, $entry, 'activity:object-type', Activity\ObjectType::COMMENT);
|
||||
}
|
||||
|
||||
$actobj = self::createActivity($doc, "activity:object", $item['object'] ?? '', $item['uri-id']);
|
||||
$actobj = self::createActivity($doc, 'activity:object', $item['object'] ?? '', $item['uri-id']);
|
||||
if ($actobj) {
|
||||
$entry->appendChild($actobj);
|
||||
}
|
||||
|
||||
$actarg = self::createActivity($doc, "activity:target", $item['target'] ?? '', $item['uri-id']);
|
||||
$actarg = self::createActivity($doc, 'activity:target', $item['target'] ?? '', $item['uri-id']);
|
||||
if ($actarg) {
|
||||
$entry->appendChild($actarg);
|
||||
}
|
||||
|
|
@ -919,7 +924,7 @@ class DFRN
|
|||
if (count($tags)) {
|
||||
foreach ($tags as $tag) {
|
||||
if (($type != 'html') || ($tag['type'] == Tag::HASHTAG)) {
|
||||
XML::addElement($doc, $entry, "category", "", ["scheme" => "X-DFRN:" . Tag::TAG_CHARACTER[$tag['type']] . ":" . $tag['url'], "term" => $tag['name']]);
|
||||
XML::addElement($doc, $entry, 'category', '', ['scheme' => 'X-DFRN:' . Tag::TAG_CHARACTER[$tag['type']] . ':' . $tag['url'], 'term' => $tag['name']]);
|
||||
}
|
||||
if ($tag['type'] != Tag::HASHTAG) {
|
||||
$mentioned[$tag['url']] = $tag['url'];
|
||||
|
|
@ -928,28 +933,32 @@ class DFRN
|
|||
}
|
||||
|
||||
foreach ($mentioned as $mention) {
|
||||
$condition = ['uid' => $owner["uid"], 'nurl' => Strings::normaliseLink($mention)];
|
||||
$condition = ['uid' => $owner['uid'], 'nurl' => Strings::normaliseLink($mention)];
|
||||
$contact = DBA::selectFirst('contact', ['contact-type'], $condition);
|
||||
|
||||
if (DBA::isResult($contact) && ($contact['contact-type'] == Contact::TYPE_COMMUNITY)) {
|
||||
XML::addElement(
|
||||
$doc,
|
||||
$entry,
|
||||
"link",
|
||||
"",
|
||||
["rel" => "mentioned",
|
||||
"ostatus:object-type" => Activity\ObjectType::GROUP,
|
||||
"href" => $mention]
|
||||
'link',
|
||||
'',
|
||||
[
|
||||
'rel' => 'mentioned',
|
||||
'ostatus:object-type' => Activity\ObjectType::GROUP,
|
||||
'href' => $mention,
|
||||
],
|
||||
);
|
||||
} else {
|
||||
XML::addElement(
|
||||
$doc,
|
||||
$entry,
|
||||
"link",
|
||||
"",
|
||||
["rel" => "mentioned",
|
||||
"ostatus:object-type" => Activity\ObjectType::PERSON,
|
||||
"href" => $mention]
|
||||
'link',
|
||||
'',
|
||||
[
|
||||
'rel' => 'mentioned',
|
||||
'ostatus:object-type' => Activity\ObjectType::PERSON,
|
||||
'href' => $mention,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -999,22 +1008,22 @@ class DFRN
|
|||
$envelope = Diaspora::buildMessage($atom, $owner, $contact, $owner['uprvkey'], $pubkey, $public_batch);
|
||||
|
||||
// Create the endpoint for public posts. This is some WIP and should later be added to the probing
|
||||
if ($public_batch && empty($contact["batch"])) {
|
||||
$parts = parse_url($contact["notify"]);
|
||||
if ($public_batch && empty($contact['batch'])) {
|
||||
$parts = parse_url($contact['notify']);
|
||||
$path_parts = explode('/', $parts['path']);
|
||||
array_pop($path_parts);
|
||||
$parts['path'] = implode('/', $path_parts);
|
||||
$contact["batch"] = Network::unparseURL($parts);
|
||||
$contact['batch'] = Network::unparseURL($parts);
|
||||
}
|
||||
|
||||
$dest_url = ($public_batch ? $contact["batch"] : $contact["notify"]);
|
||||
$dest_url = ($public_batch ? $contact['batch'] : $contact['notify']);
|
||||
|
||||
if (empty($dest_url)) {
|
||||
Logger::info('Empty destination', ['public' => $public_batch, 'contact' => $contact]);
|
||||
return -24;
|
||||
}
|
||||
|
||||
$content_type = ($public_batch ? "application/magic-envelope+xml" : "application/json");
|
||||
$content_type = ($public_batch ? 'application/magic-envelope+xml' : 'application/json');
|
||||
|
||||
$postResult = DI::httpClient()->post($dest_url, $envelope, ['Content-Type' => $content_type]);
|
||||
$xml = $postResult->getBody();
|
||||
|
|
@ -1331,28 +1340,27 @@ class DFRN
|
|||
/**
|
||||
* Processes the mail elements
|
||||
*
|
||||
* @param object $xpath XPath object
|
||||
* @param object $mail mail elements
|
||||
* @param array $importer Record of the importer user mixed with contact of the content
|
||||
* @param DOMXPath $xpath XPath object
|
||||
* @param DOMNode $mail mail elements
|
||||
* @param array $importer Record of the importer user mixed with contact of the content
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
* @todo Find good type-hints for all parameter
|
||||
*/
|
||||
private static function processMail($xpath, $mail, array $importer)
|
||||
private static function processMail(DOMXPath $xpath, DOMNode $mail, array $importer)
|
||||
{
|
||||
Logger::notice("Processing mails");
|
||||
|
||||
$msg = [];
|
||||
$msg["uid"] = $importer["importer_uid"];
|
||||
$msg["from-name"] = XML::getFirstValue($xpath, "dfrn:sender/dfrn:name/text()", $mail);
|
||||
$msg["from-url"] = XML::getFirstValue($xpath, "dfrn:sender/dfrn:uri/text()", $mail);
|
||||
$msg["from-photo"] = XML::getFirstValue($xpath, "dfrn:sender/dfrn:avatar/text()", $mail);
|
||||
$msg["contact-id"] = $importer["id"];
|
||||
$msg["uri"] = XML::getFirstValue($xpath, "dfrn:id/text()", $mail);
|
||||
$msg["parent-uri"] = XML::getFirstValue($xpath, "dfrn:in-reply-to/text()", $mail);
|
||||
$msg["created"] = DateTimeFormat::utc(XML::getFirstValue($xpath, "dfrn:sentdate/text()", $mail));
|
||||
$msg["title"] = XML::getFirstValue($xpath, "dfrn:subject/text()", $mail);
|
||||
$msg["body"] = XML::getFirstValue($xpath, "dfrn:content/text()", $mail);
|
||||
$msg['uid'] = $importer['importer_uid'];
|
||||
$msg['from-name'] = XML::getFirstValue($xpath, 'dfrn:sender/dfrn:name/text()', $mail);
|
||||
$msg['from-url'] = XML::getFirstValue($xpath, 'dfrn:sender/dfrn:uri/text()', $mail);
|
||||
$msg['from-photo'] = XML::getFirstValue($xpath, 'dfrn:sender/dfrn:avatar/text()', $mail);
|
||||
$msg['contact-id'] = $importer['id'];
|
||||
$msg['uri'] = XML::getFirstValue($xpath, 'dfrn:id/text()', $mail);
|
||||
$msg['parent-uri'] = XML::getFirstValue($xpath, 'dfrn:in-reply-to/text()', $mail);
|
||||
$msg['created'] = DateTimeFormat::utc(XML::getFirstValue($xpath, 'dfrn:sentdate/text()', $mail));
|
||||
$msg['title'] = XML::getFirstValue($xpath, 'dfrn:subject/text()', $mail);
|
||||
$msg['body'] = XML::getFirstValue($xpath, 'dfrn:content/text()', $mail);
|
||||
|
||||
Mail::insert($msg);
|
||||
}
|
||||
|
|
@ -1360,14 +1368,13 @@ class DFRN
|
|||
/**
|
||||
* Processes the suggestion elements
|
||||
*
|
||||
* @param object $xpath XPath object
|
||||
* @param object $suggestion suggestion elements
|
||||
* @param array $importer Record of the importer user mixed with contact of the content
|
||||
* @param DOMXPath $xpath XPath object
|
||||
* @param DOMNode $suggestion suggestion elements
|
||||
* @param array $importer Record of the importer user mixed with contact of the content
|
||||
* @return boolean
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @todo Find good type-hints for all parameter
|
||||
*/
|
||||
private static function processSuggestion($xpath, $suggestion, array $importer)
|
||||
private static function processSuggestion(DOMXPath $xpath, DOMNode $suggestion, array $importer)
|
||||
{
|
||||
Logger::notice('Processing suggestions');
|
||||
|
||||
|
|
@ -1435,45 +1442,45 @@ class DFRN
|
|||
/**
|
||||
* Processes the relocation elements
|
||||
*
|
||||
* @param object $xpath XPath object
|
||||
* @param object $relocation relocation elements
|
||||
* @param array $importer Record of the importer user mixed with contact of the content
|
||||
* @param DOMXPath $xpath XPath object
|
||||
* @param DOMNode $relocation relocation elements
|
||||
* @param array $importer Record of the importer user mixed with contact of the content
|
||||
* @return boolean
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
* @todo Find good type-hints for all parameter
|
||||
*/
|
||||
private static function processRelocation($xpath, $relocation, array $importer): bool
|
||||
private static function processRelocation(DOMXPath $xpath, DOMNode $relocation, array $importer): bool
|
||||
{
|
||||
Logger::notice("Processing relocations");
|
||||
|
||||
/// @TODO Rewrite this to one statement
|
||||
$relocate = [];
|
||||
$relocate["uid"] = $importer["importer_uid"];
|
||||
$relocate["cid"] = $importer["id"];
|
||||
$relocate["url"] = $xpath->query("dfrn:url/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["addr"] = $xpath->query("dfrn:addr/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["name"] = $xpath->query("dfrn:name/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["avatar"] = $xpath->query("dfrn:avatar/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["photo"] = $xpath->query("dfrn:photo/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["thumb"] = $xpath->query("dfrn:thumb/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["micro"] = $xpath->query("dfrn:micro/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["request"] = $xpath->query("dfrn:request/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["confirm"] = $xpath->query("dfrn:confirm/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["notify"] = $xpath->query("dfrn:notify/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["poll"] = $xpath->query("dfrn:poll/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate["sitepubkey"] = $xpath->query("dfrn:sitepubkey/text()", $relocation)->item(0)->nodeValue;
|
||||
$relocate['uid'] = $importer['importer_uid'];
|
||||
$relocate['cid'] = $importer['id'];
|
||||
$relocate['url'] = $xpath->query('dfrn:url/text()', $relocation)->item(0)->nodeValue;
|
||||
$relocate['addr'] = $xpath->query('dfrn:addr/text()', $relocation)->item(0)->nodeValue;
|
||||
$relocate['name'] = $xpath->query('dfrn:name/text()', $relocation)->item(0)->nodeValue;
|
||||
$relocate['avatar'] = $xpath->query('dfrn:avatar/text()', $relocation)->item(0)->nodeValue;
|
||||
$relocate['photo'] = $xpath->query('dfrn:photo/text()', $relocation)->item(0)->nodeValue;
|
||||
$relocate['thumb'] = $xpath->query('dfrn:thumb/text()', $relocation)->item(0)->nodeValue;
|
||||
$relocate['micro'] = $xpath->query('dfrn:micro/text()', $relocation)->item(0)->nodeValue;
|
||||
$relocate['request'] = $xpath->query('dfrn:request/text()', $relocation)->item(0)->nodeValue;
|
||||
$relocate['confirm'] = $xpath->query('dfrn:confirm/text()', $relocation)->item(0)->nodeValue;
|
||||
$relocate['notify'] = $xpath->query('dfrn:notify/text()', $relocation)->item(0)->nodeValue;
|
||||
$relocate['poll'] = $xpath->query('dfrn:poll/text()', $relocation)->item(0)->nodeValue;
|
||||
$relocate['sitepubkey'] = $xpath->query('dfrn:sitepubkey/text()', $relocation)->item(0)->nodeValue;
|
||||
|
||||
if (($relocate["avatar"] == "") && ($relocate["photo"] != "")) {
|
||||
$relocate["avatar"] = $relocate["photo"];
|
||||
if (($relocate['avatar'] == '') && ($relocate['photo'] != '')) {
|
||||
$relocate['avatar'] = $relocate['photo'];
|
||||
}
|
||||
|
||||
if ($relocate["addr"] == "") {
|
||||
$relocate["addr"] = preg_replace("=(https?://)(.*)/profile/(.*)=ism", "$3@$2", $relocate["url"]);
|
||||
if ($relocate['addr'] == '') {
|
||||
$relocate['addr'] = preg_replace("=(https?://)(.*)/profile/(.*)=ism", '$3@$2', $relocate['url']);
|
||||
}
|
||||
|
||||
// update contact
|
||||
$old = Contact::selectFirst(['photo', 'url'], ['id' => $importer["id"], 'uid' => $importer["importer_uid"]]);
|
||||
$old = Contact::selectFirst(['photo', 'url'], ['id' => $importer['id'], 'uid' => $importer['importer_uid']]);
|
||||
|
||||
if (!DBA::isResult($old)) {
|
||||
Logger::notice("Query failed to execute, no result returned in " . __FUNCTION__);
|
||||
|
|
@ -1481,16 +1488,23 @@ class DFRN
|
|||
}
|
||||
|
||||
// Update the contact table. We try to find every entry.
|
||||
$fields = ['name' => $relocate["name"], 'avatar' => $relocate["avatar"],
|
||||
'url' => $relocate["url"], 'nurl' => Strings::normaliseLink($relocate["url"]),
|
||||
'addr' => $relocate["addr"], 'request' => $relocate["request"],
|
||||
'confirm' => $relocate["confirm"], 'notify' => $relocate["notify"],
|
||||
'poll' => $relocate["poll"], 'site-pubkey' => $relocate["sitepubkey"]];
|
||||
$condition = ["(`id` = ?) OR (`nurl` = ?)", $importer["id"], Strings::normaliseLink($old["url"])];
|
||||
$fields = [
|
||||
'name' => $relocate['name'],
|
||||
'avatar' => $relocate['avatar'],
|
||||
'url' => $relocate['url'],
|
||||
'nurl' => Strings::normaliseLink($relocate['url']),
|
||||
'addr' => $relocate['addr'],
|
||||
'request' => $relocate['request'],
|
||||
'confirm' => $relocate['confirm'],
|
||||
'notify' => $relocate['notify'],
|
||||
'poll' => $relocate['poll'],
|
||||
'site-pubkey' => $relocate['sitepubkey'],
|
||||
];
|
||||
$condition = ["(`id` = ?) OR (`nurl` = ?)", $importer['id'], Strings::normaliseLink($old['url'])];
|
||||
|
||||
Contact::update($fields, $condition);
|
||||
|
||||
Contact::updateAvatar($importer["id"], $relocate["avatar"], true);
|
||||
Contact::updateAvatar($importer['id'], $relocate['avatar'], true);
|
||||
|
||||
Logger::notice('Contacts are updated.');
|
||||
|
||||
|
|
@ -1519,15 +1533,18 @@ class DFRN
|
|||
|
||||
if (self::isEditedTimestampNewer($current, $item)) {
|
||||
// do not accept (ignore) an earlier edit than one we currently have.
|
||||
if (DateTimeFormat::utc($item["edited"]) < $current["edited"]) {
|
||||
if (DateTimeFormat::utc($item['edited']) < $current['edited']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$fields = ['title' => $item['title'] ?? '', 'body' => $item['body'] ?? '',
|
||||
'changed' => DateTimeFormat::utcNow(),
|
||||
'edited' => DateTimeFormat::utc($item["edited"])];
|
||||
$fields = [
|
||||
'title' => $item['title'] ?? '',
|
||||
'body' => $item['body'] ?? '',
|
||||
'changed' => DateTimeFormat::utcNow(),
|
||||
'edited' => DateTimeFormat::utc($item['edited']),
|
||||
];
|
||||
|
||||
$condition = ["`uri` = ? AND `uid` IN (0, ?)", $item["uri"], $importer["importer_uid"]];
|
||||
$condition = ["`uri` = ? AND `uid` IN (0, ?)", $item['uri'], $importer['importer_uid']];
|
||||
Item::update($fields, $condition);
|
||||
|
||||
$changed = true;
|
||||
|
|
@ -1547,11 +1564,11 @@ class DFRN
|
|||
*/
|
||||
private static function getEntryType(array $importer, array $item): int
|
||||
{
|
||||
if ($item["thr-parent"] != $item["uri"]) {
|
||||
if ($item['thr-parent'] != $item['uri']) {
|
||||
$community = false;
|
||||
|
||||
if ($importer['account-type'] == User::ACCOUNT_TYPE_COMMUNITY) {
|
||||
$sql_extra = "";
|
||||
$sql_extra = '';
|
||||
$community = true;
|
||||
Logger::notice("possible community action");
|
||||
} else {
|
||||
|
|
@ -1561,7 +1578,7 @@ class DFRN
|
|||
// was the top-level post for this action written by somebody on this site?
|
||||
// Specifically, the recipient?
|
||||
$parent = Post::selectFirst(['wall'],
|
||||
["`uri` = ? AND `uid` = ?" . $sql_extra, $item["thr-parent"], $importer["importer_uid"]]);
|
||||
["`uri` = ? AND `uid` = ?" . $sql_extra, $item['thr-parent'], $importer['importer_uid']]);
|
||||
|
||||
$is_a_remote_action = DBA::isResult($parent);
|
||||
|
||||
|
|
@ -1586,43 +1603,44 @@ class DFRN
|
|||
*/
|
||||
private static function doPoke(array $item, array $importer)
|
||||
{
|
||||
$verb = urldecode(substr($item["verb"], strpos($item["verb"], "#")+1));
|
||||
$verb = urldecode(substr($item['verb'], strpos($item['verb'], '#')+1));
|
||||
if (!$verb) {
|
||||
return;
|
||||
}
|
||||
$xo = XML::parseString($item["object"]);
|
||||
$xo = XML::parseString($item['object']);
|
||||
|
||||
if (($xo->type == Activity\ObjectType::PERSON) && ($xo->id)) {
|
||||
// somebody was poked/prodded. Was it me?
|
||||
$Blink = '';
|
||||
foreach ($xo->link as $l) {
|
||||
$atts = $l->attributes();
|
||||
switch ($atts["rel"]) {
|
||||
case "alternate":
|
||||
$Blink = $atts["href"];
|
||||
switch ($atts['rel']) {
|
||||
case 'alternate':
|
||||
$Blink = $atts['href'];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($Blink && Strings::compareLink($Blink, DI::baseUrl() . "/profile/" . $importer["nickname"])) {
|
||||
if ($Blink && Strings::compareLink($Blink, DI::baseUrl() . '/profile/' . $importer['nickname'])) {
|
||||
$author = DBA::selectFirst('contact', ['id', 'name', 'thumb', 'url'], ['id' => $item['author-id']]);
|
||||
|
||||
$parent = Post::selectFirst(['id'], ['uri' => $item['thr-parent'], 'uid' => $importer["importer_uid"]]);
|
||||
$parent = Post::selectFirst(['id'], ['uri' => $item['thr-parent'], 'uid' => $importer['importer_uid']]);
|
||||
$item['parent'] = $parent['id'];
|
||||
|
||||
// send a notification
|
||||
DI::notify()->createFromArray(
|
||||
[
|
||||
"type" => Notification\Type::POKE,
|
||||
"otype" => Notification\ObjectType::PERSON,
|
||||
"activity" => $verb,
|
||||
"verb" => $item["verb"],
|
||||
"uid" => $importer["importer_uid"],
|
||||
"cid" => $author["id"],
|
||||
"item" => $item,
|
||||
"link" => DI::baseUrl() . "/display/" . urlencode($item['guid']),
|
||||
'type' => Notification\Type::POKE,
|
||||
'otype' => Notification\ObjectType::PERSON,
|
||||
'activity' => $verb,
|
||||
'verb' => $item['verb'],
|
||||
'uid' => $importer['importer_uid'],
|
||||
'cid' => $author['id'],
|
||||
'item' => $item,
|
||||
'link' => DI::baseUrl() . '/display/' . urlencode($item['guid']),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
@ -1639,11 +1657,10 @@ class DFRN
|
|||
*
|
||||
* @return bool Should the processing of the entries be continued?
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @todo set proper type-hints (array?)
|
||||
*/
|
||||
private static function processVerbs(int $entrytype, array $importer, array &$item, bool &$is_like)
|
||||
{
|
||||
Logger::info("Process verb ".$item["verb"]." and object-type ".$item["object-type"]." for entrytype ".$entrytype);
|
||||
Logger::info('Process verb ' . $item['verb'] . ' and object-type ' . $item['object-type'] . ' for entrytype ' . $entrytype);
|
||||
|
||||
if (($entrytype == DFRN::TOP_LEVEL) && !empty($importer['id'])) {
|
||||
// The filling of the the "contact" variable is done for legcy reasons
|
||||
|
|
@ -1654,65 +1671,70 @@ class DFRN
|
|||
|
||||
// Big question: Do we need these functions? They were part of the "consume_feed" function.
|
||||
// This function once was responsible for DFRN and OStatus.
|
||||
if ($activity->match($item["verb"], Activity::FOLLOW)) {
|
||||
if ($activity->match($item['verb'], Activity::FOLLOW)) {
|
||||
Logger::notice("New follower");
|
||||
Contact::addRelationship($importer, $contact, $item);
|
||||
return false;
|
||||
}
|
||||
if ($activity->match($item["verb"], Activity::UNFOLLOW)) {
|
||||
if ($activity->match($item['verb'], Activity::UNFOLLOW)) {
|
||||
Logger::notice("Lost follower");
|
||||
Contact::removeFollower($contact);
|
||||
return false;
|
||||
}
|
||||
if ($activity->match($item["verb"], Activity::REQ_FRIEND)) {
|
||||
if ($activity->match($item['verb'], Activity::REQ_FRIEND)) {
|
||||
Logger::notice("New friend request");
|
||||
Contact::addRelationship($importer, $contact, $item, true);
|
||||
return false;
|
||||
}
|
||||
if ($activity->match($item["verb"], Activity::UNFRIEND)) {
|
||||
if ($activity->match($item['verb'], Activity::UNFRIEND)) {
|
||||
Logger::notice("Lost sharer");
|
||||
Contact::removeSharer($contact);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (($item["verb"] == Activity::LIKE)
|
||||
|| ($item["verb"] == Activity::DISLIKE)
|
||||
|| ($item["verb"] == Activity::ATTEND)
|
||||
|| ($item["verb"] == Activity::ATTENDNO)
|
||||
|| ($item["verb"] == Activity::ATTENDMAYBE)
|
||||
|| ($item["verb"] == Activity::ANNOUNCE)
|
||||
if (($item['verb'] == Activity::LIKE)
|
||||
|| ($item['verb'] == Activity::DISLIKE)
|
||||
|| ($item['verb'] == Activity::ATTEND)
|
||||
|| ($item['verb'] == Activity::ATTENDNO)
|
||||
|| ($item['verb'] == Activity::ATTENDMAYBE)
|
||||
|| ($item['verb'] == Activity::ANNOUNCE)
|
||||
) {
|
||||
$is_like = true;
|
||||
$item["gravity"] = GRAVITY_ACTIVITY;
|
||||
$item['gravity'] = GRAVITY_ACTIVITY;
|
||||
// only one like or dislike per person
|
||||
// split into two queries for performance issues
|
||||
$condition = ['uid' => $item["uid"], 'author-id' => $item["author-id"], 'gravity' => GRAVITY_ACTIVITY,
|
||||
'verb' => $item['verb'], 'parent-uri' => $item['thr-parent']];
|
||||
$condition = [
|
||||
'uid' => $item['uid'],
|
||||
'author-id' => $item['author-id'],
|
||||
'gravity' => GRAVITY_ACTIVITY,
|
||||
'verb' => $item['verb'],
|
||||
'parent-uri' => $item['thr-parent'],
|
||||
];
|
||||
if (Post::exists($condition)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$condition = ['uid' => $item["uid"], 'author-id' => $item["author-id"], 'gravity' => GRAVITY_ACTIVITY,
|
||||
$condition = ['uid' => $item['uid'], 'author-id' => $item['author-id'], 'gravity' => GRAVITY_ACTIVITY,
|
||||
'verb' => $item['verb'], 'thr-parent' => $item['thr-parent']];
|
||||
if (Post::exists($condition)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The owner of an activity must be the author
|
||||
$item["owner-name"] = $item["author-name"];
|
||||
$item["owner-link"] = $item["author-link"];
|
||||
$item["owner-avatar"] = $item["author-avatar"];
|
||||
$item["owner-id"] = $item["author-id"];
|
||||
$item['owner-name'] = $item['author-name'];
|
||||
$item['owner-link'] = $item['author-link'];
|
||||
$item['owner-avatar'] = $item['author-avatar'];
|
||||
$item['owner-id'] = $item['author-id'];
|
||||
} else {
|
||||
$is_like = false;
|
||||
}
|
||||
|
||||
if (($item["verb"] == Activity::TAG) && ($item["object-type"] == Activity\ObjectType::TAGTERM)) {
|
||||
$xo = XML::parseString($item["object"]);
|
||||
$xt = XML::parseString($item["target"]);
|
||||
if (($item['verb'] == Activity::TAG) && ($item['object-type'] == Activity\ObjectType::TAGTERM)) {
|
||||
$xo = XML::parseString($item['object']);
|
||||
$xt = XML::parseString($item['target']);
|
||||
|
||||
if ($xt->type == Activity\ObjectType::NOTE) {
|
||||
$item_tag = Post::selectFirst(['id', 'uri-id'], ['uri' => $xt->id, 'uid' => $importer["importer_uid"]]);
|
||||
$item_tag = Post::selectFirst(['id', 'uri-id'], ['uri' => $xt->id, 'uid' => $importer['importer_uid']]);
|
||||
|
||||
if (!DBA::isResult($item_tag)) {
|
||||
Logger::notice("Query failed to execute, no result returned in " . __FUNCTION__);
|
||||
|
|
@ -1739,27 +1761,28 @@ class DFRN
|
|||
*/
|
||||
private static function parseLinks($links, array &$item)
|
||||
{
|
||||
$rel = "";
|
||||
$href = "";
|
||||
$rel = '';
|
||||
$href = '';
|
||||
$type = null;
|
||||
$length = null;
|
||||
$title = null;
|
||||
foreach ($links as $link) {
|
||||
foreach ($link->attributes as $attributes) {
|
||||
switch ($attributes->name) {
|
||||
case "href" : $href = $attributes->textContent; break;
|
||||
case "rel" : $rel = $attributes->textContent; break;
|
||||
case "type" : $type = $attributes->textContent; break;
|
||||
case "length": $length = $attributes->textContent; break;
|
||||
case "title" : $title = $attributes->textContent; break;
|
||||
case 'href' : $href = $attributes->textContent; break;
|
||||
case 'rel' : $rel = $attributes->textContent; break;
|
||||
case 'type' : $type = $attributes->textContent; break;
|
||||
case 'length': $length = $attributes->textContent; break;
|
||||
case 'title' : $title = $attributes->textContent; break;
|
||||
}
|
||||
}
|
||||
if (($rel != "") && ($href != "")) {
|
||||
if (($rel != '') && ($href != '')) {
|
||||
switch ($rel) {
|
||||
case "alternate":
|
||||
$item["plink"] = $href;
|
||||
case 'alternate':
|
||||
$item['plink'] = $href;
|
||||
break;
|
||||
case "enclosure":
|
||||
|
||||
case 'enclosure':
|
||||
Post\Media::insert(['uri-id' => $item['uri-id'], 'type' => Post\Media::DOCUMENT,
|
||||
'url' => $href, 'mimetype' => $type, 'size' => $length, 'description' => $title]);
|
||||
break;
|
||||
|
|
@ -1805,162 +1828,159 @@ class DFRN
|
|||
/**
|
||||
* Processes the entry elements which contain the items and comments
|
||||
*
|
||||
* @param array $header Array of the header elements that always stay the same
|
||||
* @param object $xpath XPath object
|
||||
* @param object $entry entry elements
|
||||
* @param array $importer Record of the importer user mixed with contact of the content
|
||||
* @param string $xml xml
|
||||
* @param array $header Array of the header elements that always stay the same
|
||||
* @param DOMXPath $xpath XPath object
|
||||
* @param DOMNode $entry entry elements
|
||||
* @param array $importer Record of the importer user mixed with contact of the content
|
||||
* @param string $xml XML
|
||||
* @param int $protocol Protocol
|
||||
* @return void
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
* @todo Add type-hints
|
||||
*/
|
||||
private static function processEntry(array $header, $xpath, $entry, array $importer, string $xml, int $protocol)
|
||||
private static function processEntry(array $header, DOMXPath $xpath, DOMNode $entry, array $importer, string $xml, int $protocol)
|
||||
{
|
||||
Logger::notice("Processing entries");
|
||||
|
||||
$item = $header;
|
||||
|
||||
$item["protocol"] = $protocol;
|
||||
$item['protocol'] = $protocol;
|
||||
|
||||
$item["source"] = $xml;
|
||||
$item['source'] = $xml;
|
||||
|
||||
// Get the uri
|
||||
$item["uri"] = XML::getFirstNodeValue($xpath, "atom:id/text()", $entry);
|
||||
$item['uri'] = XML::getFirstNodeValue($xpath, 'atom:id/text()', $entry);
|
||||
|
||||
$item["edited"] = XML::getFirstNodeValue($xpath, "atom:updated/text()", $entry);
|
||||
$item['edited'] = XML::getFirstNodeValue($xpath, 'atom:updated/text()', $entry);
|
||||
|
||||
$current = Post::selectFirst(['id', 'uid', 'edited', 'body'],
|
||||
['uri' => $item["uri"], 'uid' => $importer["importer_uid"]]
|
||||
['uri' => $item['uri'], 'uid' => $importer['importer_uid']]
|
||||
);
|
||||
// Is there an existing item?
|
||||
if (DBA::isResult($current) && !self::isEditedTimestampNewer($current, $item)) {
|
||||
Logger::info("Item ".$item["uri"]." (".$item['edited'].") already existed.");
|
||||
Logger::info("Item " . $item['uri'] . " (" . $item['edited'] . ") already existed.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch the owner
|
||||
$owner = self::fetchauthor($xpath, $entry, $importer, "dfrn:owner", true, $xml);
|
||||
$owner = self::fetchauthor($xpath, $entry, $importer, 'dfrn:owner', true, $xml);
|
||||
|
||||
$owner_unknown = (isset($owner["contact-unknown"]) && $owner["contact-unknown"]);
|
||||
$owner_unknown = (isset($owner['contact-unknown']) && $owner['contact-unknown']);
|
||||
|
||||
$item["owner-name"] = $owner["name"];
|
||||
$item["owner-link"] = $owner["link"];
|
||||
$item["owner-avatar"] = $owner["avatar"];
|
||||
$item["owner-id"] = Contact::getIdForURL($owner["link"], 0);
|
||||
$item['owner-name'] = $owner['name'];
|
||||
$item['owner-link'] = $owner['link'];
|
||||
$item['owner-avatar'] = $owner['avatar'];
|
||||
$item['owner-id'] = Contact::getIdForURL($owner['link'], 0);
|
||||
|
||||
// fetch the author
|
||||
$author = self::fetchauthor($xpath, $entry, $importer, "atom:author", true, $xml);
|
||||
$author = self::fetchauthor($xpath, $entry, $importer, 'atom:author', true, $xml);
|
||||
|
||||
$item["author-name"] = $author["name"];
|
||||
$item["author-link"] = $author["link"];
|
||||
$item["author-avatar"] = $author["avatar"];
|
||||
$item["author-id"] = Contact::getIdForURL($author["link"], 0);
|
||||
$item['author-name'] = $author['name'];
|
||||
$item['author-link'] = $author['link'];
|
||||
$item['author-avatar'] = $author['avatar'];
|
||||
$item['author-id'] = Contact::getIdForURL($author['link'], 0);
|
||||
|
||||
$item["title"] = XML::getFirstNodeValue($xpath, "atom:title/text()", $entry);
|
||||
$item['title'] = XML::getFirstNodeValue($xpath, 'atom:title/text()', $entry);
|
||||
|
||||
if (!empty($item["title"])) {
|
||||
$item["post-type"] = Item::PT_ARTICLE;
|
||||
if (!empty($item['title'])) {
|
||||
$item['post-type'] = Item::PT_ARTICLE;
|
||||
} else {
|
||||
$item["post-type"] = Item::PT_NOTE;
|
||||
$item['post-type'] = Item::PT_NOTE;
|
||||
}
|
||||
|
||||
$item["created"] = XML::getFirstNodeValue($xpath, "atom:published/text()", $entry);
|
||||
$item['created'] = XML::getFirstNodeValue($xpath, 'atom:published/text()', $entry);
|
||||
|
||||
$item["body"] = XML::getFirstNodeValue($xpath, "dfrn:env/text()", $entry);
|
||||
$item["body"] = str_replace([' ',"\t","\r","\n"], ['','','',''], $item["body"]);
|
||||
$item['body'] = XML::getFirstNodeValue($xpath, 'dfrn:env/text()', $entry);
|
||||
$item['body'] = str_replace([' ',"\t","\r","\n"], ['','','',''], $item['body']);
|
||||
|
||||
$item["body"] = Strings::base64UrlDecode($item["body"]);
|
||||
$item['body'] = Strings::base64UrlDecode($item['body']);
|
||||
|
||||
$item["body"] = BBCode::limitBodySize($item["body"]);
|
||||
$item['body'] = BBCode::limitBodySize($item['body']);
|
||||
|
||||
/// @todo We should check for a repeated post and if we know the repeated author.
|
||||
|
||||
// We don't need the content element since "dfrn:env" is always present
|
||||
//$item["body"] = $xpath->query("atom:content/text()", $entry)->item(0)->nodeValue;
|
||||
//$item['body'] = $xpath->query('atom:content/text()', $entry)->item(0)->nodeValue;
|
||||
$item['location'] = XML::getFirstNodeValue($xpath, 'dfrn:location/text()', $entry);
|
||||
$item['coord'] = XML::getFirstNodeValue($xpath, 'georss:point', $entry);
|
||||
$item['private'] = XML::getFirstNodeValue($xpath, 'dfrn:private/text()', $entry);
|
||||
|
||||
$item["location"] = XML::getFirstNodeValue($xpath, "dfrn:location/text()", $entry);
|
||||
|
||||
$item["coord"] = XML::getFirstNodeValue($xpath, "georss:point", $entry);
|
||||
|
||||
$item["private"] = XML::getFirstNodeValue($xpath, "dfrn:private/text()", $entry);
|
||||
|
||||
$unlisted = XML::getFirstNodeValue($xpath, "dfrn:unlisted/text()", $entry);
|
||||
$unlisted = XML::getFirstNodeValue($xpath, 'dfrn:unlisted/text()', $entry);
|
||||
if (!empty($unlisted) && ($item['private'] != Item::PRIVATE)) {
|
||||
$item['private'] = Item::UNLISTED;
|
||||
}
|
||||
|
||||
$item["extid"] = XML::getFirstNodeValue($xpath, "dfrn:extid/text()", $entry);
|
||||
$item['extid'] = XML::getFirstNodeValue($xpath, 'dfrn:extid/text()', $entry);
|
||||
|
||||
if (XML::getFirstNodeValue($xpath, "dfrn:bookmark/text()", $entry) == "true") {
|
||||
$item["post-type"] = Item::PT_PAGE;
|
||||
if (XML::getFirstNodeValue($xpath, 'dfrn:bookmark/text()', $entry) == 'true') {
|
||||
$item['post-type'] = Item::PT_PAGE;
|
||||
}
|
||||
|
||||
$notice_info = $xpath->query("statusnet:notice_info", $entry);
|
||||
$notice_info = $xpath->query('statusnet:notice_info', $entry);
|
||||
if ($notice_info && ($notice_info->length > 0)) {
|
||||
foreach ($notice_info->item(0)->attributes as $attributes) {
|
||||
if ($attributes->name == "source") {
|
||||
$item["app"] = strip_tags($attributes->textContent);
|
||||
if ($attributes->name == 'source') {
|
||||
$item['app'] = strip_tags($attributes->textContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$item["guid"] = XML::getFirstNodeValue($xpath, "dfrn:diaspora_guid/text()", $entry);
|
||||
$item['guid'] = XML::getFirstNodeValue($xpath, 'dfrn:diaspora_guid/text()', $entry);
|
||||
|
||||
$item['uri-id'] = ItemURI::insert(['uri' => $item['uri'], 'guid' => $item['guid']]);
|
||||
|
||||
$item["body"] = Item::improveSharedDataInBody($item);
|
||||
$item['body'] = Item::improveSharedDataInBody($item);
|
||||
|
||||
Tag::storeFromBody($item['uri-id'], $item["body"]);
|
||||
Tag::storeFromBody($item['uri-id'], $item['body']);
|
||||
|
||||
// We store the data from "dfrn:diaspora_signature" in a different table, this is done in "Item::insert"
|
||||
$dsprsig = XML::unescape(XML::getFirstNodeValue($xpath, "dfrn:diaspora_signature/text()", $entry));
|
||||
if ($dsprsig != "") {
|
||||
$dsprsig = XML::unescape(XML::getFirstNodeValue($xpath, 'dfrn:diaspora_signature/text()', $entry));
|
||||
if ($dsprsig != '') {
|
||||
$signature = json_decode(base64_decode($dsprsig));
|
||||
// We don't store the old style signatures anymore that also contained the "signature" and "signer"
|
||||
if (!empty($signature->signed_text) && empty($signature->signature) && empty($signature->signer)) {
|
||||
$item["diaspora_signed_text"] = $signature->signed_text;
|
||||
$item['diaspora_signed_text'] = $signature->signed_text;
|
||||
}
|
||||
}
|
||||
|
||||
$item["verb"] = XML::getFirstNodeValue($xpath, "activity:verb/text()", $entry);
|
||||
$item['verb'] = XML::getFirstNodeValue($xpath, 'activity:verb/text()', $entry);
|
||||
|
||||
if (XML::getFirstNodeValue($xpath, "activity:object-type/text()", $entry) != "") {
|
||||
$item["object-type"] = XML::getFirstNodeValue($xpath, "activity:object-type/text()", $entry);
|
||||
if (XML::getFirstNodeValue($xpath, 'activity:object-type/text()', $entry) != '') {
|
||||
$item['object-type'] = XML::getFirstNodeValue($xpath, 'activity:object-type/text()', $entry);
|
||||
}
|
||||
|
||||
$object = $xpath->query("activity:object", $entry)->item(0);
|
||||
$item["object"] = self::transformActivity($xpath, $object, "object");
|
||||
$object = $xpath->query('activity:object', $entry)->item(0);
|
||||
$item['object'] = self::transformActivity($xpath, $object, 'object');
|
||||
|
||||
if (trim($item["object"]) != "") {
|
||||
$r = XML::parseString($item["object"]);
|
||||
if (trim($item['object']) != '') {
|
||||
$r = XML::parseString($item['object']);
|
||||
if (isset($r->type)) {
|
||||
$item["object-type"] = $r->type;
|
||||
$item['object-type'] = $r->type;
|
||||
}
|
||||
}
|
||||
|
||||
$target = $xpath->query("activity:target", $entry)->item(0);
|
||||
$item["target"] = self::transformActivity($xpath, $target, "target");
|
||||
$target = $xpath->query('activity:target', $entry)->item(0);
|
||||
$item['target'] = self::transformActivity($xpath, $target, 'target');
|
||||
|
||||
$categories = $xpath->query("atom:category", $entry);
|
||||
$categories = $xpath->query('atom:category', $entry);
|
||||
if ($categories) {
|
||||
foreach ($categories as $category) {
|
||||
$term = "";
|
||||
$scheme = "";
|
||||
$term = '';
|
||||
$scheme = '';
|
||||
foreach ($category->attributes as $attributes) {
|
||||
if ($attributes->name == "term") {
|
||||
if ($attributes->name == 'term') {
|
||||
$term = $attributes->textContent;
|
||||
}
|
||||
|
||||
if ($attributes->name == "scheme") {
|
||||
if ($attributes->name == 'scheme') {
|
||||
$scheme = $attributes->textContent;
|
||||
}
|
||||
}
|
||||
|
||||
if (($term != "") && ($scheme != "")) {
|
||||
$parts = explode(":", $scheme);
|
||||
if ((count($parts) >= 4) && (array_shift($parts) == "X-DFRN")) {
|
||||
if (($term != '') && ($scheme != '')) {
|
||||
$parts = explode(':', $scheme);
|
||||
if ((count($parts) >= 4) && (array_shift($parts) == 'X-DFRN')) {
|
||||
$termurl = array_pop($parts);
|
||||
$termurl = array_pop($parts) . ':' . $termurl;
|
||||
Tag::store($item['uri-id'], Tag::IMPLICIT_MENTION, $term, $termurl);
|
||||
|
|
@ -1969,7 +1989,7 @@ class DFRN
|
|||
}
|
||||
}
|
||||
|
||||
$links = $xpath->query("atom:link", $entry);
|
||||
$links = $xpath->query('atom:link', $entry);
|
||||
if ($links) {
|
||||
self::parseLinks($links, $item);
|
||||
}
|
||||
|
|
@ -1979,10 +1999,10 @@ class DFRN
|
|||
$conv = $xpath->query('ostatus:conversation', $entry);
|
||||
if (is_object($conv->item(0))) {
|
||||
foreach ($conv->item(0)->attributes as $attributes) {
|
||||
if ($attributes->name == "ref") {
|
||||
if ($attributes->name == 'ref') {
|
||||
$item['conversation-uri'] = $attributes->textContent;
|
||||
}
|
||||
if ($attributes->name == "href") {
|
||||
if ($attributes->name == 'href') {
|
||||
$item['conversation-href'] = $attributes->textContent;
|
||||
}
|
||||
}
|
||||
|
|
@ -1991,10 +2011,10 @@ class DFRN
|
|||
// Is it a reply or a top level posting?
|
||||
$item['thr-parent'] = $item['uri'];
|
||||
|
||||
$inreplyto = $xpath->query("thr:in-reply-to", $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") {
|
||||
if ($attributes->name == 'ref') {
|
||||
$item['thr-parent'] = $attributes->textContent;
|
||||
}
|
||||
}
|
||||
|
|
@ -2011,24 +2031,24 @@ class DFRN
|
|||
|
||||
// Now assign the rest of the values that depend on the type of the message
|
||||
if (in_array($entrytype, [DFRN::REPLY, DFRN::REPLY_RC])) {
|
||||
if (!isset($item["object-type"])) {
|
||||
$item["object-type"] = Activity\ObjectType::COMMENT;
|
||||
if (!isset($item['object-type'])) {
|
||||
$item['object-type'] = Activity\ObjectType::COMMENT;
|
||||
}
|
||||
|
||||
if ($item["contact-id"] != $owner["contact-id"]) {
|
||||
$item["contact-id"] = $owner["contact-id"];
|
||||
if ($item['contact-id'] != $owner['contact-id']) {
|
||||
$item['contact-id'] = $owner['contact-id'];
|
||||
}
|
||||
|
||||
if (($item["network"] != $owner["network"]) && ($owner["network"] != "")) {
|
||||
$item["network"] = $owner["network"];
|
||||
if (($item['network'] != $owner['network']) && ($owner['network'] != '')) {
|
||||
$item['network'] = $owner['network'];
|
||||
}
|
||||
|
||||
if ($item["contact-id"] != $author["contact-id"]) {
|
||||
$item["contact-id"] = $author["contact-id"];
|
||||
if ($item['contact-id'] != $author['contact-id']) {
|
||||
$item['contact-id'] = $author['contact-id'];
|
||||
}
|
||||
|
||||
if (($item["network"] != $author["network"]) && ($author["network"] != "")) {
|
||||
$item["network"] = $author["network"];
|
||||
if (($item['network'] != $author['network']) && ($author['network'] != '')) {
|
||||
$item['network'] = $author['network'];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2036,34 +2056,34 @@ class DFRN
|
|||
$item = Item::addShareDataFromOriginal($item);
|
||||
|
||||
if ($entrytype == DFRN::REPLY_RC) {
|
||||
$item["wall"] = 1;
|
||||
$item['wall'] = 1;
|
||||
} elseif ($entrytype == DFRN::TOP_LEVEL) {
|
||||
if (!isset($item["object-type"])) {
|
||||
$item["object-type"] = Activity\ObjectType::NOTE;
|
||||
if (!isset($item['object-type'])) {
|
||||
$item['object-type'] = Activity\ObjectType::NOTE;
|
||||
}
|
||||
|
||||
// Is it an event?
|
||||
if (($item["object-type"] == Activity\ObjectType::EVENT) && !$owner_unknown) {
|
||||
Logger::info("Item ".$item["uri"]." seems to contain an event.");
|
||||
$ev = Event::fromBBCode($item["body"]);
|
||||
if (($item['object-type'] == Activity\ObjectType::EVENT) && !$owner_unknown) {
|
||||
Logger::info("Item " . $item['uri'] . " seems to contain an event.");
|
||||
$ev = Event::fromBBCode($item['body']);
|
||||
if ((!empty($ev['desc']) || !empty($ev['summary'])) && !empty($ev['start'])) {
|
||||
Logger::info("Event in item ".$item["uri"]." was found.");
|
||||
$ev["cid"] = $importer["id"];
|
||||
$ev["uid"] = $importer["importer_uid"];
|
||||
$ev["uri"] = $item["uri"];
|
||||
$ev["edited"] = $item["edited"];
|
||||
$ev["private"] = $item["private"];
|
||||
$ev["guid"] = $item["guid"];
|
||||
$ev["plink"] = $item["plink"];
|
||||
$ev["network"] = $item["network"];
|
||||
$ev["protocol"] = $item["protocol"];
|
||||
$ev["direction"] = $item["direction"];
|
||||
$ev["source"] = $item["source"];
|
||||
Logger::info("Event in item " . $item['uri'] . " was found.");
|
||||
$ev['cid'] = $importer['id'];
|
||||
$ev['uid'] = $importer['importer_uid'];
|
||||
$ev['uri'] = $item['uri'];
|
||||
$ev['edited'] = $item['edited'];
|
||||
$ev['private'] = $item['private'];
|
||||
$ev['guid'] = $item['guid'];
|
||||
$ev['plink'] = $item['plink'];
|
||||
$ev['network'] = $item['network'];
|
||||
$ev['protocol'] = $item['protocol'];
|
||||
$ev['direction'] = $item['direction'];
|
||||
$ev['source'] = $item['source'];
|
||||
|
||||
$condition = ['uri' => $item["uri"], 'uid' => $importer["importer_uid"]];
|
||||
$condition = ['uri' => $item['uri'], 'uid' => $importer['importer_uid']];
|
||||
$event = DBA::selectFirst('event', ['id'], $condition);
|
||||
if (DBA::isResult($event)) {
|
||||
$ev["id"] = $event["id"];
|
||||
$ev['id'] = $event['id'];
|
||||
}
|
||||
|
||||
$event_id = Event::store($ev);
|
||||
|
|
@ -2084,7 +2104,7 @@ class DFRN
|
|||
|
||||
// This check is done here to be able to receive connection requests in "processVerbs"
|
||||
if (($entrytype == DFRN::TOP_LEVEL) && $owner_unknown) {
|
||||
Logger::info("Item won't be stored because user " . $importer["importer_uid"] . " doesn't follow " . $item["owner-link"] . ".");
|
||||
Logger::info("Item won't be stored because user " . $importer['importer_uid'] . " doesn't follow " . $item['owner-link'] . ".");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2092,9 +2112,9 @@ class DFRN
|
|||
// Update content if 'updated' changes
|
||||
if (DBA::isResult($current)) {
|
||||
if (self::updateContent($current, $item, $importer, $entrytype)) {
|
||||
Logger::info("Item ".$item["uri"]." was updated.");
|
||||
Logger::info("Item " . $item['uri'] . " was updated.");
|
||||
} else {
|
||||
Logger::info("Item " . $item["uri"] . " already existed.");
|
||||
Logger::info("Item " . $item['uri'] . " already existed.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -2107,7 +2127,7 @@ class DFRN
|
|||
|
||||
$posted_id = Item::insert($item);
|
||||
if ($posted_id) {
|
||||
Logger::info("Reply from contact ".$item["contact-id"]." was stored with id ".$posted_id);
|
||||
Logger::info("Reply from contact " . $item['contact-id'] . " was stored with id " . $posted_id);
|
||||
|
||||
if ($item['uid'] == 0) {
|
||||
Item::distribute($posted_id);
|
||||
|
|
@ -2116,11 +2136,11 @@ class DFRN
|
|||
return true;
|
||||
}
|
||||
} else { // $entrytype == DFRN::TOP_LEVEL
|
||||
if (($importer["uid"] == 0) && ($importer["importer_uid"] != 0)) {
|
||||
Logger::info("Contact ".$importer["id"]." isn't known to user ".$importer["importer_uid"].". The post will be ignored.");
|
||||
if (($importer['uid'] == 0) && ($importer['importer_uid'] != 0)) {
|
||||
Logger::info("Contact " . $importer['id'] . " isn't known to user " . $importer['importer_uid'] . ". The post will be ignored.");
|
||||
return;
|
||||
}
|
||||
if (!Strings::compareLink($item["owner-link"], $importer["url"])) {
|
||||
if (!Strings::compareLink($item['owner-link'], $importer['url'])) {
|
||||
/*
|
||||
* The item owner info is not our contact. It's OK and is to be expected if this is a tgroup delivery,
|
||||
* but otherwise there's a possible data mixup on the sender's system.
|
||||
|
|
@ -2128,12 +2148,12 @@ class DFRN
|
|||
* but we're going to unconditionally correct it here so that the post will always be owned by our contact.
|
||||
*/
|
||||
Logger::info('Correcting item owner.');
|
||||
$item["owner-link"] = $importer["url"];
|
||||
$item["owner-id"] = Contact::getIdForURL($importer["url"], 0);
|
||||
$item['owner-link'] = $importer['url'];
|
||||
$item['owner-id'] = Contact::getIdForURL($importer['url'], 0);
|
||||
}
|
||||
|
||||
if (($importer["rel"] == Contact::FOLLOWER) && (!self::tgroupCheck($importer["importer_uid"], $item))) {
|
||||
Logger::info("Contact ".$importer["id"]." is only follower and tgroup check was negative.");
|
||||
if (($importer['rel'] == Contact::FOLLOWER) && (!self::tgroupCheck($importer['importer_uid'], $item))) {
|
||||
Logger::info("Contact " . $importer['id'] . " is only follower and tgroup check was negative.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2147,13 +2167,13 @@ class DFRN
|
|||
$posted_id = $notify;
|
||||
}
|
||||
|
||||
Logger::info("Item was stored with id ".$posted_id);
|
||||
Logger::info("Item was stored with id " . $posted_id);
|
||||
|
||||
if ($item['uid'] == 0) {
|
||||
Item::distribute($posted_id);
|
||||
}
|
||||
|
||||
if (stristr($item["verb"], Activity::POKE)) {
|
||||
if (stristr($item['verb'], Activity::POKE)) {
|
||||
$item['id'] = $posted_id;
|
||||
self::doPoke($item, $importer);
|
||||
}
|
||||
|
|
@ -2163,56 +2183,55 @@ class DFRN
|
|||
/**
|
||||
* Deletes items
|
||||
*
|
||||
* @param object $xpath XPath object
|
||||
* @param object $deletion deletion elements
|
||||
* @param array $importer Record of the importer user mixed with contact of the content
|
||||
* @param DOMXPath $xpath XPath object
|
||||
* @param DOMNode $deletion deletion elements
|
||||
* @param array $importer Record of the importer user mixed with contact of the content
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
* @todo set proper type-hints
|
||||
*/
|
||||
private static function processDeletion($xpath, $deletion, array $importer)
|
||||
private static function processDeletion(DOMXPath $xpath, DOMNode $deletion, array $importer)
|
||||
{
|
||||
Logger::notice("Processing deletions");
|
||||
$uri = null;
|
||||
|
||||
foreach ($deletion->attributes as $attributes) {
|
||||
if ($attributes->name == "ref") {
|
||||
if ($attributes->name == 'ref') {
|
||||
$uri = $attributes->textContent;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$uri || !$importer["id"]) {
|
||||
if (!$uri || !$importer['id']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$condition = ['uri' => $uri, 'uid' => $importer["importer_uid"]];
|
||||
$condition = ['uri' => $uri, 'uid' => $importer['importer_uid']];
|
||||
$item = Post::selectFirst(['id', 'parent', 'contact-id', 'uri-id', 'deleted', 'gravity'], $condition);
|
||||
if (!DBA::isResult($item)) {
|
||||
Logger::info("Item with uri " . $uri . " for user " . $importer["importer_uid"] . " wasn't found.");
|
||||
Logger::info('Item with URI ' . $uri . ' for user ' . $importer['importer_uid'] . ' was not found.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (DBA::exists('post-category', ['uri-id' => $item['uri-id'], 'uid' => $importer['importer_uid'], 'type' => Post\Category::FILE])) {
|
||||
Logger::notice("Item is filed. It won't be deleted.", ['uri' => $uri, 'uri-id' => $item['uri_id'], 'uid' => $importer["importer_uid"]]);
|
||||
Logger::notice('Item is filed. It will not be deleted.', ['uri' => $uri, 'uri-id' => $item['uri_id'], 'uid' => $importer['importer_uid']]);
|
||||
return;
|
||||
}
|
||||
|
||||
// When it is a starting post it has to belong to the person that wants to delete it
|
||||
if (($item['gravity'] == GRAVITY_PARENT) && ($item['contact-id'] != $importer["id"])) {
|
||||
Logger::info("Item with uri " . $uri . " don't belong to contact " . $importer["id"] . " - ignoring deletion.");
|
||||
if (($item['gravity'] == GRAVITY_PARENT) && ($item['contact-id'] != $importer['id'])) {
|
||||
Logger::info('Item with URI ' . $uri . ' do not belong to contact ' . $importer['id'] . ' - ignoring deletion.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Comments can be deleted by the thread owner or comment owner
|
||||
if (($item['gravity'] != GRAVITY_PARENT) && ($item['contact-id'] != $importer["id"])) {
|
||||
$condition = ['id' => $item['parent'], 'contact-id' => $importer["id"]];
|
||||
if (($item['gravity'] != GRAVITY_PARENT) && ($item['contact-id'] != $importer['id'])) {
|
||||
$condition = ['id' => $item['parent'], 'contact-id' => $importer['id']];
|
||||
if (!Post::exists($condition)) {
|
||||
Logger::info("Item with uri " . $uri . " wasn't found or mustn't be deleted by contact " . $importer["id"] . " - ignoring deletion.");
|
||||
Logger::info('Item with URI ' . $uri . ' was not found or must not be deleted by contact ' . $importer['id'] . ' - ignoring deletion.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ($item["deleted"]) {
|
||||
if ($item['deleted']) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2234,7 +2253,7 @@ class DFRN
|
|||
*/
|
||||
public static function import(string $xml, array $importer, int $protocol, int $direction): int
|
||||
{
|
||||
if ($xml == "") {
|
||||
if ($xml == '') {
|
||||
return 400;
|
||||
}
|
||||
|
||||
|
|
@ -2242,24 +2261,24 @@ class DFRN
|
|||
@$doc->loadXML($xml);
|
||||
|
||||
$xpath = new DOMXPath($doc);
|
||||
$xpath->registerNamespace("atom", ActivityNamespace::ATOM1);
|
||||
$xpath->registerNamespace("thr", ActivityNamespace::THREAD);
|
||||
$xpath->registerNamespace("at", ActivityNamespace::TOMB);
|
||||
$xpath->registerNamespace("media", ActivityNamespace::MEDIA);
|
||||
$xpath->registerNamespace("dfrn", ActivityNamespace::DFRN);
|
||||
$xpath->registerNamespace("activity", ActivityNamespace::ACTIVITY);
|
||||
$xpath->registerNamespace("georss", ActivityNamespace::GEORSS);
|
||||
$xpath->registerNamespace("poco", ActivityNamespace::POCO);
|
||||
$xpath->registerNamespace("ostatus", ActivityNamespace::OSTATUS);
|
||||
$xpath->registerNamespace("statusnet", ActivityNamespace::STATUSNET);
|
||||
$xpath->registerNamespace('atom', ActivityNamespace::ATOM1);
|
||||
$xpath->registerNamespace('thr', ActivityNamespace::THREAD);
|
||||
$xpath->registerNamespace('at', ActivityNamespace::TOMB);
|
||||
$xpath->registerNamespace('media', ActivityNamespace::MEDIA);
|
||||
$xpath->registerNamespace('dfrn', ActivityNamespace::DFRN);
|
||||
$xpath->registerNamespace('activity', ActivityNamespace::ACTIVITY);
|
||||
$xpath->registerNamespace('georss', ActivityNamespace::GEORSS);
|
||||
$xpath->registerNamespace('poco', ActivityNamespace::POCO);
|
||||
$xpath->registerNamespace('ostatus', ActivityNamespace::OSTATUS);
|
||||
$xpath->registerNamespace('statusnet', ActivityNamespace::STATUSNET);
|
||||
|
||||
$header = [];
|
||||
$header["uid"] = $importer["importer_uid"];
|
||||
$header["network"] = Protocol::DFRN;
|
||||
$header["wall"] = 0;
|
||||
$header["origin"] = 0;
|
||||
$header["contact-id"] = $importer["id"];
|
||||
$header["direction"] = $direction;
|
||||
$header['uid'] = $importer['importer_uid'];
|
||||
$header['network'] = Protocol::DFRN;
|
||||
$header['wall'] = 0;
|
||||
$header['origin'] = 0;
|
||||
$header['contact-id'] = $importer['id'];
|
||||
$header['direction'] = $direction;
|
||||
|
||||
if ($direction === Conversation::RELAY) {
|
||||
$header['post-reason'] = Item::PR_RELAY;
|
||||
|
|
@ -2268,31 +2287,31 @@ class DFRN
|
|||
// Update the contact table if the data has changed
|
||||
|
||||
// The "atom:author" is only present in feeds
|
||||
if ($xpath->query("/atom:feed/atom:author")->length > 0) {
|
||||
self::fetchauthor($xpath, $doc->firstChild, $importer, "atom:author", false, $xml);
|
||||
if ($xpath->query('/atom:feed/atom:author')->length > 0) {
|
||||
self::fetchauthor($xpath, $doc->firstChild, $importer, 'atom:author', false, $xml);
|
||||
}
|
||||
|
||||
// Only the "dfrn:owner" in the head section contains all data
|
||||
if ($xpath->query("/atom:feed/dfrn:owner")->length > 0) {
|
||||
self::fetchauthor($xpath, $doc->firstChild, $importer, "dfrn:owner", false, $xml);
|
||||
if ($xpath->query('/atom:feed/dfrn:owner')->length > 0) {
|
||||
self::fetchauthor($xpath, $doc->firstChild, $importer, 'dfrn:owner', false, $xml);
|
||||
}
|
||||
|
||||
Logger::info("Import DFRN message for user " . $importer["importer_uid"] . " from contact " . $importer["id"]);
|
||||
Logger::info("Import DFRN message for user " . $importer['importer_uid'] . " from contact " . $importer['id']);
|
||||
|
||||
if (!empty($importer['gsid']) && ($protocol == Conversation::PARCEL_DIASPORA_DFRN)) {
|
||||
GServer::setProtocol($importer['gsid'], Post\DeliveryData::DFRN);
|
||||
}
|
||||
|
||||
// is it a public forum? Private forums aren't exposed with this method
|
||||
$forum = intval(XML::getFirstNodeValue($xpath, "/atom:feed/dfrn:community/text()"));
|
||||
$forum = intval(XML::getFirstNodeValue($xpath, '/atom:feed/dfrn:community/text()'));
|
||||
|
||||
// The account type is new since 3.5.1
|
||||
if ($xpath->query("/atom:feed/dfrn:account_type")->length > 0) {
|
||||
if ($xpath->query('/atom:feed/dfrn:account_type')->length > 0) {
|
||||
// Hint: We are using separate update calls for uid=0 and uid!=0 since a combined call is bad for the database performance
|
||||
|
||||
$accounttype = intval(XML::getFirstNodeValue($xpath, "/atom:feed/dfrn:account_type/text()"));
|
||||
$accounttype = intval(XML::getFirstNodeValue($xpath, '/atom:feed/dfrn:account_type/text()'));
|
||||
|
||||
if ($accounttype != $importer["contact-type"]) {
|
||||
if ($accounttype != $importer['contact-type']) {
|
||||
Contact::update(['contact-type' => $accounttype], ['id' => $importer['id']]);
|
||||
|
||||
// Updating the public contact as well
|
||||
|
|
@ -2316,8 +2335,8 @@ class DFRN
|
|||
$condition = ['(`forum` OR `prv`) AND `uid` = 0 AND `nurl` = ?', $importer['nurl']];
|
||||
Contact::update(['forum' => false, 'prv' => false], $condition);
|
||||
}
|
||||
} elseif ($forum != $importer["forum"]) { // Deprecated since 3.5.1
|
||||
$condition = ['`forum` != ? AND `id` = ?', $forum, $importer["id"]];
|
||||
} elseif ($forum != $importer['forum']) { // Deprecated since 3.5.1
|
||||
$condition = ['`forum` != ? AND `id` = ?', $forum, $importer['id']];
|
||||
Contact::update(['forum' => $forum], $condition);
|
||||
|
||||
// Updating the public contact as well
|
||||
|
|
@ -2327,40 +2346,40 @@ class DFRN
|
|||
|
||||
|
||||
// We are processing relocations even if we are ignoring a contact
|
||||
$relocations = $xpath->query("/atom:feed/dfrn:relocate");
|
||||
$relocations = $xpath->query('/atom:feed/dfrn:relocate');
|
||||
foreach ($relocations as $relocation) {
|
||||
self::processRelocation($xpath, $relocation, $importer);
|
||||
}
|
||||
|
||||
if (($importer["uid"] != 0) && !$importer["readonly"]) {
|
||||
$mails = $xpath->query("/atom:feed/dfrn:mail");
|
||||
if (($importer['uid'] != 0) && !$importer['readonly']) {
|
||||
$mails = $xpath->query('/atom:feed/dfrn:mail');
|
||||
foreach ($mails as $mail) {
|
||||
self::processMail($xpath, $mail, $importer);
|
||||
}
|
||||
|
||||
$suggestions = $xpath->query("/atom:feed/dfrn:suggest");
|
||||
$suggestions = $xpath->query('/atom:feed/dfrn:suggest');
|
||||
foreach ($suggestions as $suggestion) {
|
||||
self::processSuggestion($xpath, $suggestion, $importer);
|
||||
}
|
||||
}
|
||||
|
||||
$deletions = $xpath->query("/atom:feed/at:deleted-entry");
|
||||
$deletions = $xpath->query('/atom:feed/at:deleted-entry');
|
||||
if (!empty($deletions)) {
|
||||
foreach ($deletions as $deletion) {
|
||||
self::processDeletion($xpath, $deletion, $importer);
|
||||
}
|
||||
if (count($deletions) > 0) {
|
||||
Logger::notice('Deletions had been processed');
|
||||
Logger::notice(count($deletions) . ' deletions had been processed');
|
||||
return 200;
|
||||
}
|
||||
}
|
||||
|
||||
$entries = $xpath->query("/atom:feed/atom:entry");
|
||||
$entries = $xpath->query('/atom:feed/atom:entry');
|
||||
foreach ($entries as $entry) {
|
||||
self::processEntry($header, $xpath, $entry, $importer, $xml, $protocol);
|
||||
}
|
||||
|
||||
Logger::info("Import done for user " . $importer["importer_uid"] . " from contact " . $importer["id"]);
|
||||
Logger::info("Import done for user " . $importer['importer_uid'] . " from contact " . $importer['id']);
|
||||
return 200;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,10 +38,10 @@ class Email
|
|||
* @param string $mailbox The mailbox name
|
||||
* @param string $username The username
|
||||
* @param string $password The password
|
||||
* @return Connection|resource
|
||||
* @return Connection|resource|bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function connect($mailbox, $username, $password)
|
||||
public static function connect(string $mailbox, string $username, string $password)
|
||||
{
|
||||
if (!function_exists('imap_open')) {
|
||||
return false;
|
||||
|
|
@ -68,7 +68,7 @@ class Email
|
|||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function poll($mbox, $email_addr): array
|
||||
public static function poll($mbox, string $email_addr): array
|
||||
{
|
||||
if (!$mbox || !$email_addr) {
|
||||
return [];
|
||||
|
|
@ -101,10 +101,12 @@ class Email
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns mailbox name
|
||||
*
|
||||
* @param array $mailacct mail account
|
||||
* @return string
|
||||
*/
|
||||
public static function constructMailboxName($mailacct)
|
||||
public static function constructMailboxName(array $mailacct): string
|
||||
{
|
||||
$ret = '{' . $mailacct['server'] . ((intval($mailacct['port'])) ? ':' . $mailacct['port'] : '');
|
||||
$ret .= (($mailacct['ssltype']) ? '/' . $mailacct['ssltype'] . '/novalidate-cert' : '');
|
||||
|
|
@ -117,7 +119,7 @@ class Email
|
|||
* @param integer $uid user id
|
||||
* @return mixed
|
||||
*/
|
||||
public static function messageMeta($mbox, $uid)
|
||||
public static function messageMeta($mbox, int $uid)
|
||||
{
|
||||
$ret = (($mbox && $uid) ? @imap_fetch_overview($mbox, $uid, FT_UID) : [[]]); // POSSIBLE CLEANUP --> array(array()) is probably redundant now
|
||||
return (count($ret)) ? $ret : [];
|
||||
|
|
@ -127,10 +129,11 @@ class Email
|
|||
* @param Connection|resource $mbox mailbox
|
||||
* @param integer $uid user id
|
||||
* @param string $reply reply
|
||||
* @param array $item Item
|
||||
* @return array
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function getMessage($mbox, $uid, $reply, $item): array
|
||||
public static function getMessage($mbox, int $uid, string $reply, array $item): array
|
||||
{
|
||||
$ret = $item;
|
||||
|
||||
|
|
@ -218,7 +221,7 @@ class Email
|
|||
* @param string $subtype sub type
|
||||
* @return string
|
||||
*/
|
||||
private static function messageGetPart($mbox, $uid, $p, $partno, $subtype)
|
||||
private static function messageGetPart($mbox, int $uid, $p, in $partno, string $subtype): string
|
||||
{
|
||||
// $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple
|
||||
global $htmlmsg,$plainmsg,$charset,$attachments;
|
||||
|
|
@ -296,11 +299,13 @@ class Email
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns encoded header
|
||||
*
|
||||
* @param string $in_str in string
|
||||
* @param string $charset character set
|
||||
* @return string
|
||||
*/
|
||||
public static function encodeHeader($in_str, $charset)
|
||||
public static function encodeHeader(string $in_str, string $charset): string
|
||||
{
|
||||
$out_str = $in_str;
|
||||
$need_to_convert = false;
|
||||
|
|
@ -360,21 +365,20 @@ class Email
|
|||
* @param string $subject subject
|
||||
* @param string $headers headers
|
||||
* @param array $item item
|
||||
*
|
||||
* @return void
|
||||
* @return bool Status from mail()
|
||||
*
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
* @todo This could be changed to use the Emailer class
|
||||
*/
|
||||
public static function send($addr, $subject, $headers, $item)
|
||||
public static function send(string $addr, string $subject, string $headers, array$item)
|
||||
{
|
||||
//$headers .= 'MIME-Version: 1.0' . "\n";
|
||||
//$headers .= 'Content-Type: text/html; charset=UTF-8' . "\n";
|
||||
//$headers .= 'Content-Type: text/plain; charset=UTF-8' . "\n";
|
||||
//$headers .= 'Content-Transfer-Encoding: 8bit' . "\n\n";
|
||||
|
||||
$part = uniqid("", true);
|
||||
$part = uniqid('', true);
|
||||
|
||||
$html = Item::prepareBody($item);
|
||||
|
||||
|
|
@ -398,52 +402,70 @@ class Email
|
|||
//$message = '<html><body>' . $html . '</body></html>';
|
||||
//$message = html2plain($html);
|
||||
Logger::notice('notifier: email delivery to ' . $addr);
|
||||
mail($addr, $subject, $body, $headers);
|
||||
return mail($addr, $subject, $body, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $iri string
|
||||
* @return string
|
||||
* Convert item URI to message id
|
||||
*
|
||||
* @param string $itemUri Item URI
|
||||
* @return string Message id
|
||||
*/
|
||||
public static function iri2msgid($iri)
|
||||
public static function iri2msgid(string $itemUri): string
|
||||
{
|
||||
if (!strpos($iri, "@")) {
|
||||
$msgid = preg_replace("/urn:(\S+):(\S+)\.(\S+):(\d+):(\S+)/i", "urn!$1!$4!$5@$2.$3", $iri);
|
||||
} else {
|
||||
$msgid = $iri;
|
||||
$msgid = $itemUri;
|
||||
|
||||
if (!strpos($itemUri, '@')) {
|
||||
$msgid = preg_replace("/urn:(\S+):(\S+)\.(\S+):(\d+):(\S+)/i", "urn!$1!$4!$5@$2.$3", $itemUri);
|
||||
}
|
||||
|
||||
return $msgid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $msgid msgid
|
||||
* @return string
|
||||
* Converts message id to item URI
|
||||
*
|
||||
* @param string $msgid Message id
|
||||
* @return string Item URI
|
||||
*/
|
||||
public static function msgid2iri($msgid)
|
||||
public static function msgid2iri(string $msgid): string
|
||||
{
|
||||
if (strpos($msgid, "@")) {
|
||||
$iri = preg_replace("/urn!(\S+)!(\d+)!(\S+)@(\S+)\.(\S+)/i", "urn:$1:$4.$5:$2:$3", $msgid);
|
||||
} else {
|
||||
$iri = $msgid;
|
||||
$itemUri = $msgid;
|
||||
|
||||
if (strpos($msgid, '@')) {
|
||||
$itemUri = preg_replace("/urn!(\S+)!(\d+)!(\S+)@(\S+)\.(\S+)/i", "urn:$1:$4.$5:$2:$3", $msgid);
|
||||
}
|
||||
|
||||
return $iri;
|
||||
return $itemUri;
|
||||
}
|
||||
|
||||
private static function saveReplace($pattern, $replace, $text)
|
||||
/**
|
||||
* Invokes preg_replace() but does return full text from parameter if it
|
||||
* returned an empty message.
|
||||
*
|
||||
* @param string $pattern Pattern to match
|
||||
* @param string $replace String to replace with
|
||||
* @param string $text String to check
|
||||
* @return string Replaced string
|
||||
*/
|
||||
private static function saveReplace(string $pattern, string $replace, string $text): string
|
||||
{
|
||||
$save = $text;
|
||||
$return = preg_replace($pattern, $replace, $text);
|
||||
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
|
||||
if ($text == '') {
|
||||
$text = $save;
|
||||
if ($return == '') {
|
||||
$return = $text;
|
||||
}
|
||||
return $text;
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
private static function unifyAttributionLine($message)
|
||||
/**
|
||||
* Unifies attribution line(s)
|
||||
*
|
||||
* @param string $message Unfiltered message
|
||||
* @return string Message with unified attribution line(s)
|
||||
*/
|
||||
private static function unifyAttributionLine(string $message): string
|
||||
{
|
||||
$quotestr = ['quote', 'spoiler'];
|
||||
foreach ($quotestr as $quote) {
|
||||
|
|
@ -520,7 +542,13 @@ class Email
|
|||
return $message;
|
||||
}
|
||||
|
||||
private static function removeGPG($message)
|
||||
/**
|
||||
* Removes GPG part from message
|
||||
*
|
||||
* @param string $message Unfiltered message
|
||||
* @return string Message with GPG part
|
||||
*/
|
||||
private static function removeGPG(string $message): string
|
||||
{
|
||||
$pattern = '/(.*)\s*-----BEGIN PGP SIGNED MESSAGE-----\s*[\r\n].*Hash:.*?[\r\n](.*)'.
|
||||
'[\r\n]\s*-----BEGIN PGP SIGNATURE-----\s*[\r\n].*'.
|
||||
|
|
@ -537,7 +565,13 @@ class Email
|
|||
return $cleaned;
|
||||
}
|
||||
|
||||
private static function removeSig($message)
|
||||
/**
|
||||
* Removes signature from message
|
||||
*
|
||||
* @param string $message Unfiltered message
|
||||
* @return string Message with no signature
|
||||
*/
|
||||
private static function removeSig(string $message): string
|
||||
{
|
||||
$sigpos = strrpos($message, "\n-- \n");
|
||||
$quotepos = strrpos($message, "[/quote]");
|
||||
|
|
@ -569,7 +603,13 @@ class Email
|
|||
return ['body' => $cleaned, 'sig' => $sig];
|
||||
}
|
||||
|
||||
private static function removeLinebreak($message)
|
||||
/**
|
||||
* Removes lines breaks from message
|
||||
*
|
||||
* @param string $message Unfiltered message
|
||||
* @return string Message with no line breaks
|
||||
*/
|
||||
private static function removeLinebreak(string $message): string
|
||||
{
|
||||
$arrbody = explode("\n", trim($message));
|
||||
|
||||
|
|
@ -622,7 +662,7 @@ class Email
|
|||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
private static function convertQuote($body, $reply)
|
||||
private static function convertQuote(strng $body, string $reply): string
|
||||
{
|
||||
// Convert Quotes
|
||||
$arrbody = explode("\n", trim($body));
|
||||
|
|
@ -682,14 +722,14 @@ class Email
|
|||
return $body;
|
||||
}
|
||||
|
||||
private static function removeToFu($message)
|
||||
private static function removeToFu(string $message): string
|
||||
{
|
||||
$message = trim($message);
|
||||
|
||||
do {
|
||||
$oldmessage = $message;
|
||||
$message = preg_replace('=\[/quote\][\s](.*?)\[quote\]=i', '$1', $message);
|
||||
$message = str_replace("[/quote][quote]", "", $message);
|
||||
$message = str_replace('[/quote][quote]', '', $message);
|
||||
} while ($message != $oldmessage);
|
||||
|
||||
$quotes = [];
|
||||
|
|
@ -724,8 +764,9 @@ class Email
|
|||
$start = $pos + 7;
|
||||
}
|
||||
|
||||
if (strtolower(substr($message, -8)) != '[/quote]')
|
||||
if (strtolower(substr($message, -8)) != '[/quote]') {
|
||||
return($message);
|
||||
}
|
||||
|
||||
krsort($quotes);
|
||||
|
||||
|
|
@ -739,7 +780,7 @@ class Email
|
|||
}
|
||||
|
||||
if ($quotestart != 0) {
|
||||
$message = trim(substr($message, 0, $quotestart))."\n[spoiler]".substr($message, $quotestart+7, -8).'[/spoiler]';
|
||||
$message = trim(substr($message, 0, $quotestart))."\n[spoiler]".substr($message, $quotestart+7, -8) . '[/spoiler]';
|
||||
}
|
||||
|
||||
return $message;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
namespace Friendica\Protocol;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMElement;
|
||||
use DOMXPath;
|
||||
use Friendica\Content\PageInfo;
|
||||
use Friendica\Content\Text\BBCode;
|
||||
|
|
@ -66,7 +67,7 @@ class Feed
|
|||
if ($dryRun) {
|
||||
Logger::info("Test Atom/RSS feed");
|
||||
} else {
|
||||
Logger::info("Import Atom/RSS feed '" . $contact["name"] . "' (Contact " . $contact["id"] . ") for user " . $importer["uid"]);
|
||||
Logger::info('Import Atom/RSS feed "' . $contact['name'] . '" (Contact ' . $contact['id'] . ') for user ' . $importer['uid']);
|
||||
}
|
||||
|
||||
$xml = trim($xml);
|
||||
|
|
@ -378,7 +379,7 @@ class Feed
|
|||
if (DBA::isResult($previous)) {
|
||||
// Use the creation date when the post had been stored. It can happen this date changes in the feed.
|
||||
$creation_dates[] = $previous['created'];
|
||||
Logger::info("Item with uri " . $item["uri"] . " for user " . $importer["uid"] . " already existed under id " . $previous["id"]);
|
||||
Logger::info('Item with URI ' . $item['uri'] . ' for user ' . $importer['uid'] . ' already existed under id ' . $previous['id']);
|
||||
continue;
|
||||
}
|
||||
$creation_dates[] = DateTimeFormat::utc($item['created']);
|
||||
|
|
@ -683,7 +684,7 @@ class Feed
|
|||
/**
|
||||
* Automatically adjust the poll frequency according to the post frequency
|
||||
*
|
||||
* @param array $contact
|
||||
* @param array $contact Contact array
|
||||
* @param array $creation_dates
|
||||
* @return void
|
||||
*/
|
||||
|
|
@ -803,7 +804,7 @@ class Feed
|
|||
* @param array $contact
|
||||
* @return int Poll interval in minutes
|
||||
*/
|
||||
public static function getPollInterval(array $contact)
|
||||
public static function getPollInterval(array $contact): int
|
||||
{
|
||||
if (in_array($contact['network'], [Protocol::MAIL, Protocol::FEED])) {
|
||||
$ratings = [0, 3, 7, 8, 9, 10];
|
||||
|
|
@ -852,39 +853,39 @@ class Feed
|
|||
* @param array $tags
|
||||
* @return string tag string
|
||||
*/
|
||||
private static function tagToString(array $tags)
|
||||
private static function tagToString(array $tags): string
|
||||
{
|
||||
$tagstr = '';
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
if ($tagstr != "") {
|
||||
$tagstr .= ", ";
|
||||
if ($tagstr != '') {
|
||||
$tagstr .= ', ';
|
||||
}
|
||||
|
||||
$tagstr .= "#[url=" . DI::baseUrl() . "/search?tag=" . urlencode($tag) . "]" . $tag . "[/url]";
|
||||
$tagstr .= '#[url=' . DI::baseUrl() . '/search?tag=' . urlencode($tag) . ']' . $tag . '[/url]';
|
||||
}
|
||||
|
||||
return $tagstr;
|
||||
}
|
||||
|
||||
private static function titleIsBody($title, $body)
|
||||
private static function titleIsBody(string $title, string $body): bool
|
||||
{
|
||||
$title = strip_tags($title);
|
||||
$title = trim($title);
|
||||
$title = html_entity_decode($title, ENT_QUOTES, 'UTF-8');
|
||||
$title = str_replace(["\n", "\r", "\t", " "], ["", "", "", ""], $title);
|
||||
$title = str_replace(["\n", "\r", "\t", " "], ['', '', '', ''], $title);
|
||||
|
||||
$body = strip_tags($body);
|
||||
$body = trim($body);
|
||||
$body = html_entity_decode($body, ENT_QUOTES, 'UTF-8');
|
||||
$body = str_replace(["\n", "\r", "\t", " "], ["", "", "", ""], $body);
|
||||
$body = str_replace(["\n", "\r", "\t", " "], ['', '', '', ''], $body);
|
||||
|
||||
if (strlen($title) < strlen($body)) {
|
||||
$body = substr($body, 0, strlen($title));
|
||||
}
|
||||
|
||||
if (($title != $body) && (substr($title, -3) == "...")) {
|
||||
$pos = strrpos($title, "...");
|
||||
if (($title != $body) && (substr($title, -3) == '...')) {
|
||||
$pos = strrpos($title, '...');
|
||||
if ($pos > 0) {
|
||||
$title = substr($title, 0, $pos);
|
||||
$body = substr($body, 0, $pos);
|
||||
|
|
@ -914,7 +915,7 @@ class Feed
|
|||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public static function atom($owner_nick, $last_update, $max_items = 300, $filter = 'activity', $nocache = false)
|
||||
public static function atom(string $owner_nick, string $last_update, int $max_items = 300, string $filter = 'activity', bool $nocache = false)
|
||||
{
|
||||
$stamp = microtime(true);
|
||||
|
||||
|
|
@ -923,7 +924,7 @@ class Feed
|
|||
return;
|
||||
}
|
||||
|
||||
$cachekey = "feed:feed:" . $owner_nick . ":" . $filter . ":" . $last_update;
|
||||
$cachekey = 'feed:feed:' . $owner_nick . ':' . $filter . ':' . $last_update;
|
||||
|
||||
// Display events in the users's timezone
|
||||
if (strlen($owner['timezone'])) {
|
||||
|
|
@ -942,11 +943,11 @@ class Feed
|
|||
}
|
||||
|
||||
$check_date = empty($last_update) ? '' : DateTimeFormat::utc($last_update);
|
||||
$authorid = Contact::getIdForURL($owner["url"]);
|
||||
$authorid = Contact::getIdForURL($owner['url']);
|
||||
|
||||
$condition = ["`uid` = ? AND `received` > ? AND NOT `deleted` AND `gravity` IN (?, ?)
|
||||
AND `private` != ? AND `visible` AND `wall` AND `parent-network` IN (?, ?, ?, ?)",
|
||||
$owner["uid"], $check_date, GRAVITY_PARENT, GRAVITY_COMMENT,
|
||||
$owner['uid'], $check_date, GRAVITY_PARENT, GRAVITY_COMMENT,
|
||||
Item::PRIVATE, Protocol::ACTIVITYPUB,
|
||||
Protocol::OSTATUS, Protocol::DFRN, Protocol::DIASPORA];
|
||||
|
||||
|
|
@ -957,7 +958,7 @@ class Feed
|
|||
|
||||
if ($owner['account-type'] != User::ACCOUNT_TYPE_COMMUNITY) {
|
||||
$condition[0] .= " AND `contact-id` = ? AND `author-id` = ?";
|
||||
$condition[] = $owner["id"];
|
||||
$condition[] = $owner['id'];
|
||||
$condition[] = $authorid;
|
||||
}
|
||||
|
||||
|
|
@ -1002,16 +1003,16 @@ class Feed
|
|||
* @param array $owner Contact data of the poster
|
||||
* @param string $filter The related feed filter (activity, posts or comments)
|
||||
*
|
||||
* @return object header root element
|
||||
* @return DOMElement Header root element
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function addHeader(DOMDocument $doc, array $owner, $filter)
|
||||
private static function addHeader(DOMDocument $doc, array $owner, string $filter): DOMElement
|
||||
{
|
||||
$root = $doc->createElementNS(ActivityNamespace::ATOM1, 'feed');
|
||||
$doc->appendChild($root);
|
||||
|
||||
$title = '';
|
||||
$selfUri = '/feed/' . $owner["nick"] . '/';
|
||||
$selfUri = '/feed/' . $owner['nick'] . '/';
|
||||
switch ($filter) {
|
||||
case 'activity':
|
||||
$title = DI::l10n()->t('%s\'s timeline', $owner['name']);
|
||||
|
|
@ -1026,24 +1027,24 @@ class Feed
|
|||
break;
|
||||
}
|
||||
|
||||
$attributes = ["uri" => "https://friendi.ca", "version" => FRIENDICA_VERSION . "-" . DB_UPDATE_VERSION];
|
||||
XML::addElement($doc, $root, "generator", FRIENDICA_PLATFORM, $attributes);
|
||||
XML::addElement($doc, $root, "id", DI::baseUrl() . "/profile/" . $owner["nick"]);
|
||||
XML::addElement($doc, $root, "title", $title);
|
||||
XML::addElement($doc, $root, "subtitle", sprintf("Updates from %s on %s", $owner["name"], DI::config()->get('config', 'sitename')));
|
||||
XML::addElement($doc, $root, "logo", User::getAvatarUrl($owner, Proxy::SIZE_SMALL));
|
||||
XML::addElement($doc, $root, "updated", DateTimeFormat::utcNow(DateTimeFormat::ATOM));
|
||||
$attributes = ['uri' => 'https://friendi.ca', 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION];
|
||||
XML::addElement($doc, $root, 'generator', FRIENDICA_PLATFORM, $attributes);
|
||||
XML::addElement($doc, $root, 'id', DI::baseUrl() . '/profile/' . $owner['nick']);
|
||||
XML::addElement($doc, $root, 'title', $title);
|
||||
XML::addElement($doc, $root, 'subtitle', sprintf("Updates from %s on %s", $owner['name'], DI::config()->get('config', 'sitename')));
|
||||
XML::addElement($doc, $root, 'logo', User::getAvatarUrl($owner, Proxy::SIZE_SMALL));
|
||||
XML::addElement($doc, $root, 'updated', DateTimeFormat::utcNow(DateTimeFormat::ATOM));
|
||||
|
||||
$author = self::addAuthor($doc, $owner);
|
||||
$root->appendChild($author);
|
||||
|
||||
$attributes = ["href" => $owner["url"], "rel" => "alternate", "type" => "text/html"];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = ['href' => $owner['url'], 'rel' => 'alternate', 'type' => 'text/html'];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
|
||||
OStatus::hublinks($doc, $root, $owner["nick"]);
|
||||
OStatus::addHubLink($doc, $root, $owner['nick']);
|
||||
|
||||
$attributes = ["href" => DI::baseUrl() . $selfUri, "rel" => "self", "type" => "application/atom+xml"];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = ['href' => DI::baseUrl() . $selfUri, 'rel' => 'self', 'type' => 'application/atom+xml'];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
|
||||
return $root;
|
||||
}
|
||||
|
|
@ -1053,16 +1054,15 @@ class Feed
|
|||
*
|
||||
* @param DOMDocument $doc XML document
|
||||
* @param array $owner Contact data of the poster
|
||||
*
|
||||
* @return \DOMElement author element
|
||||
* @return DOMElement author element
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function addAuthor(DOMDocument $doc, array $owner)
|
||||
private static function addAuthor(DOMDocument $doc, array $owner): DOMElement
|
||||
{
|
||||
$author = $doc->createElement("author");
|
||||
XML::addElement($doc, $author, "uri", $owner["url"]);
|
||||
XML::addElement($doc, $author, "name", $owner["nick"]);
|
||||
XML::addElement($doc, $author, "email", $owner["addr"]);
|
||||
$author = $doc->createElement('author');
|
||||
XML::addElement($doc, $author, 'uri', $owner['url']);
|
||||
XML::addElement($doc, $author, 'name', $owner['nick']);
|
||||
XML::addElement($doc, $author, 'email', $owner['addr']);
|
||||
|
||||
return $author;
|
||||
}
|
||||
|
|
@ -1074,15 +1074,14 @@ class Feed
|
|||
* @param array $item Data of the item that is to be posted
|
||||
* @param array $owner Contact data of the poster
|
||||
* @param bool $toplevel Is it for en entry element (false) or a feed entry (true)?
|
||||
*
|
||||
* @return \DOMElement Entry element
|
||||
* @return DOMElement Entry element
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function noteEntry(DOMDocument $doc, array $item, array $owner)
|
||||
private static function noteEntry(DOMDocument $doc, array $item, array $owner): DOMElement
|
||||
{
|
||||
if (($item['gravity'] != GRAVITY_PARENT) && (Strings::normaliseLink($item["author-link"]) != Strings::normaliseLink($owner["url"]))) {
|
||||
Logger::info('Feed entry author does not match feed owner', ['owner' => $owner["url"], 'author' => $item["author-link"]]);
|
||||
if (($item['gravity'] != GRAVITY_PARENT) && (Strings::normaliseLink($item['author-link']) != Strings::normaliseLink($owner['url']))) {
|
||||
Logger::info('Feed entry author does not match feed owner', ['owner' => $owner['url'], 'author' => $item['author-link']]);
|
||||
}
|
||||
|
||||
$entry = OStatus::entryHeader($doc, $owner, $item, false);
|
||||
|
|
@ -1104,31 +1103,30 @@ class Feed
|
|||
* @param string $title Title for the post
|
||||
* @param string $verb The activity verb
|
||||
* @param bool $complete Add the "status_net" element?
|
||||
* @param bool $feed_mode Behave like a regular feed for users if true
|
||||
* @return void
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function entryContent(DOMDocument $doc, \DOMElement $entry, array $item, $title, $verb = "", $complete = true)
|
||||
private static function entryContent(DOMDocument $doc, DOMElement $entry, array $item, $title, string $verb = '', bool $complete = true)
|
||||
{
|
||||
if ($verb == "") {
|
||||
if ($verb == '') {
|
||||
$verb = OStatus::constructVerb($item);
|
||||
}
|
||||
|
||||
XML::addElement($doc, $entry, "id", $item["uri"]);
|
||||
XML::addElement($doc, $entry, "title", html_entity_decode($title, ENT_QUOTES, 'UTF-8'));
|
||||
XML::addElement($doc, $entry, 'id', $item['uri']);
|
||||
XML::addElement($doc, $entry, 'title', html_entity_decode($title, ENT_QUOTES, 'UTF-8'));
|
||||
|
||||
$body = OStatus::formatPicturePost($item['body'], $item['uri-id']);
|
||||
|
||||
$body = BBCode::convertForUriId($item['uri-id'], $body, BBCode::ACTIVITYPUB);
|
||||
|
||||
XML::addElement($doc, $entry, "content", $body, ["type" => "html"]);
|
||||
XML::addElement($doc, $entry, 'content', $body, ['type' => 'html']);
|
||||
|
||||
XML::addElement($doc, $entry, "link", "", ["rel" => "alternate", "type" => "text/html",
|
||||
"href" => DI::baseUrl()."/display/".$item["guid"]]
|
||||
XML::addElement($doc, $entry, 'link', '', ['rel' => 'alternate', 'type' => 'text/html',
|
||||
'href' => DI::baseUrl() . '/display/' . $item['guid']]
|
||||
);
|
||||
|
||||
XML::addElement($doc, $entry, "published", DateTimeFormat::utc($item["created"]."+00:00", DateTimeFormat::ATOM));
|
||||
XML::addElement($doc, $entry, "updated", DateTimeFormat::utc($item["edited"]."+00:00", DateTimeFormat::ATOM));
|
||||
XML::addElement($doc, $entry, 'published', DateTimeFormat::utc($item['created'] . '+00:00', DateTimeFormat::ATOM));
|
||||
XML::addElement($doc, $entry, 'updated', DateTimeFormat::utc($item['edited'] . '+00:00', DateTimeFormat::ATOM));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1197,28 +1195,28 @@ class Feed
|
|||
* @param array $item
|
||||
* @return string title
|
||||
*/
|
||||
private static function getTitle(array $item)
|
||||
private static function getTitle(array $item): string
|
||||
{
|
||||
if ($item['title'] != '') {
|
||||
return BBCode::convertForUriId($item['uri-id'], $item['title'], BBCode::ACTIVITYPUB);
|
||||
}
|
||||
|
||||
// Fetch information about the post
|
||||
$siteinfo = BBCode::getAttachedData($item["body"]);
|
||||
if (isset($siteinfo["title"])) {
|
||||
return $siteinfo["title"];
|
||||
$siteinfo = BBCode::getAttachedData($item['body']);
|
||||
if (isset($siteinfo['title'])) {
|
||||
return $siteinfo['title'];
|
||||
}
|
||||
|
||||
// If no bookmark is found then take the first line
|
||||
// Remove the share element before fetching the first line
|
||||
$title = trim(preg_replace("/\[share.*?\](.*?)\[\/share\]/ism","\n$1\n",$item['body']));
|
||||
$title = trim(preg_replace("/\[share.*?\](.*?)\[\/share\]/ism", "\n$1\n", $item['body']));
|
||||
|
||||
$title = BBCode::toPlaintext($title)."\n";
|
||||
$pos = strpos($title, "\n");
|
||||
$trailer = "";
|
||||
$trailer = '';
|
||||
if (($pos == 0) || ($pos > 100)) {
|
||||
$pos = 100;
|
||||
$trailer = "...";
|
||||
$trailer = '...';
|
||||
}
|
||||
|
||||
return substr($title, 0, $pos) . $trailer;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
namespace Friendica\Protocol;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMElement;
|
||||
use DOMXPath;
|
||||
use Friendica\Content\Text\BBCode;
|
||||
use Friendica\Content\Text\HTML;
|
||||
|
|
@ -67,24 +68,24 @@ class OStatus
|
|||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function fetchAuthor(DOMXPath $xpath, $context, array $importer, array &$contact = null, $onlyfetch)
|
||||
private static function fetchAuthor(DOMXPath $xpath, $context, array $importer, array &$contact = null, bool $onlyfetch): array
|
||||
{
|
||||
$author = [];
|
||||
$author["author-link"] = XML::getFirstNodeValue($xpath, 'atom:author/atom:uri/text()', $context);
|
||||
$author["author-name"] = XML::getFirstNodeValue($xpath, 'atom:author/atom:name/text()', $context);
|
||||
$author['author-link'] = XML::getFirstNodeValue($xpath, 'atom:author/atom:uri/text()', $context);
|
||||
$author['author-name'] = XML::getFirstNodeValue($xpath, 'atom:author/atom:name/text()', $context);
|
||||
$addr = XML::getFirstNodeValue($xpath, 'atom:author/atom:email/text()', $context);
|
||||
|
||||
$aliaslink = $author["author-link"];
|
||||
$aliaslink = $author['author-link'];
|
||||
|
||||
$alternate_item = $xpath->query("atom:author/atom:link[@rel='alternate']", $context)->item(0);
|
||||
if (is_object($alternate_item)) {
|
||||
foreach ($alternate_item->attributes as $attributes) {
|
||||
if (($attributes->name == "href") && ($attributes->textContent != "")) {
|
||||
$author["author-link"] = $attributes->textContent;
|
||||
if (($attributes->name == 'href') && ($attributes->textContent != '')) {
|
||||
$author['author-link'] = $attributes->textContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
$author["author-id"] = Contact::getIdForURL($author["author-link"]);
|
||||
$author['author-id'] = Contact::getIdForURL($author['author-link']);
|
||||
|
||||
$author['contact-id'] = ($contact['id'] ?? 0) ?: $author['author-id'];
|
||||
|
||||
|
|
@ -94,34 +95,45 @@ class OStatus
|
|||
This here would be better, but we would get problems with contacts from the statusnet addon
|
||||
This is kept here as a reminder for the future
|
||||
|
||||
$cid = Contact::getIdForURL($author["author-link"], $importer["uid"]);
|
||||
$cid = Contact::getIdForURL($author['author-link'], $importer['uid']);
|
||||
if ($cid) {
|
||||
$contact = DBA::selectFirst('contact', [], ['id' => $cid]);
|
||||
}
|
||||
*/
|
||||
if ($aliaslink != '') {
|
||||
$condition = ["`uid` = ? AND `alias` = ? AND `network` != ? AND `rel` IN (?, ?)",
|
||||
$importer["uid"], $aliaslink, Protocol::STATUSNET,
|
||||
Contact::SHARING, Contact::FRIEND];
|
||||
$contact = DBA::selectFirst('contact', [], $condition);
|
||||
$contact = DBA::selectFirst('contact', [], [
|
||||
"`uid` = ? AND `alias` = ? AND `network` != ? AND `rel` IN (?, ?)",
|
||||
$importer['uid'],
|
||||
$aliaslink, Protocol::STATUSNET,
|
||||
Contact::SHARING, Contact::FRIEND,
|
||||
]);
|
||||
}
|
||||
|
||||
if (!DBA::isResult($contact) && $author["author-link"] != '') {
|
||||
if ($aliaslink == "") {
|
||||
$aliaslink = $author["author-link"];
|
||||
if (!DBA::isResult($contact) && $author['author-link'] != '') {
|
||||
if ($aliaslink == '') {
|
||||
$aliaslink = $author['author-link'];
|
||||
}
|
||||
|
||||
$condition = ["`uid` = ? AND `nurl` IN (?, ?) AND `network` != ? AND `rel` IN (?, ?)",
|
||||
$importer["uid"], Strings::normaliseLink($author["author-link"]), Strings::normaliseLink($aliaslink),
|
||||
Protocol::STATUSNET, Contact::SHARING, Contact::FRIEND];
|
||||
$contact = DBA::selectFirst('contact', [], $condition);
|
||||
$contact = DBA::selectFirst('contact', [], [
|
||||
"`uid` = ? AND `nurl` IN (?, ?) AND `network` != ? AND `rel` IN (?, ?)",
|
||||
$importer['uid'],
|
||||
Strings::normaliseLink($author['author-link']),
|
||||
Strings::normaliseLink($aliaslink),
|
||||
Protocol::STATUSNET,
|
||||
Contact::SHARING,
|
||||
Contact::FRIEND,
|
||||
]);
|
||||
}
|
||||
|
||||
if (!DBA::isResult($contact) && ($addr != '')) {
|
||||
$condition = ["`uid` = ? AND `addr` = ? AND `network` != ? AND `rel` IN (?, ?)",
|
||||
$importer["uid"], $addr, Protocol::STATUSNET,
|
||||
Contact::SHARING, Contact::FRIEND];
|
||||
$contact = DBA::selectFirst('contact', [], $condition);
|
||||
$contact = DBA::selectFirst('contact', [], [
|
||||
"`uid` = ? AND `addr` = ? AND `network` != ? AND `rel` IN (?, ?)",
|
||||
$importer['uid'],
|
||||
$addr,
|
||||
Protocol::STATUSNET,
|
||||
Contact::SHARING,
|
||||
Contact::FRIEND,
|
||||
]);
|
||||
}
|
||||
|
||||
if (DBA::isResult($contact)) {
|
||||
|
|
@ -130,40 +142,40 @@ class OStatus
|
|||
} elseif (!empty(APContact::getByURL($contact['url'], false))) {
|
||||
ActivityPub\Receiver::switchContact($contact['id'], $importer['uid'], $contact['url']);
|
||||
}
|
||||
$author["contact-id"] = $contact["id"];
|
||||
$author['contact-id'] = $contact['id'];
|
||||
}
|
||||
|
||||
$avatarlist = [];
|
||||
$avatars = $xpath->query("atom:author/atom:link[@rel='avatar']", $context);
|
||||
foreach ($avatars as $avatar) {
|
||||
$href = "";
|
||||
$href = '';
|
||||
$width = 0;
|
||||
foreach ($avatar->attributes as $attributes) {
|
||||
if ($attributes->name == "href") {
|
||||
if ($attributes->name == 'href') {
|
||||
$href = $attributes->textContent;
|
||||
}
|
||||
if ($attributes->name == "width") {
|
||||
if ($attributes->name == 'width') {
|
||||
$width = $attributes->textContent;
|
||||
}
|
||||
}
|
||||
if ($href != "") {
|
||||
if ($href != '') {
|
||||
$avatarlist[$width] = $href;
|
||||
}
|
||||
}
|
||||
if (count($avatarlist) > 0) {
|
||||
krsort($avatarlist);
|
||||
$author["author-avatar"] = Probe::fixAvatar(current($avatarlist), $author["author-link"]);
|
||||
$author['author-avatar'] = Probe::fixAvatar(current($avatarlist), $author['author-link']);
|
||||
}
|
||||
|
||||
$displayname = XML::getFirstNodeValue($xpath, 'atom:author/poco:displayName/text()', $context);
|
||||
if ($displayname != "") {
|
||||
$author["author-name"] = $displayname;
|
||||
if ($displayname != '') {
|
||||
$author['author-name'] = $displayname;
|
||||
}
|
||||
|
||||
$author["owner-id"] = $author["author-id"];
|
||||
$author['owner-id'] = $author['author-id'];
|
||||
|
||||
// Only update the contacts if it is an OStatus contact
|
||||
if (DBA::isResult($contact) && ($contact['id'] > 0) && !$onlyfetch && ($contact["network"] == Protocol::OSTATUS)) {
|
||||
if (DBA::isResult($contact) && ($contact['id'] > 0) && !$onlyfetch && ($contact['network'] == Protocol::OSTATUS)) {
|
||||
|
||||
// Update contact data
|
||||
$current = $contact;
|
||||
|
|
@ -179,41 +191,41 @@ class OStatus
|
|||
// if ($value != "")
|
||||
// $contact["poll"] = $value;
|
||||
|
||||
$contact['url'] = $author["author-link"];
|
||||
$contact['url'] = $author['author-link'];
|
||||
$contact['nurl'] = Strings::normaliseLink($contact['url']);
|
||||
|
||||
$value = XML::getFirstNodeValue($xpath, 'atom:author/atom:uri/text()', $context);
|
||||
if ($value != "") {
|
||||
$contact["alias"] = $value;
|
||||
if ($value != '') {
|
||||
$contact['alias'] = $value;
|
||||
}
|
||||
|
||||
$value = XML::getFirstNodeValue($xpath, 'atom:author/poco:displayName/text()', $context);
|
||||
if ($value != "") {
|
||||
$contact["name"] = $value;
|
||||
if ($value != '') {
|
||||
$contact['name'] = $value;
|
||||
}
|
||||
|
||||
$value = XML::getFirstNodeValue($xpath, 'atom:author/poco:preferredUsername/text()', $context);
|
||||
if ($value != "") {
|
||||
$contact["nick"] = $value;
|
||||
if ($value != '') {
|
||||
$contact['nick'] = $value;
|
||||
}
|
||||
|
||||
$value = XML::getFirstNodeValue($xpath, 'atom:author/poco:note/text()', $context);
|
||||
if ($value != "") {
|
||||
$contact["about"] = HTML::toBBCode($value);
|
||||
if ($value != '') {
|
||||
$contact['about'] = HTML::toBBCode($value);
|
||||
}
|
||||
|
||||
$value = XML::getFirstNodeValue($xpath, 'atom:author/poco:address/poco:formatted/text()', $context);
|
||||
if ($value != "") {
|
||||
$contact["location"] = $value;
|
||||
if ($value != '') {
|
||||
$contact['location'] = $value;
|
||||
}
|
||||
|
||||
$contact['name-date'] = DateTimeFormat::utcNow();
|
||||
|
||||
Contact::update($contact, ['id' => $contact["id"]], $current);
|
||||
Contact::update($contact, ['id' => $contact['id']], $current);
|
||||
|
||||
if (!empty($author["author-avatar"]) && ($author["author-avatar"] != $current['avatar'])) {
|
||||
Logger::info("Update profile picture for contact ".$contact["id"]);
|
||||
Contact::updateAvatar($contact["id"], $author["author-avatar"]);
|
||||
if (!empty($author['author-avatar']) && ($author['author-avatar'] != $current['avatar'])) {
|
||||
Logger::info('Update profile picture for contact ' . $contact['id']);
|
||||
Contact::updateAvatar($contact['id'], $author['author-avatar']);
|
||||
}
|
||||
|
||||
// Ensure that we are having this contact (with uid=0)
|
||||
|
|
@ -224,20 +236,26 @@ class OStatus
|
|||
$old_contact = DBA::selectFirst('contact', $fields, ['id' => $cid]);
|
||||
|
||||
// Update it with the current values
|
||||
$fields = ['url' => $author["author-link"], 'name' => $contact["name"],
|
||||
'nurl' => Strings::normaliseLink($author["author-link"]),
|
||||
'nick' => $contact["nick"], 'alias' => $contact["alias"],
|
||||
'about' => $contact["about"], 'location' => $contact["location"],
|
||||
'success_update' => DateTimeFormat::utcNow(), 'last-update' => DateTimeFormat::utcNow()];
|
||||
$fields = [
|
||||
'url' => $author['author-link'],
|
||||
'name' => $contact['name'],
|
||||
'nurl' => Strings::normaliseLink($author['author-link']),
|
||||
'nick' => $contact['nick'],
|
||||
'alias' => $contact['alias'],
|
||||
'about' => $contact['about'],
|
||||
'location' => $contact['location'],
|
||||
'success_update' => DateTimeFormat::utcNow(),
|
||||
'last-update' => DateTimeFormat::utcNow(),
|
||||
];
|
||||
|
||||
Contact::update($fields, ['id' => $cid], $old_contact);
|
||||
|
||||
// Update the avatar
|
||||
if (!empty($author["author-avatar"])) {
|
||||
Contact::updateAvatar($cid, $author["author-avatar"]);
|
||||
if (!empty($author['author-avatar'])) {
|
||||
Contact::updateAvatar($cid, $author['author-avatar']);
|
||||
}
|
||||
}
|
||||
} elseif (empty($contact["network"]) || ($contact["network"] != Protocol::DFRN)) {
|
||||
} elseif (empty($contact['network']) || ($contact['network'] != Protocol::DFRN)) {
|
||||
$contact = [];
|
||||
}
|
||||
|
||||
|
|
@ -254,10 +272,10 @@ class OStatus
|
|||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public static function salmonAuthor($xml, array $importer)
|
||||
public static function salmonAuthor(string $xml, array $importer): array
|
||||
{
|
||||
if ($xml == "") {
|
||||
return;
|
||||
if (empty($xml)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$doc = new DOMDocument();
|
||||
|
|
@ -273,7 +291,7 @@ class OStatus
|
|||
$xpath->registerNamespace('ostatus', ActivityNamespace::OSTATUS);
|
||||
$xpath->registerNamespace('statusnet', ActivityNamespace::STATUSNET);
|
||||
|
||||
$contact = ["id" => 0];
|
||||
$contact = ['id' => 0];
|
||||
|
||||
// Fetch the first author
|
||||
$authordata = $xpath->query('//author')->item(0);
|
||||
|
|
@ -285,10 +303,9 @@ class OStatus
|
|||
* Read attributes from element
|
||||
*
|
||||
* @param object $element Element object
|
||||
*
|
||||
* @return array attributes
|
||||
*/
|
||||
private static function readAttributes($element)
|
||||
private static function readAttributes($element): array
|
||||
{
|
||||
$attribute = [];
|
||||
|
||||
|
|
@ -324,12 +341,12 @@ class OStatus
|
|||
* @param string $hub Called by reference, returns the fetched hub data
|
||||
* @param boolean $stored Is the post fresh imported or from the database?
|
||||
* @param boolean $initialize Is it the leading post so that data has to be initialized?
|
||||
*
|
||||
* @param integer $direction Direction, default UNKNOWN(0)
|
||||
* @return boolean Could the XML be processed?
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function process($xml, array $importer, array &$contact = null, &$hub, $stored = false, $initialize = true, $direction = Conversation::UNKNOWN)
|
||||
private static function process(string $xml, array $importer, array &$contact = null, string &$hub, bool $stored = false, bool $initialize = true, int $direction = Conversation::UNKNOWN)
|
||||
{
|
||||
if ($initialize) {
|
||||
self::$itemlist = [];
|
||||
|
|
@ -338,9 +355,10 @@ class OStatus
|
|||
|
||||
Logger::info('Import OStatus message for user ' . $importer['uid']);
|
||||
|
||||
if ($xml == "") {
|
||||
if (empty($xml)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$doc = new DOMDocument();
|
||||
@$doc->loadXML($xml);
|
||||
|
||||
|
|
@ -354,26 +372,26 @@ class OStatus
|
|||
$xpath->registerNamespace('ostatus', ActivityNamespace::OSTATUS);
|
||||
$xpath->registerNamespace('statusnet', ActivityNamespace::STATUSNET);
|
||||
|
||||
$hub = "";
|
||||
$hub = '';
|
||||
$hub_items = $xpath->query("/atom:feed/atom:link[@rel='hub']")->item(0);
|
||||
if (is_object($hub_items)) {
|
||||
$hub_attributes = $hub_items->attributes;
|
||||
if (is_object($hub_attributes)) {
|
||||
foreach ($hub_attributes as $hub_attribute) {
|
||||
if ($hub_attribute->name == "href") {
|
||||
if ($hub_attribute->name == 'href') {
|
||||
$hub = $hub_attribute->textContent;
|
||||
Logger::info("Found hub ".$hub);
|
||||
Logger::info('Found hub ', ['hub' => $hub]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$header = [];
|
||||
$header["uid"] = $importer["uid"];
|
||||
$header["network"] = Protocol::OSTATUS;
|
||||
$header["wall"] = 0;
|
||||
$header["origin"] = 0;
|
||||
$header["gravity"] = GRAVITY_COMMENT;
|
||||
$header['uid'] = $importer['uid'];
|
||||
$header['network'] = Protocol::OSTATUS;
|
||||
$header['wall'] = 0;
|
||||
$header['origin'] = 0;
|
||||
$header['gravity'] = GRAVITY_COMMENT;
|
||||
|
||||
if (!is_object($doc->firstChild) || empty($doc->firstChild->tagName)) {
|
||||
return false;
|
||||
|
|
@ -381,7 +399,7 @@ class OStatus
|
|||
|
||||
$first_child = $doc->firstChild->tagName;
|
||||
|
||||
if ($first_child == "feed") {
|
||||
if ($first_child == 'feed') {
|
||||
$entries = $xpath->query('/atom:feed/atom:entry');
|
||||
} else {
|
||||
$entries = $xpath->query('/atom:entry');
|
||||
|
|
@ -395,9 +413,9 @@ class OStatus
|
|||
$doc2->formatOutput = true;
|
||||
$xml2 = $doc2->saveXML();
|
||||
|
||||
$header["protocol"] = Conversation::PARCEL_SALMON;
|
||||
$header["source"] = $xml2;
|
||||
$header["direction"] = $direction;
|
||||
$header['protocol'] = Conversation::PARCEL_SALMON;
|
||||
$header['source'] = $xml2;
|
||||
$header['direction'] = $direction;
|
||||
} elseif (!$initialize) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -427,67 +445,67 @@ class OStatus
|
|||
|
||||
$item = array_merge($header, $author);
|
||||
|
||||
$item["uri"] = XML::getFirstNodeValue($xpath, 'atom:id/text()', $entry);
|
||||
$item['uri'] = XML::getFirstNodeValue($xpath, 'atom:id/text()', $entry);
|
||||
$item['uri-id'] = ItemURI::insert(['uri' => $item['uri']]);
|
||||
|
||||
$item["verb"] = XML::getFirstNodeValue($xpath, 'activity:verb/text()', $entry);
|
||||
$item['verb'] = XML::getFirstNodeValue($xpath, 'activity:verb/text()', $entry);
|
||||
|
||||
// Delete a message
|
||||
if (in_array($item["verb"], ['qvitter-delete-notice', Activity::DELETE, 'delete'])) {
|
||||
if (in_array($item['verb'], ['qvitter-delete-notice', Activity::DELETE, 'delete'])) {
|
||||
self::deleteNotice($item);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($item["verb"], [Activity::O_UNFAVOURITE, Activity::UNFAVORITE])) {
|
||||
if (in_array($item['verb'], [Activity::O_UNFAVOURITE, Activity::UNFAVORITE])) {
|
||||
// Ignore "Unfavorite" message
|
||||
Logger::info("Ignore unfavorite message ", ['item' => $item]);
|
||||
Logger::info('Ignore unfavorite message ', ['item' => $item]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Deletions come with the same uri, so we check for duplicates after processing deletions
|
||||
if (Post::exists(['uid' => $importer["uid"], 'uri' => $item["uri"]])) {
|
||||
Logger::info('Post with URI '.$item["uri"].' already existed for user '.$importer["uid"].'.');
|
||||
if (Post::exists(['uid' => $importer['uid'], 'uri' => $item['uri']])) {
|
||||
Logger::info('Post with URI ' . $item['uri'] . ' already existed for user ' . $importer['uid'] . '.');
|
||||
continue;
|
||||
} else {
|
||||
Logger::info('Processing post with URI '.$item["uri"].' for user '.$importer["uid"].'.');
|
||||
Logger::info('Processing post with URI ' . $item['uri'] . ' for user ' . $importer['uid'] . '.');
|
||||
}
|
||||
|
||||
if ($item["verb"] == Activity::JOIN) {
|
||||
if ($item['verb'] == Activity::JOIN) {
|
||||
// ignore "Join" messages
|
||||
Logger::info("Ignore join message ", ['item' => $item]);
|
||||
Logger::info('Ignore join message ', ['item' => $item]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($item["verb"] == "http://mastodon.social/schema/1.0/block") {
|
||||
if ($item['verb'] == 'http://mastodon.social/schema/1.0/block') {
|
||||
// ignore mastodon "block" messages
|
||||
Logger::info("Ignore block message ", ['item' => $item]);
|
||||
Logger::info('Ignore block message ', ['item' => $item]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($item["verb"] == Activity::FOLLOW) {
|
||||
if ($item['verb'] == Activity::FOLLOW) {
|
||||
Contact::addRelationship($importer, $contact, $item);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($item["verb"] == Activity::O_UNFOLLOW) {
|
||||
if ($item['verb'] == Activity::O_UNFOLLOW) {
|
||||
$dummy = null;
|
||||
Contact::removeFollower($contact);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($item["verb"] == Activity::FAVORITE) {
|
||||
$orig_uri = $xpath->query("activity:object/atom:id", $entry)->item(0)->nodeValue;
|
||||
Logger::notice("Favorite", ['uri' => $orig_uri, 'item' => $item]);
|
||||
if ($item['verb'] == Activity::FAVORITE) {
|
||||
$orig_uri = $xpath->query('activity:object/atom:id', $entry)->item(0)->nodeValue;
|
||||
Logger::notice('Favorite', ['uri' => $orig_uri, 'item' => $item]);
|
||||
|
||||
$item["verb"] = Activity::LIKE;
|
||||
$item["thr-parent"] = $orig_uri;
|
||||
$item["gravity"] = GRAVITY_ACTIVITY;
|
||||
$item["object-type"] = Activity\ObjectType::NOTE;
|
||||
$item['verb'] = Activity::LIKE;
|
||||
$item['thr-parent'] = $orig_uri;
|
||||
$item['gravity'] = GRAVITY_ACTIVITY;
|
||||
$item['object-type'] = Activity\ObjectType::NOTE;
|
||||
}
|
||||
|
||||
// http://activitystrea.ms/schema/1.0/rsvp-yes
|
||||
if (!in_array($item["verb"], [Activity::POST, Activity::LIKE, Activity::SHARE])) {
|
||||
Logger::info("Unhandled verb", ['verb' => $item["verb"], 'item' => $item]);
|
||||
if (!in_array($item['verb'], [Activity::POST, Activity::LIKE, Activity::SHARE])) {
|
||||
Logger::info('Unhandled verb', ['verb' => $item['verb'], 'item' => $item]);
|
||||
}
|
||||
|
||||
self::processPost($xpath, $entry, $item, $importer);
|
||||
|
|
@ -503,10 +521,10 @@ class OStatus
|
|||
$valid = !$uid || DI::pConfig()->get($uid, 'system', 'accept_only_sharer') != Item::COMPLETION_NONE;
|
||||
|
||||
if ($valid) {
|
||||
Logger::info("Item with uri ".self::$itemlist[0]['uri']." will be imported due to the system settings.");
|
||||
Logger::info('Item with URI ' . self::$itemlist[0]['uri'] . ' will be imported due to the system settings.');
|
||||
}
|
||||
} else {
|
||||
Logger::info("Item with uri ".self::$itemlist[0]['uri']." belongs to a contact (".self::$itemlist[0]['contact-id']."). It will be imported.");
|
||||
Logger::info('Item with URI ' . self::$itemlist[0]['uri'] . ' belongs to a contact (' . self::$itemlist[0]['contact-id'] . '). It will be imported.');
|
||||
}
|
||||
|
||||
if ($valid && DI::pConfig()->get($uid, 'system', 'accept_only_sharer') != Item::COMPLETION_LIKE) {
|
||||
|
|
@ -519,7 +537,7 @@ class OStatus
|
|||
}
|
||||
}
|
||||
if ($valid) {
|
||||
Logger::info("Item with uri ".self::$itemlist[0]['uri']." will be imported since the thread contains posts or shares.");
|
||||
Logger::info('Item with URI ' . self::$itemlist[0]['uri'] . ' will be imported since the thread contains posts or shares.');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -536,20 +554,20 @@ class OStatus
|
|||
}
|
||||
}
|
||||
foreach (self::$itemlist as $item) {
|
||||
$found = Post::exists(['uid' => $importer["uid"], 'uri' => $item["uri"]]);
|
||||
$found = Post::exists(['uid' => $importer['uid'], 'uri' => $item['uri']]);
|
||||
if ($found) {
|
||||
Logger::notice("Item with uri ".$item["uri"]." for user ".$importer["uid"]." already exists.");
|
||||
Logger::notice('Item with URI ' . $item['uri'] . ' for user ' . $importer['uid'] . ' already exists.');
|
||||
} elseif ($item['contact-id'] < 0) {
|
||||
Logger::notice("Item with uri ".$item["uri"]." is from a blocked contact.");
|
||||
Logger::notice('Item with URI ' . $item['uri'] . ' is from a blocked contact.');
|
||||
} else {
|
||||
$ret = Item::insert($item);
|
||||
Logger::info("Item with uri ".$item["uri"]." for user ".$importer["uid"].' stored. Return value: '.$ret);
|
||||
Logger::info('Item with URI ' . $item['uri'] . ' for user ' . $importer['uid'] . ' stored. Return value: ' . $ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
self::$itemlist = [];
|
||||
}
|
||||
Logger::info('Processing done for post with URI '.$item["uri"].' for user '.$importer["uid"].'.');
|
||||
Logger::info('Processing done for post with URI ' . $item['uri'] . ' for user '.$importer['uid'] . '.');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -565,13 +583,13 @@ class OStatus
|
|||
{
|
||||
$condition = ['uid' => $item['uid'], 'author-id' => $item['author-id'], 'uri' => $item['uri']];
|
||||
if (!Post::exists($condition)) {
|
||||
Logger::notice('Item from '.$item['author-link'].' with uri '.$item['uri'].' for user '.$item['uid']." wasn't found. We don't delete it.");
|
||||
Logger::notice('Item from ' . $item['author-link'] . ' with uri ' . $item['uri'] . ' for user ' . $item['uid'] . " wasn't found. We don't delete it.");
|
||||
return;
|
||||
}
|
||||
|
||||
Item::markForDeletion($condition);
|
||||
|
||||
Logger::notice('Deleted item with uri '.$item['uri'].' for user '.$item['uid']);
|
||||
Logger::notice('Deleted item with URI ' . $item['uri'] . ' for user ' . $item['uid']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -587,40 +605,40 @@ class OStatus
|
|||
*/
|
||||
private static function processPost(DOMXPath $xpath, $entry, array &$item, array $importer)
|
||||
{
|
||||
$item["body"] = HTML::toBBCode(XML::getFirstNodeValue($xpath, 'atom:content/text()', $entry));
|
||||
$item["object-type"] = XML::getFirstNodeValue($xpath, 'activity:object-type/text()', $entry);
|
||||
if (($item["object-type"] == Activity\ObjectType::BOOKMARK) || ($item["object-type"] == Activity\ObjectType::EVENT)) {
|
||||
$item["title"] = XML::getFirstNodeValue($xpath, 'atom:title/text()', $entry);
|
||||
$item["body"] = XML::getFirstNodeValue($xpath, 'atom:summary/text()', $entry);
|
||||
} elseif ($item["object-type"] == Activity\ObjectType::QUESTION) {
|
||||
$item["title"] = XML::getFirstNodeValue($xpath, 'atom:title/text()', $entry);
|
||||
$item['body'] = HTML::toBBCode(XML::getFirstNodeValue($xpath, 'atom:content/text()', $entry));
|
||||
$item['object-type'] = XML::getFirstNodeValue($xpath, 'activity:object-type/text()', $entry);
|
||||
if (($item['object-type'] == Activity\ObjectType::BOOKMARK) || ($item['object-type'] == Activity\ObjectType::EVENT)) {
|
||||
$item['title'] = XML::getFirstNodeValue($xpath, 'atom:title/text()', $entry);
|
||||
$item['body'] = XML::getFirstNodeValue($xpath, 'atom:summary/text()', $entry);
|
||||
} elseif ($item['object-type'] == Activity\ObjectType::QUESTION) {
|
||||
$item['title'] = XML::getFirstNodeValue($xpath, 'atom:title/text()', $entry);
|
||||
}
|
||||
|
||||
$item["created"] = XML::getFirstNodeValue($xpath, 'atom:published/text()', $entry);
|
||||
$item["edited"] = XML::getFirstNodeValue($xpath, 'atom:updated/text()', $entry);
|
||||
$item['created'] = XML::getFirstNodeValue($xpath, 'atom:published/text()', $entry);
|
||||
$item['edited'] = XML::getFirstNodeValue($xpath, 'atom:updated/text()', $entry);
|
||||
$item['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") {
|
||||
if ($attributes->name == 'ref') {
|
||||
$item['conversation-uri'] = $attributes->textContent;
|
||||
}
|
||||
if ($attributes->name == "href") {
|
||||
if ($attributes->name == 'href') {
|
||||
$item['conversation-href'] = $attributes->textContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$related = "";
|
||||
$related = '';
|
||||
|
||||
$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") {
|
||||
$item["thr-parent"] = $attributes->textContent;
|
||||
if ($attributes->name == 'ref') {
|
||||
$item['thr-parent'] = $attributes->textContent;
|
||||
}
|
||||
if ($attributes->name == "href") {
|
||||
if ($attributes->name == 'href') {
|
||||
$related = $attributes->textContent;
|
||||
}
|
||||
}
|
||||
|
|
@ -628,7 +646,7 @@ class OStatus
|
|||
|
||||
$georsspoint = $xpath->query('georss:point', $entry);
|
||||
if (!empty($georsspoint) && ($georsspoint->length > 0)) {
|
||||
$item["coord"] = $georsspoint->item(0)->nodeValue;
|
||||
$item['coord'] = $georsspoint->item(0)->nodeValue;
|
||||
}
|
||||
|
||||
$categories = $xpath->query('atom:category', $entry);
|
||||
|
|
@ -653,33 +671,33 @@ class OStatus
|
|||
$add_body = $link_data['add_body'];
|
||||
}
|
||||
|
||||
$repeat_of = "";
|
||||
$repeat_of = '';
|
||||
|
||||
$notice_info = $xpath->query('statusnet:notice_info', $entry);
|
||||
if ($notice_info && ($notice_info->length > 0)) {
|
||||
foreach ($notice_info->item(0)->attributes as $attributes) {
|
||||
if ($attributes->name == "source") {
|
||||
$item["app"] = strip_tags($attributes->textContent);
|
||||
if ($attributes->name == 'source') {
|
||||
$item['app'] = strip_tags($attributes->textContent);
|
||||
}
|
||||
if ($attributes->name == "repeat_of") {
|
||||
if ($attributes->name == 'repeat_of') {
|
||||
$repeat_of = $attributes->textContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Is it a repeated post?
|
||||
if (($repeat_of != "") || ($item["verb"] == Activity::SHARE)) {
|
||||
if (($repeat_of != '') || ($item['verb'] == Activity::SHARE)) {
|
||||
$link_data = self::processRepeatedItem($xpath, $entry, $item, $importer);
|
||||
if (!empty($link_data['add_body'])) {
|
||||
$add_body .= $link_data['add_body'];
|
||||
}
|
||||
}
|
||||
|
||||
$item["body"] .= $add_body;
|
||||
$item['body'] .= $add_body;
|
||||
|
||||
Tag::storeFromBody($item['uri-id'], $item['body']);
|
||||
|
||||
// Mastodon Content Warning
|
||||
if (($item["verb"] == Activity::POST) && $xpath->evaluate('boolean(atom:summary)', $entry)) {
|
||||
if (($item['verb'] == Activity::POST) && $xpath->evaluate('boolean(atom:summary)', $entry)) {
|
||||
$clear_text = XML::getFirstNodeValue($xpath, 'atom:summary/text()', $entry);
|
||||
if (!empty($clear_text)) {
|
||||
$item['content-warning'] = HTML::toBBCode($clear_text);
|
||||
|
|
@ -690,21 +708,21 @@ class OStatus
|
|||
self::fetchSelf($self, $item);
|
||||
}
|
||||
|
||||
if (!empty($item["conversation-href"])) {
|
||||
if (!empty($item['conversation-href'])) {
|
||||
self::fetchConversation($item['conversation-href'], $item['conversation-uri']);
|
||||
}
|
||||
|
||||
if (isset($item["thr-parent"])) {
|
||||
if (!Post::exists(['uid' => $importer["uid"], 'uri' => $item['thr-parent']])) {
|
||||
if (isset($item['thr-parent'])) {
|
||||
if (!Post::exists(['uid' => $importer['uid'], 'uri' => $item['thr-parent']])) {
|
||||
if ($related != '') {
|
||||
self::fetchRelated($related, $item["thr-parent"], $importer);
|
||||
self::fetchRelated($related, $item['thr-parent'], $importer);
|
||||
}
|
||||
} else {
|
||||
Logger::info('Reply with URI '.$item["uri"].' already existed for user '.$importer["uid"].'.');
|
||||
Logger::info('Reply with URI ' . $item['uri'] . ' already existed for user ' . $importer['uid'] . '.');
|
||||
}
|
||||
} else {
|
||||
$item["thr-parent"] = $item["uri"];
|
||||
$item["gravity"] = GRAVITY_PARENT;
|
||||
$item['thr-parent'] = $item['uri'];
|
||||
$item['gravity'] = GRAVITY_PARENT;
|
||||
}
|
||||
|
||||
if (($item['author-link'] != '') && !empty($item['protocol'])) {
|
||||
|
|
@ -722,7 +740,7 @@ class OStatus
|
|||
* @return void
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function fetchConversation($conversation, $conversation_uri)
|
||||
private static function fetchConversation(string $conversation, string $conversation_uri)
|
||||
{
|
||||
// Ensure that we only store a conversation once in a process
|
||||
if (isset(self::$conv_list[$conversation])) {
|
||||
|
|
@ -786,7 +804,7 @@ class OStatus
|
|||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function storeConversation($xml, $conversation = '', $conversation_uri = '')
|
||||
private static function storeConversation(string $xml, string $conversation = '', string $conversation_uri = '')
|
||||
{
|
||||
$doc = new DOMDocument();
|
||||
@$doc->loadXML($xml);
|
||||
|
|
@ -814,7 +832,7 @@ class OStatus
|
|||
$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") {
|
||||
if ($attributes->name == 'ref') {
|
||||
$conv_data['reply-to-uri'] = $attributes->textContent;
|
||||
}
|
||||
}
|
||||
|
|
@ -825,10 +843,10 @@ class OStatus
|
|||
$conv = $xpath->query('ostatus:conversation', $entry);
|
||||
if (is_object($conv->item(0))) {
|
||||
foreach ($conv->item(0)->attributes as $attributes) {
|
||||
if ($attributes->name == "ref") {
|
||||
if ($attributes->name == 'ref') {
|
||||
$conv_data['conversation-uri'] = $attributes->textContent;
|
||||
}
|
||||
if ($attributes->name == "href") {
|
||||
if ($attributes->name == 'href') {
|
||||
$conv_data['conversation-href'] = $attributes->textContent;
|
||||
}
|
||||
}
|
||||
|
|
@ -865,7 +883,7 @@ class OStatus
|
|||
* @return void
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function fetchSelf($self, array &$item)
|
||||
private static function fetchSelf(string $self, array &$item)
|
||||
{
|
||||
$condition = ['item-uri' => $self, 'protocol' => [Conversation::PARCEL_DFRN,
|
||||
Conversation::PARCEL_DIASPORA_DFRN, Conversation::PARCEL_LOCAL_DFRN,
|
||||
|
|
@ -888,9 +906,9 @@ class OStatus
|
|||
$doc->formatOutput = true;
|
||||
$xml = $doc->saveXML();
|
||||
|
||||
$item["protocol"] = Conversation::PARCEL_SALMON;
|
||||
$item["source"] = $xml;
|
||||
$item["direction"] = Conversation::PULL;
|
||||
$item['protocol'] = Conversation::PARCEL_SALMON;
|
||||
$item['source'] = $xml;
|
||||
$item['direction'] = Conversation::PULL;
|
||||
|
||||
Logger::info('Conversation '.$item['uri'].' is now fetched.');
|
||||
}
|
||||
|
|
@ -905,11 +923,18 @@ class OStatus
|
|||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function fetchRelated($related, $related_uri, $importer)
|
||||
private static function fetchRelated(string $related, string $related_uri, array $importer)
|
||||
{
|
||||
$condition = ['item-uri' => $related_uri, 'protocol' => [Conversation::PARCEL_DFRN,
|
||||
Conversation::PARCEL_DIASPORA_DFRN, Conversation::PARCEL_LOCAL_DFRN,
|
||||
Conversation::PARCEL_DIRECT, Conversation::PARCEL_SALMON]];
|
||||
$condition = [
|
||||
'item-uri' => $related_uri,
|
||||
'protocol' => [
|
||||
Conversation::PARCEL_DFRN,
|
||||
Conversation::PARCEL_DIASPORA_DFRN,
|
||||
Conversation::PARCEL_LOCAL_DFRN,
|
||||
Conversation::PARCEL_DIRECT,
|
||||
Conversation::PARCEL_SALMON,
|
||||
],
|
||||
];
|
||||
$conversation = DBA::selectFirst('conversation', ['source', 'protocol'], $condition);
|
||||
if (DBA::isResult($conversation)) {
|
||||
$stored = true;
|
||||
|
|
@ -994,7 +1019,7 @@ class OStatus
|
|||
$conversation = DBA::selectFirst('conversation', ['source'], $condition);
|
||||
if (DBA::isResult($conversation)) {
|
||||
$stored = true;
|
||||
Logger::info('Got cached XML from conversation for URI '.$related_uri);
|
||||
Logger::info('Got cached XML from conversation for URI ' . $related_uri);
|
||||
$xml = $conversation['source'];
|
||||
}
|
||||
}
|
||||
|
|
@ -1002,7 +1027,7 @@ class OStatus
|
|||
if ($xml != '') {
|
||||
self::process($xml, $importer, $contact, $hub, $stored, false, Conversation::PULL);
|
||||
} else {
|
||||
Logger::info("XML couldn't be fetched for URI: ".$related_uri." - href: ".$related);
|
||||
Logger::info('XML could not be fetched for URI: ' . $related_uri . ' - href: ' . $related);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -1019,7 +1044,7 @@ class OStatus
|
|||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function processRepeatedItem(DOMXPath $xpath, $entry, array &$item, array $importer)
|
||||
private static function processRepeatedItem(DOMXPath $xpath, $entry, array &$item, array $importer): array
|
||||
{
|
||||
$activityobject = $xpath->query('activity:object', $entry)->item(0);
|
||||
|
||||
|
|
@ -1031,7 +1056,7 @@ class OStatus
|
|||
|
||||
$orig_uri = XML::getFirstNodeValue($xpath, 'atom:id/text()', $activityobject);
|
||||
|
||||
$links = $xpath->query("atom:link", $activityobject);
|
||||
$links = $xpath->query('atom:link', $activityobject);
|
||||
if ($links) {
|
||||
$link_data = self::processLinks($links, $item);
|
||||
}
|
||||
|
|
@ -1042,22 +1067,22 @@ class OStatus
|
|||
|
||||
$orig_author = self::fetchAuthor($xpath, $activityobject, $importer, $dummy, false);
|
||||
|
||||
$item["author-name"] = $orig_author["author-name"];
|
||||
$item["author-link"] = $orig_author["author-link"];
|
||||
$item["author-id"] = $orig_author["author-id"];
|
||||
$item['author-name'] = $orig_author['author-name'];
|
||||
$item['author-link'] = $orig_author['author-link'];
|
||||
$item['author-id'] = $orig_author['author-id'];
|
||||
|
||||
$item["body"] = HTML::toBBCode($orig_body);
|
||||
$item["created"] = $orig_created;
|
||||
$item["edited"] = $orig_edited;
|
||||
$item['body'] = HTML::toBBCode($orig_body);
|
||||
$item['created'] = $orig_created;
|
||||
$item['edited'] = $orig_edited;
|
||||
|
||||
$item["uri"] = $orig_uri;
|
||||
$item['uri'] = $orig_uri;
|
||||
|
||||
$item["verb"] = XML::getFirstNodeValue($xpath, 'activity:verb/text()', $activityobject);
|
||||
$item['verb'] = XML::getFirstNodeValue($xpath, 'activity:verb/text()', $activityobject);
|
||||
|
||||
$item["object-type"] = XML::getFirstNodeValue($xpath, 'activity:object-type/text()', $activityobject);
|
||||
$item['object-type'] = XML::getFirstNodeValue($xpath, 'activity:object-type/text()', $activityobject);
|
||||
|
||||
// Mastodon Content Warning
|
||||
if (($item["verb"] == Activity::POST) && $xpath->evaluate('boolean(atom:summary)', $activityobject)) {
|
||||
if (($item['verb'] == Activity::POST) && $xpath->evaluate('boolean(atom:summary)', $activityobject)) {
|
||||
$clear_text = XML::getFirstNodeValue($xpath, 'atom:summary/text()', $activityobject);
|
||||
if (!empty($clear_text)) {
|
||||
$item['content-warning'] = HTML::toBBCode($clear_text);
|
||||
|
|
@ -1067,8 +1092,8 @@ class OStatus
|
|||
$inreplyto = $xpath->query('thr:in-reply-to', $activityobject);
|
||||
if (is_object($inreplyto->item(0))) {
|
||||
foreach ($inreplyto->item(0)->attributes as $attributes) {
|
||||
if ($attributes->name == "ref") {
|
||||
$item["thr-parent"] = $attributes->textContent;
|
||||
if ($attributes->name == 'ref') {
|
||||
$item['thr-parent'] = $attributes->textContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1081,10 +1106,9 @@ class OStatus
|
|||
*
|
||||
* @param object $links The xml data that contain links
|
||||
* @param array $item The item array
|
||||
*
|
||||
* @return array with data from the links
|
||||
*/
|
||||
private static function processLinks($links, array &$item)
|
||||
private static function processLinks($links, array &$item): array
|
||||
{
|
||||
$link_data = ['add_body' => '', 'self' => ''];
|
||||
|
||||
|
|
@ -1093,24 +1117,26 @@ class OStatus
|
|||
|
||||
if (!empty($attribute['rel']) && !empty($attribute['href'])) {
|
||||
switch ($attribute['rel']) {
|
||||
case "alternate":
|
||||
$item["plink"] = $attribute['href'];
|
||||
if (($item["object-type"] == Activity\ObjectType::QUESTION)
|
||||
|| ($item["object-type"] == Activity\ObjectType::EVENT)
|
||||
case 'alternate':
|
||||
$item['plink'] = $attribute['href'];
|
||||
if (($item['object-type'] == Activity\ObjectType::QUESTION)
|
||||
|| ($item['object-type'] == Activity\ObjectType::EVENT)
|
||||
) {
|
||||
Post\Media::insert(['uri-id' => $item['uri-id'], 'type' => Post\Media::UNKNOWN,
|
||||
'url' => $attribute['href'], 'mimetype' => $attribute['type'] ?? null,
|
||||
'size' => $attribute['length'] ?? null, 'description' => $attribute['title'] ?? null]);
|
||||
}
|
||||
break;
|
||||
case "ostatus:conversation":
|
||||
|
||||
case 'ostatus:conversation':
|
||||
$link_data['conversation'] = $attribute['href'];
|
||||
$item['conversation-href'] = $link_data['conversation'];
|
||||
if (!isset($item['conversation-uri'])) {
|
||||
$item['conversation-uri'] = $item['conversation-href'];
|
||||
}
|
||||
break;
|
||||
case "enclosure":
|
||||
|
||||
case 'enclosure':
|
||||
$filetype = strtolower(substr($attribute['type'], 0, strpos($attribute['type'], '/')));
|
||||
if ($filetype == 'image') {
|
||||
$link_data['add_body'] .= "\n[img]".$attribute['href'].'[/img]';
|
||||
|
|
@ -1120,10 +1146,11 @@ class OStatus
|
|||
'size' => $attribute['length'] ?? null, 'description' => $attribute['title'] ?? null]);
|
||||
}
|
||||
break;
|
||||
case "related":
|
||||
if ($item["object-type"] != Activity\ObjectType::BOOKMARK) {
|
||||
if (!isset($item["thr-parent"])) {
|
||||
$item["thr-parent"] = $attribute['href'];
|
||||
|
||||
case 'related':
|
||||
if ($item['object-type'] != Activity\ObjectType::BOOKMARK) {
|
||||
if (!isset($item['thr-parent'])) {
|
||||
$item['thr-parent'] = $attribute['href'];
|
||||
}
|
||||
$link_data['related'] = $attribute['href'];
|
||||
} else {
|
||||
|
|
@ -1132,12 +1159,16 @@ class OStatus
|
|||
'size' => $attribute['length'] ?? null, 'description' => $attribute['title'] ?? null]);
|
||||
}
|
||||
break;
|
||||
case "self":
|
||||
if (empty($item["plink"])) {
|
||||
$item["plink"] = $attribute['href'];
|
||||
|
||||
case 'self':
|
||||
if (empty($item['plink'])) {
|
||||
$item['plink'] = $attribute['href'];
|
||||
}
|
||||
$link_data['self'] = $attribute['href'];
|
||||
break;
|
||||
|
||||
default:
|
||||
Logger::warning('Unsupported rel=' . $attribute['rel'] . ', href=' . $attribute['href'] . ', object-type=' . $attribute['object-type']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1148,31 +1179,31 @@ class OStatus
|
|||
* Create an url out of an uri
|
||||
*
|
||||
* @param string $href URI in the format "parameter1:parameter1:..."
|
||||
*
|
||||
* @return string URL in the format http(s)://....
|
||||
*/
|
||||
private static function convertHref($href)
|
||||
private static function convertHref(string $href): string
|
||||
{
|
||||
$elements = explode(":", $href);
|
||||
$elements = explode(':', $href);
|
||||
|
||||
if ((count($elements) <= 2) || ($elements[0] != "tag")) {
|
||||
if ((count($elements) <= 2) || ($elements[0] != 'tag')) {
|
||||
return $href;
|
||||
}
|
||||
|
||||
$server = explode(",", $elements[1]);
|
||||
$conversation = explode("=", $elements[2]);
|
||||
$server = explode(',', $elements[1]);
|
||||
$conversation = explode('=', $elements[2]);
|
||||
|
||||
if ((count($elements) == 4) && ($elements[2] == "post")) {
|
||||
return "http://".$server[0]."/notice/".$elements[3];
|
||||
if ((count($elements) == 4) && ($elements[2] == 'post')) {
|
||||
return 'http://' . $server[0] . '/notice/' . $elements[3];
|
||||
}
|
||||
|
||||
if ((count($conversation) != 2) || ($conversation[1] =="")) {
|
||||
if ((count($conversation) != 2) || ($conversation[1] == '')) {
|
||||
return $href;
|
||||
}
|
||||
if ($elements[3] == "objectType=thread") {
|
||||
return "http://".$server[0]."/conversation/".$conversation[1];
|
||||
|
||||
if ($elements[3] == 'objectType=thread') {
|
||||
return 'http://' . $server[0] . '/conversation/' . $conversation[1];
|
||||
} else {
|
||||
return "http://".$server[0]."/notice/".$conversation[1];
|
||||
return 'http://' . $server[0] . '/notice/' . $conversation[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1180,35 +1211,35 @@ class OStatus
|
|||
* Cleans the body of a post if it contains picture links
|
||||
*
|
||||
* @param string $body The body
|
||||
*
|
||||
* @param integer $uriid URI id
|
||||
* @return string The cleaned body
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function formatPicturePost($body, $uriid)
|
||||
public static function formatPicturePost(string $body, int $uriid): string
|
||||
{
|
||||
$siteinfo = BBCode::getAttachedData($body);
|
||||
|
||||
if (($siteinfo["type"] == "photo") && (!empty($siteinfo["preview"]) || !empty($siteinfo["image"]))) {
|
||||
if (isset($siteinfo["preview"])) {
|
||||
$preview = $siteinfo["preview"];
|
||||
if (($siteinfo['type'] == 'photo') && (!empty($siteinfo['preview']) || !empty($siteinfo['image']))) {
|
||||
if (isset($siteinfo['preview'])) {
|
||||
$preview = $siteinfo['preview'];
|
||||
} else {
|
||||
$preview = $siteinfo["image"];
|
||||
$preview = $siteinfo['image'];
|
||||
}
|
||||
|
||||
// Is it a remote picture? Then make a smaller preview here
|
||||
$preview = Post\Link::getByLink($uriid, $preview, Proxy::SIZE_SMALL);
|
||||
|
||||
// Is it a local picture? Then make it smaller here
|
||||
$preview = str_replace(["-0.jpg", "-0.png"], ["-2.jpg", "-2.png"], $preview);
|
||||
$preview = str_replace(["-1.jpg", "-1.png"], ["-2.jpg", "-2.png"], $preview);
|
||||
$preview = str_replace(['-0.jpg', '-0.png'], ['-2.jpg', '-2.png'], $preview);
|
||||
$preview = str_replace(['-1.jpg', '-1.png'], ['-2.jpg', '-2.png'], $preview);
|
||||
|
||||
if (isset($siteinfo["url"])) {
|
||||
$url = $siteinfo["url"];
|
||||
if (isset($siteinfo['url'])) {
|
||||
$url = $siteinfo['url'];
|
||||
} else {
|
||||
$url = $siteinfo["image"];
|
||||
$url = $siteinfo['image'];
|
||||
}
|
||||
|
||||
$body = trim($siteinfo["text"])." [url]".$url."[/url]\n[img]".$preview."[/img]";
|
||||
$body = trim($siteinfo['text']) . ' [url]' . $url . "[/url]\n[img]" . $preview . '[/img]';
|
||||
}
|
||||
|
||||
return $body;
|
||||
|
|
@ -1221,54 +1252,63 @@ class OStatus
|
|||
* @param array $owner Contact data of the poster
|
||||
* @param string $filter The related feed filter (activity, posts or comments)
|
||||
*
|
||||
* @return object header root element
|
||||
* @return DOMElement Header root element
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function addHeader(DOMDocument $doc, array $owner, $filter)
|
||||
private static function addHeader(DOMDocument $doc, array $owner, string $filter): DOMElement
|
||||
{
|
||||
$root = $doc->createElementNS(ActivityNamespace::ATOM1, 'feed');
|
||||
$doc->appendChild($root);
|
||||
|
||||
$root->setAttribute("xmlns:thr", ActivityNamespace::THREAD);
|
||||
$root->setAttribute("xmlns:georss", ActivityNamespace::GEORSS);
|
||||
$root->setAttribute("xmlns:activity", ActivityNamespace::ACTIVITY);
|
||||
$root->setAttribute("xmlns:media", ActivityNamespace::MEDIA);
|
||||
$root->setAttribute("xmlns:poco", ActivityNamespace::POCO);
|
||||
$root->setAttribute("xmlns:ostatus", ActivityNamespace::OSTATUS);
|
||||
$root->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET);
|
||||
$root->setAttribute("xmlns:mastodon", ActivityNamespace::MASTODON);
|
||||
$root->setAttribute('xmlns:thr', ActivityNamespace::THREAD);
|
||||
$root->setAttribute('xmlns:georss', ActivityNamespace::GEORSS);
|
||||
$root->setAttribute('xmlns:activity', ActivityNamespace::ACTIVITY);
|
||||
$root->setAttribute('xmlns:media', ActivityNamespace::MEDIA);
|
||||
$root->setAttribute('xmlns:poco', ActivityNamespace::POCO);
|
||||
$root->setAttribute('xmlns:ostatus', ActivityNamespace::OSTATUS);
|
||||
$root->setAttribute('xmlns:statusnet', ActivityNamespace::STATUSNET);
|
||||
$root->setAttribute('xmlns:mastodon', ActivityNamespace::MASTODON);
|
||||
|
||||
$title = '';
|
||||
$selfUri = '/feed/' . $owner["nick"] . '/';
|
||||
$selfUri = '/feed/' . $owner['nick'] . '/';
|
||||
switch ($filter) {
|
||||
case 'activity':
|
||||
$title = DI::l10n()->t('%s\'s timeline', $owner['name']);
|
||||
$selfUri .= $filter;
|
||||
break;
|
||||
|
||||
case 'posts':
|
||||
$title = DI::l10n()->t('%s\'s posts', $owner['name']);
|
||||
break;
|
||||
|
||||
case 'comments':
|
||||
$title = DI::l10n()->t('%s\'s comments', $owner['name']);
|
||||
$selfUri .= $filter;
|
||||
break;
|
||||
}
|
||||
|
||||
$selfUri = "/dfrn_poll/" . $owner["nick"];
|
||||
$selfUri = '/dfrn_poll/' . $owner['nick'];
|
||||
|
||||
$attributes = ["uri" => "https://friendi.ca", "version" => FRIENDICA_VERSION . "-" . DB_UPDATE_VERSION];
|
||||
XML::addElement($doc, $root, "generator", FRIENDICA_PLATFORM, $attributes);
|
||||
XML::addElement($doc, $root, "id", DI::baseUrl() . "/profile/" . $owner["nick"]);
|
||||
XML::addElement($doc, $root, "title", $title);
|
||||
XML::addElement($doc, $root, "subtitle", sprintf("Updates from %s on %s", $owner["name"], DI::config()->get('config', 'sitename')));
|
||||
XML::addElement($doc, $root, "logo", User::getAvatarUrl($owner, Proxy::SIZE_SMALL));
|
||||
XML::addElement($doc, $root, "updated", DateTimeFormat::utcNow(DateTimeFormat::ATOM));
|
||||
$attributes = [
|
||||
'uri' => 'https://friendi.ca',
|
||||
'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION,
|
||||
];
|
||||
XML::addElement($doc, $root, 'generator', FRIENDICA_PLATFORM, $attributes);
|
||||
XML::addElement($doc, $root, 'id', DI::baseUrl() . '/profile/' . $owner['nick']);
|
||||
XML::addElement($doc, $root, 'title', $title);
|
||||
XML::addElement($doc, $root, 'subtitle', sprintf("Updates from %s on %s", $owner['name'], DI::config()->get('config', 'sitename')));
|
||||
XML::addElement($doc, $root, 'logo', User::getAvatarUrl($owner, Proxy::SIZE_SMALL));
|
||||
XML::addElement($doc, $root, 'updated', DateTimeFormat::utcNow(DateTimeFormat::ATOM));
|
||||
|
||||
$author = self::addAuthor($doc, $owner, true);
|
||||
$root->appendChild($author);
|
||||
|
||||
$attributes = ["href" => $owner["url"], "rel" => "alternate", "type" => "text/html"];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = [
|
||||
'href' => $owner['url'],
|
||||
'rel' => 'alternate',
|
||||
'type' => 'text/html',
|
||||
];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
|
||||
/// @TODO We have to find out what this is
|
||||
/// $attributes = array("href" => DI::baseUrl()."/sup",
|
||||
|
|
@ -1276,25 +1316,30 @@ class OStatus
|
|||
/// "type" => "application/json");
|
||||
/// XML::addElement($doc, $root, "link", "", $attributes);
|
||||
|
||||
self::hublinks($doc, $root, $owner["nick"]);
|
||||
self::addHubLink($doc, $root, $owner['nick']);
|
||||
|
||||
$attributes = ["href" => DI::baseUrl() . "/salmon/" . $owner["nick"], "rel" => "salmon"];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = ['href' => DI::baseUrl() . '/salmon/' . $owner['nick'], 'rel' => 'salmon'];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
|
||||
$attributes = ["href" => DI::baseUrl() . "/salmon/" . $owner["nick"], "rel" => "http://salmon-protocol.org/ns/salmon-replies"];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = ['href' => DI::baseUrl() . '/salmon/' . $owner['nick'], 'rel' => 'http://salmon-protocol.org/ns/salmon-replies'];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
|
||||
$attributes = ["href" => DI::baseUrl() . "/salmon/" . $owner["nick"], "rel" => "http://salmon-protocol.org/ns/salmon-mention"];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = ['href' => DI::baseUrl() . '/salmon/' . $owner['nick'], 'rel' => 'http://salmon-protocol.org/ns/salmon-mention'];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
|
||||
$attributes = ["href" => DI::baseUrl() . $selfUri, "rel" => "self", "type" => "application/atom+xml"];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = ['href' => DI::baseUrl() . $selfUri, 'rel' => 'self', 'type' => 'application/atom+xml'];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
|
||||
if ($owner['contact-type'] == Contact::TYPE_COMMUNITY) {
|
||||
$condition = ['uid' => $owner['uid'], 'self' => false, 'pending' => false,
|
||||
'archive' => false, 'hidden' => false, 'blocked' => false];
|
||||
$members = DBA::count('contact', $condition);
|
||||
XML::addElement($doc, $root, "statusnet:group_info", "", ["member_count" => $members]);
|
||||
$members = DBA::count('contact', [
|
||||
'uid' => $owner['uid'],
|
||||
'self' => false,
|
||||
'pending' => false,
|
||||
'archive' => false,
|
||||
'hidden' => false,
|
||||
'blocked' => false,
|
||||
]);
|
||||
XML::addElement($doc, $root, 'statusnet:group_info', '', ['member_count' => $members]);
|
||||
}
|
||||
|
||||
return $root;
|
||||
|
|
@ -1304,65 +1349,70 @@ class OStatus
|
|||
* Add the link to the push hubs to the XML document
|
||||
*
|
||||
* @param DOMDocument $doc XML document
|
||||
* @param object $root XML root element where the hub links are added
|
||||
* @param object $nick nick
|
||||
* @param DOMElement $root XML root element where the hub links are added
|
||||
* @param string $nick Nickname
|
||||
* @return void
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function hublinks(DOMDocument $doc, $root, $nick)
|
||||
public static function addHubLink(DOMDocument $doc, DOMElement $root, string $nick)
|
||||
{
|
||||
$h = DI::baseUrl() . '/pubsubhubbub/'.$nick;
|
||||
XML::addElement($doc, $root, "link", "", ["href" => $h, "rel" => "hub"]);
|
||||
$h = DI::baseUrl() . '/pubsubhubbub/' . $nick;
|
||||
XML::addElement($doc, $root, 'link', '', ['href' => $h, 'rel' => 'hub']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds attachment data to the XML document
|
||||
*
|
||||
* @param DOMDocument $doc XML document
|
||||
* @param object $root XML root element where the hub links are added
|
||||
* @param DOMElement $root XML root element where the hub links are added
|
||||
* @param array $item Data of the item that is to be posted
|
||||
* @return void
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function getAttachment(DOMDocument $doc, $root, $item)
|
||||
public static function getAttachment(DOMDocument $doc, DOMElement $root, array $item)
|
||||
{
|
||||
$siteinfo = BBCode::getAttachedData($item["body"]);
|
||||
$siteinfo = BBCode::getAttachedData($item['body']);
|
||||
|
||||
switch ($siteinfo["type"]) {
|
||||
switch ($siteinfo['type']) {
|
||||
case 'photo':
|
||||
if (!empty($siteinfo["image"])) {
|
||||
$imgdata = Images::getInfoFromURLCached($siteinfo["image"]);
|
||||
if (!empty($siteinfo['image'])) {
|
||||
$imgdata = Images::getInfoFromURLCached($siteinfo['image']);
|
||||
if ($imgdata) {
|
||||
$attributes = ["rel" => "enclosure",
|
||||
"href" => $siteinfo["image"],
|
||||
"type" => $imgdata["mime"],
|
||||
"length" => intval($imgdata["size"])];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
$attributes = [
|
||||
'rel' => 'enclosure',
|
||||
'href' => $siteinfo['image'],
|
||||
'type' => $imgdata['mime'],
|
||||
'length' => intval($imgdata['size']),
|
||||
];
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'video':
|
||||
$attributes = ["rel" => "enclosure",
|
||||
"href" => $siteinfo["url"],
|
||||
"type" => "text/html; charset=UTF-8",
|
||||
"length" => "0",
|
||||
"title" => ($siteinfo["title"] ?? '') ?: $siteinfo["url"],
|
||||
$attributes = [
|
||||
'rel' => 'enclosure',
|
||||
'href' => $siteinfo['url'],
|
||||
'type' => 'text/html; charset=UTF-8',
|
||||
'length' => '0',
|
||||
'title' => ($siteinfo['title'] ?? '') ?: $siteinfo['url'],
|
||||
];
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!DI::config()->get('system', 'ostatus_not_attach_preview') && ($siteinfo["type"] != "photo") && isset($siteinfo["image"])) {
|
||||
$imgdata = Images::getInfoFromURLCached($siteinfo["image"]);
|
||||
if (!DI::config()->get('system', 'ostatus_not_attach_preview') && ($siteinfo['type'] != 'photo') && isset($siteinfo['image'])) {
|
||||
$imgdata = Images::getInfoFromURLCached($siteinfo['image']);
|
||||
if ($imgdata) {
|
||||
$attributes = ["rel" => "enclosure",
|
||||
"href" => $siteinfo["image"],
|
||||
"type" => $imgdata["mime"],
|
||||
"length" => intval($imgdata["size"])];
|
||||
$attributes = [
|
||||
'rel' => 'enclosure',
|
||||
'href' => $siteinfo['image'],
|
||||
'type' => $imgdata['mime'],
|
||||
'length' => intval($imgdata['size']),
|
||||
];
|
||||
|
||||
XML::addElement($doc, $root, "link", "", $attributes);
|
||||
XML::addElement($doc, $root, 'link', '', $attributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1388,75 +1438,80 @@ class OStatus
|
|||
* @param DOMDocument $doc XML document
|
||||
* @param array $owner Contact data of the poster
|
||||
* @param bool $show_profile Whether to show profile
|
||||
*
|
||||
* @return \DOMElement author element
|
||||
* @return DOMElement Author element
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function addAuthor(DOMDocument $doc, array $owner, $show_profile = true)
|
||||
private static function addAuthor(DOMDocument $doc, array $owner, bool $show_profile = true): DOMElement
|
||||
{
|
||||
$profile = DBA::selectFirst('profile', ['homepage', 'publish'], ['uid' => $owner['uid']]);
|
||||
$author = $doc->createElement("author");
|
||||
XML::addElement($doc, $author, "id", $owner["url"]);
|
||||
$author = $doc->createElement('author');
|
||||
XML::addElement($doc, $author, 'id', $owner['url']);
|
||||
if ($owner['contact-type'] == Contact::TYPE_COMMUNITY) {
|
||||
XML::addElement($doc, $author, "activity:object-type", Activity\ObjectType::GROUP);
|
||||
XML::addElement($doc, $author, 'activity:object-type', Activity\ObjectType::GROUP);
|
||||
} else {
|
||||
XML::addElement($doc, $author, "activity:object-type", Activity\ObjectType::PERSON);
|
||||
XML::addElement($doc, $author, 'activity:object-type', Activity\ObjectType::PERSON);
|
||||
}
|
||||
|
||||
XML::addElement($doc, $author, "uri", $owner["url"]);
|
||||
XML::addElement($doc, $author, "name", $owner["nick"]);
|
||||
XML::addElement($doc, $author, "email", $owner["addr"]);
|
||||
XML::addElement($doc, $author, 'uri', $owner['url']);
|
||||
XML::addElement($doc, $author, 'name', $owner['nick']);
|
||||
XML::addElement($doc, $author, 'email', $owner['addr']);
|
||||
if ($show_profile) {
|
||||
XML::addElement($doc, $author, "summary", BBCode::convertForUriId($owner['uri-id'], $owner["about"], BBCode::OSTATUS));
|
||||
XML::addElement($doc, $author, 'summary', BBCode::convertForUriId($owner['uri-id'], $owner['about'], BBCode::OSTATUS));
|
||||
}
|
||||
|
||||
$attributes = ["rel" => "alternate", "type" => "text/html", "href" => $owner["url"]];
|
||||
XML::addElement($doc, $author, "link", "", $attributes);
|
||||
|
||||
$attributes = [
|
||||
"rel" => "avatar",
|
||||
"type" => "image/jpeg", // To-Do?
|
||||
"media:width" => Proxy::PIXEL_SMALL,
|
||||
"media:height" => Proxy::PIXEL_SMALL,
|
||||
"href" => User::getAvatarUrl($owner, Proxy::SIZE_SMALL)];
|
||||
XML::addElement($doc, $author, "link", "", $attributes);
|
||||
'rel' => 'alternate',
|
||||
'type' => 'text/html',
|
||||
'href' => $owner['url'],
|
||||
];
|
||||
XML::addElement($doc, $author, 'link', '', $attributes);
|
||||
|
||||
if (isset($owner["thumb"])) {
|
||||
$attributes = [
|
||||
'rel' => 'avatar',
|
||||
'type' => 'image/jpeg', // To-Do?
|
||||
'media:width' => Proxy::PIXEL_SMALL,
|
||||
'media:height' => Proxy::PIXEL_SMALL,
|
||||
'href' => User::getAvatarUrl($owner, Proxy::SIZE_SMALL),
|
||||
];
|
||||
XML::addElement($doc, $author, 'link', '', $attributes);
|
||||
|
||||
if (isset($owner['thumb'])) {
|
||||
$attributes = [
|
||||
"rel" => "avatar",
|
||||
"type" => "image/jpeg", // To-Do?
|
||||
"media:width" => Proxy::PIXEL_THUMB,
|
||||
"media:height" => Proxy::PIXEL_THUMB,
|
||||
"href" => User::getAvatarUrl($owner, Proxy::SIZE_THUMB)];
|
||||
XML::addElement($doc, $author, "link", "", $attributes);
|
||||
'rel' => 'avatar',
|
||||
'type' => 'image/jpeg', // To-Do?
|
||||
'media:width' => Proxy::PIXEL_THUMB,
|
||||
'media:height' => Proxy::PIXEL_THUMB,
|
||||
'href' => User::getAvatarUrl($owner, Proxy::SIZE_THUMB),
|
||||
];
|
||||
XML::addElement($doc, $author, 'link', '', $attributes);
|
||||
}
|
||||
|
||||
XML::addElement($doc, $author, "poco:preferredUsername", $owner["nick"]);
|
||||
XML::addElement($doc, $author, "poco:displayName", $owner["name"]);
|
||||
XML::addElement($doc, $author, 'poco:preferredUsername', $owner['nick']);
|
||||
XML::addElement($doc, $author, 'poco:displayName', $owner['name']);
|
||||
if ($show_profile) {
|
||||
XML::addElement($doc, $author, "poco:note", BBCode::convertForUriId($owner['uri-id'], $owner["about"], BBCode::OSTATUS));
|
||||
XML::addElement($doc, $author, 'poco:note', BBCode::convertForUriId($owner['uri-id'], $owner['about'], BBCode::OSTATUS));
|
||||
|
||||
if (trim($owner["location"]) != "") {
|
||||
$element = $doc->createElement("poco:address");
|
||||
XML::addElement($doc, $element, "poco:formatted", $owner["location"]);
|
||||
if (trim($owner['location']) != '') {
|
||||
$element = $doc->createElement('poco:address');
|
||||
XML::addElement($doc, $element, 'poco:formatted', $owner['location']);
|
||||
$author->appendChild($element);
|
||||
}
|
||||
}
|
||||
|
||||
if (DBA::isResult($profile) && !$show_profile) {
|
||||
if (trim($profile["homepage"]) != "") {
|
||||
$urls = $doc->createElement("poco:urls");
|
||||
XML::addElement($doc, $urls, "poco:type", "homepage");
|
||||
XML::addElement($doc, $urls, "poco:value", $profile["homepage"]);
|
||||
XML::addElement($doc, $urls, "poco:primary", "true");
|
||||
if (trim($profile['homepage']) != '') {
|
||||
$urls = $doc->createElement('poco:urls');
|
||||
XML::addElement($doc, $urls, 'poco:type', 'homepage');
|
||||
XML::addElement($doc, $urls, 'poco:value', $profile['homepage']);
|
||||
XML::addElement($doc, $urls, 'poco:primary', 'true');
|
||||
$author->appendChild($urls);
|
||||
}
|
||||
|
||||
XML::addElement($doc, $author, "followers", "", ["url" => DI::baseUrl() . "/profile/" . $owner["nick"] . "/contacts/followers"]);
|
||||
XML::addElement($doc, $author, "statusnet:profile_info", "", ["local_id" => $owner["uid"]]);
|
||||
XML::addElement($doc, $author, 'followers', '', ['url' => DI::baseUrl() . '/profile/' . $owner['nick'] . '/contacts/followers']);
|
||||
XML::addElement($doc, $author, 'statusnet:profile_info', '', ['local_id' => $owner['uid']]);
|
||||
|
||||
if ($profile["publish"]) {
|
||||
XML::addElement($doc, $author, "mastodon:scope", "public");
|
||||
if ($profile['publish']) {
|
||||
XML::addElement($doc, $author, 'mastodon:scope', 'public');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1473,10 +1528,9 @@ class OStatus
|
|||
* Returns the given activity if present - otherwise returns the "post" activity
|
||||
*
|
||||
* @param array $item Data of the item that is to be posted
|
||||
*
|
||||
* @return string activity
|
||||
*/
|
||||
public static function constructVerb(array $item)
|
||||
public static function constructVerb(array $item): string
|
||||
{
|
||||
if (!empty($item['verb'])) {
|
||||
return $item['verb'];
|
||||
|
|
@ -1489,10 +1543,9 @@ class OStatus
|
|||
* Returns the given object type if present - otherwise returns the "note" object type
|
||||
*
|
||||
* @param array $item Data of the item that is to be posted
|
||||
*
|
||||
* @return string Object type
|
||||
*/
|
||||
private static function constructObjecttype(array $item)
|
||||
private static function constructObjecttype(array $item): string
|
||||
{
|
||||
if (!empty($item['object-type']) && in_array($item['object-type'], [Activity\ObjectType::NOTE, Activity\ObjectType::COMMENT])) {
|
||||
return $item['object-type'];
|
||||
|
|
@ -1509,15 +1562,15 @@ class OStatus
|
|||
* @param array $owner Contact data of the poster
|
||||
* @param bool $toplevel optional default false
|
||||
*
|
||||
* @return \DOMElement Entry element
|
||||
* @return DOMElement Entry element
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function entry(DOMDocument $doc, array $item, array $owner, $toplevel = false)
|
||||
private static function entry(DOMDocument $doc, array $item, array $owner, bool $toplevel = false): DOMElement
|
||||
{
|
||||
if ($item["verb"] == Activity::LIKE) {
|
||||
if ($item['verb'] == Activity::LIKE) {
|
||||
return self::likeEntry($doc, $item, $owner, $toplevel);
|
||||
} elseif (in_array($item["verb"], [Activity::FOLLOW, Activity::O_UNFOLLOW])) {
|
||||
} elseif (in_array($item['verb'], [Activity::FOLLOW, Activity::O_UNFOLLOW])) {
|
||||
return self::followEntry($doc, $item, $owner, $toplevel);
|
||||
} else {
|
||||
return self::noteEntry($doc, $item, $owner, $toplevel);
|
||||
|
|
@ -1531,29 +1584,28 @@ class OStatus
|
|||
* @param array $item Data of the item that is to be posted
|
||||
* @param array $owner Contact data of the poster
|
||||
* @param bool $toplevel Is it for en entry element (false) or a feed entry (true)?
|
||||
*
|
||||
* @return \DOMElement Entry element with "like"
|
||||
* @return DOMElement Entry element with "like"
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function likeEntry(DOMDocument $doc, array $item, array $owner, $toplevel)
|
||||
private static function likeEntry(DOMDocument $doc, array $item, array $owner, bool $toplevel): DOMElement
|
||||
{
|
||||
if (($item['gravity'] != GRAVITY_PARENT) && (Strings::normaliseLink($item["author-link"]) != Strings::normaliseLink($owner["url"]))) {
|
||||
Logger::info("OStatus entry is from author ".$owner["url"]." - not from ".$item["author-link"].". Quitting.");
|
||||
if (($item['gravity'] != GRAVITY_PARENT) && (Strings::normaliseLink($item['author-link']) != Strings::normaliseLink($owner['url']))) {
|
||||
Logger::info('OStatus entry is from author ' . $owner['url'] . ' - not from ' . $item['author-link'] . '. Quitting.');
|
||||
}
|
||||
|
||||
$entry = self::entryHeader($doc, $owner, $item, $toplevel);
|
||||
|
||||
$verb = ActivityNamespace::ACTIVITY_SCHEMA . "favorite";
|
||||
self::entryContent($doc, $entry, $item, $owner, "Favorite", $verb, false);
|
||||
$verb = ActivityNamespace::ACTIVITY_SCHEMA . 'favorite';
|
||||
self::entryContent($doc, $entry, $item, $owner, 'Favorite', $verb, false);
|
||||
|
||||
$parent = Post::selectFirst([], ['uri' => $item["thr-parent"], 'uid' => $item["uid"]]);
|
||||
$parent = Post::selectFirst([], ['uri' => $item['thr-parent'], 'uid' => $item['uid']]);
|
||||
if (DBA::isResult($parent)) {
|
||||
$as_object = $doc->createElement("activity:object");
|
||||
$as_object = $doc->createElement('activity:object');
|
||||
|
||||
XML::addElement($doc, $as_object, "activity:object-type", self::constructObjecttype($parent));
|
||||
XML::addElement($doc, $as_object, 'activity:object-type', self::constructObjecttype($parent));
|
||||
|
||||
self::entryContent($doc, $as_object, $parent, $owner, "New entry");
|
||||
self::entryContent($doc, $as_object, $parent, $owner, 'New entry');
|
||||
|
||||
$entry->appendChild($as_object);
|
||||
}
|
||||
|
|
@ -1569,39 +1621,42 @@ class OStatus
|
|||
* @param DOMDocument $doc XML document
|
||||
* @param array $owner Contact data of the poster
|
||||
* @param array $contact Contact data of the target
|
||||
*
|
||||
* @return object author element
|
||||
* @return DOMElement author element
|
||||
*/
|
||||
private static function addPersonObject(DOMDocument $doc, array $owner, array $contact)
|
||||
private static function addPersonObject(DOMDocument $doc, array $owner, array $contact): DOMElement
|
||||
{
|
||||
$object = $doc->createElement("activity:object");
|
||||
XML::addElement($doc, $object, "activity:object-type", Activity\ObjectType::PERSON);
|
||||
$object = $doc->createElement('activity:object');
|
||||
XML::addElement($doc, $object, 'activity:object-type', Activity\ObjectType::PERSON);
|
||||
|
||||
if ($contact['network'] == Protocol::PHANTOM) {
|
||||
XML::addElement($doc, $object, "id", $contact['url']);
|
||||
XML::addElement($doc, $object, 'id', $contact['url']);
|
||||
return $object;
|
||||
}
|
||||
|
||||
XML::addElement($doc, $object, "id", $contact["alias"]);
|
||||
XML::addElement($doc, $object, "title", $contact["nick"]);
|
||||
XML::addElement($doc, $object, 'id', $contact['alias']);
|
||||
XML::addElement($doc, $object, 'title', $contact['nick']);
|
||||
|
||||
$attributes = ["rel" => "alternate", "type" => "text/html", "href" => $contact["url"]];
|
||||
XML::addElement($doc, $object, "link", "", $attributes);
|
||||
XML::addElement($doc, $object, 'link', '', [
|
||||
'rel' => 'alternate',
|
||||
'type' => 'text/html',
|
||||
'href' => $contact['url'],
|
||||
]);
|
||||
|
||||
$attributes = [
|
||||
"rel" => "avatar",
|
||||
"type" => "image/jpeg", // To-Do?
|
||||
"media:width" => 300,
|
||||
"media:height" => 300,
|
||||
"href" => $contact["photo"]];
|
||||
XML::addElement($doc, $object, "link", "", $attributes);
|
||||
'rel' => 'avatar',
|
||||
'type' => 'image/jpeg', // To-Do?
|
||||
'media:width' => 300,
|
||||
'media:height' => 300,
|
||||
'href' => $contact['photo'],
|
||||
];
|
||||
XML::addElement($doc, $object, 'link', '', $attributes);
|
||||
|
||||
XML::addElement($doc, $object, "poco:preferredUsername", $contact["nick"]);
|
||||
XML::addElement($doc, $object, "poco:displayName", $contact["name"]);
|
||||
XML::addElement($doc, $object, 'poco:preferredUsername', $contact['nick']);
|
||||
XML::addElement($doc, $object, 'poco:displayName', $contact['name']);
|
||||
|
||||
if (trim($contact["location"]) != "") {
|
||||
$element = $doc->createElement("poco:address");
|
||||
XML::addElement($doc, $element, "poco:formatted", $contact["location"]);
|
||||
if (trim($contact['location']) != '') {
|
||||
$element = $doc->createElement('poco:address');
|
||||
XML::addElement($doc, $element, 'poco:formatted', $contact['location']);
|
||||
$object->appendChild($element);
|
||||
}
|
||||
|
||||
|
|
@ -1615,16 +1670,15 @@ class OStatus
|
|||
* @param array $item Data of the follow/unfollow message
|
||||
* @param array $owner Contact data of the poster
|
||||
* @param bool $toplevel Is it for en entry element (false) or a feed entry (true)?
|
||||
*
|
||||
* @return \DOMElement Entry element
|
||||
* @return DOMElement Entry element
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function followEntry(DOMDocument $doc, array $item, array $owner, $toplevel)
|
||||
private static function followEntry(DOMDocument $doc, array $item, array $owner, bool $toplevel): DOMElement
|
||||
{
|
||||
$item["id"] = $item['parent'] = 0;
|
||||
$item["created"] = $item["edited"] = date("c");
|
||||
$item["private"] = Item::PRIVATE;
|
||||
$item['id'] = $item['parent'] = 0;
|
||||
$item['created'] = $item['edited'] = date('c');
|
||||
$item['private'] = Item::PRIVATE;
|
||||
|
||||
$contact = Contact::getByURL($item['follow']);
|
||||
$item['follow'] = $contact['url'];
|
||||
|
|
@ -1635,7 +1689,7 @@ class OStatus
|
|||
$contact['alias'] = $contact['url'];
|
||||
}
|
||||
|
||||
$condition = ['uid' => $owner['uid'], 'nurl' => Strings::normaliseLink($contact["url"])];
|
||||
$condition = ['uid' => $owner['uid'], 'nurl' => Strings::normaliseLink($contact['url'])];
|
||||
$user_contact = DBA::selectFirst('contact', ['id'], $condition);
|
||||
|
||||
if (DBA::isResult($user_contact)) {
|
||||
|
|
@ -1647,19 +1701,19 @@ class OStatus
|
|||
if ($item['verb'] == Activity::FOLLOW) {
|
||||
$message = DI::l10n()->t('%s is now following %s.');
|
||||
$title = DI::l10n()->t('following');
|
||||
$action = "subscription";
|
||||
$action = 'subscription';
|
||||
} else {
|
||||
$message = DI::l10n()->t('%s stopped following %s.');
|
||||
$title = DI::l10n()->t('stopped following');
|
||||
$action = "unfollow";
|
||||
$action = 'unfollow';
|
||||
}
|
||||
|
||||
$item["uri"] = $item['parent-uri'] = $item['thr-parent']
|
||||
$item['uri'] = $item['parent-uri'] = $item['thr-parent']
|
||||
= 'tag:' . DI::baseUrl()->getHostname().
|
||||
','.date('Y-m-d').':'.$action.':'.$owner['uid'].
|
||||
':person:'.$connect_id.':'.$item['created'];
|
||||
|
||||
$item["body"] = sprintf($message, $owner["nick"], $contact["nick"]);
|
||||
$item['body'] = sprintf($message, $owner['nick'], $contact['nick']);
|
||||
|
||||
$entry = self::entryHeader($doc, $owner, $item, $toplevel);
|
||||
|
||||
|
|
@ -1680,30 +1734,29 @@ class OStatus
|
|||
* @param array $item Data of the item that is to be posted
|
||||
* @param array $owner Contact data of the poster
|
||||
* @param bool $toplevel Is it for en entry element (false) or a feed entry (true)?
|
||||
*
|
||||
* @return \DOMElement Entry element
|
||||
* @return DOMElement Entry element
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function noteEntry(DOMDocument $doc, array $item, array $owner, $toplevel)
|
||||
private static function noteEntry(DOMDocument $doc, array $item, array $owner, bool $toplevel): DOMElement
|
||||
{
|
||||
if (($item['gravity'] != GRAVITY_PARENT) && (Strings::normaliseLink($item["author-link"]) != Strings::normaliseLink($owner["url"]))) {
|
||||
Logger::info("OStatus entry is from author ".$owner["url"]." - not from ".$item["author-link"].". Quitting.");
|
||||
if (($item['gravity'] != GRAVITY_PARENT) && (Strings::normaliseLink($item['author-link']) != Strings::normaliseLink($owner['url']))) {
|
||||
Logger::info('OStatus entry is from author ' . $owner['url'] . ' - not from ' . $item['author-link'] . '. Quitting.');
|
||||
}
|
||||
|
||||
if (!$toplevel) {
|
||||
if (!empty($item['title'])) {
|
||||
$title = BBCode::convertForUriId($item['uri-id'], $item['title'], BBCode::OSTATUS);
|
||||
} else {
|
||||
$title = sprintf("New note by %s", $owner["nick"]);
|
||||
$title = sprintf('New note by %s', $owner['nick']);
|
||||
}
|
||||
} else {
|
||||
$title = sprintf("New comment by %s", $owner["nick"]);
|
||||
$title = sprintf('New comment by %s', $owner['nick']);
|
||||
}
|
||||
|
||||
$entry = self::entryHeader($doc, $owner, $item, $toplevel);
|
||||
|
||||
XML::addElement($doc, $entry, "activity:object-type", Activity\ObjectType::NOTE);
|
||||
XML::addElement($doc, $entry, 'activity:object-type', Activity\ObjectType::NOTE);
|
||||
|
||||
self::entryContent($doc, $entry, $item, $owner, $title, '', true);
|
||||
|
||||
|
|
@ -1719,15 +1772,14 @@ class OStatus
|
|||
* @param array $owner Contact data of the poster
|
||||
* @param array $item
|
||||
* @param bool $toplevel Is it for en entry element (false) or a feed entry (true)?
|
||||
*
|
||||
* @return \DOMElement The entry element where the elements are added
|
||||
* @return DOMElement The entry element where the elements are added
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public static function entryHeader(DOMDocument $doc, array $owner, array $item, $toplevel)
|
||||
public static function entryHeader(DOMDocument $doc, array $owner, array $item, bool $toplevel): DOMElement
|
||||
{
|
||||
if (!$toplevel) {
|
||||
$entry = $doc->createElement("entry");
|
||||
$entry = $doc->createElement('entry');
|
||||
|
||||
if ($owner['contact-type'] == Contact::TYPE_COMMUNITY) {
|
||||
$contact = Contact::getByURL($item['author-link']) ?: $owner;
|
||||
|
|
@ -1736,16 +1788,16 @@ class OStatus
|
|||
$entry->appendChild($author);
|
||||
}
|
||||
} else {
|
||||
$entry = $doc->createElementNS(ActivityNamespace::ATOM1, "entry");
|
||||
$entry = $doc->createElementNS(ActivityNamespace::ATOM1, 'entry');
|
||||
|
||||
$entry->setAttribute("xmlns:thr", ActivityNamespace::THREAD);
|
||||
$entry->setAttribute("xmlns:georss", ActivityNamespace::GEORSS);
|
||||
$entry->setAttribute("xmlns:activity", ActivityNamespace::ACTIVITY);
|
||||
$entry->setAttribute("xmlns:media", ActivityNamespace::MEDIA);
|
||||
$entry->setAttribute("xmlns:poco", ActivityNamespace::POCO);
|
||||
$entry->setAttribute("xmlns:ostatus", ActivityNamespace::OSTATUS);
|
||||
$entry->setAttribute("xmlns:statusnet", ActivityNamespace::STATUSNET);
|
||||
$entry->setAttribute("xmlns:mastodon", ActivityNamespace::MASTODON);
|
||||
$entry->setAttribute('xmlns:thr', ActivityNamespace::THREAD);
|
||||
$entry->setAttribute('xmlns:georss', ActivityNamespace::GEORSS);
|
||||
$entry->setAttribute('xmlns:activity', ActivityNamespace::ACTIVITY);
|
||||
$entry->setAttribute('xmlns:media', ActivityNamespace::MEDIA);
|
||||
$entry->setAttribute('xmlns:poco', ActivityNamespace::POCO);
|
||||
$entry->setAttribute('xmlns:ostatus', ActivityNamespace::OSTATUS);
|
||||
$entry->setAttribute('xmlns:statusnet', ActivityNamespace::STATUSNET);
|
||||
$entry->setAttribute('xmlns:mastodon', ActivityNamespace::MASTODON);
|
||||
|
||||
$author = self::addAuthor($doc, $owner);
|
||||
$entry->appendChild($author);
|
||||
|
|
@ -1758,7 +1810,7 @@ class OStatus
|
|||
* Adds elements to the XML document
|
||||
*
|
||||
* @param DOMDocument $doc XML document
|
||||
* @param \DOMElement $entry Entry element where the content is added
|
||||
* @param DOMElement $entry Entry element where the content is added
|
||||
* @param array $item Data of the item that is to be posted
|
||||
* @param array $owner Contact data of the poster
|
||||
* @param string $title Title for the post
|
||||
|
|
@ -1767,38 +1819,40 @@ class OStatus
|
|||
* @return void
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function entryContent(DOMDocument $doc, \DOMElement $entry, array $item, array $owner, $title, $verb = "", $complete = true)
|
||||
private static function entryContent(DOMDocument $doc, DOMElement $entry, array $item, array $owner, string $title, string $verb = '', bool $complete = true)
|
||||
{
|
||||
if ($verb == "") {
|
||||
if ($verb == '') {
|
||||
$verb = self::constructVerb($item);
|
||||
}
|
||||
|
||||
XML::addElement($doc, $entry, "id", $item["uri"]);
|
||||
XML::addElement($doc, $entry, "title", html_entity_decode($title, ENT_QUOTES, 'UTF-8'));
|
||||
XML::addElement($doc, $entry, 'id', $item['uri']);
|
||||
XML::addElement($doc, $entry, 'title', html_entity_decode($title, ENT_QUOTES, 'UTF-8'));
|
||||
|
||||
$body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']);
|
||||
$body = self::formatPicturePost($body, $item['uri-id']);
|
||||
|
||||
if (!empty($item['title'])) {
|
||||
$body = "[b]".$item['title']."[/b]\n\n".$body;
|
||||
$body = '[b]' . $item['title'] . "[/b]\n\n" . $body;
|
||||
}
|
||||
|
||||
$body = BBCode::convertForUriId($item['uri-id'], $body, BBCode::OSTATUS);
|
||||
|
||||
XML::addElement($doc, $entry, "content", $body, ["type" => "html"]);
|
||||
XML::addElement($doc, $entry, 'content', $body, ['type' => 'html']);
|
||||
|
||||
XML::addElement($doc, $entry, "link", "", ["rel" => "alternate", "type" => "text/html",
|
||||
"href" => DI::baseUrl()."/display/".$item["guid"]]
|
||||
);
|
||||
XML::addElement($doc, $entry, 'link', '', [
|
||||
'rel' => 'alternate',
|
||||
'type' => 'text/html',
|
||||
'href' => DI::baseUrl() . '/display/' . $item['guid'],
|
||||
]);
|
||||
|
||||
if ($complete && ($item["id"] > 0)) {
|
||||
XML::addElement($doc, $entry, "status_net", "", ["notice_id" => $item["id"]]);
|
||||
if ($complete && ($item['id'] > 0)) {
|
||||
XML::addElement($doc, $entry, 'status_net', '', ['notice_id' => $item['id']]);
|
||||
}
|
||||
|
||||
XML::addElement($doc, $entry, "activity:verb", $verb);
|
||||
XML::addElement($doc, $entry, 'activity:verb', $verb);
|
||||
|
||||
XML::addElement($doc, $entry, "published", DateTimeFormat::utc($item["created"]."+00:00", DateTimeFormat::ATOM));
|
||||
XML::addElement($doc, $entry, "updated", DateTimeFormat::utc($item["edited"]."+00:00", DateTimeFormat::ATOM));
|
||||
XML::addElement($doc, $entry, 'published', DateTimeFormat::utc($item['created'] . '+00:00', DateTimeFormat::ATOM));
|
||||
XML::addElement($doc, $entry, 'updated', DateTimeFormat::utc($item['edited'] . '+00:00', DateTimeFormat::ATOM));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1812,7 +1866,7 @@ class OStatus
|
|||
* @return void
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
private static function entryFooter(DOMDocument $doc, $entry, array $item, array $owner, $complete = true)
|
||||
private static function entryFooter(DOMDocument $doc, $entry, array $item, array $owner, bool $complete = true)
|
||||
{
|
||||
$mentioned = [];
|
||||
|
||||
|
|
@ -1861,14 +1915,15 @@ class OStatus
|
|||
}
|
||||
}
|
||||
|
||||
XML::addElement($doc, $entry, "link", "", ["rel" => "ostatus:conversation", "href" => $conversation_href]);
|
||||
XML::addElement($doc, $entry, 'link', '', ['rel' => 'ostatus:conversation', 'href' => $conversation_href]);
|
||||
|
||||
$attributes = [
|
||||
"href" => $conversation_href,
|
||||
"local_id" => $item['parent'],
|
||||
"ref" => $conversation_uri];
|
||||
'href' => $conversation_href,
|
||||
'local_id' => $item['parent'],
|
||||
'ref' => $conversation_uri,
|
||||
];
|
||||
|
||||
XML::addElement($doc, $entry, "ostatus:conversation", $conversation_uri, $attributes);
|
||||
XML::addElement($doc, $entry, 'ostatus:conversation', $conversation_uri, $attributes);
|
||||
}
|
||||
|
||||
// uri-id isn't present for follow entry pseudo-items
|
||||
|
|
@ -1880,72 +1935,70 @@ class OStatus
|
|||
// Make sure that mentions are accepted (GNU Social has problems with mixing HTTP and HTTPS)
|
||||
$newmentions = [];
|
||||
foreach ($mentioned as $mention) {
|
||||
$newmentions[str_replace("http://", "https://", $mention)] = str_replace("http://", "https://", $mention);
|
||||
$newmentions[str_replace("https://", "http://", $mention)] = str_replace("https://", "http://", $mention);
|
||||
$newmentions[str_replace('http://', 'https://', $mention)] = str_replace('http://', 'https://', $mention);
|
||||
$newmentions[str_replace('https://', 'http://', $mention)] = str_replace('https://', 'http://', $mention);
|
||||
}
|
||||
$mentioned = $newmentions;
|
||||
|
||||
foreach ($mentioned as $mention) {
|
||||
$contact = Contact::getByURL($mention, false, ['contact-type']);
|
||||
if (!empty($contact) && ($contact['contact-type'] == Contact::TYPE_COMMUNITY)) {
|
||||
XML::addElement($doc, $entry, "link", "",
|
||||
[
|
||||
"rel" => "mentioned",
|
||||
"ostatus:object-type" => Activity\ObjectType::GROUP,
|
||||
"href" => $mention]
|
||||
);
|
||||
XML::addElement($doc, $entry, 'link', '', [
|
||||
'rel' => 'mentioned',
|
||||
'ostatus:object-type' => Activity\ObjectType::GROUP,
|
||||
'href' => $mention,
|
||||
]);
|
||||
} else {
|
||||
XML::addElement($doc, $entry, "link", "",
|
||||
[
|
||||
"rel" => "mentioned",
|
||||
"ostatus:object-type" => Activity\ObjectType::PERSON,
|
||||
"href" => $mention]
|
||||
);
|
||||
XML::addElement($doc, $entry, 'link', '', [
|
||||
'rel' => 'mentioned',
|
||||
'ostatus:object-type' => Activity\ObjectType::PERSON,
|
||||
'href' => $mention,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($owner['contact-type'] == Contact::TYPE_COMMUNITY) {
|
||||
XML::addElement($doc, $entry, "link", "", [
|
||||
"rel" => "mentioned",
|
||||
"ostatus:object-type" => "http://activitystrea.ms/schema/1.0/group",
|
||||
"href" => $owner['url']
|
||||
XML::addElement($doc, $entry, 'link', '', [
|
||||
'rel' => 'mentioned',
|
||||
'ostatus:object-type' => 'http://activitystrea.ms/schema/1.0/group',
|
||||
'href' => $owner['url']
|
||||
]);
|
||||
}
|
||||
|
||||
if ($item['private'] != Item::PRIVATE) {
|
||||
XML::addElement($doc, $entry, "link", "", ["rel" => "ostatus:attention",
|
||||
"href" => "http://activityschema.org/collection/public"]);
|
||||
XML::addElement($doc, $entry, "link", "", ["rel" => "mentioned",
|
||||
"ostatus:object-type" => "http://activitystrea.ms/schema/1.0/collection",
|
||||
"href" => "http://activityschema.org/collection/public"]);
|
||||
XML::addElement($doc, $entry, "mastodon:scope", "public");
|
||||
XML::addElement($doc, $entry, 'link', '', ['rel' => 'ostatus:attention',
|
||||
'href' => 'http://activityschema.org/collection/public']);
|
||||
XML::addElement($doc, $entry, 'link', '', ['rel' => 'mentioned',
|
||||
'ostatus:object-type' => 'http://activitystrea.ms/schema/1.0/collection',
|
||||
'href' => 'http://activityschema.org/collection/public']);
|
||||
XML::addElement($doc, $entry, 'mastodon:scope', 'public');
|
||||
}
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
if ($tag['type'] == Tag::HASHTAG) {
|
||||
XML::addElement($doc, $entry, "category", "", ["term" => $tag['name']]);
|
||||
XML::addElement($doc, $entry, 'category', '', ['term' => $tag['name']]);
|
||||
}
|
||||
}
|
||||
|
||||
self::getAttachment($doc, $entry, $item);
|
||||
|
||||
if ($complete && ($item["id"] > 0)) {
|
||||
$app = $item["app"];
|
||||
if ($app == "") {
|
||||
$app = "web";
|
||||
if ($complete && ($item['id'] > 0)) {
|
||||
$app = $item['app'];
|
||||
if ($app == '') {
|
||||
$app = 'web';
|
||||
}
|
||||
|
||||
$attributes = ["local_id" => $item["id"], "source" => $app];
|
||||
$attributes = ['local_id' => $item['id'], 'source' => $app];
|
||||
|
||||
if (isset($parent["id"])) {
|
||||
$attributes["repeat_of"] = $parent["id"];
|
||||
if (isset($parent['id'])) {
|
||||
$attributes['repeat_of'] = $parent['id'];
|
||||
}
|
||||
|
||||
if ($item["coord"] != "") {
|
||||
XML::addElement($doc, $entry, "georss:point", $item["coord"]);
|
||||
if ($item['coord'] != '') {
|
||||
XML::addElement($doc, $entry, 'georss:point', $item['coord']);
|
||||
}
|
||||
|
||||
XML::addElement($doc, $entry, "statusnet:notice_info", "", $attributes);
|
||||
XML::addElement($doc, $entry, 'statusnet:notice_info', '', $attributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1965,21 +2018,20 @@ class OStatus
|
|||
* @param integer $max_items Number of maximum items to fetch
|
||||
* @param string $filter Feed items filter (activity, posts or comments)
|
||||
* @param boolean $nocache Wether to bypass caching
|
||||
*
|
||||
* @return string XML feed
|
||||
* @return string XML feed or empty string on error
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public static function feed($owner_nick, &$last_update, $max_items = 300, $filter = 'activity', $nocache = false)
|
||||
public static function feed(string $owner_nick, string &$last_update, int $max_items = 300, string $filter = 'activity', bool $nocache = false): string
|
||||
{
|
||||
$stamp = microtime(true);
|
||||
|
||||
$owner = User::getOwnerDataByNick($owner_nick);
|
||||
if (!$owner) {
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
|
||||
$cachekey = "ostatus:feed:" . $owner_nick . ":" . $filter . ":" . $last_update;
|
||||
$cachekey = 'ostatus:feed:' . $owner_nick . ':' . $filter . ':' . $last_update;
|
||||
|
||||
$previous_created = $last_update;
|
||||
|
||||
|
|
@ -1998,11 +2050,16 @@ class OStatus
|
|||
}
|
||||
|
||||
$check_date = DateTimeFormat::utc($last_update);
|
||||
$authorid = Contact::getIdForURL($owner["url"]);
|
||||
$authorid = Contact::getIdForURL($owner['url']);
|
||||
|
||||
$condition = ["`uid` = ? AND `received` > ? AND NOT `deleted`
|
||||
AND `private` != ? AND `visible` AND `wall` AND `parent-network` IN (?, ?)",
|
||||
$owner["uid"], $check_date, Item::PRIVATE, Protocol::OSTATUS, Protocol::DFRN];
|
||||
$condition = [
|
||||
"`uid` = ? AND `received` > ? AND NOT `deleted` AND `private` != ? AND `visible` AND `wall` AND `parent-network` IN (?, ?)",
|
||||
$owner['uid'],
|
||||
$check_date,
|
||||
Item::PRIVATE,
|
||||
Protocol::OSTATUS,
|
||||
Protocol::DFRN,
|
||||
];
|
||||
|
||||
if ($filter === 'comments') {
|
||||
$condition[0] .= " AND `object-type` = ? ";
|
||||
|
|
@ -2011,7 +2068,7 @@ class OStatus
|
|||
|
||||
if ($owner['contact-type'] != Contact::TYPE_COMMUNITY) {
|
||||
$condition[0] .= " AND `contact-id` = ? AND `author-id` = ?";
|
||||
$condition[] = $owner["id"];
|
||||
$condition[] = $owner['id'];
|
||||
$condition[] = $authorid;
|
||||
}
|
||||
|
||||
|
|
@ -2035,7 +2092,7 @@ class OStatus
|
|||
$item['body'] .= '🍼';
|
||||
}
|
||||
|
||||
if (in_array($item["verb"], [Activity::FOLLOW, Activity::O_UNFOLLOW, Activity::LIKE])) {
|
||||
if (in_array($item['verb'], [Activity::FOLLOW, Activity::O_UNFOLLOW, Activity::LIKE])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -2067,7 +2124,7 @@ class OStatus
|
|||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public static function salmon(array $item, array $owner)
|
||||
public static function salmon(array $item, array $owner): string
|
||||
{
|
||||
$doc = new DOMDocument('1.0', 'utf-8');
|
||||
$doc->formatOutput = true;
|
||||
|
|
@ -2091,7 +2148,7 @@ class OStatus
|
|||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
public static function isSupportedByContactUrl($url)
|
||||
public static function isSupportedByContactUrl(string $url): bool
|
||||
{
|
||||
$probe = Probe::uri($url, Protocol::OSTATUS);
|
||||
return $probe['network'] == Protocol::OSTATUS;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class Relay
|
|||
* @param string $url
|
||||
* @return boolean "true" is the post is wanted by the system
|
||||
*/
|
||||
public static function isSolicitedPost(array $tags, string $body, int $authorid, string $url, string $network = '')
|
||||
public static function isSolicitedPost(array $tags, string $body, int $authorid, string $url, string $network = ''): bool
|
||||
{
|
||||
$config = DI::config();
|
||||
|
||||
|
|
@ -139,6 +139,7 @@ class Relay
|
|||
*
|
||||
* @param array $gserver Global server record
|
||||
* @param array $fields Optional network specific fields
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function updateContact(array $gserver, array $fields = [])
|
||||
|
|
@ -198,6 +199,7 @@ class Relay
|
|||
* The relay contact is a technical contact entry that exists once per server.
|
||||
*
|
||||
* @param array $contact of the relay contact
|
||||
* @return void
|
||||
*/
|
||||
public static function markForArchival(array $contact)
|
||||
{
|
||||
|
|
@ -229,15 +231,14 @@ class Relay
|
|||
* @param integer $item_id id of the item that is sent
|
||||
* @param array $contacts Previously fetched contacts
|
||||
* @param array $networks Networks of the relay servers
|
||||
*
|
||||
* @return array of relay servers
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function getDirectRelayList(int $item_id)
|
||||
public static function getDirectRelayList(int $item_id): array
|
||||
{
|
||||
$serverlist = [];
|
||||
|
||||
if (!DI::config()->get("system", "relay_directly", false)) {
|
||||
if (!DI::config()->get('system', 'relay_directly', false)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
@ -302,10 +303,10 @@ class Relay
|
|||
* Return a list of relay servers
|
||||
*
|
||||
* @param array $fields Field list
|
||||
* @return array
|
||||
* @return array List of relay servers
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getList($fields = []):array
|
||||
public static function getList(array $fields = []): array
|
||||
{
|
||||
return DBA::selectToArray('apcontact', $fields,
|
||||
["`type` = ? AND `url` IN (SELECT `url` FROM `contact` WHERE `uid` = ? AND `rel` = ?)", 'Application', 0, Contact::FRIEND]);
|
||||
|
|
@ -316,7 +317,7 @@ class Relay
|
|||
*
|
||||
* @param array $gserver Global server record
|
||||
* @param array $fields Fieldlist
|
||||
* @return array with the contact
|
||||
* @return array|bool Array with the contact or false on error
|
||||
* @throws \Exception
|
||||
*/
|
||||
private static function getContact(array $gserver, array $fields = ['batch', 'id', 'url', 'name', 'network', 'protocol', 'archive', 'blocked'])
|
||||
|
|
@ -344,6 +345,8 @@ class Relay
|
|||
|
||||
/**
|
||||
* Resubscribe to all relay servers
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function reSubscribe()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,10 +40,10 @@ class Salmon
|
|||
/**
|
||||
* @param string $uri Uniform Resource Identifier
|
||||
* @param string $keyhash encoded key
|
||||
* @return mixed
|
||||
* @return string Key or empty string on any errors
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function getKey(string $uri, string $keyhash)
|
||||
public static function getKey(string $uri, string $keyhash): string
|
||||
{
|
||||
$ret = [];
|
||||
|
||||
|
|
@ -83,13 +83,13 @@ class Salmon
|
|||
Logger::notice('Key located', ['ret' => $ret]);
|
||||
|
||||
if (count($ret) == 1) {
|
||||
// We only found one one key so we don't care if the hash matches.
|
||||
// If it's the wrong key we'll find out soon enough because
|
||||
// message verification will fail. This also covers some older
|
||||
// software which don't supply a keyhash. As long as they only
|
||||
// have one key we'll be right.
|
||||
|
||||
return $ret[0];
|
||||
/* We only found one one key so we don't care if the hash matches.
|
||||
* If it's the wrong key we'll find out soon enough because
|
||||
* message verification will fail. This also covers some older
|
||||
* software which don't supply a keyhash. As long as they only
|
||||
* have one key we'll be right.
|
||||
*/
|
||||
return (string) $ret[0];
|
||||
} else {
|
||||
foreach ($ret as $a) {
|
||||
$hash = Strings::base64UrlEncode(hash('sha256', $a));
|
||||
|
|
|
|||
|
|
@ -34,23 +34,23 @@ class Images
|
|||
/**
|
||||
* Maps Mime types to Imagick formats
|
||||
*
|
||||
* @return array
|
||||
* @return array Format map
|
||||
*/
|
||||
public static function getFormatsMap()
|
||||
{
|
||||
$m = [
|
||||
return [
|
||||
'image/jpeg' => 'JPG',
|
||||
'image/jpg' => 'JPG',
|
||||
'image/png' => 'PNG',
|
||||
'image/gif' => 'GIF'
|
||||
'image/gif' => 'GIF',
|
||||
];
|
||||
|
||||
return $m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return file extension for mime type
|
||||
* @param string $mimetype
|
||||
* @return string
|
||||
* Return file extension for MIME type
|
||||
*
|
||||
* @param string $mimetype MIME type
|
||||
* @return string File extension for MIME type
|
||||
*/
|
||||
public static function getExtensionByMimeType(string $mimetype): string
|
||||
{
|
||||
|
|
@ -63,9 +63,14 @@ class Images
|
|||
$imagetype = IMAGETYPE_GIF;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'image/jpeg':
|
||||
case 'image/jpg':
|
||||
$imagetype = IMAGETYPE_JPEG;
|
||||
break;
|
||||
|
||||
default: // Unknown type must be a blob then
|
||||
return 'blob';
|
||||
break;
|
||||
}
|
||||
|
||||
return image_type_to_extension($imagetype);
|
||||
|
|
@ -76,11 +81,13 @@ class Images
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function supportedTypes()
|
||||
public static function supportedTypes(): array
|
||||
{
|
||||
$types = [
|
||||
'image/jpeg' => 'jpg'
|
||||
'image/jpeg' => 'jpg',
|
||||
'image/jpg' => 'jpg',
|
||||
];
|
||||
|
||||
if (class_exists('Imagick')) {
|
||||
// Imagick::queryFormats won't help us a lot there...
|
||||
// At least, not yet, other parts of friendica uses this array
|
||||
|
|
@ -102,21 +109,20 @@ class Images
|
|||
*
|
||||
* @param string $image_data Image data
|
||||
* @param string $filename File name (for guessing the type via the extension)
|
||||
* @param string $mime default mime type
|
||||
*
|
||||
* @return string
|
||||
* @param string $default Default MIME type
|
||||
* @return string MIME type
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getMimeTypeByData(string $image_data, string $filename = '', string $mime = '')
|
||||
public static function getMimeTypeByData(string $image_data, string $filename = '', string $default = ''): string
|
||||
{
|
||||
if (substr($mime, 0, 6) == 'image/') {
|
||||
Logger::info('Using default mime type', ['filename' => $filename, 'mime' => $mime]);
|
||||
return $mime;
|
||||
if (substr($default, 0, 6) == 'image/') {
|
||||
Logger::info('Using default mime type', ['filename' => $filename, 'mime' => $default]);
|
||||
return $default;
|
||||
}
|
||||
|
||||
$image = @getimagesizefromstring($image_data);
|
||||
if (!empty($image['mime'])) {
|
||||
Logger::info('Mime type detected via data', ['filename' => $filename, 'default' => $mime, 'mime' => $image['mime']]);
|
||||
Logger::info('Mime type detected via data', ['filename' => $filename, 'default' => $default, 'mime' => $image['mime']]);
|
||||
return $image['mime'];
|
||||
}
|
||||
|
||||
|
|
@ -128,21 +134,20 @@ class Images
|
|||
*
|
||||
* @param string $sourcefile Source file of the image
|
||||
* @param string $filename File name (for guessing the type via the extension)
|
||||
* @param string $mime default mime type
|
||||
*
|
||||
* @return string
|
||||
* @param string $default default MIME type
|
||||
* @return string MIME type
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getMimeTypeBySource(string $sourcefile, string $filename = '', string $mime = '')
|
||||
public static function getMimeTypeBySource(string $sourcefile, string $filename = '', string $default = ''): string
|
||||
{
|
||||
if (substr($mime, 0, 6) == 'image/') {
|
||||
Logger::info('Using default mime type', ['filename' => $filename, 'mime' => $mime]);
|
||||
return $mime;
|
||||
if (substr($default, 0, 6) == 'image/') {
|
||||
Logger::info('Using default mime type', ['filename' => $filename, 'mime' => $default]);
|
||||
return $default;
|
||||
}
|
||||
|
||||
$image = @getimagesize($sourcefile);
|
||||
if (!empty($image['mime'])) {
|
||||
Logger::info('Mime type detected via file', ['filename' => $filename, 'default' => $mime, 'image' => $image]);
|
||||
Logger::info('Mime type detected via file', ['filename' => $filename, 'default' => $default, 'image' => $image]);
|
||||
return $image['mime'];
|
||||
}
|
||||
|
||||
|
|
@ -150,14 +155,13 @@ class Images
|
|||
}
|
||||
|
||||
/**
|
||||
* Guess image mimetype from the filename
|
||||
* Guess image MIME type from the filename's extension
|
||||
*
|
||||
* @param string $filename Image filename
|
||||
*
|
||||
* @return string
|
||||
* @param string $filename Image filename
|
||||
* @return string Guessed MIME type by extension
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function guessTypeByExtension(string $filename)
|
||||
public static function guessTypeByExtension(string $filename): string
|
||||
{
|
||||
$ext = pathinfo(parse_url($filename, PHP_URL_PATH), PATHINFO_EXTENSION);
|
||||
$types = self::supportedTypes();
|
||||
|
|
@ -173,11 +177,13 @@ class Images
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return array
|
||||
* Gets info array from given URL, cached data has priority
|
||||
*
|
||||
* @param string $url URL
|
||||
* @return array Info
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function getInfoFromURLCached($url)
|
||||
public static function getInfoFromURLCached(string $url): array
|
||||
{
|
||||
$data = [];
|
||||
|
||||
|
|
@ -195,15 +201,17 @@ class Images
|
|||
DI::cache()->set($cacheKey, $data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
return $data ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return array
|
||||
* Gets info from URL uncached
|
||||
*
|
||||
* @param string $url URL
|
||||
* @return array Info array
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
public static function getInfoFromURL($url)
|
||||
public static function getInfoFromURL(string $url): array
|
||||
{
|
||||
$data = [];
|
||||
|
||||
|
|
@ -239,16 +247,18 @@ class Images
|
|||
$data['size'] = $filesize;
|
||||
}
|
||||
|
||||
return $data;
|
||||
return $data ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $width
|
||||
* @param integer $height
|
||||
* @param integer $max
|
||||
* @return array
|
||||
* Returns scaling information
|
||||
*
|
||||
* @param integer $width Width
|
||||
* @param integer $height Height
|
||||
* @param integer $max Max width/height
|
||||
* @return array Scaling dimensions
|
||||
*/
|
||||
public static function getScalingDimensions($width, $height, $max)
|
||||
public static function getScalingDimensions(int $width, int $height, int $max): array
|
||||
{
|
||||
if ((!$width) || (!$height)) {
|
||||
return ['width' => 0, 'height' => 0];
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ class XML
|
|||
|
||||
foreach ($attributes as $key => $value) {
|
||||
$attribute = $doc->createAttribute($key);
|
||||
$attribute->value = self::escape($value);
|
||||
$attribute->value = self::escape($value ?? '');
|
||||
$element->appendChild($attribute);
|
||||
}
|
||||
return $element;
|
||||
|
|
@ -177,7 +177,7 @@ class XML
|
|||
/**
|
||||
* Create an XML and append it to the parent object
|
||||
*
|
||||
* @param DOMDocument $doc XML root
|
||||
* @param DOMDocument $doc XML root
|
||||
* @param object $parent parent object
|
||||
* @param string $element XML element name
|
||||
* @param string $value XML value
|
||||
|
|
|
|||
|
|
@ -475,12 +475,13 @@ class Delivery
|
|||
* @param array $owner Owner record of the sender
|
||||
* @param array $target_item Item record of the content
|
||||
* @param array $thr_parent Item record of the direct parent in the thread
|
||||
* @return void
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
* @throws \ImagickException
|
||||
*/
|
||||
private static function deliverMail(string $cmd, array $contact, array $owner, array $target_item, array $thr_parent)
|
||||
{
|
||||
if (DI::config()->get('system','imap_disabled')) {
|
||||
if (DI::config()->get('system', 'imap_disabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -570,10 +571,16 @@ class Delivery
|
|||
}
|
||||
}
|
||||
|
||||
Email::send($addr, $subject, $headers, $target_item);
|
||||
// Try to send email
|
||||
$success = Email::send($addr, $subject, $headers, $target_item);
|
||||
|
||||
Model\Post\DeliveryData::incrementQueueDone($target_item['uri-id'], Model\Post\DeliveryData::MAIL);
|
||||
|
||||
Logger::info('Delivered via mail', ['guid' => $target_item['guid'], 'to' => $addr, 'subject' => $subject]);
|
||||
if ($success) {
|
||||
// Success
|
||||
Model\Post\DeliveryData::incrementQueueDone($target_item['uri-id'], Model\Post\DeliveryData::MAIL);
|
||||
Logger::info('Delivered via mail', ['guid' => $target_item['guid'], 'to' => $addr, 'subject' => $subject]);
|
||||
} else {
|
||||
// Failed
|
||||
Logger::warning('Delivery of mail has FAILED', ['to' => $addr, 'subject' => $subject, 'guid' => $target_item['guid']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,10 +31,9 @@ class Image
|
|||
* Give all available options for the background image
|
||||
*
|
||||
* @param array $arr Array with the present user settings
|
||||
*
|
||||
* @return array Array with the immage options
|
||||
*/
|
||||
public static function get_options($arr)
|
||||
public static function get_options(array $arr): array
|
||||
{
|
||||
$bg_image_options = [
|
||||
'stretch' => ['frio_bg_image_option', DI::l10n()->t('Top Banner'), 'stretch', DI::l10n()->t('Resize image to the width of the screen and show background color below on long pages.'), ($arr['bg_image_option'] == 'stretch')],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue