-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(contactsMenu): Attach user cloud to each contact entry #44954
base: stable29
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ | |
|
||
namespace OC\Contacts\ContactsMenu; | ||
|
||
use OC\Federation\CloudId; | ||
use OC\KnownUser\KnownUserService; | ||
use OC\Profile\ProfileManager; | ||
use OCA\UserStatus\Db\UserStatus; | ||
|
@@ -44,6 +45,7 @@ | |
use OCP\IUser; | ||
use OCP\IUserManager; | ||
use OCP\L10N\IFactory as IL10NFactory; | ||
use Psr\Log\LoggerInterface; | ||
use function array_column; | ||
use function array_fill_keys; | ||
use function array_filter; | ||
|
@@ -62,6 +64,7 @@ | |
private IGroupManager $groupManager, | ||
private KnownUserService $knownUserService, | ||
private IL10NFactory $l10nFactory, | ||
private LoggerInterface $logger, | ||
) { | ||
} | ||
|
||
|
@@ -351,19 +354,35 @@ | |
|
||
private function contactArrayToEntry(array $contact): Entry { | ||
$entry = new Entry(); | ||
|
||
if (!empty($contact['UID'])) { | ||
$uid = $contact['UID']; | ||
$entry->setId($uid); | ||
$entry->setProperty('isUser', false); | ||
$username = ''; | ||
$remoteServer = ''; | ||
|
||
if (isset($contact['CLOUD']) && is_array($contact['CLOUD']) && isset($contact['CLOUD'][0])) { | ||
preg_match('/^(.*?)@(https?:\/\/.*?)$/', $contact['CLOUD'][0], $matches); | ||
if (count($matches) === 3) { | ||
$username = $matches[1]; | ||
$remoteServer = $matches[2]; | ||
$cloud = new CloudId($entry->getId(), $username, $remoteServer); | ||
$entry->setCloudId($cloud); | ||
$this->logger->warning('Set address cloud: ' . json_encode(['username' => $username, 'server' => $remoteServer])); | ||
} else { | ||
$this->logger->warning('Unable to process contact remote server: ' . $contact['CLOUD'][0]); | ||
} | ||
} else { | ||
$this->logger->warning('Invalid remote server data'); | ||
} | ||
// overloaded usage so leaving as-is for now | ||
if (isset($contact['isLocalSystemBook'])) { | ||
$avatar = $this->urlGenerator->linkToRouteAbsolute('core.avatar.getAvatar', ['userId' => $uid, 'size' => 64]); | ||
$entry->setProperty('isUser', true); | ||
} elseif (!empty($contact['FN'])) { | ||
$avatar = $this->urlGenerator->linkToRouteAbsolute('core.GuestAvatar.getAvatar', ['guestName' => str_replace('/', ' ', $contact['FN']), 'size' => 64]); | ||
} elseif ($username != '') { | ||
$avatar = $this->urlGenerator->linkToRemoteRouteAbsolute($remoteServer, 'core.avatar.getAvatar', ['userId' => str_replace('/', ' ', $username), 'size' => 64]); | ||
Check failure on line 383 in lib/private/Contacts/ContactsMenu/ContactsStore.php GitHub Actions / static-code-analysisUndefinedInterfaceMethod
|
||
Check failure Code scanning / Psalm UndefinedInterfaceMethod Error
Method OCP\IURLGenerator::linkToRemoteRouteAbsolute does not exist
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This assumes every cloud ID is a nextcloud? 🫣 |
||
} else { | ||
$avatar = $this->urlGenerator->linkToRouteAbsolute('core.GuestAvatar.getAvatar', ['guestName' => str_replace('/', ' ', $uid), 'size' => 64]); | ||
$avatar = $this->urlGenerator->linkToRemoteRouteAbsolute($remoteServer, 'core.avatar.getAvatar', ['userId' => str_replace('/', ' ', $uid), 'size' => 64]); | ||
Check failure on line 385 in lib/private/Contacts/ContactsMenu/ContactsStore.php GitHub Actions / static-code-analysisUndefinedInterfaceMethod
|
||
Check failure Code scanning / Psalm UndefinedInterfaceMethod Error
Method OCP\IURLGenerator::linkToRemoteRouteAbsolute does not exist
|
||
} | ||
$entry->setAvatar($avatar); | ||
} | ||
|
@@ -374,7 +393,7 @@ | |
|
||
$avatarPrefix = "VALUE=uri:"; | ||
if (!empty($contact['PHOTO']) && str_starts_with($contact['PHOTO'], $avatarPrefix)) { | ||
$entry->setAvatar(substr($contact['PHOTO'], strlen($avatarPrefix))); | ||
//$entry->setAvatar(substr($contact['PHOTO'], strlen($avatarPrefix))); | ||
} | ||
|
||
if (!empty($contact['EMAIL'])) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,41 +27,40 @@ | |
|
||
namespace OC\Contacts\ContactsMenu; | ||
|
||
use OC\Federation\CloudId; | ||
use OCP\Contacts\ContactsMenu\IAction; | ||
use OCP\Contacts\ContactsMenu\IEntry; | ||
use function array_merge; | ||
|
||
class Entry implements IEntry { | ||
public const PROPERTY_STATUS_MESSAGE_TIMESTAMP = 'statusMessageTimestamp'; | ||
|
||
/** @var string|int|null */ | ||
private $id = null; | ||
|
||
private string $fullName = ''; | ||
|
||
/** @var string[] */ | ||
private array $emailAddresses = []; | ||
|
||
private ?string $avatar = null; | ||
|
||
private ?string $profileTitle = null; | ||
|
||
private ?string $profileUrl = null; | ||
|
||
/** @var IAction[] */ | ||
private array $actions = []; | ||
|
||
private array $properties = []; | ||
public function __construct( | ||
private ?string $id = null, | ||
private string $fullName = '', | ||
private array $emailAddresses = [], | ||
private ?string $avatar = null, | ||
private ?string $profileTitle = null, | ||
private ?string $profileUrl = null, | ||
private array $actions = [], | ||
private array $properties = [], | ||
private ?string $status = null, | ||
private ?string $statusMessage = null, | ||
private ?int $statusMessageTimestamp = null, | ||
private ?string $statusIcon = null, | ||
private ?CloudId $cloud = null | ||
) { | ||
} | ||
|
||
private ?string $status = null; | ||
private ?string $statusMessage = null; | ||
private ?int $statusMessageTimestamp = null; | ||
private ?string $statusIcon = null; | ||
|
||
public function setId(string $id): void { | ||
$this->id = $id; | ||
} | ||
|
||
public function getId(): string { | ||
Check failure on line 60 in lib/private/Contacts/ContactsMenu/Entry.php GitHub Actions / static-code-analysisInvalidNullableReturnType
|
||
Check failure Code scanning / Psalm InvalidNullableReturnType Error
The declared return type 'string' for OC\Contacts\ContactsMenu\Entry::getId is not nullable, but 'null|string' contains null
|
||
return $this->id; | ||
Check failure on line 61 in lib/private/Contacts/ContactsMenu/Entry.php GitHub Actions / static-code-analysisNullableReturnStatement
|
||
Check failure Code scanning / Psalm NullableReturnStatement Error
The declared return type 'string' for OC\Contacts\ContactsMenu\Entry::getId is not nullable, but the function returns 'null|string'
|
||
} | ||
|
||
public function setFullName(string $displayName): void { | ||
$this->fullName = $displayName; | ||
} | ||
|
@@ -163,8 +162,25 @@ | |
return $this->properties[$key]; | ||
} | ||
|
||
|
||
public function getStatusMessage(): ?string { | ||
return $this->statusMessage; | ||
} | ||
|
||
public function getStatusMessageTimestamp(): ?int { | ||
return $this->statusMessageTimestamp; | ||
} | ||
|
||
public function setCloudId(CloudId $cloudId) { | ||
$this->cloud = $cloudId; | ||
} | ||
|
||
public function getCloud(): CloudId { | ||
Check failure on line 178 in lib/private/Contacts/ContactsMenu/Entry.php GitHub Actions / static-code-analysisInvalidNullableReturnType
|
||
Check failure Code scanning / Psalm InvalidNullableReturnType Error
The declared return type 'OC\Federation\CloudId' for OC\Contacts\ContactsMenu\Entry::getCloud is not nullable, but 'OC\Federation\CloudId|null' contains null
|
||
return $this->cloud; | ||
Check failure on line 179 in lib/private/Contacts/ContactsMenu/Entry.php GitHub Actions / static-code-analysisNullableReturnStatement
|
||
Check failure Code scanning / Psalm NullableReturnStatement Error
The declared return type 'OC\Federation\CloudId' for OC\Contacts\ContactsMenu\Entry::getCloud is not nullable, but the function returns 'OC\Federation\CloudId|null'
|
||
} | ||
|
||
/** | ||
* @return array{id: int|string|null, fullName: string, avatar: string|null, topAction: mixed, actions: array, lastMessage: '', emailAddresses: string[], profileTitle: string|null, profileUrl: string|null, status: string|null, statusMessage: null|string, statusMessageTimestamp: null|int, statusIcon: null|string, isUser: bool, uid: mixed} | ||
* @return array{id: int|string|null, fullName: string, avatar: string|null, topAction: mixed, actions: array, lastMessage: '', emailAddresses: string[], profileTitle: string|null, profileUrl: string|null, status: string|null, statusMessage: null|string, statusMessageTimestamp: null|int, statusIcon: null|string, isUser: bool, uid: mixed, cloud: mixed} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cloud should be called cloudId to be more clear and the type should be the array you define in the other file |
||
*/ | ||
public function jsonSerialize(): array { | ||
$topAction = !empty($this->actions) ? $this->actions[0]->jsonSerialize() : null; | ||
|
@@ -188,14 +204,7 @@ | |
'statusIcon' => $this->statusIcon, | ||
'isUser' => $this->getProperty('isUser') === true, | ||
'uid' => $this->getProperty('UID'), | ||
'cloud' => $this->cloud, | ||
]; | ||
} | ||
|
||
public function getStatusMessage(): ?string { | ||
return $this->statusMessage; | ||
} | ||
|
||
public function getStatusMessageTimestamp(): ?int { | ||
return $this->statusMessageTimestamp; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -88,4 +88,16 @@ public function getUser(): string { | |
public function getRemote(): string { | ||
return $this->remote; | ||
} | ||
|
||
/** | ||
* @return array{id: string, user: string, remote: string, displayName: string|null} | ||
*/ | ||
public function jsonSerialize(): array { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should implement the interface JsonSerializable? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That being said, should be on the public interface? |
||
return [ | ||
'id' => $this->id, | ||
'user' => $this->user, | ||
'remote' => $this->remote, | ||
'displayName' => $this->displayName, | ||
]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -115,6 +115,19 @@ | |
return $this->getAbsoluteURL($this->linkToRoute($routeName, $arguments)); | ||
} | ||
|
||
|
||
public function linkToRemoteRouteAbsolute(string $remote, $routeName, array $arguments = []): string { | ||
Check failure on line 119 in lib/private/URLGenerator.php GitHub Actions / static-code-analysisInvalidNullableReturnType
|
||
Check failure Code scanning / Psalm InvalidNullableReturnType Error
The declared return type 'string' for OC\URLGenerator::linkToRemoteRouteAbsolute is not nullable, but 'null|string' contains null
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should not be here or on the public interface |
||
return $this->formatAsUrl($remote, $this->linkToRoute($routeName, $arguments)); | ||
Check failure on line 120 in lib/private/URLGenerator.php GitHub Actions / static-code-analysisNullableReturnStatement
|
||
Check failure Code scanning / Psalm NullableReturnStatement Error
The declared return type 'string' for OC\URLGenerator::linkToRemoteRouteAbsolute is not nullable, but the function returns 'null|string'
|
||
} | ||
|
||
private function formatAsUrl(string $baseUrl, string $restUrl): ?string { | ||
$baseUrl = trim($baseUrl); | ||
if (empty($baseUrl) || !filter_var(preg_match("~^(?:f|ht)tps?://~i", $baseUrl) ? $baseUrl : "http://$baseUrl", FILTER_VALIDATE_URL)) { | ||
return null; | ||
} | ||
return filter_var($baseUrl . $restUrl, FILTER_VALIDATE_URL) ? $baseUrl . $restUrl : null; | ||
} | ||
|
||
public function linkToOCSRouteAbsolute(string $routeName, array $arguments = []): string { | ||
// Returns `/subfolder/index.php/ocsapp/…` with `'htaccess.IgnoreFrontController' => false` in config.php | ||
// And `/subfolder/ocsapp/…` with `'htaccess.IgnoreFrontController' => true` in config.php | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the
ICloudManager::resolve()
method instead?