1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace GeminiLabs\SiteReviews\Modules\Migrations\Migrate_5_0_0; |
4
|
|
|
|
5
|
|
|
use GeminiLabs\SiteReviews\Database; |
6
|
|
|
use GeminiLabs\SiteReviews\Database\Query; |
7
|
|
|
use GeminiLabs\SiteReviews\Defaults\RatingDefaults; |
8
|
|
|
use GeminiLabs\SiteReviews\Helpers\Arr; |
9
|
|
|
use GeminiLabs\SiteReviews\Install; |
10
|
|
|
|
11
|
|
|
class MigrateReviews |
12
|
|
|
{ |
13
|
|
|
public $db; |
14
|
|
|
public $limit; |
15
|
|
|
|
16
|
7 |
|
public function __construct() |
17
|
|
|
{ |
18
|
7 |
|
global $wpdb; |
19
|
7 |
|
$this->db = $wpdb; |
20
|
7 |
|
$this->limit = 250; |
21
|
7 |
|
} |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @return void |
25
|
|
|
*/ |
26
|
7 |
|
public function run() |
27
|
|
|
{ |
28
|
7 |
|
$this->createDatabaseTable(); |
29
|
7 |
|
$this->migrateRatings(); |
30
|
7 |
|
$this->migrateAssignedTo(); |
31
|
7 |
|
$this->migrateTerms(); |
32
|
7 |
|
$this->migrateCustom(); |
33
|
7 |
|
} |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @return void |
37
|
|
|
*/ |
38
|
7 |
|
protected function createDatabaseTable() |
39
|
|
|
{ |
40
|
7 |
|
glsr(Install::class)->run(); |
41
|
7 |
|
} |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* @return array |
45
|
|
|
*/ |
46
|
|
|
protected function filterCustomValues(array $values) |
47
|
|
|
{ |
48
|
|
|
$filtered = []; |
49
|
|
|
foreach ($values as $postId => $meta) { |
50
|
|
|
$custom = Arr::consolidate(maybe_unserialize(Arr::get($meta, '_custom'))); |
51
|
|
|
if (!empty($custom)) { |
52
|
|
|
$custom = Arr::prefixKeys($custom, '_custom_'); |
53
|
|
|
$filtered[$postId] = array_diff_key($custom, $meta); |
54
|
|
|
} |
55
|
|
|
} |
56
|
|
|
return array_filter($filtered); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @return array |
61
|
|
|
*/ |
62
|
|
|
protected function groupCustomValues(array $values) |
63
|
|
|
{ |
64
|
|
|
$grouped = []; |
65
|
|
|
foreach ($values as $result) { |
66
|
|
|
if (empty($grouped[$result->post_id])) { |
67
|
|
|
$grouped[$result->post_id] = []; |
68
|
|
|
} |
69
|
|
|
$grouped[$result->post_id][$result->meta_key] = $result->meta_value; |
70
|
|
|
} |
71
|
|
|
return $grouped; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* @return void |
76
|
|
|
*/ |
77
|
7 |
|
protected function migrateAssignedTo() |
78
|
|
|
{ |
79
|
7 |
|
glsr(Database::class)->beginTransaction('assigned_posts'); |
80
|
7 |
|
$offset = 0; |
81
|
7 |
|
$table = glsr(Query::class)->table('ratings'); |
82
|
7 |
|
while (true) { |
83
|
7 |
|
$sql = glsr(Query::class)->sql($this->db->prepare(" |
84
|
|
|
SELECT r.ID AS rating_id, m.meta_value AS post_id, CAST(IF(p.post_status = 'publish', 1, 0) AS UNSIGNED) AS is_published |
85
|
7 |
|
FROM {$table} AS r |
86
|
7 |
|
INNER JOIN {$this->db->posts} AS p ON r.review_id = p.ID |
87
|
7 |
|
INNER JOIN {$this->db->postmeta} AS m ON r.review_id = m.post_id |
88
|
|
|
WHERE m.meta_key = '_assigned_to' AND m.meta_value > 0 |
89
|
|
|
ORDER BY r.ID |
90
|
|
|
LIMIT %d, %d |
91
|
7 |
|
", $offset, $this->limit), 'migrate-assigned-posts'); |
92
|
7 |
|
$results = glsr(Database::class)->dbGetResults($sql, ARRAY_A); |
93
|
7 |
|
if (empty($results)) { |
94
|
7 |
|
break; |
95
|
|
|
} |
96
|
|
|
glsr(Database::class)->insertBulk('assigned_posts', $results, [ |
97
|
|
|
'rating_id', |
98
|
|
|
'post_id', |
99
|
|
|
'is_published', |
100
|
|
|
]); |
101
|
|
|
$offset += $this->limit; |
102
|
|
|
} |
103
|
7 |
|
glsr(Database::class)->finishTransaction('assigned_posts'); |
104
|
7 |
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* @return void |
108
|
|
|
*/ |
109
|
7 |
|
protected function migrateCustom() |
110
|
|
|
{ |
111
|
7 |
|
glsr(Database::class)->beginTransaction('postmeta'); |
112
|
7 |
|
$offset = 0; |
113
|
7 |
|
while (true) { |
114
|
7 |
|
$sql = glsr(Query::class)->sql($this->db->prepare(" |
115
|
|
|
SELECT m1.post_id, m1.meta_key, m1.meta_value |
116
|
7 |
|
FROM {$this->db->postmeta} AS m1 |
117
|
7 |
|
INNER JOIN {$this->db->posts} AS p ON m1.post_id = p.ID |
118
|
7 |
|
LEFT JOIN {$this->db->postmeta} AS m2 ON (m1.post_id = m2.post_id AND m1.meta_key = m2.meta_key AND m1.meta_id < m2.meta_id) |
119
|
|
|
WHERE m2.meta_id IS NULL |
120
|
|
|
AND p.post_type = '%s' |
121
|
|
|
AND m1.meta_value != '%s' |
122
|
|
|
AND m1.meta_key LIKE '_custom%%' |
123
|
|
|
ORDER BY m1.meta_id |
124
|
|
|
LIMIT %d, %d |
125
|
7 |
|
", glsr()->post_type, serialize([]), $offset, $this->limit), 'migrate-custom'); |
126
|
7 |
|
$results = glsr(Database::class)->dbGetResults($sql, OBJECT); |
127
|
7 |
|
if (empty($results)) { |
128
|
7 |
|
break; |
129
|
|
|
} |
130
|
|
|
if ($values = $this->prepareCustomValuesForInsert($results)) { |
131
|
|
|
glsr(Database::class)->insertBulk('postmeta', $values, [ |
132
|
|
|
'post_id', |
133
|
|
|
'meta_key', |
134
|
|
|
'meta_value', |
135
|
|
|
]); |
136
|
|
|
} |
137
|
|
|
$offset += $this->limit; |
138
|
|
|
} |
139
|
7 |
|
glsr(Database::class)->finishTransaction('postmeta'); |
140
|
7 |
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* @return void |
144
|
|
|
*/ |
145
|
7 |
|
protected function migrateRatings() |
146
|
|
|
{ |
147
|
7 |
|
glsr(Database::class)->beginTransaction('ratings'); |
148
|
7 |
|
$offset = 0; |
149
|
7 |
|
$table = glsr(Query::class)->table('ratings'); |
150
|
7 |
|
while (true) { |
151
|
7 |
|
$sql = glsr(Query::class)->sql($this->db->prepare(" |
152
|
|
|
SELECT p.ID, m.meta_key AS mk, m.meta_value AS mv, CAST(IF(p.post_status = 'publish', 1, 0) AS UNSIGNED) AS is_approved |
153
|
7 |
|
FROM {$this->db->posts} AS p |
154
|
7 |
|
LEFT JOIN {$this->db->postmeta} AS m ON p.ID = m.post_id |
155
|
|
|
WHERE p.ID IN ( |
156
|
|
|
SELECT * FROM ( |
157
|
|
|
SELECT ID |
158
|
7 |
|
FROM {$this->db->posts} |
159
|
|
|
WHERE post_type = '%s' |
160
|
|
|
ORDER BY ID |
161
|
|
|
LIMIT %d, %d |
162
|
|
|
) AS post_ids |
163
|
|
|
) |
164
|
|
|
AND NOT EXISTS ( |
165
|
|
|
SELECT r.review_id |
166
|
7 |
|
FROM {$table} AS r |
167
|
|
|
WHERE r.review_id = p.ID |
168
|
|
|
) |
169
|
7 |
|
", glsr()->post_type, $offset, $this->limit), 'migrate-ratings'); |
170
|
7 |
|
$results = glsr(Database::class)->dbGetResults($sql, OBJECT); |
171
|
7 |
|
if (empty($results)) { |
172
|
7 |
|
break; |
173
|
|
|
} |
174
|
|
|
$values = $this->parseRatings($results); |
175
|
|
|
$fields = array_keys(glsr(RatingDefaults::class)->defaults()); |
176
|
|
|
glsr(Database::class)->insertBulk('ratings', $values, $fields); |
177
|
|
|
$offset += $this->limit; |
178
|
|
|
} |
179
|
7 |
|
glsr(Database::class)->finishTransaction('ratings'); |
180
|
7 |
|
} |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* @return void |
184
|
|
|
*/ |
185
|
7 |
|
protected function migrateTerms() |
186
|
|
|
{ |
187
|
7 |
|
glsr(Database::class)->beginTransaction('assigned_terms'); |
188
|
7 |
|
$offset = 0; |
189
|
7 |
|
$table = glsr(Query::class)->table('ratings'); |
190
|
7 |
|
while (true) { |
191
|
7 |
|
$sql = glsr(Query::class)->sql($this->db->prepare(" |
192
|
|
|
SELECT r.ID AS rating_id, tt.term_id AS term_id |
193
|
7 |
|
FROM {$table} AS r |
194
|
7 |
|
INNER JOIN {$this->db->term_relationships} AS tr ON r.review_id = tr.object_id |
195
|
7 |
|
INNER JOIN {$this->db->term_taxonomy} AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id |
196
|
|
|
ORDER BY r.ID |
197
|
|
|
LIMIT %d, %d |
198
|
7 |
|
", $offset, $this->limit), 'migrate-assigned-terms'); |
199
|
7 |
|
$results = glsr(Database::class)->dbGetResults($sql, ARRAY_A); |
200
|
7 |
|
if (empty($results)) { |
201
|
7 |
|
break; |
202
|
|
|
} |
203
|
|
|
glsr(Database::class)->insertBulk('assigned_terms', $results, [ |
204
|
|
|
'rating_id', |
205
|
|
|
'term_id', |
206
|
|
|
]); |
207
|
|
|
$offset += $this->limit; |
208
|
|
|
} |
209
|
7 |
|
glsr(Database::class)->finishTransaction('assigned_terms'); |
210
|
7 |
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* @return array |
214
|
|
|
*/ |
215
|
|
|
protected function parseRatings(array $results) |
216
|
|
|
{ |
217
|
|
|
$values = []; |
218
|
|
|
foreach ($results as $result) { |
219
|
|
|
$value = maybe_unserialize($result->mv); |
220
|
|
|
if (is_array($value)) { |
221
|
|
|
continue; |
222
|
|
|
} |
223
|
|
|
if (!isset($values[$result->ID])) { |
224
|
|
|
$values[$result->ID] = ['is_approved' => (int) $result->is_approved]; |
225
|
|
|
} |
226
|
|
|
$values[$result->ID][$result->mk] = $value; |
227
|
|
|
} |
228
|
|
|
$results = []; |
229
|
|
|
foreach ($values as $postId => $value) { |
230
|
|
|
$meta = Arr::unprefixKeys($value); |
231
|
|
|
$meta['name'] = Arr::get($meta, 'author'); |
232
|
|
|
$meta['is_pinned'] = Arr::get($meta, 'pinned'); |
233
|
|
|
$meta['review_id'] = $postId; |
234
|
|
|
$meta['type'] = Arr::get($meta, 'review_type', 'local'); |
235
|
|
|
$meta = Arr::removeEmptyValues($meta); |
236
|
|
|
$meta = glsr(RatingDefaults::class)->restrict($meta); |
237
|
|
|
$results[] = $meta; |
238
|
|
|
} |
239
|
|
|
return $results; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* @return array |
244
|
|
|
*/ |
245
|
|
|
protected function prepareCustomValuesForInsert(array $results) |
246
|
|
|
{ |
247
|
|
|
$filtered = $this->filterCustomValues( |
248
|
|
|
$this->groupCustomValues($results) |
249
|
|
|
); |
250
|
|
|
$values = []; |
251
|
|
|
foreach ($filtered as $postId => $meta) { |
252
|
|
|
foreach ($meta as $metaKey => $metaValue) { |
253
|
|
|
$values[] = [ |
254
|
|
|
'post_id' => $postId, |
255
|
|
|
'meta_key' => $metaKey, |
256
|
|
|
'meta_value' => $metaValue, |
257
|
|
|
]; |
258
|
|
|
} |
259
|
|
|
} |
260
|
|
|
return $values; |
261
|
|
|
} |
262
|
|
|
} |
263
|
|
|
|