ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
TranslationsTable.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
36 use ILIAS\Data\URI;
41 
43 {
44  private const QUERY_PARAMETER_NAME_SPACE = ['obj', 'trans'];
45  private const TOKEN_STRING_ACTION = 'a';
46  private const TOKEN_STRING_ROW_ID = 't';
47  private const TOKEN_STRING_ACTON_AFFECTED_ITEMS = 'ai';
48 
49  public const ACTION_EDIT = 'e';
50  public const ACTION_MAKE_DEFAULT = 'md';
51  public const ACTION_DELETE = 'd';
52 
57 
59 
63  public function __construct(
64  private readonly UIFactory $ui_factory,
65  private readonly UIRenderer $ui_renderer,
66  private readonly SystemLanguage $lng,
67  private readonly Refinery $refinery,
68  private readonly \ilGlobalTemplateInterface $tpl,
69  private readonly HTTPService $http,
70  private readonly \ilCtrl $ctrl,
71  private Translations $translations,
72  private readonly ObjectProperties $object_properties,
73  URI $here_uri
74  ) {
75  [
80  ] = (new URLBuilder($here_uri))->acquireParameters(
81  self::QUERY_PARAMETER_NAME_SPACE,
82  self::TOKEN_STRING_ACTION,
83  self::TOKEN_STRING_ROW_ID,
84  self::TOKEN_STRING_ACTON_AFFECTED_ITEMS
85  );
86  }
87 
88  public function runAction(): void
89  {
90  $action = $this->http->wrapper()->query()->retrieve(
91  $this->token_action->getName(),
92  $this->refinery->byTrying([
93  $this->refinery->kindlyTo()->string(),
94  $this->refinery->always('')
95  ])
96  );
97 
98  if ($action === '') {
99  return;
100  }
101 
102  match ($action) {
103  self::ACTION_EDIT => $this->editTranslation(),
104  self::ACTION_MAKE_DEFAULT => $this->makeDefault(),
105  self::ACTION_DELETE => $this->deleteTranslations()
106  };
107  }
108 
109  public function getTable(): array
110  {
111  $content = [];
112  if ($this->modal_with_error !== null) {
113  $content[] = $this->modal_with_error;
114  }
115 
116  $content[] = $this->ui_factory->table()->data(
117  $this,
118  $this->lng->txt('available_languages'),
119  $this->getColumns()
120  )->withActions($this->getActions())
121  ->withRequest($this->http->request());
122 
123  return $content;
124  }
125 
126  public function getRows(
127  DataRowBuilder $row_builder,
128  array $visible_column_ids,
129  Range $range,
130  Order $order,
131  ?array $filter_data,
132  ?array $additional_parameters
133  ): \Generator {
134  foreach ($this->translations->getLanguages() as $langauge) {
135  yield $langauge->toRow($row_builder, $this->lng);
136  }
137  }
138 
139  public function getTotalRowCount(
140  ?array $filter_data,
141  ?array $additional_parameters
142  ): ?int {
143  return count($this->translations->getLanguages());
144  }
145 
146 
147  private function getColumns(): array
148  {
149  $cf = $this->ui_factory->table()->column();
150  $columns = [
151  'language' => $cf->text($this->lng->txt('language')),
152  ];
153  if ($this->translations->getContentTranslationActivated()) {
154  $columns['base'] = $cf->boolean(
155  $this->lng->txt('obj_base_lang'),
156  $this->ui_factory->symbol()->icon()->custom('assets/images/standard/icon_checked.svg', '', 'small'),
157  $this->ui_factory->symbol()->icon()->custom('assets/images/standard/icon_unchecked.svg', '', 'small')
158  );
159  }
160 
161  return $columns + [
162  'default' => $cf->boolean(
163  $this->lng->txt('default'),
164  $this->ui_factory->symbol()->icon()->custom('assets/images/standard/icon_checked.svg', '', 'small'),
165  $this->ui_factory->symbol()->icon()->custom('assets/images/standard/icon_unchecked.svg', '', 'small')
166  ),
167  'title' => $cf->text($this->lng->txt('title')),
168  'description' => $cf->text($this->lng->txt('description')),
169  ];
170 
171  }
172 
173  private function getActions(): array
174  {
175  if ($this->translations->migrationMissing()) {
176  return [];
177  }
178  return [
179  self::ACTION_EDIT => $this->ui_factory->table()->action()->single(
180  $this->lng->txt('edit'),
181  $this->url_builder->withParameter(
182  $this->token_action,
183  self::ACTION_EDIT
184  ),
186  )->withAsync(),
187  self::ACTION_MAKE_DEFAULT => $this->ui_factory->table()->action()->single(
188  $this->lng->txt('make_default_language'),
189  $this->url_builder->withParameter(
190  $this->token_action,
191  self::ACTION_MAKE_DEFAULT
192  ),
194  ),
195  self::ACTION_DELETE => $this->ui_factory->table()->action()->standard(
196  $this->lng->txt('delete'),
197  $this->url_builder->withParameter(
198  $this->token_action,
199  self::ACTION_DELETE
200  ),
202  )->withAsync()
203  ];
204  }
205 
206  private function editTranslation(): void
207  {
208  if ($this->http->wrapper()->query()->retrieve(
209  $this->token_action_affected_items->getName(),
210  $this->refinery->kindlyTo()->string()
211  ) === '') {
212  $this->sendAsync(
213  $this->buildEditLanguageModal(
215  )
216  );
217  }
218 
219  $modal = $this->buildEditLanguageModal(
220  $this->http->wrapper()->query()->retrieve(
221  $this->token_action_affected_items->getName(),
222  $this->refinery->kindlyTo()->string()
223  )
224  )->withRequest($this->http->request());
225  $data = $modal->getData();
226  if ($data === null) {
227  $this->modal_with_error = $modal->withOnLoad($modal->getShowSignal());
228  return;
229  }
230 
231  $this->translations = $this->translations->withLanguage($data[0]);
232  $this->object_properties->storePropertyTranslations(
233  $this->translations
234  );
235 
236  $this->object_properties->storePropertyTranslations(
237  $this->translations->withLanguage($data[0])
238  );
239  $this->tpl->setOnScreenMessage('success', $this->lng->txt('saved_successfully'), true);
240  $this->ctrl->redirectByClass($this->ctrl->getCurrentClassPath());
241  }
242 
243  private function makeDefault(): void
244  {
245  $this->translations = $this->translations->withDefaultLanguage(
247  );
248  $this->object_properties->storePropertyTranslations(
249  $this->translations
250  );
251  }
252 
253  private function deleteTranslations(): void
254  {
255  if ($this->http->wrapper()->query()->retrieve(
256  $this->token_action_affected_items->getName(),
257  $this->refinery->byTrying([
258  $this->refinery->kindlyTo()->string(),
259  $this->refinery->kindlyTo()->listOf(
260  $this->refinery->kindlyTo()->string()
261  )
262  ])
263  ) === '') {
264  $this->sendAsync(
265  $this->buildConfirmationModal(
267  )
268  );
269  }
270 
271  $this->object_properties->storePropertyTranslations(
272  array_reduce(
273  $this->http->wrapper()->post()->retrieve(
274  'interruptive_items',
275  $this->refinery->kindlyTo()->listOf(
276  $this->refinery->kindlyTo()->string()
277  )
278  ),
279  static fn(Translations $c, string $v): Translations => $c->withoutLanguage($v),
280  $this->translations
281  )
282  );
283  $this->tpl->setOnScreenMessage('success', $this->lng->txt('saved_successfully'), true);
284  $this->ctrl->redirectByClass($this->ctrl->getCurrentClassPath());
285  }
286 
287  private function buildEditLanguageModal(string $language_code): RoundtripModal
288  {
289  return $this->ui_factory->modal()->roundtrip(
290  $this->lng->txt('edit_language'),
291  null,
292  $this->translations->getLaguageForCode(
293  $language_code
294  )->toForm(
295  $this->lng,
296  $this->ui_factory->input()->field(),
298  ),
299  $this->url_builder
300  ->withParameter($this->token_action, self::ACTION_EDIT)
301  ->withParameter($this->token_action_affected_items, $language_code)
302  ->buildURI()->__toString()
303  );
304  }
305 
306  private function buildConfirmationModal(array $languages_to_delete): InterruptiveModal
307  {
308  return $this->ui_factory->modal()->interruptive(
309  $this->lng->txt('confirm'),
310  $this->lng->txt('obj_conf_delete_lang'),
311  $this->url_builder
312  ->withParameter($this->token_action, self::ACTION_DELETE)
313  ->withParameter($this->token_action_affected_items, $languages_to_delete)
314  ->buildURI()->__toString()
315  )->withAffectedItems(
316  array_map(
317  fn(string $v): InterruptiveItem => $this->ui_factory->modal()
318  ->interruptiveItem()->standard($v, $this->lng->txt("meta_l_{$v}")),
319  $languages_to_delete
320  )
321  );
322  }
323 
325  {
326  $affected_items = $this->retrieveAffectedItemsFromQuery();
327  if (in_array($this->translations->getDefaultLanguage(), $affected_items)
328  || in_array($this->translations->getBaseLanguage(), $affected_items)) {
329  $this->sendAsync(
330  $this->ui_factory->messageBox()->failure(
331  $this->lng->txt('default_base_lang_not_deletable')
332  )
333  );
334  }
335  return $affected_items;
336  }
337 
338  private function retrieveAffectedItemsFromQuery(): array
339  {
340  $affected_items = [];
341  if ($this->http->wrapper()->query()->has($this->token_row_id->getName())) {
342  $affected_items = $this->http->wrapper()->query()->retrieve(
343  $this->token_row_id->getName(),
344  $this->refinery->byTrying(
345  [
346  $this->refinery->container()->mapValues(
347  $this->refinery->kindlyTo()->string()
348  ),
349  $this->refinery->always([])
350  ]
351  )
352  );
353  }
354  if ($affected_items === []) {
355  $this->sendAsync(
356  $this->ui_factory->messageBox()->failure(
357  $this->lng->txt('no_checkbox')
358  )
359  );
360  }
361 
362  return $affected_items;
363  }
364 
365  private function sendAsync(UIComponent $response): void
366  {
367  $this->http->saveResponse(
368  $this->http->response()->withBody(
370  $this->ui_renderer->renderAsync($response)
371  )
372  )
373  );
374  $this->http->sendResponse();
375  $this->http->close();
376  }
377 }
Class handles translation mode for an object.
getTotalRowCount(?array $filter_data, ?array $additional_parameters)
Mainly for the purpose of pagination-support, it is important to know about the total number of recor...
$response
Definition: xapitoken.php:93
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__construct(private readonly UIFactory $ui_factory, private readonly UIRenderer $ui_renderer, private readonly SystemLanguage $lng, private readonly Refinery $refinery, private readonly \ilGlobalTemplateInterface $tpl, private readonly HTTPService $http, private readonly \ilCtrl $ctrl, private Translations $translations, private readonly ObjectProperties $object_properties, URI $here_uri)
$http
Definition: deliver.php:30
$c
Definition: deliver.php:25
Both the subject and the direction need to be specified when expressing an order. ...
Definition: Order.php:28
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static http()
Fetches the global http state from ILIAS.
static ofString(string $string)
Creates a new stream with an initial value.
Definition: Streams.php:41
getRows(DataRowBuilder $row_builder, array $visible_column_ids, Range $range, Order $order, ?array $filter_data, ?array $additional_parameters)
This is called by the table to retrieve rows; map data-records to rows using the $row_builder e...
global $lng
Definition: privfeed.php:31
URLBuilder.
Definition: URLBuilder.php:40
A simple class to express a naive range of whole positive numbers.
Definition: Range.php:28