diff --git a/src/Module/Delegation.php b/src/Module/Delegation.php deleted file mode 100644 index 8a2b313000..0000000000 --- a/src/Module/Delegation.php +++ /dev/null @@ -1,152 +0,0 @@ -. - * - */ - -namespace Friendica\Module; - -use Friendica\BaseModule; -use Friendica\Core\Hook; -use Friendica\Core\Renderer; -use Friendica\Database\DBA; -use Friendica\DI; -use Friendica\Model\Notification; -use Friendica\Model\User; -use Friendica\Network\HTTPException\ForbiddenException; -use Friendica\Util\Proxy; - -/** - * Switches current user between delegates/parent user - */ -class Delegation extends BaseModule -{ - protected function post(array $request = []) - { - if (!DI::userSession()->getLocalUserId()) { - return; - } - - $uid = DI::userSession()->getLocalUserId(); - $orig_record = User::getById(DI::app()->getLoggedInUserId()); - - if (DI::userSession()->getSubManagedUserId()) { - $user = User::getById(DI::userSession()->getSubManagedUserId()); - if (DBA::isResult($user)) { - $uid = intval($user['uid']); - $orig_record = $user; - } - } - - $identity = intval($request['identity'] ?? 0); - if (!$identity) { - return; - } - - $limited_id = 0; - $original_id = $uid; - - $manages = DBA::selectToArray('manage', ['mid'], ['uid' => $uid]); - foreach ($manages as $manage) { - if ($identity == $manage['mid']) { - $limited_id = $manage['mid']; - break; - } - } - - if ($limited_id) { - $user = User::getById($limited_id); - } else { - // Check if the target user is one of our children - $user = DBA::selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['uid']]); - - // Check if the target user is one of our siblings - if (!DBA::isResult($user) && $orig_record['parent-uid']) { - $user = DBA::selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['parent-uid']]); - } - - // Check if it's our parent or our own user - if (!DBA::isResult($user) - && ( - $orig_record['parent-uid'] && $orig_record['parent-uid'] === $identity - || - $orig_record['uid'] && $orig_record['uid'] === $identity - ) - ) { - $user = User::getById($identity); - } - } - - if (!DBA::isResult($user)) { - return; - } - - DI::session()->clear(); - - DI::auth()->setForUser(DI::app(), $user, true, true); - - if ($limited_id) { - DI::userSession()->setSubManagedUserId($original_id); - } - - $ret = []; - Hook::callAll('home_init', $ret); - - DI::sysmsg()->addNotice($this->t('You are now logged in as %s', $user['username'])); - - DI::baseUrl()->redirect('network'); - } - - protected function content(array $request = []): string - { - if (!DI::userSession()->getLocalUserId()) { - throw new ForbiddenException(DI::l10n()->t('Permission denied.')); - } - - $identities = User::identities(DI::userSession()->getSubManagedUserId() ?: DI::userSession()->getLocalUserId()); - - //getting additional information for each identity - foreach ($identities as $key => $identity) { - $identities[$key]['thumb'] = User::getAvatarUrl($identity, Proxy::SIZE_THUMB); - - $identities[$key]['selected'] = ($identity['nickname'] === DI::app()->getLoggedInUserNickname()); - - $condition = ["`msg` != '' AND NOT (`type` IN (?, ?)) AND NOT `seen`", Notification\Type::INTRO, Notification\Type::MAIL]; - $params = ['distinct' => true, 'expression' => 'parent']; - $notifications = DI::notify()->countForUser($identity['uid'], $condition, $params); - - $params = ['distinct' => true, 'expression' => 'convid']; - $notifications += DBA::count('mail', ['uid' => $identity['uid'], 'seen' => false], $params); - - $notifications += DI::intro()->countActiveForUser($identity['uid']); - - $identities[$key]['notifications'] = $notifications; - } - - $o = Renderer::replaceMacros(Renderer::getMarkupTemplate('delegation.tpl'), [ - '$title' => DI::l10n()->t('Switch between your accounts'), - '$settings_label' => DI::l10n()->t('Manage your accounts'), - '$desc' => DI::l10n()->t('Toggle between different identities or community/group pages which share your account details or which you have been granted "manage" permissions'), - '$choose' => DI::l10n()->t('Select an identity to manage: '), - '$identities' => $identities, - '$submit' => DI::l10n()->t('Submit'), - ]); - - return $o; - } -} diff --git a/src/Module/Settings/Delegation.php b/src/Module/Settings/Delegation.php index 3fd5fef49f..e122dc62d5 100644 --- a/src/Module/Settings/Delegation.php +++ b/src/Module/Settings/Delegation.php @@ -21,29 +21,48 @@ namespace Friendica\Module\Settings; +use Friendica\App; use Friendica\BaseModule; +use Friendica\Core\L10n; use Friendica\Core\Renderer; -use Friendica\Database\DBA; -use Friendica\DI; +use Friendica\Core\Session\Capability\IHandleUserSessions; +use Friendica\Database\Database; use Friendica\Model\User; use Friendica\Module\BaseSettings; +use Friendica\Module\Response; +use Friendica\Navigation\SystemMessages; use Friendica\Network\HTTPException; +use Friendica\Util\Profiler; use Friendica\Util\Strings; +use Psr\Log\LoggerInterface; /** * Account delegation settings module */ class Delegation extends BaseSettings { + /** @var SystemMessages */ + private $systemMessages; + /** @var Database */ + private $db; + + public function __construct(Database $db, SystemMessages $systemMessages, IHandleUserSessions $session, App\Page $page, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = []) + { + parent::__construct($session, $page, $l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); + + $this->systemMessages = $systemMessages; + $this->db = $db; + } + protected function post(array $request = []) { - if (!DI::app()->isLoggedIn()) { - throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.')); + if (!$this->session->isAuthenticated()) { + return; } BaseModule::checkFormSecurityTokenRedirectOnError('settings/delegation', 'delegate'); - $parent_uid = $request['parent_user'] ?? null; + $parent_uid = $request['parent_user'] ?? null; $parent_password = $request['parent_password'] ?? ''; if ($parent_uid) { @@ -51,66 +70,63 @@ class Delegation extends BaseSettings // An integer value will trigger the direct user query on uid in User::getAuthenticationInfo $parent_uid = (int)$parent_uid; User::getIdFromPasswordAuthentication($parent_uid, $parent_password); - DI::sysmsg()->addInfo(DI::l10n()->t('Delegation successfully granted.')); + $this->systemMessages->addInfo($this->t('Delegation successfully granted.')); } catch (\Exception $ex) { - DI::sysmsg()->addNotice(DI::l10n()->t('Parent user not found, unavailable or password doesn\'t match.')); + $this->systemMessages->addNotice($this->t('Parent user not found, unavailable or password doesn\'t match.')); return; } } else { - DI::sysmsg()->addInfo(DI::l10n()->t('Delegation successfully revoked.')); + $this->systemMessages->addInfo($this->t('Delegation successfully revoked.')); } - DBA::update('user', ['parent-uid' => $parent_uid], ['uid' => DI::userSession()->getLocalUserId()]); + $this->db->update('user', ['parent-uid' => $parent_uid], ['uid' => $this->session->getLocalUserId()]); } protected function content(array $request = []): string { parent::content(); - if (!DI::userSession()->getLocalUserId()) { - throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.')); + if (!$this->session->isAuthenticated()) { + throw new HTTPException\ForbiddenException($this->t('Permission denied.')); } - $args = DI::args(); - - // @TODO Replace with router-provided arguments - $action = $args->get(2); - $user_id = $args->get(3); + $action = $this->parameters['action'] ?? ''; + $user_id = $this->parameters['user_id'] ?? 0; if ($action === 'add' && $user_id) { - if (DI::userSession()->getSubManagedUserId()) { - DI::sysmsg()->addNotice(DI::l10n()->t('Delegated administrators can view but not change delegation permissions.')); - DI::baseUrl()->redirect('settings/delegation'); + if ($this->session->getSubManagedUserId()) { + $this->systemMessages->addNotice($this->t('Delegated administrators can view but not change delegation permissions.')); + $this->baseUrl->redirect('settings/delegation'); } $user = User::getById($user_id, ['nickname']); - if (DBA::isResult($user)) { + if ($this->db->isResult($user)) { $condition = [ - 'uid' => DI::userSession()->getLocalUserId(), - 'nurl' => Strings::normaliseLink(DI::baseUrl() . '/profile/' . $user['nickname']) + 'uid' => $this->session->getLocalUserId(), + 'nurl' => Strings::normaliseLink($this->baseUrl . '/profile/' . $user['nickname']) ]; - if (DBA::exists('contact', $condition)) { - DBA::insert('manage', ['uid' => $user_id, 'mid' => DI::userSession()->getLocalUserId()]); + if ($this->db->exists('contact', $condition)) { + $this->db->insert('manage', ['uid' => $user_id, 'mid' => $this->session->getLocalUserId()]); } } else { - DI::sysmsg()->addNotice(DI::l10n()->t('Delegate user not found.')); + $this->systemMessages->addNotice($this->t('Delegate user not found.')); } - DI::baseUrl()->redirect('settings/delegation'); + $this->baseUrl->redirect('settings/delegation'); } if ($action === 'remove' && $user_id) { - if (DI::userSession()->getSubManagedUserId()) { - DI::sysmsg()->addNotice(DI::l10n()->t('Delegated administrators can view but not change delegation permissions.')); - DI::baseUrl()->redirect('settings/delegation'); + if ($this->session->getSubManagedUserId()) { + $this->systemMessages->addNotice($this->t('Delegated administrators can view but not change delegation permissions.')); + $this->baseUrl->redirect('settings/delegation'); } - DBA::delete('manage', ['uid' => $user_id, 'mid' => DI::userSession()->getLocalUserId()]); - DI::baseUrl()->redirect('settings/delegation'); + $this->db->delete('manage', ['uid' => $user_id, 'mid' => $this->session->getLocalUserId()]); + $this->baseUrl->redirect('settings/delegation'); } // find everybody that currently has delegated management to this account/page - $delegates = DBA::selectToArray('user', [], ['`uid` IN (SELECT `uid` FROM `manage` WHERE `mid` = ?)', DI::userSession()->getLocalUserId()]); + $delegates = $this->db->selectToArray('user', [], ['`uid` IN (SELECT `uid` FROM `manage` WHERE `mid` = ?)', $this->session->getLocalUserId()]); $uids = []; foreach ($delegates as $user) { @@ -119,69 +135,76 @@ class Delegation extends BaseSettings // find every contact who might be a candidate for delegation $potentials = []; - $nicknames = []; + $nicknames = []; - $condition = ['baseurl' => DI::baseUrl(), 'self' => false, 'uid' => DI::userSession()->getLocalUserId(), 'blocked' => false]; - $contacts = DBA::select('contact', ['nick'], $condition); - while ($contact = DBA::fetch($contacts)) { + $condition = ['baseurl' => $this->baseUrl, 'self' => false, 'uid' => $this->session->getLocalUserId(), 'blocked' => false]; + $contacts = $this->db->select('contact', ['nick'], $condition); + while ($contact = $this->db->fetch($contacts)) { $nicknames[] = $contact['nick']; } - DBA::close($contacts); + $this->db->close($contacts); // get user records for all potential page delegates who are not already delegates or managers - $potentialDelegateUsers = DBA::selectToArray('user', ['uid', 'username', 'nickname'], ['nickname' => $nicknames]); + $potentialDelegateUsers = $this->db->selectToArray( + 'user', + ['uid', 'username', 'nickname'], + [ + 'nickname' => $nicknames, + 'account_removed' => false, + 'account_expired' => false, + 'blocked' => false, + ] + ); foreach ($potentialDelegateUsers as $user) { if (!in_array($user['uid'], $uids)) { $potentials[] = $user; } } - $parent_user = null; + $parent_user = null; $parent_password = null; - $user = User::getById(DI::userSession()->getLocalUserId(), ['parent-uid', 'email']); - if (DBA::isResult($user) && !DBA::exists('user', ['parent-uid' => DI::userSession()->getLocalUserId()])) { + $user = User::getById($this->session->getLocalUserId(), ['parent-uid', 'email']); + if ($this->db->isResult($user) && !$this->db->exists('user', ['parent-uid' => $this->session->getLocalUserId()])) { $parent_uid = $user['parent-uid']; - $parents = [0 => DI::l10n()->t('No parent user')]; + $parents = [0 => $this->t('No parent user')]; - $fields = ['uid', 'username', 'nickname']; - $condition = ['email' => $user['email'], 'verified' => true, 'blocked' => false, 'parent-uid' => null]; - $parent_users = DBA::selectToArray('user', $fields, $condition); - foreach($parent_users as $parent) { - if ($parent['uid'] != DI::userSession()->getLocalUserId()) { + $fields = ['uid', 'username', 'nickname']; + $condition = ['email' => $user['email'], 'verified' => true, 'blocked' => false, 'parent-uid' => null]; + $parent_users = $this->db->selectToArray('user', $fields, $condition); + foreach ($parent_users as $parent) { + if ($parent['uid'] != $this->session->getLocalUserId()) { $parents[$parent['uid']] = sprintf('%s (%s)', $parent['username'], $parent['nickname']); } } - $parent_user = ['parent_user', DI::l10n()->t('Parent User'), $parent_uid, '', $parents]; - $parent_password = ['parent_password', DI::l10n()->t('Parent Password:'), '', DI::l10n()->t('Please enter the password of the parent account to legitimize your request.')]; + $parent_user = ['parent_user', $this->t('Parent User'), $parent_uid, '', $parents]; + $parent_password = ['parent_password', $this->t('Parent Password:'), '', $this->t('Please enter the password of the parent account to legitimize your request.')]; } $is_child_user = !empty($user['parent-uid']); - $o = Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/delegation.tpl'), [ - '$form_security_token' => BaseModule::getFormSecurityToken('delegate'), - '$account_header' => DI::l10n()->t('Additional Accounts'), - '$account_desc' => DI::l10n()->t('Register additional accounts that are automatically connected to your existing account so you can manage them from this account.'), - '$add_account' => DI::l10n()->t('Register an additional account'), - '$parent_header' => DI::l10n()->t('Parent User'), - '$parent_user' => $parent_user, - '$parent_password' => $parent_password, - '$parent_desc' => DI::l10n()->t('Parent users have total control about this account, including the account settings. Please double check whom you give this access.'), - '$is_child_user' => $is_child_user, - '$submit' => DI::l10n()->t('Save Settings'), - '$header' => DI::l10n()->t('Manage Accounts'), - '$delegates_header' => DI::l10n()->t('Delegates'), - '$base' => DI::baseUrl(), - '$desc' => DI::l10n()->t('Delegates are able to manage all aspects of this account/page except for basic account settings. Please do not delegate your personal account to anybody that you do not trust completely.'), - '$head_delegates' => DI::l10n()->t('Existing Page Delegates'), - '$delegates' => $delegates, - '$head_potentials' => DI::l10n()->t('Potential Delegates'), - '$potentials' => $potentials, - '$remove' => DI::l10n()->t('Remove'), - '$add' => DI::l10n()->t('Add'), - '$none' => DI::l10n()->t('No entries.') - ]); + return Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/delegation.tpl'), [ + '$l10n' => [ + 'account_header' => $this->t('Additional Accounts'), + 'account_desc' => $this->t('Register additional accounts that are automatically connected to your existing account so you can manage them from this account.'), + 'add_account' => $this->t('Register an additional account'), + 'parent_header' => $this->t('Parent User'), + 'parent_desc' => $this->t('Parent users have total control about this account, including the account settings. Please double check whom you give this access.'), + 'submit' => $this->t('Save Settings'), + 'header' => $this->t('Manage Accounts'), + 'delegates_header' => $this->t('Delegates'), + 'desc' => $this->t('Delegates are able to manage all aspects of this account/page except for basic account settings. Please do not delegate your personal account to anybody that you do not trust completely.'), + 'head_delegates' => $this->t('Existing Page Delegates'), + 'head_potentials' => $this->t('Potential Delegates'), + 'none' => $this->t('No entries.'), + ], - return $o; + '$form_security_token' => BaseModule::getFormSecurityToken('delegate'), + '$parent_user' => $parent_user, + '$parent_password' => $parent_password, + '$is_child_user' => $is_child_user, + '$delegates' => $delegates, + '$potentials' => $potentials, + ]); } } diff --git a/src/Module/User/Delegation.php b/src/Module/User/Delegation.php new file mode 100644 index 0000000000..6f20b9facb --- /dev/null +++ b/src/Module/User/Delegation.php @@ -0,0 +1,195 @@ +. + * + */ + +namespace Friendica\Module\User; + +use Friendica\App; +use Friendica\BaseModule; +use Friendica\Contact\Introduction\Repository\Introduction; +use Friendica\Core\Hook; +use Friendica\Core\L10n; +use Friendica\Core\Renderer; +use Friendica\Core\Session\Capability\IHandleUserSessions; +use Friendica\Database\Database; +use Friendica\Model\Notification; +use Friendica\Model\User; +use Friendica\Module\Response; +use Friendica\Navigation\Notifications\Repository\Notify; +use Friendica\Navigation\SystemMessages; +use Friendica\Network\HTTPException\ForbiddenException; +use Friendica\Security\Authentication; +use Friendica\Util; +use Psr\Log\LoggerInterface; + +/** + * Switches current user between delegates/parent user + */ +class Delegation extends BaseModule +{ + /** @var IHandleUserSessions */ + private $session; + /** @var Database */ + private $db; + /** @var Authentication */ + private $auth; + /** @var SystemMessages */ + private $systemMessages; + /** @var Notify */ + private $notify; + /** @var Introduction */ + private $intro; + /** @var App */ + private $app; + + public function __construct(App $app, Introduction $intro, Notify $notify, SystemMessages $systemMessages, Authentication $auth, Database $db, IHandleUserSessions $session, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Util\Profiler $profiler, Response $response, array $server, array $parameters = []) + { + parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters); + + $this->session = $session; + $this->db = $db; + $this->auth = $auth; + $this->systemMessages = $systemMessages; + $this->notify = $notify; + $this->intro = $intro; + $this->app = $app; + } + + protected function post(array $request = []) + { + if (!$this->session->getLocalUserId()) { + return; + } + + $uid = $this->session->getLocalUserId(); + $orig_record = User::getById($this->session->getLocalUserId()); + + if ($this->session->getSubManagedUserId()) { + $user = User::getById($this->session->getSubManagedUserId()); + if ($this->db->isResult($user)) { + $uid = intval($user['uid']); + $orig_record = $user; + } + } + + $identity = intval($request['identity'] ?? 0); + if (!$identity) { + return; + } + + $limited_id = 0; + $original_id = $uid; + + $manages = $this->db->selectToArray('manage', ['mid'], ['uid' => $uid]); + foreach ($manages as $manage) { + if ($identity == $manage['mid']) { + $limited_id = $manage['mid']; + break; + } + } + + if ($limited_id) { + $user = User::getById($limited_id); + } else { + // Check if the target user is one of our children + $user = $this->db->selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['uid']]); + + // Check if the target user is one of our siblings + if (!$this->db->isResult($user) && $orig_record['parent-uid']) { + $user = $this->db->selectFirst('user', [], ['uid' => $identity, 'parent-uid' => $orig_record['parent-uid']]); + } + + // Check if it's our parent or our own user + if (!$this->db->isResult($user) + && ( + $orig_record['parent-uid'] && $orig_record['parent-uid'] === $identity + || + $orig_record['uid'] && $orig_record['uid'] === $identity + ) + ) { + $user = User::getById($identity); + } + } + + if (!$this->db->isResult($user)) { + return; + } + + $this->session->clear(); + + $this->auth->setForUser($this->app, $user, true, true); + + if ($limited_id) { + $this->session->setSubManagedUserId($original_id); + } + + $ret = []; + Hook::callAll('home_init', $ret); + + $this->systemMessages->addNotice($this->t('You are now logged in as %s', $user['username'])); + + $this->baseUrl->redirect('network'); + } + + protected function content(array $request = []): string + { + if (!$this->session->getLocalUserId()) { + throw new ForbiddenException($this->t('Permission denied.')); + } + + $identities = User::identities($this->session->getSubManagedUserId() ?: $this->session->getLocalUserId()); + + //getting additional information for each identity + foreach ($identities as $key => $identity) { + $identities[$key]['thumb'] = User::getAvatarUrl($identity, Util\Proxy::SIZE_THUMB); + + $identities[$key]['selected'] = ($identity['nickname'] === $this->session->getLocalUserNickname()); + + $notifications = $this->notify->countForUser( + $identity['uid'], + ["`msg` != '' AND NOT (`type` IN (?, ?)) AND NOT `seen`", Notification\Type::INTRO, Notification\Type::MAIL], + ['distinct' => true, 'expression' => 'parent'] + ); + + $notifications += $this->db->count( + 'mail', + ['uid' => $identity['uid'], 'seen' => false], + ['distinct' => true, 'expression' => 'convid'] + ); + + $notifications += $this->intro->countActiveForUser($identity['uid']); + + $identities[$key]['notifications'] = $notifications; + } + + $tpl = Renderer::getMarkupTemplate('delegation.tpl'); + return Renderer::replaceMacros($tpl, [ + '$l10n' => [ + 'title' => $this->t('Switch between your accounts'), + 'settings_label' => $this->t('Manage your accounts'), + 'desc' => $this->t('Toggle between different identities or community/group pages which share your account details or which you have been granted "manage" permissions'), + 'choose' => $this->t('Select an identity to manage: '), + 'submit' => $this->t('Submit'), + ], + + '$identities' => $identities, + ]); + } +} diff --git a/static/routes.config.php b/static/routes.config.php index 1b708140ca..e1dbc6321b 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -423,8 +423,8 @@ return [ ], '/credits' => [Module\Credits::class, [R::GET]], - '/delegation' => [Module\Delegation::class, [R::GET, R::POST]], - '/dfrn_notify[/{nickname}]' => [Module\DFRN\Notify::class, [R::POST]], + '/delegation' => [Module\User\Delegation::class, [R::GET, R::POST]], + '/dfrn_notify[/{nickname}]' => [Module\DFRN\Notify::class, [ R::POST]], '/dfrn_poll/{nickname}' => [Module\DFRN\Poll::class, [R::GET]], '/dirfind' => [Module\Search\Directory::class, [R::GET]], '/directory' => [Module\Directory::class, [R::GET]], diff --git a/view/templates/delegation.tpl b/view/templates/delegation.tpl index 0e819cdada..1faab170e9 100644 --- a/view/templates/delegation.tpl +++ b/view/templates/delegation.tpl @@ -1,11 +1,12 @@ -

{{$title}}

-

{{$desc nofilter}}

-

{{$choose}}

+
+

{{$l10n.title}}

+

{{$l10n.desc}}

+

{{$l10n.choose}}

- - -

- {{$settings_label}} -

diff --git a/view/templates/settings/delegation.tpl b/view/templates/settings/delegation.tpl index 74e3350d60..d7c59fd636 100644 --- a/view/templates/settings/delegation.tpl +++ b/view/templates/settings/delegation.tpl @@ -1,54 +1,56 @@
-

{{$header}}

+

{{$l10n.header}}

{{if !$is_child_user}} -

{{$account_header}}

- -

{{$add_account}}

+

{{$l10n.account_header}}

+ +

{{$l10n.add_account}}

{{/if}} {{if $parent_user}} -

{{$parent_header}}

-

{{$parent_desc}}

-
-
- - {{include file="field_select.tpl" field=$parent_user}} - {{include file="field_password.tpl" field=$parent_password}} -
-
-
+

{{$l10n.parent_header}}

+

{{$l10n.parent_desc}}

+
+
+ + {{include file="field_select.tpl" field=$parent_user}} + {{include file="field_password.tpl" field=$parent_password}} +
+ +
+
+
{{/if}} -

{{$delegates_header}}

+

{{$l10n.delegates_header}}

-

{{$desc nofilter}}

+

{{$l10n.desc}}

-

{{$head_delegates}}

+

{{$l10n.head_delegates}}

{{if $delegates}} - {{foreach $delegates as $x}} - + {{foreach $delegates as $delegate}} +
+ + + +
{{/foreach}} -
+
{{else}} -

{{$none}}

+

{{$l10n.none}}

{{/if}} -

{{$head_potentials}}

+

{{$l10n.head_potentials}}

{{if $potentials}} - {{foreach $potentials as $x}} - + {{foreach $potentials as $potential}} +
+ + + +
{{/foreach}} -
+
{{else}} -

{{$none}}

+

{{$l10n.none}}

{{/if}}