ILIAS  trunk Revision v11.0_alpha-1744-gb0451eebef4
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
ParticipantTableIpRangeAction.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 namespace ILIAS\Test\Participants;
22 
31 
33 {
34  public const ACTION_ID = 'client_ip_range';
35 
36  public function __construct(
37  private readonly Language $lng,
38  private readonly \ilGlobalTemplateInterface $tpl,
39  private readonly UIFactory $ui_factory,
40  private readonly Refinery $refinery,
41  private readonly ParticipantRepository $participant_repository,
42  private readonly \ilTestAccess $test_access,
43  ) {
44  }
45 
46  public function getActionId(): string
47  {
48  return self::ACTION_ID;
49  }
50 
51  public function isAvailable(): bool
52  {
53  return $this->test_access->checkManageParticipantsAccess();
54  }
55 
56  public function getTableAction(
57  URLBuilder $url_builder,
58  URLBuilderToken $row_id_token,
59  URLBuilderToken $action_token,
60  URLBuilderToken $action_type_token
61  ): Action {
62  return $this->ui_factory->table()->action()->standard(
63  $this->lng->txt(self::ACTION_ID),
64  $url_builder
65  ->withParameter($action_token, self::ACTION_ID)
66  ->withParameter($action_type_token, ParticipantTableActions::SHOW_ACTION),
67  $row_id_token
68  )->withAsync();
69  }
70 
71  public function getModal(
72  URLBuilder $url_builder,
73  array $selected_participants,
74  bool $all_participants_selected
75  ): ?Modal {
76  $valid_ip_constraint = $this->refinery->custom()->constraint(
77  fn(?string $ip): bool => $ip === null
78  || $ip === ''
79  || filter_var($ip, FILTER_VALIDATE_IP) !== false,
80  $this->lng->txt('invalid_ip')
81  );
82  $validate_order = $this->refinery->custom()->constraint(
83  function (?array $vs): bool {
84  if ($vs === null) {
85  return true;
86  }
87  return $this->checkIpRangeValidity(
88  $vs['from'],
89  $vs['to']
90  );
91  },
92  sprintf($this->lng->txt('not_greater_than'), $this->lng->txt('max_ip_label'), $this->lng->txt('min_ip_label'))
93  );
94  $ip_range_group_trafo = $this->refinery->custom()->transformation(
95  static function (?array $vs): array {
96  if ($vs === null) {
97  $vs = [
98  'from' => null,
99  'to' => null
100  ];
101  }
102  return $vs;
103  }
104  );
105 
106 
107  $participant_rows = array_map(
108  fn(Participant $participant) => sprintf(
109  '%s, %s',
110  $participant->getLastname(),
111  $participant->getFirstname()
112  ),
113  $selected_participants
114  );
115 
116  return $this->ui_factory->modal()->roundtrip(
117  $this->lng->txt('client_ip_range'),
118  [
119  $this->ui_factory->messageBox()->info(
120  $this->lng->txt(
121  $this->resolveInfoMessage(
122  $selected_participants,
123  $all_participants_selected
124  )
125  )
126  ),
127  $this->ui_factory->listing()->unordered($participant_rows)
128  ],
129  [
130  'ip_range' => $this->ui_factory->input()->field()->group([
131  'from' => $this->ui_factory->input()->field()->text(
132  $this->lng->txt('min_ip_label')
133  )->withAdditionalTransformation($valid_ip_constraint),
134  'to' => $this->ui_factory->input()->field()->text(
135  $this->lng->txt('max_ip_label'),
136  $this->lng->txt('ip_range_byline')
137  )->withAdditionalTransformation($valid_ip_constraint),
138  ])->withValue(
139  $this->isUniqueClientIp($selected_participants)
140  ? [
141  'from' => $selected_participants[0]->getClientIpFrom() ?? '',
142  'to' => $selected_participants[0]->getClientIpTo() ?? ''
143  ]
144  : [
145  'from' => '',
146  'to' => ''
147  ]
148  )
149  ->withAdditionalTransformation($ip_range_group_trafo)
150  ->withAdditionalTransformation($validate_order)
151  ],
152  $url_builder->buildURI()->__toString()
153  )->withSubmitLabel($this->lng->txt('change'));
154  }
155 
156  public function onSubmit(
157  URLBuilder $url_builder,
158  ServerRequestInterface $request,
159  array $selected_participants,
160  bool $all_participants_selected
161  ): ?Modal {
162  if (!$this->test_access->checkManageParticipantsAccess()) {
163  $this->tpl->setOnScreenMessage(
165  $this->lng->txt('no_permission'),
166  true
167  );
168  return null;
169  }
170 
171  $modal = $this->getModal(
172  $url_builder,
173  $selected_participants,
174  $all_participants_selected
175  )->withRequest($request);
176 
177  $data = $modal->getData();
178  if ($data === null) {
179  return $modal->withOnLoad($modal->getShowSignal());
180  }
181 
182  $this->participant_repository->updateIpRange(
183  array_map(
184  static fn(Participant $v) => $v->withClientIpFrom($data['ip_range']['from'])
185  ->withClientIpTo($data['ip_range']['to']),
186  $selected_participants
187  )
188  );
189 
190  $this->tpl->setOnScreenMessage(
192  $this->lng->txt('ip_range_updated'),
193  true
194  );
195  return null;
196  }
197 
198  public function allowActionForRecord(Participant $record): bool
199  {
200  return $record->isInvitedParticipant();
201  }
202 
206  private function resolveInfoMessage(
207  array $selected_participants,
208  bool $all_participants_selected
209  ): string {
210  if ($all_participants_selected) {
211  return 'ip_range_for_all_participants';
212  }
213 
214  if (count($selected_participants) === 1) {
215  return 'ip_range_for_single_participant';
216  }
217 
218  return 'ip_range_for_selected_participants';
219  }
220 
221  private function isUniqueClientIp(array $selected_participants): bool
222  {
223  return count($selected_participants) === 1
224  || count(array_unique(array_map(
225  fn(Participant $participant) => $participant->getClientIpFrom() . '-' . $participant->getClientIpTo(),
226  $selected_participants
227  ))) === 1;
228  }
229 
230  private function checkIpRangeValidity(string $start, string $end): bool
231  {
232  if (filter_var($start, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false
233  && filter_var($end, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) {
234  return ip2long($start) <= ip2long($end);
235  }
236 
237  if (filter_var($start, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false
238  && filter_var($end, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
239  return bin2hex(inet_pton($start)) <= bin2hex(inet_pton($end));
240  }
241  return false;
242  }
243 
244  public function getSelectionErrorMessage(): ?string
245  {
246  return null;
247  }
248 }
This describes commonalities between the different modals.
Definition: Modal.php:34
onSubmit(URLBuilder $url_builder, ServerRequestInterface $request, array $selected_participants, bool $all_participants_selected)
buildURI()
Get a URI representation of the full URL including query string and fragment/hash.
Definition: URLBuilder.php:212
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: Participant.php:21
getTableAction(URLBuilder $url_builder, URLBuilderToken $row_id_token, URLBuilderToken $action_token, URLBuilderToken $action_type_token)
resolveInfoMessage(array $selected_participants, bool $all_participants_selected)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
withValue($value)
Get an input like this with another value displayed on the client side.
Definition: Group.php:61
getModal(URLBuilder $url_builder, array $selected_participants, bool $all_participants_selected)
withParameter(URLBuilderToken $token, string|array $value)
Change an acquired parameter&#39;s value if the supplied token is valid.
Definition: URLBuilder.php:166
__construct(private readonly Language $lng, private readonly \ilGlobalTemplateInterface $tpl, private readonly UIFactory $ui_factory, private readonly Refinery $refinery, private readonly ParticipantRepository $participant_repository, private readonly \ilTestAccess $test_access,)
global $lng
Definition: privfeed.php:31
URLBuilder.
Definition: URLBuilder.php:40