19declare(strict_types=1);
23use PHPUnit\Framework\TestCase;
46 [
'field_id' => 1,
'lang_code' =>
'de',
'idx' => 0,
'value' =>
'1val0de',
'position' => 1],
47 [
'field_id' => 1,
'lang_code' =>
'en',
'idx' => 0,
'value' =>
'1val0en',
'position' => 1],
48 [
'field_id' => 1,
'lang_code' =>
'de',
'idx' => 1,
'value' =>
'1val1de',
'position' => 0],
49 [
'field_id' => 1,
'lang_code' =>
'en',
'idx' => 1,
'value' =>
'1val1en',
'position' => 0],
50 [
'field_id' => 1,
'lang_code' =>
'de',
'idx' => 2,
'value' =>
'1val2de',
'position' => 2],
51 [
'field_id' => 1,
'lang_code' =>
'en',
'idx' => 2,
'value' =>
'1val2en',
'position' => 2],
52 [
'field_id' => 2,
'lang_code' =>
'de',
'idx' => 0,
'value' =>
'2val0de',
'position' => 1],
53 [
'field_id' => 2,
'lang_code' =>
'en',
'idx' => 0,
'value' =>
'2val0en',
'position' => 1],
54 [
'field_id' => 2,
'lang_code' =>
'de',
'idx' => 1,
'value' =>
'2val1de',
'position' => 0],
55 [
'field_id' => 2,
'lang_code' =>
'en',
'idx' => 1,
'value' =>
'2val1en',
'position' => 0],
56 [
'field_id' => 2,
'lang_code' =>
'de',
'idx' => 2,
'value' =>
'2val2de',
'position' => 2],
57 [
'field_id' => 2,
'lang_code' =>
'en',
'idx' => 2,
'value' =>
'2val2en',
'position' => 2]
62 foreach (
$a as $key => $item) {
63 if (isset($item[
'status'])) {
64 unset(
$a[$key][
'status']);
67 foreach (
$b as $key => $item) {
68 if (isset($item[
'status'])) {
69 unset(
$b[$key][
'status']);
73 if (count(
$a) !== count(
$b)) {
77 foreach (
$a as $item) {
78 if (!in_array($item,
$b)) {
93 public function exposeData(): array
98 protected function deleteOptionsExcept(
int $field_id,
int ...$keep_option_ids):
void
100 foreach ($this->data as $key => $datum) {
101 if ($datum[
'field_id'] !== $field_id) {
104 if (!in_array($datum[
'idx'], $keep_option_ids)) {
105 unset($this->data[$key]);
110 protected function deleteTranslationsOfOptionExcept(
113 string ...$keep_languages
115 foreach ($this->data as $key => $datum) {
116 if ($datum[
'idx'] !== $option_id || $datum[
'field_id'] !== $field_id) {
119 if (!in_array($datum[
'lang_code'], $keep_languages)) {
120 unset($this->data[$key]);
125 protected function createTranslation(
132 'field_id' => $field_id,
133 'lang_code' => $translation->
language(),
135 'value' => $translation->
getValue(),
136 'position' => $position
140 protected function updateTranslation(
146 foreach ($this->data as $key => $datum) {
148 $datum[
'idx'] !== $option_id ||
149 $datum[
'field_id'] !== $field_id ||
150 $datum[
'lang_code'] !== $translation->
language()
154 $this->data[$key][
'value'] = $translation->
getValue();
155 $this->data[$key][
'position'] = $position;
159 protected function getNextOptionIDInField(
int $field_id):
int
162 foreach ($this->data as $datum) {
163 if ($datum[
'field_id'] !== $field_id) {
166 $max_id = max($max_id, $datum[
'idx']);
176 bool $contains_changes,
179 $rows_by_option_id = [];
180 foreach ($rows as $row) {
181 if ($row[
'field_id'] !== $field_id) {
184 $rows_by_option_id[$row[
'idx']][] = $row;
188 foreach ($rows_by_option_id as $rows) {
192 $field_id = $is_persisted ? $field_id :
null;
194 return new class ($field_id, $contains_changes, $options) extends NullSelectSpecificData {
196 protected ?
int $field_id,
197 protected bool $contains_changes,
198 protected array $options
202 public function isPersisted(): bool
204 return !is_null($this->field_id);
207 public function containsChanges(): bool
209 return $this->contains_changes;
212 public function fieldID(): ?
int
214 return $this->field_id;
217 public function getOptions(): \Generator
219 yield
from $this->options;
226 $first_row = $rows[0];
227 $option_id = in_array(self::OPTION_NOT_PERSISTED, $first_row[
'status'] ?? []) ?
230 $position = $first_row[
'position'];
231 $contains_changes = in_array(self::OPTION_CHANGED, $first_row[
'status'] ?? []);
234 foreach ($rows as $row) {
235 $translations[] = $this->getTranslation($row);
238 return new class ($option_id, $position, $contains_changes, $translations) extends
NullOption {
240 protected ?
int $option_id,
241 protected int $position,
242 protected bool $contains_changes,
243 protected array $translations
247 public function isPersisted():
bool
249 return !is_null($this->option_id);
252 public function containsChanges():
bool
254 return $this->contains_changes;
257 public function optionID(): ?
int
259 return $this->option_id;
262 public function getPosition():
int
264 return $this->position;
267 public function getTranslations(): \Generator
269 yield
from $this->translations;
276 $language = $row[
'lang_code'];
277 $value = $row[
'value'];
278 $is_persisted = !in_array(self::TRANSLATION_NOT_PERSISTED, $row[
'status'] ?? []);
279 $contains_changes = in_array(self::TRANSLATION_CHANGED, $row[
'status'] ?? []);
281 return new class ($language, $value, $is_persisted, $contains_changes) extends
NullOptionTranslation {
283 protected string $language,
284 protected string $value,
285 protected bool $is_persisted,
286 protected bool $contains_changes
290 public function isPersisted():
bool
292 return $this->is_persisted;
295 public function containsChanges():
bool
297 return $this->contains_changes;
302 return $this->language;
314 $gateway = $this->getDBGateway();
316 self::OPTION_CHANGED,
317 self::OPTION_NOT_PERSISTED,
318 self::TRANSLATION_CHANGED,
319 self::TRANSLATION_NOT_PERSISTED
321 $added_data_array = [
322 [
'field_id' => 78,
'lang_code' =>
'de',
'idx' => 1,
'value' =>
'3val0de',
'position' => 1,
'status' => $status],
323 [
'field_id' => 78,
'lang_code' =>
'en',
'idx' => 1,
'value' =>
'3val0en',
'position' => 1,
'status' => $status],
324 [
'field_id' => 78,
'lang_code' =>
'de',
'idx' => 2,
'value' =>
'3val1de',
'position' => 0,
'status' => $status]
326 $new_data_array = array_merge(self::ORIGINAL_DATA, $added_data_array);
327 $new_data = $this->getData(
334 $gateway->create(78, $new_data);
335 $this->assertTrue($this->doArraysHaveSameEntriesIgnoreStatus(
337 $gateway->exposeData()
343 $gateway = $this->getDBGateway();
344 $new_data_array = self::ORIGINAL_DATA;
345 foreach ($new_data_array as $key => $item) {
346 if ($item[
'field_id'] === 1 && $item[
'idx'] === 0) {
347 unset($new_data_array[$key]);
350 $new_data = $this->getData(
357 $gateway->update($new_data);
358 $this->assertTrue($this->doArraysHaveSameEntriesIgnoreStatus(
360 $gateway->exposeData()
366 $gateway = $this->getDBGateway();
368 self::OPTION_CHANGED,
369 self::OPTION_NOT_PERSISTED,
370 self::TRANSLATION_CHANGED,
371 self::TRANSLATION_NOT_PERSISTED
373 $added_data_array = [
374 [
'field_id' => 1,
'lang_code' =>
'de',
'idx' => 3,
'value' =>
'1val3de',
'position' => 3,
'status' => $status],
375 [
'field_id' => 1,
'lang_code' =>
'en',
'idx' => 3,
'value' =>
'1val3en',
'position' => 3,
'status' => $status]
377 $new_data_array = array_merge(self::ORIGINAL_DATA, $added_data_array);
378 $new_data = $this->getData(
385 $gateway->update($new_data);
386 $this->assertTrue($this->doArraysHaveSameEntriesIgnoreStatus(
388 $gateway->exposeData()
394 $gateway = $this->getDBGateway();
395 $new_data_array = self::ORIGINAL_DATA;
396 $status = [self::OPTION_CHANGED];
397 $new_data_array[0][
'position'] = 54;
398 $new_data_array[0][
'status'] = $status;
399 $new_data_array[1][
'position'] = 54;
400 $new_data_array[1][
'status'] = $status;
401 $new_data = $this->getData(
408 $gateway->update($new_data);
409 $this->assertTrue($this->doArraysHaveSameEntriesIgnoreStatus(
411 $gateway->exposeData()
417 $gateway = $this->getDBGateway();
418 $new_data_array = self::ORIGINAL_DATA;
419 $status = [self::OPTION_CHANGED];
420 foreach ($new_data_array as $key => $item) {
421 if ($item[
'field_id'] !== 1 || $item[
'idx'] !== 0) {
424 if ($item[
'lang_code'] ===
'en') {
425 unset($new_data_array[$key]);
428 $new_data_array[$key][
'status'] = $status;
430 $new_data = $this->getData(
437 $gateway->update($new_data);
438 $this->assertTrue($this->doArraysHaveSameEntriesIgnoreStatus(
440 $gateway->exposeData()
446 $gateway = $this->getDBGateway();
448 self::OPTION_CHANGED,
449 self::TRANSLATION_CHANGED,
450 self::TRANSLATION_NOT_PERSISTED
452 $new_data_array = self::ORIGINAL_DATA;
453 foreach ($new_data_array as $key => $item) {
454 if ($item[
'field_id'] === 1 || $item[
'idx'] === 1) {
455 $new_data_array[$key][
'status'] = [self::OPTION_CHANGED];
459 [
'field_id' => 1,
'lang_code' =>
'fr',
'idx' => 1,
'value' =>
'1val1fr',
'position' => 0,
'status' => $status];
460 $new_data = $this->getData(
467 $gateway->update($new_data);
468 $this->assertTrue($this->doArraysHaveSameEntriesIgnoreStatus(
470 $gateway->exposeData()
476 $gateway = $this->getDBGateway();
477 $new_data_array = self::ORIGINAL_DATA;
478 foreach ($new_data_array as $key => $item) {
479 if ($item[
'field_id'] === 2 || $item[
'idx'] === 1) {
480 $new_data_array[$key][
'status'] = [self::OPTION_CHANGED];
483 $new_data_array[4][
'value'] =
'different value';
484 $new_data_array[4][
'status'] = [self::OPTION_CHANGED, self::TRANSLATION_CHANGED];
485 $new_data = $this->getData(
492 $gateway->update($new_data);
493 $this->assertTrue($this->doArraysHaveSameEntriesIgnoreStatus(
495 $gateway->exposeData()
__construct()
Constructor setup ILIAS global object @access public.
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples