ILIAS  trunk Revision v13.0_alpha-62-g3b72d83f2e5
class.ilSAHSMigration.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
24
33class ilSAHSMigration implements Migration
34{
35 private const TABLE_NAME = 'sahs_lm';
36
38 protected ?IOWrapper $io = null;
39
40 public function getLabel(): string
41 {
42 return 'Migration of SCORM/AICC Learning Modules to the Resource Storage Service.';
43 }
44
46 {
47 return 10000;
48 }
49
50 public function getPreconditions(Environment $environment): array
51 {
52 return array_merge(
54 [
56 new \ILIAS\ScormAicc\Setup\ScormAiccDatabaseUpdateSteps()
57 )
58 ]
59 );
60 }
61
62 public function prepare(Environment $environment): void
63 {
64 $this->helper = new ilResourceStorageMigrationHelper(
66 $environment
67 );
68 $io = $environment->getResource(Environment::RESOURCE_ADMIN_INTERACTION);
69 if ($io instanceof IOWrapper) {
70 $this->io = $io;
71 }
72 }
73
74 public function step(Environment $environment): void
75 {
76 $r = $this->helper->getDatabase()->query(
77 "SELECT lm.id, object_data.owner AS owner_id
78 FROM " . self::TABLE_NAME . " lm
79 LEFT JOIN object_data ON object_data.obj_id = lm.id
80 WHERE rid IS NULL OR rid = ''
81 LIMIT 1;"
82 );
83
84 $d = $this->helper->getDatabase()->fetchObject($r);
85 $object_id = (int) ($d->id ?? null);
86
87 $resource_owner_id = (int) ($d->owner_id ?? 6);
88
89 $lm_path = $this->buildBasePath($object_id);
90
91 if (!is_dir($lm_path)) {
92 $this->error(
93 "Legacy SCORM/AICC directory $lm_path for object id $object_id does not exist. " .
94 "Marking record as migration-failed (rid='-')."
95 );
96 $this->helper->getDatabase()->update(
97 self::TABLE_NAME,
98 ['rid' => ['text', '-']],
99 ['id' => ['integer', $object_id],]
100 );
101 return;
102 }
103
104 try {
105 $this->inform(
106 "Trying to move SCORM/AICC directory $lm_path for object id $object_id to the storage service."
107 );
108 $rid = $this->helper->moveDirectoryToContainerResource(
109 $lm_path,
110 $resource_owner_id
111 );
112 $this->inform("Migration proceeded without error for object id $object_id.");
113 } catch (\Throwable $e) {
114 $this->error(
115 "Failed to move SCORM/AICC directory $lm_path for object id $object_id " .
116 "to the storage service with exception: {$e->getMessage()}"
117 );
118 $this->error($e->getTraceAsString());
119 throw $e;
120 }
121
122 if ($rid !== null) {
123 $this->inform(
124 "IRSS identification for object id $object_id: {$rid->serialize()}",
125 true
126 );
127 $this->helper->getDatabase()->update(
128 self::TABLE_NAME,
129 ['rid' => ['text', $rid->serialize()]],
130 ['id' => ['integer', $object_id],]
131 );
132
133 $this->recursiveRmDir($lm_path);
134 } else {
135 $this->error(
136 'IRSS returned NULL as identification when trying to move SCORM/AICC directory ' .
137 "$lm_path for object id $object_id to the storage service."
138 );
139 $this->helper->getDatabase()->update(
140 self::TABLE_NAME,
141 ['rid' => ['text', '-']],
142 ['id' => ['integer', $object_id],]
143 );
144 }
145 }
146
147 private function recursiveRmDir(string $path): void
148 {
149 if (!is_dir($path)) {
150 return;
151 }
152 // recursively remove directory
153 $files = array_diff(scandir($path), ['.', '..']);
154 foreach ($files as $file) {
155 (is_dir("$path/$file")) ? $this->recursiveRmDir("$path/$file") : unlink("$path/$file");
156 }
157 rmdir($path);
158 }
159
161 {
162 $r = $this->helper->getDatabase()->query(
163 "SELECT COUNT(id) AS amount FROM " . self::TABLE_NAME . " WHERE rid IS NULL OR rid = ''"
164 );
165 $d = $this->helper->getDatabase()->fetchObject($r) ?? new stdClass();
166
167 return (int) ($d->amount ?? 0);
168 }
169
170 protected function buildBasePath(int $object_id): string
171 {
172 return CLIENT_WEB_DIR . '/lm_data/lm_' . $object_id;
173 }
174
175 private function inform(string $text, bool $force = false): void
176 {
177 if ($this->io === null || (!$force && !$this->io->isVerbose())) {
178 return;
179 }
180
181 $this->io->inform($text);
182 }
183
184 private function error(string $text): void
185 {
186 if ($this->io === null) {
187 return;
188 }
189
190 $this->io->error($text);
191 }
192}
Wrapper around symfonies input and output facilities to provide just the functionality required for t...
Definition: IOWrapper.php:33
This class attempt to achieve a set of database update steps.
Moves the on-disk content of SCORM/AICC learning modules (public/data/lm_data/lm_<id>) into a contain...
inform(string $text, bool $force=false)
recursiveRmDir(string $path)
prepare(Environment $environment)
Prepare the migration by means of some environment.
getPreconditions(Environment $environment)
Objectives the migration depend on.
buildBasePath(int $object_id)
step(Environment $environment)
Run one step of the migration.
getRemainingAmountOfSteps()
Count up how many "things" need to be migrated.
ilResourceStorageMigrationHelper $helper
getDefaultAmountOfStepsPerRun()
Tell the default amount of steps to be executed for one run of the migration.
Stakeholder for SCORM/AICC learning module content (table sahs_lm).
const CLIENT_WEB_DIR
Definition: constants.php:47
An environment holds resources to be used in the setup process.
Definition: Environment.php:28
getResource(string $id)
Consumers of this method should check if the result is what they expect, e.g.
A migration is a potentially long lasting operation that can be broken into discrete steps.
Definition: Migration.php:29
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
$text
Definition: xapiexit.php:21