diff --git a/include/api.php b/include/api.php index 164a9de53..fe6321791 100644 --- a/include/api.php +++ b/include/api.php @@ -464,168 +464,23 @@ function api_get_user($contact_id = null) $user )); - // Selecting the id by priority, friendica first - if (is_array($uinfo)) { + if (DBA::isResult($uinfo)) { + // Selecting the id by priority, friendica first api_best_nickname($uinfo); + return DI::twitterUser()->createFromContactId($uinfo[0]['cid'], $uinfo[0]['uid'])->toArray(); } - // if the contact wasn't found, fetch it from the contacts with uid = 0 - if (!DBA::isResult($uinfo)) { - if ($url == "") { - throw new BadRequestException("User not found."); - } - - $contact = DBA::selectFirst('contact', [], ['uid' => 0, 'nurl' => Strings::normaliseLink($url)]); - - if (DBA::isResult($contact)) { - $ret = [ - 'id' => $contact["id"], - 'id_str' => (string) $contact["id"], - 'name' => $contact["name"], - 'screen_name' => (($contact['nick']) ? $contact['nick'] : $contact['name']), - 'location' => ($contact["location"] != "") ? $contact["location"] : ContactSelector::networkToName($contact['network'], $contact['url'], $contact['protocol']), - 'description' => BBCode::toPlaintext($contact["about"] ?? ''), - 'profile_image_url' => Contact::getAvatarUrlForUrl($contact['url'], api_user(), Proxy::SIZE_MICRO), - 'profile_image_url_https' => Contact::getAvatarUrlForUrl($contact['url'], api_user(), Proxy::SIZE_MICRO), - 'profile_image_url_profile_size' => Contact::getAvatarUrlForUrl($contact['url'], api_user(), Proxy::SIZE_THUMB), - 'profile_image_url_large' => Contact::getAvatarUrlForUrl($contact['url'], api_user(), Proxy::SIZE_SMALL), - 'url' => $contact["url"], - 'protected' => false, - 'followers_count' => 0, - 'friends_count' => 0, - 'listed_count' => 0, - 'created_at' => api_date($contact["created"]), - 'favourites_count' => 0, - 'utc_offset' => 0, - 'time_zone' => 'UTC', - 'geo_enabled' => false, - 'verified' => false, - 'statuses_count' => 0, - 'lang' => '', - 'contributors_enabled' => false, - 'is_translator' => false, - 'is_translation_enabled' => false, - 'following' => false, - 'follow_request_sent' => false, - 'statusnet_blocking' => false, - 'notifications' => false, - 'statusnet_profile_url' => $contact["url"], - 'uid' => 0, - 'cid' => Contact::getIdForURL($contact["url"], api_user(), false), - 'pid' => Contact::getIdForURL($contact["url"], 0, false), - 'self' => 0, - 'network' => $contact["network"], - ]; - - return $ret; - } else { - throw new BadRequestException("User ".$url." not found."); - } + if ($url == "") { + throw new BadRequestException("User not found."); } - if ($uinfo[0]['self']) { - if ($uinfo[0]['network'] == "") { - $uinfo[0]['network'] = Protocol::DFRN; - } + $cid = Contact::getIdForURL($url, 0, false); - $usr = DBA::selectFirst('user', ['default-location'], ['uid' => api_user()]); - $profile = DBA::selectFirst('profile', ['about'], ['uid' => api_user(), 'is-default' => true]); - } - $countitems = 0; - $countfriends = 0; - $countfollowers = 0; - $starred = 0; - - $pcontact_id = Contact::getIdForURL($uinfo[0]['url'], 0, false); - - if (!empty($profile['about'])) { - $description = $profile['about']; + if (!empty($cid)) { + return DI::twitterUser()->createFromContactId($cid, 0)->toArray(); } else { - $description = $uinfo[0]["about"]; + throw new BadRequestException("User ".$url." not found."); } - - if (!empty($usr['default-location'])) { - $location = $usr['default-location']; - } elseif (!empty($uinfo[0]["location"])) { - $location = $uinfo[0]["location"]; - } else { - $location = ContactSelector::networkToName($uinfo[0]['network'], $uinfo[0]['url'], $uinfo[0]['protocol']); - } - - $ret = [ - 'id' => intval($pcontact_id), - 'id_str' => (string) intval($pcontact_id), - 'name' => (($uinfo[0]['name']) ? $uinfo[0]['name'] : $uinfo[0]['nick']), - 'screen_name' => (($uinfo[0]['nick']) ? $uinfo[0]['nick'] : $uinfo[0]['name']), - 'location' => $location, - 'description' => BBCode::toPlaintext($description ?? ''), - 'profile_image_url' => Contact::getAvatarUrlForUrl($uinfo[0]['url'], api_user(), Proxy::SIZE_MICRO), - 'profile_image_url_https' => Contact::getAvatarUrlForUrl($uinfo[0]['url'], api_user(), Proxy::SIZE_MICRO), - 'profile_image_url_profile_size' => Contact::getAvatarUrlForUrl($uinfo[0]['url'], api_user(), Proxy::SIZE_THUMB), - 'profile_image_url_large' => Contact::getAvatarUrlForUrl($uinfo[0]['url'], api_user(), Proxy::SIZE_SMALL), - 'url' => $uinfo[0]['url'], - 'protected' => false, - 'followers_count' => intval($countfollowers), - 'friends_count' => intval($countfriends), - 'listed_count' => 0, - 'created_at' => api_date($uinfo[0]['created']), - 'favourites_count' => intval($starred), - 'utc_offset' => "0", - 'time_zone' => 'UTC', - 'geo_enabled' => false, - 'verified' => true, - 'statuses_count' => intval($countitems), - 'lang' => '', - 'contributors_enabled' => false, - 'is_translator' => false, - 'is_translation_enabled' => false, - 'following' => (($uinfo[0]['rel'] == Contact::FOLLOWER) || ($uinfo[0]['rel'] == Contact::FRIEND)), - 'follow_request_sent' => false, - 'statusnet_blocking' => false, - 'notifications' => false, - /// @TODO old way? - //'statusnet_profile_url' => DI::baseUrl()."/contact/".$uinfo[0]['cid'], - 'statusnet_profile_url' => $uinfo[0]['url'], - 'uid' => intval($uinfo[0]['uid']), - 'cid' => intval($uinfo[0]['cid']), - 'pid' => Contact::getIdForURL($uinfo[0]["url"], 0, false), - 'self' => $uinfo[0]['self'], - 'network' => $uinfo[0]['network'], - ]; - - // If this is a local user and it uses Frio, we can get its color preferences. - if ($ret['self']) { - $theme_info = DBA::selectFirst('user', ['theme'], ['uid' => $ret['uid']]); - if ($theme_info['theme'] === 'frio') { - $schema = DI::pConfig()->get($ret['uid'], 'frio', 'schema'); - - if ($schema && ($schema != '---')) { - if (file_exists('view/theme/frio/schema/'.$schema.'.php')) { - $schemefile = 'view/theme/frio/schema/'.$schema.'.php'; - require_once $schemefile; - } - } else { - $nav_bg = DI::pConfig()->get($ret['uid'], 'frio', 'nav_bg'); - $link_color = DI::pConfig()->get($ret['uid'], 'frio', 'link_color'); - $bgcolor = DI::pConfig()->get($ret['uid'], 'frio', 'background_color'); - } - if (empty($nav_bg)) { - $nav_bg = "#708fa0"; - } - if (empty($link_color)) { - $link_color = "#6fdbe8"; - } - if (empty($bgcolor)) { - $bgcolor = "#ededed"; - } - - $ret['profile_sidebar_fill_color'] = str_replace('#', '', $nav_bg); - $ret['profile_link_color'] = str_replace('#', '', $link_color); - $ret['profile_background_color'] = str_replace('#', '', $bgcolor); - } - } - - return $ret; } /** diff --git a/src/Module/Api/Twitter/FollowersIds.php b/src/Module/Api/Twitter/Followers/Ids.php similarity index 95% rename from src/Module/Api/Twitter/FollowersIds.php rename to src/Module/Api/Twitter/Followers/Ids.php index 01be503de..ff3953203 100644 --- a/src/Module/Api/Twitter/FollowersIds.php +++ b/src/Module/Api/Twitter/Followers/Ids.php @@ -19,10 +19,11 @@ * */ -namespace Friendica\Module\Api\Twitter; +namespace Friendica\Module\Api\Twitter\Followers; use Friendica\Core\System; use Friendica\Model\Contact; +use Friendica\Module\Api\Twitter\ContactEndpoint; /** * @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-ids diff --git a/src/Module/Api/Twitter/FollowersList.php b/src/Module/Api/Twitter/Followers/Lists.php similarity index 95% rename from src/Module/Api/Twitter/FollowersList.php rename to src/Module/Api/Twitter/Followers/Lists.php index 8e39f2201..864a77e27 100644 --- a/src/Module/Api/Twitter/FollowersList.php +++ b/src/Module/Api/Twitter/Followers/Lists.php @@ -19,10 +19,11 @@ * */ -namespace Friendica\Module\Api\Twitter; +namespace Friendica\Module\Api\Twitter\Followers; use Friendica\Core\System; use Friendica\Model\Contact; +use Friendica\Module\Api\Twitter\ContactEndpoint; /** * @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-followers-list diff --git a/src/Module/Api/Twitter/FriendsIds.php b/src/Module/Api/Twitter/Friends/Ids.php similarity index 93% rename from src/Module/Api/Twitter/FriendsIds.php rename to src/Module/Api/Twitter/Friends/Ids.php index 3500a4043..fc20336b9 100644 --- a/src/Module/Api/Twitter/FriendsIds.php +++ b/src/Module/Api/Twitter/Friends/Ids.php @@ -19,15 +19,16 @@ * */ -namespace Friendica\Module\Api\Twitter; +namespace Friendica\Module\Api\Twitter\Friends; use Friendica\Core\System; use Friendica\Model\Contact; +use Friendica\Module\Api\Twitter\ContactEndpoint; /** * @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-ids */ -class FriendsIds extends ContactEndpoint +class Ids extends ContactEndpoint { public static function rawContent(array $parameters = []) { diff --git a/src/Module/Api/Twitter/FriendsList.php b/src/Module/Api/Twitter/Friends/Lists.php similarity index 94% rename from src/Module/Api/Twitter/FriendsList.php rename to src/Module/Api/Twitter/Friends/Lists.php index 114e391cc..9c43923dd 100644 --- a/src/Module/Api/Twitter/FriendsList.php +++ b/src/Module/Api/Twitter/Friends/Lists.php @@ -19,15 +19,16 @@ * */ -namespace Friendica\Module\Api\Twitter; +namespace Friendica\Module\Api\Twitter\Friends; use Friendica\Core\System; use Friendica\Model\Contact; +use Friendica\Module\Api\Twitter\ContactEndpoint; /** * @see https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-friends-list */ -class FriendsList extends ContactEndpoint +class Lists extends ContactEndpoint { public static function rawContent(array $parameters = []) { diff --git a/src/Object/Api/Twitter/User.php b/src/Object/Api/Twitter/User.php index bbe6905ef..49e10e77e 100644 --- a/src/Object/Api/Twitter/User.php +++ b/src/Object/Api/Twitter/User.php @@ -24,6 +24,9 @@ namespace Friendica\Object\Api\Twitter; use Friendica\BaseDataTransferObject; use Friendica\Content\ContactSelector; use Friendica\Content\Text\BBCode; +use Friendica\Core\Protocol; +use Friendica\Model\Contact; +use Friendica\Util\Proxy; /** * @see https://developer.twitter.com/en/docs/tweets/data-dictionary/overview/user-object @@ -79,6 +82,14 @@ class User extends BaseDataTransferObject /** @var string */ protected $withheld_scope; + /** + * Missing fields: + * + * - profile_sidebar_fill_color + * - profile_link_color + * - profile_background_color + */ + /** * @param array $publicContact Full contact table record with uid = 0 * @param array $apcontact Optional full apcontact table record @@ -89,9 +100,11 @@ class User extends BaseDataTransferObject */ public function __construct(array $publicContact, array $apcontact = [], array $userContact = [], $skip_status = false, $include_user_entities = true) { + $uid = $userContact['uid'] ?? 0; + $this->id = (int)$publicContact['id']; $this->id_str = (string) $publicContact['id']; - $this->name = $publicContact['name']; + $this->name = $publicContact['name'] ?: $publicContact['nick']; $this->screen_name = $publicContact['nick'] ?: $publicContact['name']; $this->location = $publicContact['location'] ?: ContactSelector::networkToName($publicContact['network'], $publicContact['url'], $publicContact['protocol']); @@ -106,14 +119,14 @@ class User extends BaseDataTransferObject unset($this->entities); } $this->description = BBCode::toPlaintext($publicContact['about']); - $this->profile_image_url_https = $userContact['avatar'] ?? $publicContact['avatar']; + $this->profile_image_url_https = Contact::getAvatarUrlForUrl($publicContact['url'], $uid, Proxy::SIZE_MICRO); $this->protected = false; $this->followers_count = $apcontact['followers_count'] ?? 0; $this->friends_count = $apcontact['following_count'] ?? 0; $this->listed_count = 0; $this->created_at = api_date($publicContact['created']); $this->favourites_count = 0; - $this->verified = false; + $this->verified = $uid != 0; $this->statuses_count = $apcontact['statuses_count'] ?? 0; $this->profile_banner_url = ''; $this->default_profile = false; @@ -127,9 +140,9 @@ class User extends BaseDataTransferObject unset($this->withheld_scope); // Deprecated - $this->profile_image_url = $userContact['avatar'] ?? $publicContact['avatar']; - $this->profile_image_url_profile_size = $publicContact['thumb']; - $this->profile_image_url_large = $publicContact['photo']; + $this->profile_image_url = Contact::getAvatarUrlForUrl($publicContact['url'], $uid, Proxy::SIZE_MICRO); + $this->profile_image_url_profile_size = Contact::getAvatarUrlForUrl($publicContact['url'], $uid, Proxy::SIZE_THUMB); + $this->profile_image_url_large = Contact::getAvatarUrlForUrl($publicContact['url'], $uid, Proxy::SIZE_LARGE); $this->utc_offset = 0; $this->time_zone = 'UTC'; $this->geo_enabled = false; @@ -137,17 +150,17 @@ class User extends BaseDataTransferObject $this->contributors_enabled = false; $this->is_translator = false; $this->is_translation_enabled = false; - $this->following = false; + $this->following = in_array($userContact['rel'] ?? Contact::NOTHING, [Contact::FOLLOWER, Contact::FRIEND]); $this->follow_request_sent = false; $this->statusnet_blocking = false; $this->notifications = false; // Friendica-specific - $this->uid = (int)$userContact['uid'] ?? 0; - $this->cid = (int)$userContact['id'] ?? 0; + $this->uid = (int)$uid; + $this->cid = (int)($userContact['id'] ?? 0); $this->pid = (int)$publicContact['id']; - $this->self = (boolean)$userContact['self'] ?? false; - $this->network = $publicContact['network']; + $this->self = (boolean)($userContact['self'] ?? false); + $this->network = $publicContact['network'] ?: Protocol::DFRN; $this->statusnet_profile_url = $publicContact['url']; } } diff --git a/static/routes.config.php b/static/routes.config.php index 0dee56754..468a9f85e 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -48,27 +48,27 @@ $apiRoutes = [ '/update_profile_image[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]], ], - '/blocks/list[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], - '/conversation/show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], + '/blocks/list[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], + '/conversation/show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], '/direct_messages' => [ - '/all[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], - '/conversation[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], - '/destroy[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::DELETE, R::POST]], - '/new[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]], - '/sent[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], + '/all[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], + '/conversation[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], + '/destroy[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::DELETE, R::POST]], + '/new[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]], + '/sent[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], ], - '/direct_messages[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET, R::POST]], + '/direct_messages[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET, R::POST]], - '/externalprofile/show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], - '/favorites/create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]], - '/favorites/destroy[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::DELETE, R::POST]], - '/favorites[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], - '/followers/ids[.{extension:json|xml|rss|atom}]' => [Module\Api\Twitter\FollowersIds::class, [R::GET ]], - '/followers/list[.{extension:json|xml|rss|atom}]' => [Module\Api\Twitter\FollowersList::class, [R::GET ]], - '/friends/ids[.{extension:json|xml|rss|atom}]' => [Module\Api\Twitter\FriendsIds::class, [R::GET ]], - '/friends/list[.{extension:json|xml|rss|atom}]' => [Module\Api\Twitter\FriendsList::class, [R::GET ]], - '/friendships/destroy[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]], - '/friendships/incoming[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], + '/externalprofile/show[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], + '/favorites/create[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]], + '/favorites/destroy[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::DELETE, R::POST]], + '/favorites[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], + '/followers/ids[.{extension:json|xml|rss|atom}]' => [Module\Api\Twitter\Followers\Ids::class, [R::GET ]], + '/followers/list[.{extension:json|xml|rss|atom}]' => [Module\Api\Twitter\Followers\Lists::class, [R::GET ]], + '/friends/ids[.{extension:json|xml|rss|atom}]' => [Module\Api\Twitter\Friends\Ids::class, [R::GET ]], + '/friends/list[.{extension:json|xml|rss|atom}]' => [Module\Api\Twitter\Friends\Lists::class, [R::GET ]], + '/friendships/destroy[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [ R::POST]], + '/friendships/incoming[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Index::class, [R::GET ]], '/friendica' => [ '/activity/{verb:attendmaybe|attendno|attendyes|dislike|like|unattendmaybe|unattendno|unattendyes|undislike|unlike}[.{extension:json|xml|rss|atom}]'