Access contact avatars by guid

This commit is contained in:
Michael 2021-10-04 06:13:52 +00:00
parent fe68df8e6a
commit d30dc52101
5 changed files with 68 additions and 39 deletions

View file

@ -1,6 +1,6 @@
-- ------------------------------------------ -- ------------------------------------------
-- Friendica 2021.12-dev (Siberian Iris) -- Friendica 2021.12-dev (Siberian Iris)
-- DB_UPDATE_VERSION 1436 -- DB_UPDATE_VERSION 1437
-- ------------------------------------------ -- ------------------------------------------
@ -2355,6 +2355,7 @@ CREATE VIEW `account-view` AS SELECT
`contact`.`url` AS `url`, `contact`.`url` AS `url`,
`contact`.`nurl` AS `nurl`, `contact`.`nurl` AS `nurl`,
`contact`.`uri-id` AS `uri-id`, `contact`.`uri-id` AS `uri-id`,
`item-uri`.`guid` AS `guid`,
`contact`.`addr` AS `addr`, `contact`.`addr` AS `addr`,
`contact`.`alias` AS `alias`, `contact`.`alias` AS `alias`,
`contact`.`name` AS `name`, `contact`.`name` AS `name`,
@ -2424,6 +2425,7 @@ CREATE VIEW `account-view` AS SELECT
`apcontact`.`followers_count` AS `ap-followers_count`, `apcontact`.`followers_count` AS `ap-followers_count`,
`apcontact`.`statuses_count` AS `ap-statuses_count` `apcontact`.`statuses_count` AS `ap-statuses_count`
FROM `contact` FROM `contact`
LEFT JOIN `item-uri` ON `item-uri`.`id` = `contact`.`uri-id`
LEFT JOIN `apcontact` ON `apcontact`.`uri-id` = `contact`.`uri-id` LEFT JOIN `apcontact` ON `apcontact`.`uri-id` = `contact`.`uri-id`
LEFT JOIN `fcontact` ON `fcontact`.`uri-id` = contact.`uri-id` LEFT JOIN `fcontact` ON `fcontact`.`uri-id` = contact.`uri-id`
WHERE `contact`.`uid` = 0; WHERE `contact`.`uid` = 0;
@ -2439,6 +2441,7 @@ CREATE VIEW `account-user-view` AS SELECT
`contact`.`url` AS `url`, `contact`.`url` AS `url`,
`contact`.`nurl` AS `nurl`, `contact`.`nurl` AS `nurl`,
`contact`.`uri-id` AS `uri-id`, `contact`.`uri-id` AS `uri-id`,
`item-uri`.`guid` AS `guid`,
`contact`.`addr` AS `addr`, `contact`.`addr` AS `addr`,
`contact`.`alias` AS `alias`, `contact`.`alias` AS `alias`,
`contact`.`name` AS `name`, `contact`.`name` AS `name`,
@ -2522,6 +2525,7 @@ CREATE VIEW `account-user-view` AS SELECT
`apcontact`.`statuses_count` AS `ap-statuses_count` `apcontact`.`statuses_count` AS `ap-statuses_count`
FROM `contact` AS `ucontact` FROM `contact` AS `ucontact`
INNER JOIN `contact` ON `contact`.`uri-id` = `ucontact`.`uri-id` AND `contact`.`uid` = 0 INNER JOIN `contact` ON `contact`.`uri-id` = `ucontact`.`uri-id` AND `contact`.`uid` = 0
LEFT JOIN `item-uri` ON `item-uri`.`id` = `ucontact`.`uri-id`
LEFT JOIN `apcontact` ON `apcontact`.`uri-id` = `ucontact`.`uri-id` LEFT JOIN `apcontact` ON `apcontact`.`uri-id` = `ucontact`.`uri-id`
LEFT JOIN `fcontact` ON `fcontact`.`uri-id` = `ucontact`.`uri-id` AND `fcontact`.`network` = 'dspr'; LEFT JOIN `fcontact` ON `fcontact`.`uri-id` = `ucontact`.`uri-id` AND `fcontact`.`network` = 'dspr';

View file

@ -1726,15 +1726,18 @@ class Contact
* @param string $updated Contact update date * @param string $updated Contact update date
* @return string avatar link * @return string avatar link
*/ */
public static function getAvatarUrlForId(int $cid, string $size = '', string $updated = ''):string public static function getAvatarUrlForId(int $cid, string $size = '', string $updated = '', string $guid = ''):string
{ {
// We have to fetch the "updated" variable when it wasn't provided // We have to fetch the "updated" variable when it wasn't provided
// The parameter can be provided to improve performance // The parameter can be provided to improve performance
if (empty($updated)) { if (empty($updated) || empty($guid)) {
$contact = self::getById($cid, ['updated']); $account = DBA::selectFirst('account-user-view', ['updated', 'guid'], ['id' => $cid]);
$updated = $contact['updated'] ?? ''; $updated = $account['updated'] ?? '';
$guid = $account['guid'] ?? '';
} }
$guid = urlencode($guid);
$url = DI::baseUrl() . '/photo/contact/'; $url = DI::baseUrl() . '/photo/contact/';
switch ($size) { switch ($size) {
case Proxy::SIZE_MICRO: case Proxy::SIZE_MICRO:
@ -1753,7 +1756,7 @@ class Contact
$url .= Proxy::PIXEL_LARGE . '/'; $url .= Proxy::PIXEL_LARGE . '/';
break; break;
} }
return $url . $cid . ($updated ? '?ts=' . strtotime($updated) : ''); return $url . ($guid ?: $cid) . ($updated ? '?ts=' . strtotime($updated) : '');
} }
/** /**
@ -1780,15 +1783,18 @@ class Contact
* @param string $updated Contact update date * @param string $updated Contact update date
* @return string header link * @return string header link
*/ */
public static function getHeaderUrlForId(int $cid, string $size = '', string $updated = ''):string public static function getHeaderUrlForId(int $cid, string $size = '', string $updated = '', string $guid = ''):string
{ {
// We have to fetch the "updated" variable when it wasn't provided // We have to fetch the "updated" variable when it wasn't provided
// The parameter can be provided to improve performance // The parameter can be provided to improve performance
if (empty($updated)) { if (empty($updated) || empty($guid)) {
$contact = self::getById($cid, ['updated']); $account = DBA::selectFirst('account-user-view', ['updated', 'guid'], ['id' => $cid]);
$updated = $contact['updated'] ?? ''; $updated = $account['updated'] ?? '';
$guid = $account['guid'] ?? '';
} }
$guid = urlencode($guid);
$url = DI::baseUrl() . '/photo/header/'; $url = DI::baseUrl() . '/photo/header/';
switch ($size) { switch ($size) {
case Proxy::SIZE_MICRO: case Proxy::SIZE_MICRO:
@ -1808,7 +1814,7 @@ class Contact
break; break;
} }
return $url . $cid . ($updated ? '?ts=' . strtotime($updated) : ''); return $url . ($guid ?: $cid) . ($updated ? '?ts=' . strtotime($updated) : '');
} }
/** /**
@ -2184,7 +2190,7 @@ class Contact
} }
$update = false; $update = false;
$guid = $ret['guid'] ?? ''; $guid = $ret['guid'] ?: Item::guidFromUri($ret['url'], parse_url($ret['url'], PHP_URL_HOST));
// make sure to not overwrite existing values with blank entries except some technical fields // make sure to not overwrite existing values with blank entries except some technical fields
$keep = ['batch', 'notify', 'poll', 'request', 'confirm', 'poco', 'baseurl']; $keep = ['batch', 'notify', 'poll', 'request', 'confirm', 'poco', 'baseurl'];
@ -2212,6 +2218,12 @@ class Contact
self::updateAvatar($id, $ret['photo'], $update); self::updateAvatar($id, $ret['photo'], $update);
} }
if (empty($guid)) {
$uriid = ItemURI::getIdByURI($ret['url']);
} else {
$uriid = ItemURI::insert(['uri' => $ret['url'], 'guid' => $guid]);
}
if (!$update) { if (!$update) {
self::updateContact($id, $uid, $contact['url'], $ret['url'], ['failed' => false, 'last-update' => $updated, 'success_update' => $updated]); self::updateContact($id, $uid, $contact['url'], $ret['url'], ['failed' => false, 'last-update' => $updated, 'success_update' => $updated]);
@ -2230,12 +2242,7 @@ class Contact
return true; return true;
} }
if (empty($guid)) { $ret['uri-id'] = $uriid;
$ret['uri-id'] = ItemURI::getIdByURI($ret['url']);
} else {
$ret['uri-id'] = ItemURI::insert(['uri' => $ret['url'], 'guid' => $guid]);
}
$ret['nurl'] = Strings::normaliseLink($ret['url']); $ret['nurl'] = Strings::normaliseLink($ret['url']);
$ret['updated'] = $updated; $ret['updated'] = $updated;
$ret['failed'] = false; $ret['failed'] = false;

View file

@ -83,26 +83,41 @@ class Photo extends BaseModule
} }
if (!empty($parameters['nickname_ext'])) { if (!empty($parameters['nickname_ext'])) {
$nickname = pathinfo($parameters['nickname_ext'], PATHINFO_FILENAME); if (in_array($parameters['type'], ['contact', 'header'])) {
$user = User::getByNickname($nickname, ['uid']); $guid = pathinfo($parameters['nickname_ext'], PATHINFO_FILENAME);
if (empty($user)) { $account = DBA::selectFirst('account-user-view', ['id'], ['guid' => $guid], ['order' => ['uid' => true]]);
throw new HTTPException\NotFoundException(); if (empty($account)) {
} throw new HTTPException\NotFoundException();
}
$uid = $user['uid']; $id = $account['id'];
} else {
$nickname = pathinfo($parameters['nickname_ext'], PATHINFO_FILENAME);
$user = User::getByNickname($nickname, ['uid']);
if (empty($user)) {
throw new HTTPException\NotFoundException();
}
$id = $user['uid'];
}
} }
// User Id Fallback, to remove after version 2021.12 // User Id Fallback, to remove after version 2021.12
if (!empty($parameters['uid_ext'])) { if (!empty($parameters['uid_ext'])) {
$uid = intval(pathinfo($parameters['uid_ext'], PATHINFO_FILENAME)); $id = intval(pathinfo($parameters['uid_ext'], PATHINFO_FILENAME));
} }
// Please refactor this for the love of everything that's good // Please refactor this for the love of everything that's good
if (!empty($parameters['id'])) { if (!empty($parameters['id'])) {
$uid = $parameters['id']; $id = $parameters['id'];
} }
$photo = self::getAvatar($uid, $parameters['type'], $customsize ?: Proxy::PIXEL_SMALL); if (empty($id)) {
Logger::notice('No picture id was detected', ['parameters' => $parameters]);
throw new HTTPException\NotFoundException(DI::l10n()->t('The Photo is not available.'));
}
$photo = self::getPhotoByid($id, $parameters['type'], $customsize ?: Proxy::PIXEL_SMALL);
} else { } else {
$photoid = pathinfo($parameters['name'], PATHINFO_FILENAME); $photoid = pathinfo($parameters['name'], PATHINFO_FILENAME);
$scale = 0; $scale = 0;
@ -202,11 +217,11 @@ class Photo extends BaseModule
exit(); exit();
} }
private static function getAvatar(int $uid, $type, $customsize) private static function getPhotoByid(int $id, $type, $customsize)
{ {
switch($type) { switch($type) {
case "preview": case "preview":
$media = DBA::selectFirst('post-media', ['preview', 'url', 'mimetype', 'type', 'uri-id'], ['id' => $uid]); $media = DBA::selectFirst('post-media', ['preview', 'url', 'mimetype', 'type', 'uri-id'], ['id' => $id]);
if (empty($media)) { if (empty($media)) {
return false; return false;
} }
@ -223,10 +238,10 @@ class Photo extends BaseModule
if (Network::isLocalLink($url) && preg_match('|.*?/photo/(.*[a-fA-F0-9])\-(.*[0-9])\..*[\w]|', $url, $matches)) { if (Network::isLocalLink($url) && preg_match('|.*?/photo/(.*[a-fA-F0-9])\-(.*[0-9])\..*[\w]|', $url, $matches)) {
return MPhoto::getPhoto($matches[1], $matches[2]); return MPhoto::getPhoto($matches[1], $matches[2]);
} }
return MPhoto::createPhotoForExternalResource($url, (int)local_user(), $media['mimetype']); return MPhoto::createPhotoForExternalResource($url, (int)local_user(), $media['mimetype']);
case "media": case "media":
$media = DBA::selectFirst('post-media', ['url', 'mimetype', 'uri-id'], ['id' => $uid, 'type' => Post\Media::IMAGE]); $media = DBA::selectFirst('post-media', ['url', 'mimetype', 'uri-id'], ['id' => $id, 'type' => Post\Media::IMAGE]);
if (empty($media)) { if (empty($media)) {
return false; return false;
} }
@ -237,14 +252,14 @@ class Photo extends BaseModule
return MPhoto::createPhotoForExternalResource($media['url'], (int)local_user(), $media['mimetype']); return MPhoto::createPhotoForExternalResource($media['url'], (int)local_user(), $media['mimetype']);
case "link": case "link":
$link = DBA::selectFirst('post-link', ['url', 'mimetype'], ['id' => $uid]); $link = DBA::selectFirst('post-link', ['url', 'mimetype'], ['id' => $id]);
if (empty($link)) { if (empty($link)) {
return false; return false;
} }
return MPhoto::createPhotoForExternalResource($link['url'], (int)local_user(), $link['mimetype']); return MPhoto::createPhotoForExternalResource($link['url'], (int)local_user(), $link['mimetype']);
case "contact": case "contact":
$contact = Contact::getById($uid, ['uid', 'url', 'avatar', 'photo', 'xmpp', 'addr']); $contact = Contact::getById($id, ['uid', 'url', 'avatar', 'photo', 'xmpp', 'addr']);
if (empty($contact)) { if (empty($contact)) {
return false; return false;
} }
@ -273,7 +288,7 @@ class Photo extends BaseModule
} }
return MPhoto::createPhotoForExternalResource($url); return MPhoto::createPhotoForExternalResource($url);
case "header": case "header":
$contact = Contact::getById($uid, ['uid', 'url', 'header']); $contact = Contact::getById($id, ['uid', 'url', 'header']);
if (empty($contact)) { if (empty($contact)) {
return false; return false;
} }
@ -298,9 +313,9 @@ class Photo extends BaseModule
$scale = 5; $scale = 5;
} }
$photo = MPhoto::selectFirst([], ["scale" => $scale, "uid" => $uid, "profile" => 1]); $photo = MPhoto::selectFirst([], ["scale" => $scale, "uid" => $id, "profile" => 1]);
if (empty($photo)) { if (empty($photo)) {
$contact = DBA::selectFirst('contact', [], ['uid' => $uid, 'self' => true]) ?: []; $contact = DBA::selectFirst('contact', [], ['uid' => $id, 'self' => true]) ?: [];
switch($type) { switch($type) {
case "profile": case "profile":

View file

@ -55,7 +55,7 @@
use Friendica\Database\DBA; use Friendica\Database\DBA;
if (!defined('DB_UPDATE_VERSION')) { if (!defined('DB_UPDATE_VERSION')) {
define('DB_UPDATE_VERSION', 1436); define('DB_UPDATE_VERSION', 1437);
} }
return [ return [
@ -98,8 +98,7 @@ return [
"comment" => "The local users", "comment" => "The local users",
"fields" => [ "fields" => [
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"], "uid" => ["type" => "mediumint unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
"parent-uid" => ["type" => "mediumint unsigned", "foreign" => ["user" => "uid"], "parent-uid" => ["type" => "mediumint unsigned", "foreign" => ["user" => "uid"], "comment" => "The parent user that has full control about this user"],
"comment" => "The parent user that has full control about this user"],
"guid" => ["type" => "varchar(64)", "not null" => "1", "default" => "", "comment" => "A unique identifier for this user"], "guid" => ["type" => "varchar(64)", "not null" => "1", "default" => "", "comment" => "A unique identifier for this user"],
"username" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Name that this user is known by"], "username" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "Name that this user is known by"],
"password" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "encrypted password"], "password" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => "encrypted password"],

View file

@ -825,6 +825,7 @@
"url" => ["contact", "url"], "url" => ["contact", "url"],
"nurl" => ["contact", "nurl"], "nurl" => ["contact", "nurl"],
"uri-id" => ["contact", "uri-id"], "uri-id" => ["contact", "uri-id"],
"guid" => ["item-uri", "guid"],
"addr" => ["contact", "addr"], "addr" => ["contact", "addr"],
"alias" => ["contact", "alias"], "alias" => ["contact", "alias"],
"name" => ["contact", "name"], "name" => ["contact", "name"],
@ -895,6 +896,7 @@
"ap-statuses_count" => ["apcontact", "statuses_count"], "ap-statuses_count" => ["apcontact", "statuses_count"],
], ],
"query" => "FROM `contact` "query" => "FROM `contact`
LEFT JOIN `item-uri` ON `item-uri`.`id` = `contact`.`uri-id`
LEFT JOIN `apcontact` ON `apcontact`.`uri-id` = `contact`.`uri-id` LEFT JOIN `apcontact` ON `apcontact`.`uri-id` = `contact`.`uri-id`
LEFT JOIN `fcontact` ON `fcontact`.`uri-id` = contact.`uri-id` LEFT JOIN `fcontact` ON `fcontact`.`uri-id` = contact.`uri-id`
WHERE `contact`.`uid` = 0" WHERE `contact`.`uid` = 0"
@ -907,6 +909,7 @@
"url" => ["contact", "url"], "url" => ["contact", "url"],
"nurl" => ["contact", "nurl"], "nurl" => ["contact", "nurl"],
"uri-id" => ["contact", "uri-id"], "uri-id" => ["contact", "uri-id"],
"guid" => ["item-uri", "guid"],
"addr" => ["contact", "addr"], "addr" => ["contact", "addr"],
"alias" => ["contact", "alias"], "alias" => ["contact", "alias"],
"name" => ["contact", "name"], "name" => ["contact", "name"],
@ -991,6 +994,7 @@
], ],
"query" => "FROM `contact` AS `ucontact` "query" => "FROM `contact` AS `ucontact`
INNER JOIN `contact` ON `contact`.`uri-id` = `ucontact`.`uri-id` AND `contact`.`uid` = 0 INNER JOIN `contact` ON `contact`.`uri-id` = `ucontact`.`uri-id` AND `contact`.`uid` = 0
LEFT JOIN `item-uri` ON `item-uri`.`id` = `ucontact`.`uri-id`
LEFT JOIN `apcontact` ON `apcontact`.`uri-id` = `ucontact`.`uri-id` LEFT JOIN `apcontact` ON `apcontact`.`uri-id` = `ucontact`.`uri-id`
LEFT JOIN `fcontact` ON `fcontact`.`uri-id` = `ucontact`.`uri-id` AND `fcontact`.`network` = 'dspr'" LEFT JOIN `fcontact` ON `fcontact`.`uri-id` = `ucontact`.`uri-id` AND `fcontact`.`network` = 'dspr'"
], ],