PluginProbe
Yatra – Travel Booking & Tour Operator Software / trunk
Yatra – Travel Booking & Tour Operator Software vtrunk
3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 2.0.10 2.0.11 All 82 releases
yatra / app / Migrations / ProDownloadsMigration.php

ProDownloadsMigration.php in Yatra – Travel Booking & Tour Operator Software trunk, at app/Migrations/ProDownloadsMigration.php

172 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yatra\Migration;
4
5 use Yatra\Database\Tables\TripsTable;
6 use Yatra\Utils\Logger;
7
8 /**
9 * Migrate legacy Pro tour downloads into TripsTable.custom_fields JSON.
10 *
11 * Legacy:
12 * - option: yatra_global_downloadable_files (comma-separated attachment IDs)
13 * - postmeta (tour): downloads_downloadable_files (comma-separated attachment IDs)
14 * - postmeta (tour): downloads_description (HTML/text)
15 *
16 * New:
17 * - TripsTable.custom_fields JSON under key `downloads`:
18 * { global_files: string[], files: string[], description: string }
19 */
20 class ProDownloadsMigration extends BaseMigration
21 {
22 public function run(): array
23 {
24 $migrated = 0;
25 $skipped = 0;
26 $failed = 0;
27
28 $tripsTable = TripsTable::getTableName();
29
30 $global = (string) get_option('yatra_global_downloadable_files', '');
31 $globalList = $this->csvToList($global);
32
33 $rows = $this->wpdb->get_results(
34 $this->wpdb->prepare(
35 "SELECT pm.post_id AS tour_id, pm.meta_value AS files
36 FROM {$this->wpdb->postmeta} pm
37 INNER JOIN {$this->wpdb->posts} p ON p.ID = pm.post_id
38 WHERE p.post_type = %s
39 AND pm.meta_key = %s
40 AND pm.meta_value <> ''",
41 'tour',
42 'downloads_downloadable_files'
43 )
44 );
45
46 $total = (is_array($rows) ? count($rows) : 0) + ($globalList !== [] ? 1 : 0);
47 if ($total === 0) {
48 return compact('migrated', 'skipped', 'failed');
49 }
50
51 // Apply global downloads to every migrated trip (only when we have a migrated trip row).
52 if ($globalList !== []) {
53 try {
54 $tripIds = $this->wpdb->get_col("SELECT id FROM {$tripsTable}");
55 if (is_array($tripIds)) {
56 foreach ($tripIds as $tripId) {
57 $tripId = (int) $tripId;
58 $this->mergeTripDownloads($tripsTable, $tripId, [
59 'global_files' => $globalList,
60 ]);
61 }
62 }
63 $migrated++;
64 $this->updateProgress('pro_downloads', 'running', $migrated, $skipped, $failed, $total, null, null);
65 } catch (\Throwable $e) {
66 $failed++;
67 Logger::error('ProDownloadsMigration: global merge failed', [
68 'source' => 'migration',
69 'error' => $e->getMessage(),
70 ]);
71 $this->updateProgress('pro_downloads', 'running', $migrated, $skipped, $failed, $total, null, null);
72 }
73 }
74
75 foreach (($rows ?: []) as $row) {
76 try {
77 $tourId = (int) ($row->tour_id ?? 0);
78 if ($tourId <= 0) {
79 $skipped++;
80 $this->updateProgress('pro_downloads', 'running', $migrated, $skipped, $failed, $total, null, null);
81 continue;
82 }
83
84 $newTripId = $this->getMigratedTripId($tourId);
85 if (!$newTripId) {
86 $skipped++;
87 $this->updateProgress('pro_downloads', 'running', $migrated, $skipped, $failed, $total, null, null);
88 continue;
89 }
90
91 $files = $this->csvToList((string) ($row->files ?? ''));
92 $desc = (string) ($this->getRawPostMeta($tourId, 'downloads_description') ?? '');
93
94 $this->mergeTripDownloads($tripsTable, (int) $newTripId, [
95 'files' => $files,
96 'description' => $desc,
97 ]);
98
99 $migrated++;
100 $this->updateProgress('pro_downloads', 'running', $migrated, $skipped, $failed, $total, null, null);
101 } catch (\Throwable $e) {
102 $failed++;
103 Logger::error('ProDownloadsMigration exception', [
104 'source' => 'migration',
105 'error' => $e->getMessage(),
106 ]);
107 $this->updateProgress('pro_downloads', 'running', $migrated, $skipped, $failed, $total, null, null);
108 }
109 }
110
111 return compact('migrated', 'skipped', 'failed');
112 }
113
114 /**
115 * @return list<string>
116 */
117 private function csvToList(string $csv): array
118 {
119 $csv = trim($csv);
120 if ($csv === '') {
121 return [];
122 }
123 $parts = array_map('trim', explode(',', $csv));
124 $parts = array_values(array_filter($parts, static fn ($v) => $v !== ''));
125
126 return $parts;
127 }
128
129 /**
130 * @param array{global_files?: list<string>, files?: list<string>, description?: string} $payload
131 */
132 private function mergeTripDownloads(string $tripsTable, int $tripId, array $payload): void
133 {
134 $existing = $this->wpdb->get_var($this->wpdb->prepare("SELECT custom_fields FROM {$tripsTable} WHERE id = %d", $tripId));
135 $custom = [];
136 if (is_string($existing) && $existing !== '') {
137 $decoded = json_decode($existing, true);
138 if (is_array($decoded)) {
139 $custom = $decoded;
140 }
141 }
142
143 $downloads = [];
144 if (isset($custom['downloads']) && is_array($custom['downloads'])) {
145 $downloads = $custom['downloads'];
146 }
147
148 if (isset($payload['global_files'])) {
149 $prev = isset($downloads['global_files']) && is_array($downloads['global_files']) ? $downloads['global_files'] : [];
150 $downloads['global_files'] = array_values(array_unique(array_merge($prev, $payload['global_files'])));
151 }
152 if (isset($payload['files'])) {
153 $prev = isset($downloads['files']) && is_array($downloads['files']) ? $downloads['files'] : [];
154 $downloads['files'] = array_values(array_unique(array_merge($prev, $payload['files'])));
155 }
156 if (isset($payload['description']) && $payload['description'] !== '') {
157 if (empty($downloads['description']) || $this->isForceMigration()) {
158 $downloads['description'] = $payload['description'];
159 }
160 }
161
162 $custom['downloads'] = $downloads;
163
164 $this->wpdb->update(
165 $tripsTable,
166 ['custom_fields' => json_encode($custom)],
167 ['id' => $tripId]
168 );
169 }
170 }
171
172