diff --git a/src/Module/PermissionTooltip.php b/src/Module/Privacy/PermissionTooltip.php similarity index 68% rename from src/Module/PermissionTooltip.php rename to src/Module/Privacy/PermissionTooltip.php index 5c6b68b4cf..cca7f7f9a3 100644 --- a/src/Module/PermissionTooltip.php +++ b/src/Module/Privacy/PermissionTooltip.php @@ -19,18 +19,21 @@ * */ -namespace Friendica\Module; +namespace Friendica\Module\Privacy; use Friendica\App; use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Hook; use Friendica\Core\L10n; use Friendica\Core\Protocol; +use Friendica\Core\Renderer; use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Database\Database; use Friendica\Model; +use Friendica\Module\Response; use Friendica\Network\HTTPException; use Friendica\Network\HTTPException\InternalServerErrorException; +use Friendica\Privacy\Entity; use Friendica\Security\PermissionSet\Repository\PermissionSet; use Friendica\Util\ACLFormatter; use Friendica\Util\Profiler; @@ -101,109 +104,111 @@ class PermissionTooltip extends \Friendica\BaseModule // Kept for backwards compatibility Hook::callAll('lockview_content', $model); - if ($type == 'item') { - $receivers = $this->fetchReceivers($model['uri-id']); - if (empty($receivers)) { - switch ($model['private']) { - case Model\Item::PUBLIC: - $receivers = $this->t('Public'); - break; - - case Model\Item::UNLISTED: - $receivers = $this->t('Unlisted'); - break; - - case Model\Item::PRIVATE: - $receivers = $this->t('Limited/Private'); - break; - } - } - } else { - $receivers = ''; + $aclReceivers = new Entity\AclReceivers(); + $addressedReceivers = new Entity\AddressedReceivers(); + if (!empty($model['allow_cid']) || !empty($model['allow_gid']) || !empty($model['deny_cid']) || !empty($model['deny_gid'])) { + $aclReceivers = $this->fetchReceiversFromACL($model); + } elseif ($type == 'item') { + $addressedReceivers = $this->fetchAddressedReceivers($model['uri-id']); } - if (empty($model['allow_cid']) - && empty($model['allow_gid']) - && empty($model['deny_cid']) - && empty($model['deny_gid']) - && empty($receivers)) + $privacy = ''; + switch ($model['private'] ?? null) { + case Model\Item::PUBLIC: $privacy = $this->t('Public'); break; + case Model\Item::UNLISTED: $privacy = $this->t('Unlisted'); break; + case Model\Item::PRIVATE: $privacy = $this->t('Limited/Private'); break; + } + + if ($aclReceivers->isEmpty() && $addressedReceivers->isEmpty() && empty($privacy)) { echo $this->t('Remote privacy information not available.'); exit; } - if (!empty($model['allow_cid']) || !empty($model['allow_gid']) || !empty($model['deny_cid']) || !empty($model['deny_gid'])) { - $receivers = $this->fetchReceiversFromACL($model); - } + $tpl = Renderer::getMarkupTemplate('privacy/permission_tooltip.tpl'); + $output = Renderer::replaceMacros($tpl, [ + '$l10n' => [ + 'visible_to' => $this->t('Visible to:'), + 'to' => $this->t('To:'), + 'cc' => $this->t('CC:'), + 'bcc' => $this->t('BCC:'), + 'audience' => $this->t('Audience:'), + 'attributed' => $this->t('Attributed To:'), + ], + '$aclReceivers' => $aclReceivers, + '$addressedReceivers' => $addressedReceivers, + '$privacy' => $privacy, + ]); - $this->httpExit($this->t('Visible to:') . '
' . $receivers); + $this->httpExit($output); } /** - * Fetch a list of receivers based on the ACL data * @throws \Exception */ - private function fetchReceiversFromACL(array $model): string + private function fetchReceiversFromACL(array $model): Entity\AclReceivers { - $allowed_users = $model['allow_cid']; - $allowed_circles = $model['allow_gid']; - $deny_users = $model['deny_cid']; - $deny_circles = $model['deny_gid']; + $allow_cid = $model['allow_cid']; + $allow_gid = $model['allow_gid']; + $deny_cid = $model['deny_cid']; + $deny_gid = $model['deny_gid']; - $l = []; + $allowContacts = []; + $allowCircles = []; + $denyContacts = []; + $denyCircles = []; - if (count($allowed_circles)) { - $key = array_search(Model\Circle::FOLLOWERS, $allowed_circles); + if (count($allow_gid)) { + $key = array_search(Model\Circle::FOLLOWERS, $allow_gid); if ($key !== false) { - $l[] = '' . $this->t('Followers') . ''; - unset($allowed_circles[$key]); + $allowCircles[] = $this->t('Followers'); + unset($allow_gid[$key]); } - $key = array_search(Model\Circle::MUTUALS, $allowed_circles); + $key = array_search(Model\Circle::MUTUALS, $allow_gid); if ($key !== false) { - $l[] = '' . $this->t('Mutuals') . ''; - unset($allowed_circles[$key]); + $allowCircles[] = $this->t('Mutuals'); + unset($allow_gid[$key]); } - foreach ($this->dba->selectToArray('group', ['name'], ['id' => $allowed_circles]) as $circle) { - $l[] = '' . $circle['name'] . ''; + foreach ($this->dba->selectToArray('group', ['name'], ['id' => $allow_gid]) as $circle) { + $allowCircles[] = $circle['name']; } } - foreach ($this->dba->selectToArray('contact', ['name'], ['id' => $allowed_users]) as $contact) { - $l[] = $contact['name']; + foreach ($this->dba->selectToArray('contact', ['name'], ['id' => $allow_cid]) as $contact) { + $allowContacts[] = $contact['name']; } - if (count($deny_circles)) { - $key = array_search(Model\Circle::FOLLOWERS, $deny_circles); + if (count($deny_gid)) { + $key = array_search(Model\Circle::FOLLOWERS, $deny_gid); if ($key !== false) { - $l[] = '' . $this->t('Followers') . ''; - unset($deny_circles[$key]); + $denyCircles[] = $this->t('Followers'); + unset($deny_gid[$key]); } - $key = array_search(Model\Circle::MUTUALS, $deny_circles); + $key = array_search(Model\Circle::MUTUALS, $deny_gid); if ($key !== false) { - $l[] = '' . $this->t('Mutuals') . ''; - unset($deny_circles[$key]); + $denyCircles[] = $this->t('Mutuals'); + unset($deny_gid[$key]); } - foreach ($this->dba->selectToArray('group', ['name'], ['id' => $allowed_circles]) as $circle) { - $l[] = '' . $circle['name'] . ''; + foreach ($this->dba->selectToArray('group', ['name'], ['id' => $allow_gid]) as $circle) { + $denyCircles[] = $circle['name']; } } - foreach ($this->dba->selectToArray('contact', ['name'], ['id' => $deny_users]) as $contact) { - $l[] = '' . $contact['name'] . ''; + foreach ($this->dba->selectToArray('contact', ['name'], ['id' => $deny_cid]) as $contact) { + $denyContacts[] = $contact['name']; } - return implode(', ', $l); + return new Entity\AclReceivers($allowContacts, $allowCircles, $denyContacts, $denyCircles); } /** - * Fetch a list of receivers * @throws InternalServerErrorException */ - private function fetchReceivers(int $uriId): string + private function fetchAddressedReceivers(int $uriId): Entity\AddressedReceivers { $own_url = ''; $uid = $this->session->getLocalUserId(); @@ -242,34 +247,21 @@ class PermissionTooltip extends \Friendica\BaseModule } } - $output = ''; - foreach ($receivers as $type => $receiver) { $max = $this->config->get('system', 'max_receivers'); $total = count($receiver); if ($total > $max) { - $receiver = array_slice($receiver, 0, $max); - $receiver[] = $this->t('%d more', $total - $max); - } - switch ($type) { - case Model\Tag::TO: - $output .= $this->t('To: %s
', implode(', ', $receiver)); - break; - case Model\Tag::CC: - $output .= $this->t('CC: %s
', implode(', ', $receiver)); - break; - case Model\Tag::BCC: - $output .= $this->t('BCC: %s
', implode(', ', $receiver)); - break; - case Model\Tag::AUDIENCE: - $output .= $this->t('Audience: %s
', implode(', ', $receiver)); - break; - case Model\Tag::ATTRIBUTED: - $output .= $this->t('Attributed To: %s
', implode(', ', $receiver)); - break; + $receivers[$type] = array_slice($receiver, 0, $max); + $receivers[$type][] = $this->t('%d more', $total - $max); } } - return $output; + return new Entity\AddressedReceivers( + $receivers[Model\Tag::TO] ?? [], + $receivers[Model\Tag::CC] ?? [], + $receivers[Model\Tag::BCC] ?? [], + $receivers[Model\Tag::AUDIENCE] ?? [], + $receivers[Model\Tag::ATTRIBUTED] ?? [], + ); } } diff --git a/src/Privacy/Entity/AclReceivers.php b/src/Privacy/Entity/AclReceivers.php new file mode 100644 index 0000000000..3212c82166 --- /dev/null +++ b/src/Privacy/Entity/AclReceivers.php @@ -0,0 +1,45 @@ +. + * + */ + +namespace Friendica\Privacy\Entity; + +use Friendica\BaseEntity; + +class AclReceivers extends BaseEntity +{ + protected array $allowContacts = []; + protected array $allowCircles = []; + protected array $denyContacts = []; + protected array $denyCircles = []; + + public function __construct(array $allowContacts = [], array $allowCircles = [], array $denyContacts = [], array $denyCircles = []) + { + $this->allowContacts = $allowContacts; + $this->allowCircles = $allowCircles; + $this->denyContacts = $denyContacts; + $this->denyCircles = $denyCircles; + } + + public function isEmpty(): bool + { + return empty($this->allowContacts) && empty($this->allowCircles) && empty($this->denyContacts) && empty($this->denyCircles); + } +} diff --git a/src/Privacy/Entity/AddressedReceivers.php b/src/Privacy/Entity/AddressedReceivers.php new file mode 100644 index 0000000000..ca20db38c7 --- /dev/null +++ b/src/Privacy/Entity/AddressedReceivers.php @@ -0,0 +1,47 @@ +. + * + */ + +namespace Friendica\Privacy\Entity; + +use Friendica\BaseEntity; + +class AddressedReceivers extends BaseEntity +{ + protected array $to = []; + protected array $cc = []; + protected array $bcc = []; + protected array $audience = []; + protected array $attributed = []; + + public function __construct(array $to = [], array $cc = [], array $bcc = [], array $audience = [], array $attributed = []) + { + $this->to = $to; + $this->cc = $cc; + $this->bcc = $bcc; + $this->audience = $audience; + $this->attributed = $attributed; + } + + public function isEmpty(): bool + { + return empty($this->to) && empty($this->cc) && empty($this->bcc) && empty($this->audience) && empty($this->attributed); + } +} diff --git a/static/routes.config.php b/static/routes.config.php index 32d328b77b..dfd414c444 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -565,7 +565,7 @@ return [ '/opensearch' => [Module\OpenSearch::class, [R::GET]], '/parseurl' => [Module\ParseUrl::class, [R::GET]], - '/permission/tooltip/{type}/{id:\d+}' => [Module\PermissionTooltip::class, [R::GET]], + '/permission/tooltip/{type}/{id:\d+}' => [Module\Privacy\PermissionTooltip::class, [R::GET]], '/photo' => [ '/{size:thumb_small|scaled_full}_{name}' => [Module\Photo::class, [R::GET]], diff --git a/view/templates/privacy/permission_tooltip.tpl b/view/templates/privacy/permission_tooltip.tpl new file mode 100644 index 0000000000..a458755206 --- /dev/null +++ b/view/templates/privacy/permission_tooltip.tpl @@ -0,0 +1,50 @@ +{{$l10n.visible_to}}
+{{if !$aclReceivers->isEmpty()}} + {{foreach from=$aclReceivers->allowCircles item=circle name=allowCircles}} + {{$circle}} + {{if !$smarty.foreach.allowCircles.last}}, {{/if}} + {{/foreach}} + {{if $aclReceivers->allowContacts && $aclReceivers->allowCircles}}, {{/if}} + {{foreach from=$aclReceivers->allowContacts item=contact name=allowContacts}} + {{$contact}} + {{if !$smarty.foreach.allowContacts.last}}, {{/if}} + {{/foreach}} + {{if $aclReceivers->denyCircles && ($aclReceivers->allowContacts || $aclReceivers->allowCircles)}}, {{/if}} + {{foreach from=$aclReceivers->denyCircles item=circle name=denyCircles}} + {{$circle}} + {{if !$smarty.foreach.denyCircles.last}}, {{/if}} + {{/foreach}} + {{if $aclReceivers->denyContacts && ($aclReceivers->denyCircles || $aclReceivers->allowContacts || $aclReceivers->allowCircles)}}, {{/if}} + {{foreach from=$aclReceivers->denyContacts item=contact name=denyContacts}} + {{$contact}} + {{if !$smarty.foreach.denyContacts.last}}, {{/if}} + {{/foreach}} +{{elseif !$addressedReceivers->isEmpty()}} + {{if $addressedReceivers->to}} + {{$l10n.to}} + {{', '|join:$addressedReceivers->to}} +
+ {{/if}} + {{if $addressedReceivers->cc}} + {{$l10n.cc}} + {{', '|join:$addressedReceivers->cc}} +
+ {{/if}} + {{if $addressedReceivers->bcc}} + {{$l10n.bcc}} + {{', '|join:$addressedReceivers->bcc}} +
+ {{/if}} + {{if $addressedReceivers->audience}} + {{$l10n.audience}} + {{', '|join:$addressedReceivers->audience}} +
+ {{/if}} + {{if $addressedReceivers->attributed}} + {{$l10n.attributed}} + {{', '|join:$addressedReceivers->attributed}} +
+ {{/if}} +{{else}} + {{$privacy}} +{{/if}}