Skip to content

Commit 1f63785

Browse files
lscharmermjansenDatabay
authored andcommitted
LegalDocuments: Add dpro footer links for anonymous user
1 parent 5dab698 commit 1f63785

File tree

7 files changed

+119
-31
lines changed

7 files changed

+119
-31
lines changed

Services/DataProtection/classes/Consumer.php

+10-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
namespace ILIAS\DataProtection;
2222

23+
use ilLink;
24+
use ILIAS\Data\URI;
2325
use ILIAS\LegalDocuments\ConsumerToolbox\UI;
2426
use ILIAS\LegalDocuments\ConsumerToolbox\User;
2527
use ilDBConstants;
@@ -85,7 +87,7 @@ public function uses(UseSlot $slot, LazyProvide $provide): UseSlot
8587
} else {
8688
$slot = $slot->canWithdraw($blocks->slot()->withdrawProcess($user, $global_settings, $this->userHasWithdrawn(...)))
8789
->hasAgreement($agreement, self::GOTO_NAME)
88-
->showInFooter($blocks->slot()->modifyFooter($user))
90+
->showInFooter($blocks->slot()->modifyFooter($user, self::GOTO_NAME))
8991
->onSelfRegistration($blocks->slot()->selfRegistration($user, $build_user))
9092
->hasOnlineStatusFilter($blocks->slot()->onlineStatusFilter($this->usersWhoDidntAgree($this->container->database())))
9193
->hasUserManagementFields($blocks->userManagementAgreeDateField($build_user, 'dpro_agree_date', 'dpro'))
@@ -98,15 +100,19 @@ public function uses(UseSlot $slot, LazyProvide $provide): UseSlot
98100

99101
private function showMatchingDocument(User $user, UI $ui, Provide $legal_documents): Closure
100102
{
101-
return function ($footer) use ($user, $ui, $legal_documents) {
103+
return function (Closure $footer) use ($user, $ui, $legal_documents) {
104+
$in_footer = fn($v) => $footer('usr_agreement', $ui->txt('usr_agreement'), $v);
105+
if (!$user->isLoggedIn()) {
106+
return $in_footer(new URI(ilLink::_getLink(null, 'usr', [], self::GOTO_NAME)));
107+
}
102108
if ($user->cannotAgree()) {
103109
return $footer;
104110
}
105111

106-
$render = fn(Document $document): Footer => $footer->withAdditionalModalAndTrigger($ui->create()->modal()->roundtrip(
112+
$render = fn(Document $document): Closure => $in_footer($ui->create()->modal()->roundtrip(
107113
$document->content()->title(),
108114
[$legal_documents->document()->contentAsComponent($document->content())]
109-
), $ui->create()->button()->shy($ui->txt('usr_agreement'), ''));
115+
));
110116

111117
return $user->matchingDocument()
112118
->map($render)

Services/LegalDocuments/classes/Conductor.php

+35-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
namespace ILIAS\LegalDocuments;
2222

23+
use ILIAS\UI\Component\Modal\Modal;
2324
use ILIAS\LegalDocuments\PageFragment;
2425
use ILIAS\DI\Container;
2526
use ILIAS\LegalDocuments\ConsumerSlots\SelfRegistration;
@@ -102,7 +103,7 @@ public function logoutText(): string
102103

103104
public function modifyFooter(Footer $footer): Footer
104105
{
105-
return array_reduce($this->internal->all('footer'), fn($footer, Closure $proc) => $proc($footer), $footer);
106+
return $this->footerBridge($footer, array_reduce($this->internal->all('footer'), fn(Closure $footer, Closure $proc) => $proc($footer), $this->collectFooterItems([]))());
106107
}
107108

108109
public function agree(string $gui, string $cmd): void
@@ -274,4 +275,37 @@ private function createInternal(): Internal
274275
$action
275276
)));
276277
}
278+
279+
private function footerBridge(Footer $footer, array $collection): Footer
280+
{
281+
$new_links = [];
282+
$add_item = function (string $id, string $title, object $obj) use (&$footer, &$new_links): void {
283+
if ($obj instanceof Modal) {
284+
$footer = $footer->withAdditionalModalAndTrigger($obj, $this->container->ui()->factory()->button()->shy($title, ''));
285+
} else {
286+
$new_links[] = $this->container->ui()->factory()->link()->standard($title, (string) $obj);
287+
}
288+
};
289+
290+
foreach ($collection as $args) {
291+
$add_item(...$args);
292+
}
293+
294+
$old_links = $footer->getLinks();
295+
$modals = $footer->getModals();
296+
$new_footer = $this->container->ui()->factory()->mainControls()->footer(array_merge($old_links, $new_links), $footer->getText());
297+
$new_footer = $footer->getPermanentURL() ? $new_footer->withPermanentURL($footer->getPermanentURL()) : $new_footer;
298+
299+
return array_reduce($modals, static fn(Footer $f, array $m) => $f->withAdditionalModalAndTrigger(...$m), $new_footer);
300+
}
301+
302+
private function collectFooterItems(array $items): Closure
303+
{
304+
return function (...$args) use ($items) {
305+
if ($args === []) {
306+
return $items;
307+
}
308+
return $this->collectFooterItems(array_merge($items, [$args]));
309+
};
310+
}
277311
}

Services/LegalDocuments/classes/ConsumerToolbox/ConsumerSlots/ModifyFooter.php

+22-7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
namespace ILIAS\LegalDocuments\ConsumerToolbox\ConsumerSlots;
2222

23+
use ilLink;
2324
use ILIAS\LegalDocuments\Value\DocumentContent;
2425
use ILIAS\UI\Component\Component;
2526
use ILIAS\UI\Component\MainControls\Footer;
@@ -30,6 +31,7 @@
3031
use ILIAS\LegalDocuments\Provide;
3132
use ilTemplate;
3233
use Closure;
34+
use ILIAS\UI\Component\Modal\Modal;
3335

3436
final class ModifyFooter
3537
{
@@ -42,28 +44,33 @@ public function __construct(
4244
private readonly User $user,
4345
private readonly Provide $legal_documents,
4446
private readonly Closure $render,
45-
private readonly Closure $create_template
47+
private readonly Closure $create_template,
48+
private readonly ?Closure $goto_link,
4649
) {
4750
}
4851

49-
public function __invoke(Footer $footer): Footer
52+
public function __invoke(Closure $footer): Closure
5053
{
5154
return $this->user->acceptedVersion()->map(
52-
$this->renderModal($footer)
55+
fn($document) => $this->footer($footer, $this->renderModal($document))
5356
)->except(
54-
fn() => new Ok($footer)
57+
fn() => new Ok(
58+
!$this->goto_link || $this->user->isLoggedIn() ?
59+
$footer :
60+
$this->footer($footer, ($this->goto_link)())
61+
)
5562
)->value();
5663
}
5764

58-
public function renderModal(Footer $footer): Closure
65+
public function renderModal(DocumentContent $content): Modal
5966
{
60-
return fn(DocumentContent $content): Footer => $footer->withAdditionalModalAndTrigger($this->ui->create()->modal()->roundtrip($content->title(), [
67+
return $this->ui->create()->modal()->roundtrip($content->title(), [
6168
$this->ui->create()->legacy($this->ui->txt('usr_agreement_footer_intro')),
6269
$this->ui->create()->divider()->horizontal(),
6370
$this->legal_documents->document()->contentAsComponent($content),
6471
$this->ui->create()->divider()->horizontal(),
6572
$this->withdrawalButton(),
66-
]), $this->ui->create()->button()->shy($this->ui->txt('usr_agreement'), ''));
73+
]);
6774
}
6875

6976
public function withdrawalButton(): Component
@@ -80,4 +87,12 @@ public function withdrawalButton(): Component
8087

8188
return $this->ui->create()->legacy($template->get());
8289
}
90+
91+
/**
92+
* @param URI|Modal $value
93+
*/
94+
private function footer(Closure $footer, object $value): Closure
95+
{
96+
return $footer($this->legal_documents->id(), $this->ui->txt('usr_agreement'), $value);
97+
}
8398
}

Services/LegalDocuments/classes/ConsumerToolbox/Slot.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
namespace ILIAS\LegalDocuments\ConsumerToolbox;
2222

23+
use ILIAS\Data\URI;
24+
use ilLink;
2325
use ILIAS\Refinery\Constraint;
2426
use ILIAS\LegalDocuments\ConsumerToolbox\ConsumerSlots\OnlineStatusFilter;
2527
use ILIAS\LegalDocuments\ConsumerToolbox\ConsumerSlots\SelfRegistration;
@@ -69,9 +71,10 @@ public function agreement(User $user, Settings $settings): Agreement
6971
return new Agreement($user, $settings, $this->blocks->ui(), $this->blocks->routing(), $this->blocks->withRequest(...));
7072
}
7173

72-
public function modifyFooter(User $user): ModifyFooter
74+
public function modifyFooter(User $user, ?string $goto_target = null): ModifyFooter
7375
{
74-
return new ModifyFooter($this->blocks->ui(), $user, $this->provide, fn($arg) => $this->container->ui()->renderer()->render($arg), $this->template(...));
76+
$link = $goto_target ? static fn() => new URI(ilLink::_getLink(null, 'usr', [], $goto_target)) : null;
77+
return new ModifyFooter($this->blocks->ui(), $user, $this->provide, fn($arg) => $this->container->ui()->renderer()->render($arg), $this->template(...), $link);
7578
}
7679

7780
/**

Services/LegalDocuments/test/ConductorTest.php

+7-4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
use ilObjUser;
5151
use ILIAS\LegalDocuments\ConsumerToolbox\Routing;
5252
use ILIAS\Data\Result\Error;
53+
use Closure;
5354

5455
require_once __DIR__ . '/ContainerMock.php';
5556

@@ -140,18 +141,20 @@ public function testLogoutText(): void
140141
public function testModifyFooter(): void
141142
{
142143
$footer = $this->mock(Footer::class);
144+
$new_footer = $this->mock(Footer::class);
143145

144-
$modify_footer = function (Footer $f) use ($footer) {
145-
$this->assertSame($footer, $f);
146+
$modify_footer = function ($f) {
147+
$this->assertInstanceOf(Closure::class, $f);
146148
return $f;
147149
};
148150

149-
$instance = new Conductor($this->mock(Container::class), $this->mockMethod(Internal::class, 'all', ['footer'], [
151+
$container = $this->mockTree(Container::class, ['ui' => ['factory' => ['mainControls' => ['footer' => $new_footer]]]]);
152+
$instance = new Conductor($container, $this->mockMethod(Internal::class, 'all', ['footer'], [
150153
$modify_footer,
151154
$modify_footer,
152155
]), $this->mock(Routing::class));
153156

154-
$this->assertSame($footer, $instance->modifyFooter($footer));
157+
$this->assertSame($new_footer, $instance->modifyFooter($footer));
155158
}
156159

157160
/**

Services/LegalDocuments/test/ConsumerToolbox/ConsumerSlots/ModifyFooterTest.php

+39-12
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
namespace ILIAS\LegalDocuments\ConsumerToolbox\ConsumerSlots;
2222

23+
use ILIAS\Data\URI;
24+
use ILIAS\Data\Result\Error;
2325
use ILIAS\UI\Component\Component;
2426
use ILIAS\LegalDocuments\Value\DocumentContent;
2527
use ilTemplate;
@@ -32,6 +34,7 @@
3234
use ILIAS\LegalDocuments\ConsumerToolbox\ConsumerSlots\ModifyFooter;
3335
use PHPUnit\Framework\TestCase;
3436
use Closure;
37+
use ILIAS\UI\Component\Modal\Modal;
3538

3639
require_once __DIR__ . '/../../ContainerMock.php';
3740

@@ -46,41 +49,64 @@ public function testConstruct(): void
4649
$this->mock(User::class),
4750
$this->mock(Provide::class),
4851
$this->fail(...),
49-
$this->fail(...)
52+
$this->fail(...),
53+
null,
5054
));
5155
}
5256

5357
public function testInvoke(): void
5458
{
55-
$footer = $this->mock(Footer::class);
56-
$footer->expects(self::once())->method('withAdditionalModalAndTrigger')->willReturn($footer);
59+
$return = fn() => null;
60+
$footer = fn() => $return;
5761

5862
$instance = new ModifyFooter(
5963
$this->mock(UI::class),
6064
$this->mockTree(User::class, ['acceptedVersion' => new Ok($this->mock(DocumentContent::class))]),
6165
$this->mock(Provide::class),
6266
fn() => 'rendered',
63-
fn() => $this->mock(ilTemplate::class)
67+
fn() => $this->mock(ilTemplate::class),
68+
null,
6469
);
6570

66-
$this->assertSame($footer, $instance($footer));
71+
$this->assertSame($return, $instance($footer));
6772
}
6873

69-
public function testRenderModal(): void
74+
public function testInvokeWithGotoLink(): void
7075
{
71-
$footer = $this->mock(Footer::class);
72-
$footer->expects(self::once())->method('withAdditionalModalAndTrigger')->willReturn($footer);
76+
$dummy_uri = $this->mock(URI::class);
77+
$return = fn() => null;
78+
$footer = function ($id, $title, $uri) use ($dummy_uri, $return) {
79+
$this->assertSame('foo', $id);
80+
$this->assertSame('translated', $title);
81+
$this->assertSame($dummy_uri, $uri);
82+
return $return;
83+
};
84+
85+
$instance = new ModifyFooter(
86+
$this->mockTree(UI::class, ['txt' => 'translated']),
87+
$this->mockTree(User::class, ['acceptedVersion' => new Error('Not found.'), 'isLoggedIn' => false]),
88+
$this->mockTree(Provide::class, ['id' => 'foo']),
89+
fn() => 'rendered',
90+
fn() => $this->mock(ilTemplate::class),
91+
fn() => $dummy_uri,
92+
);
93+
94+
$this->assertSame($return, $instance($footer));
95+
}
7396

97+
public function testRenderModal(): void
98+
{
7499
$instance = new ModifyFooter(
75100
$this->mock(UI::class),
76101
$this->mock(User::class),
77102
$this->mock(Provide::class),
78103
fn() => 'rendered',
79-
fn() => $this->mock(ilTemplate::class)
104+
fn() => $this->mock(ilTemplate::class),
105+
null
80106
);
81107

82-
$proc = $instance->renderModal($footer);
83-
$this->assertSame($footer, $proc($this->mock(DocumentContent::class)));
108+
$modal = $instance->renderModal($this->mock(DocumentContent::class));
109+
$this->assertInstanceOf(Modal::class, $modal);
84110
}
85111

86112
public function testWithdrawalButton(): void
@@ -94,7 +120,8 @@ public function testWithdrawalButton(): void
94120
$this->mock(User::class),
95121
$this->mock(Provide::class),
96122
fn() => 'rendered',
97-
fn() => $template
123+
fn() => $template,
124+
null
98125
);
99126

100127
$this->assertInstanceOf(Component::class, $instance->withdrawalButton());

Services/TermsOfService/classes/Consumer.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public function uses(UseSlot $slot, LazyProvide $provide): UseSlot
7272

7373
return $slot->canWithdraw($blocks->slot()->withdrawProcess($user, $global_settings, $this->userHasWithdrawn(...)))
7474
->hasAgreement($blocks->slot()->agreement($user, $global_settings), self::GOTO_NAME)
75-
->showInFooter($blocks->slot()->modifyFooter($user))
75+
->showInFooter($blocks->slot()->modifyFooter($user, self::GOTO_NAME))
7676
->showOnLoginPage($blocks->slot()->showOnLoginPage())
7777
->onSelfRegistration($blocks->slot()->selfRegistration($user, $build_user))
7878
->hasOnlineStatusFilter($blocks->slot()->onlineStatusFilter($this->usersWhoDidntAgree($this->container->database())))

0 commit comments

Comments
 (0)