dbxapp 4.1.3
CMS, Shop, Workflows und modulare Geschäftsanwendungen
Loading...
Searching...
No Matches
4.1.2-001-media-usage-schema-repair.migration.php
Go to the documentation of this file.
1<?php
2
5use dbx\dbxContent\dbxContentMediaUsageScope;
6
7return array(
8 'id' => 'core-4.1.2-media-usage-schema-repair',
9 'version' => '4.1.2',
10 'description' => 'Repariert das Media-Usage-Schema updatefest und wiederholt die Sprachzuordnung.',
11 'affected_dd' => array('dbx|dbxMediaUsage'),
12 'operations' => array(
13 array('type' => 'sync_dd', 'dd' => 'dbx|dbxMediaUsage'),
14 ),
15 'up' => static function($db, $dd): void {
16 $moduleRoot = dirname(__DIR__, 2);
17 require_once $moduleRoot . '/dbxContent/include/dbxContent_bootstrap_sync.php';
18 require_once $moduleRoot . '/dbxContent/include/dbxContentMediaUsageScope.class.php';
19
20 $ddFile = dirname(__DIR__) . '/dd/dbxMediaUsage.dd.php';
21 $definition = (static function(string $file): array {
22 $table = array();
23 $fields = array();
24 $indexes = array();
25 include $file;
26 return array(
27 'table' => is_array($table) ? $table : array(),
28 'fields' => is_array($fields) ? $fields : array(),
29 'indexes' => is_array($indexes) ? $indexes : array(),
30 );
31 })($ddFile);
32 if ($definition['table'] === array()) {
33 throw new RuntimeException('Release-DD dbxMediaUsage ist ungueltig.');
34 }
35
36 $server = (string)$db->get_dd_server('dbx|dbxMediaUsage');
37 $table = (string)$db->get_dd_table('dbx|dbxMediaUsage');
38 if ($server === '' || $table === '') {
39 throw new RuntimeException('Media-Usage-Datenbankziel ist ungueltig.');
40 }
41
42 if (!isset($_SESSION) || !is_array($_SESSION)) {
43 $_SESSION = array();
44 }
45 if (!isset($_SESSION['dbx']['cache']['dd']['dbx'])
46 || !is_array($_SESSION['dbx']['cache']['dd']['dbx'])
47 ) {
48 $_SESSION['dbx']['cache']['dd']['dbx'] = array();
49 }
50 $hadCache = array_key_exists(
51 'dbxMediaUsage',
52 $_SESSION['dbx']['cache']['dd']['dbx']
53 );
54 $previousCache = $hadCache
55 ? $_SESSION['dbx']['cache']['dd']['dbx']['dbxMediaUsage']
56 : null;
57 $definition['table']['server'] = $server;
58 $_SESSION['dbx']['cache']['dd']['dbx']['dbxMediaUsage'] = array(
59 'table' => $definition['table'],
60 'fields' => $definition['fields'],
61 'indexes' => $definition['indexes'],
62 'file' => $ddFile,
63 'language_dynamic' => false,
64 'declared_server' => $server,
65 );
66
67 try {
68 $dd->sync_dd_to_db('dbx', 'dbxMediaUsage', 'reset');
69 $sync = array();
70 for ($step = 0; $step < 1000; $step++) {
71 $sync = $dd->sync_dd_to_db('dbx', 'dbxMediaUsage', 'apply');
72 if (in_array(
73 (string)($sync['status'] ?? ''),
74 array('finished', 'error', 'cancelled'),
75 true
76 )) {
77 break;
78 }
79 }
80 if (($sync['status'] ?? '') !== 'finished') {
81 throw new RuntimeException(
82 'dbxMediaUsage: ' . (string)($sync['message'] ?? 'DD-Sync fehlgeschlagen')
83 );
84 }
85 $physicalFields = $dd->get_db_fields($server, $table);
86 $physicalNames = array_map(
87 static fn(array $field): string => (string)($field['name'] ?? ''),
88 is_array($physicalFields) ? $physicalFields : array()
89 );
90 if (!in_array('content_lng', $physicalNames, true)) {
91 throw new RuntimeException('content_lng wurde physisch nicht angelegt.');
92 }
93
94 $languages = array_values(array_unique(array_map(
95 static fn($lng): string => dbxContentMediaUsageScope::language((string)$lng),
96 dbxContentLngSync::accessibleLngs()
97 )));
98 if (!$languages) $languages = array('de');
99 $master = dbxContentMediaUsageScope::language(dbxContentLngSync::masterLng());
100
101 $pageCache = array();
102 $folderCache = array();
103 foreach ($languages as $lng) {
104 $pageCache[$lng] = array();
105 $folderCache[$lng] = array();
106 $pages = $db->select(
107 dbxContentLng::ddContent($lng),
108 '',
109 'id,folder,hero_image_id,content',
110 'id',
111 'ASC',
112 '',
113 0,
114 0,
115 0
116 );
117 foreach (is_array($pages) ? $pages : array() as $page) {
118 if (is_array($page) && (int)($page['id'] ?? 0) > 0) {
119 $pageCache[$lng][(int)$page['id']] = $page;
120 }
121 }
122 $folders = $db->select(
123 dbxContentLng::ddFolder($lng),
124 '',
125 'id,hero_image_id',
126 'id',
127 'ASC',
128 '',
129 0,
130 0,
131 0
132 );
133 foreach (is_array($folders) ? $folders : array() as $folder) {
134 if (is_array($folder) && (int)($folder['id'] ?? 0) > 0) {
135 $folderCache[$lng][(int)$folder['id']] = $folder;
136 }
137 }
138 }
139
140 $containsMedia = static function(string $html, int $mediaId): bool {
141 if ($mediaId <= 0 || $html === '') return false;
142 return preg_match('/data-cms-media-id=["\']?' . $mediaId . '(?:["\'\s>]|$)/i', $html) === 1
143 || preg_match('/(?:dbx_mid|media_id)=' . $mediaId . '(?:[^0-9]|$)/i', $html) === 1;
144 };
145
146 $rows = $db->select('dbxMediaUsage', '', '*', 'id', 'ASC', '', 0, 0, 0);
147 $seen = array();
148 foreach (is_array($rows) ? $rows : array() as $row) {
149 if (!is_array($row)) continue;
150 $id = (int)($row['id'] ?? 0);
151 if ($id <= 0) continue;
152 if ((int)($row['active'] ?? 0) !== 1) {
153 $db->delete('dbxMediaUsage', $id, 1, 0);
154 continue;
155 }
156
157 $mediaId = (int)($row['media_id'] ?? 0);
158 $contentId = (int)($row['content_id'] ?? 0);
159 $folderId = (int)($row['folder_id'] ?? 0);
160 $slot = strtolower(trim((string)($row['slot'] ?? '')));
161 $candidates = array();
162
163 if ($slot === 'shop') {
164 $candidates = array($master);
165 } elseif ($contentId > 0) {
166 foreach ($languages as $lng) {
167 $page = $pageCache[$lng][$contentId] ?? null;
168 if (!is_array($page)) continue;
169 if ($folderId > 0 && (int)($page['folder'] ?? 0) !== $folderId) continue;
170 if ($slot === 'hero' && (int)($page['hero_image_id'] ?? 0) !== $mediaId) continue;
171 if ($slot === 'inline' && !$containsMedia((string)($page['content'] ?? ''), $mediaId)) continue;
172 $candidates[] = $lng;
173 }
174 if (!$candidates) {
175 foreach ($languages as $lng) {
176 if (isset($pageCache[$lng][$contentId])) $candidates[] = $lng;
177 }
178 }
179 } elseif ($folderId > 0) {
180 foreach ($languages as $lng) {
181 $folder = $folderCache[$lng][$folderId] ?? null;
182 if (!is_array($folder)) continue;
183 if ($slot === 'hero' && (int)($folder['hero_image_id'] ?? 0) !== $mediaId) continue;
184 $candidates[] = $lng;
185 }
186 if (!$candidates) {
187 foreach ($languages as $lng) {
188 if (isset($folderCache[$lng][$folderId])) $candidates[] = $lng;
189 }
190 }
191 }
192
193 $lng = count($candidates) === 1
194 ? $candidates[0]
195 : (in_array($master, $candidates, true)
196 ? $master
197 : ($candidates[0] ?? $master));
198 $key = $lng . ':' . $contentId . ':' . $folderId . ':' . $slot . ':' . $mediaId;
199 if (isset($seen[$key])) {
200 $db->delete('dbxMediaUsage', $id, 1, 0);
201 continue;
202 }
203 $seen[$key] = $id;
204 if ((string)($row['content_lng'] ?? '') !== $lng) {
205 $db->update(
206 'dbxMediaUsage',
207 array('content_lng' => $lng),
208 $id,
209 0,
210 1,
211 1,
212 0
213 );
214 }
215 }
216 } finally {
217 if ($hadCache) {
218 $_SESSION['dbx']['cache']['dd']['dbx']['dbxMediaUsage'] = $previousCache;
219 } else {
220 unset($_SESSION['dbx']['cache']['dd']['dbx']['dbxMediaUsage']);
221 }
222 }
223 },
224);
$table['server']
Definition .dd.php:6
$indexes[]
Definition .dd.php:167
if(!defined( 'IMG_WEBP')) define( 'IMG_WEBP'
if($cinematic===''||!str_contains($cinematic, 'data-dbx-cinema')) $page