ILIAS  trunk Revision v11.0_alpha-1723-g8e69f309bab
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
CloneIntroductionAndClosingRemarksMigration.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
21 namespace ILIAS\Test\Setup;
22 
23 use ILIAS\Setup;
26 
28 {
29  private const TESTS_PER_STEP = 100;
30 
31  private \ilDBInterface $db;
32 
33  public function getLabel(): string
34  {
35  return 'Fix missing clones for Introduction and Concluding Remarks.';
36  }
37 
39  {
40  return 1;
41  }
42 
43  public function getPreconditions(Environment $environment): array
44  {
45  return [
46  new \ilDatabaseInitializedObjective()
47  ];
48  }
49 
50  public function prepare(Environment $environment): void
51  {
52  $this->db = $environment->getResource(Setup\Environment::RESOURCE_DATABASE);
53  }
54 
55  public function step(Environment $environment): void
56  {
57  $select_page_statement = $this->db->prepare(
58  'SELECT * FROM page_object WHERE parent_type = "tst" AND page_id = ?',
60  );
61 
62  $max_steps = $this->migrateIntroductions($select_page_statement);
63  $this->migrateConcludingRemarks($select_page_statement, $max_steps);
64 
65  $this->db->free($select_page_statement);
66  }
67 
68  public function getRemainingAmountOfSteps(): int
69  {
70  $result_intro = $this->db->query('
71  SELECT COUNT(test_id) as cnt
72  FROM tst_tests
73  WHERE NOT introduction_page_id IS NULL
74  AND introduction_page_id IN
75  (SELECT introduction_page_id FROM tst_tests GROUP BY introduction_page_id HAVING COUNT(introduction_page_id) > 1)
76  ');
77  $row_intro = $this->db->fetchObject($result_intro);
78 
79  $result_conclusion = $this->db->query('
80  SELECT COUNT(test_id) as cnt
81  FROM tst_tests
82  WHERE NOT concluding_remarks_page_id IS NULL
83  AND concluding_remarks_page_id in
84  (SELECT concluding_remarks_page_id FROM tst_tests GROUP BY concluding_remarks_page_id HAVING COUNT(concluding_remarks_page_id) > 1)
85  ');
86  $row_conclusion = $this->db->fetchObject($result_conclusion);
87 
88  return (int) ceil(($row_intro->cnt + $row_conclusion->cnt) / self::TESTS_PER_STEP);
89  }
90 
91  private function migrateIntroductions(\ilDBStatement $select_page_statement): int
92  {
93  $result = $this->db->query(
94  '
95  SELECT test_id, obj_fi, introduction_page_id
96  FROM tst_tests
97  WHERE NOT introduction_page_id IS NULL
98  AND introduction_page_id IN
99  (SELECT introduction_page_id FROM tst_tests GROUP BY introduction_page_id HAVING COUNT(introduction_page_id) > 1)
100  ORDER BY introduction_page_id
101  LIMIT ' . self::TESTS_PER_STEP
102  );
103 
104  $first_row = $this->db->fetchObject($result);
105  if ($first_row === null) {
106  return self::TESTS_PER_STEP;
107  }
108 
109  $introduction_to_clone = $this->db->fetchObject(
110  $this->db->execute(
111  $select_page_statement,
112  [$first_row->introduction_page_id]
113  )
114  );
115  while (($row = $this->db->fetchObject($result)) !== null) {
116  if ($row->introduction_page_id !== $introduction_to_clone?->page_id) {
117  $introduction_to_clone = $this->db->fetchObject(
118  $this->db->execute(
119  $select_page_statement,
120  [$row->introduction_page_id]
121  )
122  );
123  continue;
124  }
125 
126  $new_page_id = $this->createPageWithNextId($row->obj_fi, $introduction_to_clone);
127  $this->db->update(
128  'tst_tests',
129  [
130  'introduction_page_id' => [\ilDBConstants::T_INTEGER, $new_page_id]
131  ],
132  [
133  'test_id' => [\ilDBConstants::T_INTEGER, $row->test_id]
134  ]
135  );
136  }
137 
138  return self::TESTS_PER_STEP - $result->numRows();
139  }
140 
141  private function migrateConcludingRemarks(\ilDBStatement $select_page_statement, int $max_steps): void
142  {
143  $result = $this->db->query(
144  '
145  SELECT test_id, obj_fi, concluding_remarks_page_id
146  FROM tst_tests
147  WHERE NOT concluding_remarks_page_id IS NULL
148  AND concluding_remarks_page_id IN
149  (SELECT concluding_remarks_page_id FROM tst_tests GROUP BY concluding_remarks_page_id HAVING COUNT(concluding_remarks_page_id) > 1)
150  ORDER BY concluding_remarks_page_id
151  LIMIT ' . $max_steps
152  );
153 
154  $first_row = $this->db->fetchObject($result);
155  if ($first_row === null) {
156  return;
157  }
158 
159  $concluding_remarks_to_clone = $this->db->fetchObject(
160  $this->db->execute(
161  $select_page_statement,
162  [$first_row->concluding_remarks_page_id]
163  )
164  );
165  while (($row = $this->db->fetchObject($result)) !== null) {
166  if ($row->concluding_remarks_page_id !== $concluding_remarks_to_clone?->page_id) {
167  $concluding_remarks_to_clone = $this->db->fetchObject(
168  $this->db->execute(
169  $select_page_statement,
170  [$row->concluding_remarks_page_id]
171  )
172  );
173  continue;
174  }
175 
176  $new_page_id = $this->createPageWithNextId($row->obj_fi, $concluding_remarks_to_clone);
177  $this->db->update(
178  'tst_tests',
179  [
180  'concluding_remarks_page_id' => [\ilDBConstants::T_INTEGER, $new_page_id]
181  ],
182  [
183  'test_id' => [\ilDBConstants::T_INTEGER, $row->test_id]
184  ]
185  );
186  }
187  }
188 
189  private function createPageWithNextId(int $test_obj_id, \stdClass $row): int
190  {
191  $query = $this->db->query('SELECT max(page_id) as last_id FROM page_object WHERE parent_type="tst"');
192  $last_row = $this->db->fetchObject($query);
193  try {
194  $this->db->insert(
195  'page_object',
196  [
197  'page_id' => ['integer', $last_row->last_id + 1],
198  'parent_id' => ['integer', $test_obj_id],
199  'lang' => ['text', $row->lang],
200  'content' => ['clob', $row->content],
201  'parent_type' => ['text', $row->parent_type],
202  'create_user' => ['integer', $row->create_user],
203  'last_change_user' => ['integer', $row->last_change_user],
204  'active' => ['integer', $row->active],
205  'activation_start' => ['timestamp', $row->activation_start],
206  'activation_end' => ['timestamp', $row->activation_end],
207  'show_activation_info' => ['integer', $row->show_activation_info],
208  'inactive_elements' => ['integer', $row->inactive_elements],
209  'int_links' => ['integer', $row->int_links],
210  'created' => ['timestamp', \ilUtil::now()],
211  'last_change' => ['timestamp', \ilUtil::now()],
212  'is_empty' => ['integer', $row->is_empty]
213  ]
214  );
215  } catch (ilDatabaseException $e) {
216  $this->createPageWithNextId($row);
217  }
218 
219  return $last_row->last_id + 1;
220  }
221 }
migrateConcludingRemarks(\ilDBStatement $select_page_statement, int $max_steps)
A migration is a potentially long lasting operation that can be broken into discrete steps...
Definition: Migration.php:28
static now()
Return current timestamp in Y-m-d H:i:s format.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
getResource(string $id)
Consumers of this method should check if the result is what they expect, e.g.
prepare(Environment $environment)
Prepare the migration by means of some environment.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
An environment holds resources to be used in the setup process.
Definition: Environment.php:27
getDefaultAmountOfStepsPerRun()
Tell the default amount of steps to be executed for one run of the migration.
getPreconditions(Environment $environment)
Objectives the migration depend on.