ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
ParticipantTableFinishTestAction.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 namespace ILIAS\Test\Participants;
22 
30 use ILIAS\UI\Component\Table\Action\Standard as StandardAction;
34 
36 {
37  public const ACTION_ID = 'finish_test';
38 
39  public function __construct(
40  private readonly Language $lng,
41  private readonly \ilGlobalTemplateInterface $tpl,
42  private readonly UIFactory $ui_factory,
43  private readonly \ilDBInterface $db,
44  private readonly \ilTestProcessLockerFactory $process_locker_factory,
45  private readonly \ilObjUser $user,
46  private readonly \ilTestAccess $test_access,
47  private readonly \ilObjTest $test_obj,
48  private readonly TestResultRepository $test_pass_result_repository
49  ) {
50  }
51 
52  public function getActionId(): string
53  {
54  return self::ACTION_ID;
55  }
56 
57  public function isAvailable(): bool
58  {
59  return $this->test_access->checkManageParticipantsAccess();
60  }
61 
62  public function getTableAction(
63  URLBuilder $url_builder,
64  URLBuilderToken $row_id_token,
65  URLBuilderToken $action_token,
66  URLBuilderToken $action_type_token
67  ): StandardAction {
68  return $this->ui_factory->table()->action()->standard(
69  $this->lng->txt(self::ACTION_ID),
70  $url_builder
71  ->withParameter($action_token, self::ACTION_ID)
72  ->withParameter($action_type_token, ParticipantTableActions::SHOW_ACTION),
73  $row_id_token
74  )->withAsync();
75  }
76 
77  public function getModal(
78  URLBuilder $url_builder,
79  array $selected_participants,
80  bool $all_participants_selected
81  ): ?Modal {
82  $modal = $this->ui_factory->modal()->interruptive(
83  $this->lng->txt('finish_test'),
84  $this->resolveMessage($selected_participants, $all_participants_selected),
85  $url_builder->buildURI()->__toString()
86  )->withActionButtonLabel($this->lng->txt('finish_test'));
87 
88  if (count($selected_participants) > 1) {
89  $modal = $modal->withAffectedItems(
90  array_map(
91  fn(Participant $participant) => $this->ui_factory->modal()->interruptiveItem()->standard(
92  (string) $participant->getUserId(),
93  (new \ilObjUser($participant->getUserId()))->getPublicName()
94  ),
95  $selected_participants
96  )
97  );
98  }
99 
100  return $modal;
101  }
102 
103  public function onSubmit(
104  URLBuilder $url_builder,
105  ServerRequestInterface $request,
106  array $selected_participants,
107  bool $all_participants_selected
108  ): ?Modal {
109  if (!$this->test_access->checkManageParticipantsAccess()) {
110  $this->tpl->setOnScreenMessage(
112  $this->lng->txt('no_permission'),
113  true
114  );
115  return null;
116  }
117 
118  if (count($selected_participants) > 1
119  && $this->test_obj->getNrOfTries() === 1
120  && $this->test_obj->getEnableProcessingTime()
121  && !$this->test_obj->getResetProcessingTime()
122  && !$this->haveAllSelectedParticipantsReachedMaxProcessingTime($selected_participants)) {
123  $this->tpl->setOnScreenMessage(
125  $this->lng->txt('finish_pass_for_multiple_users_in_processing_time'),
126  true
127  );
128  return null;
129  }
130 
131  // This is required here because of late test object binding
132  $test_session_factory = new \ilTestSessionFactory(
133  $this->test_obj,
134  $this->db,
135  $this->user
136  );
137 
138  foreach ($selected_participants as $participant) {
139  $process_locker = $this->process_locker_factory->withContextId($participant->getActiveId())->getLocker();
140  (new \ilTestPassFinishTasks(
141  $test_session_factory->getSession($participant->getActiveId()),
142  $this->test_obj,
143  $this->test_pass_result_repository
144  ))->performFinishTasks($process_locker, StatusOfAttempt::FINISHED_BY_ADMINISTRATOR);
145  }
146 
147  $logger = $this->test_obj->getTestLogger();
148  if ($logger->isLoggingEnabled()) {
149  $logger->logTestAdministrationInteraction(
150  $logger->getInteractionFactory()->buildTestAdministrationInteraction(
151  $this->test_obj->getRefId(),
152  $this->user->getId(),
153  TestAdministrationInteractionTypes::TEST_RUN_OF_PARTICIPANT_CLOSED,
154  [
156  fn(Participant $participant) => $participant->getUserId(),
157  $selected_participants
158  )
159  ]
160  )
161  );
162  }
163 
164  $this->tpl->setOnScreenMessage(
166  $this->lng->txt('test_attempts_finished'),
167  true
168  );
169  return null;
170  }
171 
172  public function allowActionForRecord(Participant $record): bool
173  {
174  return $record->hasUnfinishedAttempts();
175  }
176 
177  private function resolveMessage(
178  array $selected_participants,
179  bool $all_participants_selected
180  ): string {
181  if ($all_participants_selected) {
182  return $this->lng->txt('finish_test_all');
183  }
184 
185  if (count($selected_participants) === 1) {
186  return sprintf(
187  $this->lng->txt('finish_test_single'),
188  (new \ilObjUser($selected_participants[0]->getUserId()))->getPublicName()
189  );
190  }
191 
192  return $this->lng->txt('finish_test_multiple');
193  }
194 
195  public function getSelectionErrorMessage(): ?string
196  {
197  return $this->lng->txt('finish_test_no_valid_participants_selected');
198  }
199 
200  private function haveAllSelectedParticipantsReachedMaxProcessingTime(array $selected_participants): bool
201  {
202  foreach ($selected_participants as $participant) {
203  if (!$participant->hasUnfinishedAttempts()
204  || !$this->test_obj->isMaxProcessingTimeReached(
205  $this->test_obj->getStartingTimeOfUser($participant->getActiveId()),
206  $participant->getActiveId()
207  )) {
208  return false;
209  }
210  }
211  return true;
212  }
213 }
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:214
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: Participant.php:21
__construct(private readonly Language $lng, private readonly \ilGlobalTemplateInterface $tpl, private readonly UIFactory $ui_factory, private readonly \ilDBInterface $db, private readonly \ilTestProcessLockerFactory $process_locker_factory, private readonly \ilObjUser $user, private readonly \ilTestAccess $test_access, private readonly \ilObjTest $test_obj, private readonly TestResultRepository $test_pass_result_repository)
getTableAction(URLBuilder $url_builder, URLBuilderToken $row_id_token, URLBuilderToken $action_token, URLBuilderToken $action_type_token)
resolveMessage(array $selected_participants, bool $all_participants_selected)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
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
global $lng
Definition: privfeed.php:31
URLBuilder.
Definition: URLBuilder.php:40