From d30dc521016bd1708262b867ce0ab5b6842c9060 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 4 Oct 2021 06:13:52 +0000 Subject: [PATCH] Access contact avatars by guid --- database.sql | 6 ++++- src/Model/Contact.php | 41 ++++++++++++++++------------ src/Module/Photo.php | 51 ++++++++++++++++++++++------------- static/dbstructure.config.php | 5 ++-- static/dbview.config.php | 4 +++ 5 files changed, 68 insertions(+), 39 deletions(-) diff --git a/database.sql b/database.sql index e91c8b2f69..709d9f35ea 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- 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`.`nurl` AS `nurl`, `contact`.`uri-id` AS `uri-id`, + `item-uri`.`guid` AS `guid`, `contact`.`addr` AS `addr`, `contact`.`alias` AS `alias`, `contact`.`name` AS `name`, @@ -2424,6 +2425,7 @@ CREATE VIEW `account-view` AS SELECT `apcontact`.`followers_count` AS `ap-followers_count`, `apcontact`.`statuses_count` AS `ap-statuses_count` 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 `fcontact` ON `fcontact`.`uri-id` = contact.`uri-id` WHERE `contact`.`uid` = 0; @@ -2439,6 +2441,7 @@ CREATE VIEW `account-user-view` AS SELECT `contact`.`url` AS `url`, `contact`.`nurl` AS `nurl`, `contact`.`uri-id` AS `uri-id`, + `item-uri`.`guid` AS `guid`, `contact`.`addr` AS `addr`, `contact`.`alias` AS `alias`, `contact`.`name` AS `name`, @@ -2522,6 +2525,7 @@ CREATE VIEW `account-user-view` AS SELECT `apcontact`.`statuses_count` AS `ap-statuses_count` FROM `contact` AS `ucontact` 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 `fcontact` ON `fcontact`.`uri-id` = `ucontact`.`uri-id` AND `fcontact`.`network` = 'dspr'; diff --git a/src/Model/Contact.php b/src/Model/Contact.php index adf1b1d2c0..e4df699713 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -1726,15 +1726,18 @@ class Contact * @param string $updated Contact update date * @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 // The parameter can be provided to improve performance - if (empty($updated)) { - $contact = self::getById($cid, ['updated']); - $updated = $contact['updated'] ?? ''; + if (empty($updated) || empty($guid)) { + $account = DBA::selectFirst('account-user-view', ['updated', 'guid'], ['id' => $cid]); + $updated = $account['updated'] ?? ''; + $guid = $account['guid'] ?? ''; } + $guid = urlencode($guid); + $url = DI::baseUrl() . '/photo/contact/'; switch ($size) { case Proxy::SIZE_MICRO: @@ -1753,7 +1756,7 @@ class Contact $url .= Proxy::PIXEL_LARGE . '/'; 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 * @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 // The parameter can be provided to improve performance - if (empty($updated)) { - $contact = self::getById($cid, ['updated']); - $updated = $contact['updated'] ?? ''; + if (empty($updated) || empty($guid)) { + $account = DBA::selectFirst('account-user-view', ['updated', 'guid'], ['id' => $cid]); + $updated = $account['updated'] ?? ''; + $guid = $account['guid'] ?? ''; } + $guid = urlencode($guid); + $url = DI::baseUrl() . '/photo/header/'; switch ($size) { case Proxy::SIZE_MICRO: @@ -1808,7 +1814,7 @@ class Contact break; } - return $url . $cid . ($updated ? '?ts=' . strtotime($updated) : ''); + return $url . ($guid ?: $cid) . ($updated ? '?ts=' . strtotime($updated) : ''); } /** @@ -2184,7 +2190,7 @@ class Contact } $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 $keep = ['batch', 'notify', 'poll', 'request', 'confirm', 'poco', 'baseurl']; @@ -2212,6 +2218,12 @@ class Contact 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) { self::updateContact($id, $uid, $contact['url'], $ret['url'], ['failed' => false, 'last-update' => $updated, 'success_update' => $updated]); @@ -2230,12 +2242,7 @@ class Contact return true; } - if (empty($guid)) { - $ret['uri-id'] = ItemURI::getIdByURI($ret['url']); - } else { - $ret['uri-id'] = ItemURI::insert(['uri' => $ret['url'], 'guid' => $guid]); - } - + $ret['uri-id'] = $uriid; $ret['nurl'] = Strings::normaliseLink($ret['url']); $ret['updated'] = $updated; $ret['failed'] = false; diff --git a/src/Module/Photo.php b/src/Module/Photo.php index ea6af26367..9ab258cf67 100644 --- a/src/Module/Photo.php +++ b/src/Module/Photo.php @@ -83,26 +83,41 @@ class Photo extends BaseModule } if (!empty($parameters['nickname_ext'])) { - $nickname = pathinfo($parameters['nickname_ext'], PATHINFO_FILENAME); - $user = User::getByNickname($nickname, ['uid']); - if (empty($user)) { - throw new HTTPException\NotFoundException(); - } + if (in_array($parameters['type'], ['contact', 'header'])) { + $guid = pathinfo($parameters['nickname_ext'], PATHINFO_FILENAME); + $account = DBA::selectFirst('account-user-view', ['id'], ['guid' => $guid], ['order' => ['uid' => true]]); + 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 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 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 { $photoid = pathinfo($parameters['name'], PATHINFO_FILENAME); $scale = 0; @@ -202,11 +217,11 @@ class Photo extends BaseModule exit(); } - private static function getAvatar(int $uid, $type, $customsize) + private static function getPhotoByid(int $id, $type, $customsize) { switch($type) { 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)) { 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)) { return MPhoto::getPhoto($matches[1], $matches[2]); } - + return MPhoto::createPhotoForExternalResource($url, (int)local_user(), $media['mimetype']); 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)) { return false; } @@ -237,14 +252,14 @@ class Photo extends BaseModule return MPhoto::createPhotoForExternalResource($media['url'], (int)local_user(), $media['mimetype']); case "link": - $link = DBA::selectFirst('post-link', ['url', 'mimetype'], ['id' => $uid]); + $link = DBA::selectFirst('post-link', ['url', 'mimetype'], ['id' => $id]); if (empty($link)) { return false; } return MPhoto::createPhotoForExternalResource($link['url'], (int)local_user(), $link['mimetype']); 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)) { return false; } @@ -273,7 +288,7 @@ class Photo extends BaseModule } return MPhoto::createPhotoForExternalResource($url); case "header": - $contact = Contact::getById($uid, ['uid', 'url', 'header']); + $contact = Contact::getById($id, ['uid', 'url', 'header']); if (empty($contact)) { return false; } @@ -298,9 +313,9 @@ class Photo extends BaseModule $scale = 5; } - $photo = MPhoto::selectFirst([], ["scale" => $scale, "uid" => $uid, "profile" => 1]); + $photo = MPhoto::selectFirst([], ["scale" => $scale, "uid" => $id, "profile" => 1]); if (empty($photo)) { - $contact = DBA::selectFirst('contact', [], ['uid' => $uid, 'self' => true]) ?: []; + $contact = DBA::selectFirst('contact', [], ['uid' => $id, 'self' => true]) ?: []; switch($type) { case "profile": diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 8ea4ea1d06..8203ae5202 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -55,7 +55,7 @@ use Friendica\Database\DBA; if (!defined('DB_UPDATE_VERSION')) { - define('DB_UPDATE_VERSION', 1436); + define('DB_UPDATE_VERSION', 1437); } return [ @@ -98,8 +98,7 @@ return [ "comment" => "The local users", "fields" => [ "uid" => ["type" => "mediumint unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"], - "parent-uid" => ["type" => "mediumint unsigned", "foreign" => ["user" => "uid"], - "comment" => "The parent user that has full control about this user"], + "parent-uid" => ["type" => "mediumint unsigned", "foreign" => ["user" => "uid"], "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"], "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"], diff --git a/static/dbview.config.php b/static/dbview.config.php index 63215968b6..662425b02e 100644 --- a/static/dbview.config.php +++ b/static/dbview.config.php @@ -825,6 +825,7 @@ "url" => ["contact", "url"], "nurl" => ["contact", "nurl"], "uri-id" => ["contact", "uri-id"], + "guid" => ["item-uri", "guid"], "addr" => ["contact", "addr"], "alias" => ["contact", "alias"], "name" => ["contact", "name"], @@ -895,6 +896,7 @@ "ap-statuses_count" => ["apcontact", "statuses_count"], ], "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 `fcontact` ON `fcontact`.`uri-id` = contact.`uri-id` WHERE `contact`.`uid` = 0" @@ -907,6 +909,7 @@ "url" => ["contact", "url"], "nurl" => ["contact", "nurl"], "uri-id" => ["contact", "uri-id"], + "guid" => ["item-uri", "guid"], "addr" => ["contact", "addr"], "alias" => ["contact", "alias"], "name" => ["contact", "name"], @@ -991,6 +994,7 @@ ], "query" => "FROM `contact` AS `ucontact` 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 `fcontact` ON `fcontact`.`uri-id` = `ucontact`.`uri-id` AND `fcontact`.`network` = 'dspr'" ],