PluginProbe ʕ •ᴥ•ʔ
Admin Columns / 7.1.4
Admin Columns v7.1.4
7.1.4 7.0.19 2.3.5 2.4 2.4.1 2.4.10 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.6.1 2.5.6.2 2.5.6.3 2.5.6.4 3.0 3.0.1 3.0.2 3.0.3 3.0.5 3.0.7 3.1 3.1.1 3.1.10 3.1.2 3.1.3 3.1.5 3.2.3 3.2.7 3.3.1 3.4.1 3.4.6 3.4.8 4.0.1 4.0.3 4.1.6 4.2.2 4.2.5 4.3 4.3.2 4.4.1 4.4.4 4.4.5 4.5.5 4.6.1 4.7.18 4.7.19 4.7.20 4.7.7 7.0.13 7.0.14 7.0.16 trunk 1.0 1.1 1.1.3 1.2 1.2.1 1.3 1.3.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.5.1 1.4.6 1.4.6.1 1.4.6.2 1.4.6.3 1.4.6.4 1.4.7 1.4.8 1.4.9 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.2 2.2.1 2.2.1.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.5.1 2.2.6 2.2.6.1 2.2.6.2 2.2.6.3 2.2.6.4 2.2.7 2.2.8 2.2.8.1 2.2.9 2.3.1 2.3.2 2.3.3
codepress-admin-columns / classes / Plugin / Update / V7000.php
codepress-admin-columns / classes / Plugin / Update Last commit date
V4000.php 2 days ago V7000.php 2 days ago V7004.php 2 days ago
V7000.php
269 lines
1 <?php
2
3 declare(strict_types=1);
4
5 namespace AC\Plugin\Update;
6
7 use AC\Helper;
8 use AC\Plugin\Install\Database;
9 use AC\Plugin\Update;
10 use AC\Plugin\Version;
11 use AC\Transient;
12
13 class V7000 extends Update
14 {
15 public const PROGRESS_KEY = 'ac_update_progress_v7000';
16
17 private int $next_step;
18
19 private Database $database;
20
21 public function __construct(Database $database)
22 {
23 parent::__construct(new Version('7.0.0'));
24
25 $this->database = $database;
26 // because `get_option` could be cached we only fetch the next step from the DB on initialisation.
27 $this->next_step = $this->get_next_step();
28 }
29
30 public function apply_update(): void
31 {
32 // just in case we need a bit of extra time to execute our upgrade script
33 $max_exec = (int)ini_get('max_execution_time');
34 if ($max_exec > 0 && $max_exec < 120) {
35 @set_time_limit(120);
36 }
37
38 // Apply update in chunks to minimize the impact of a timeout.
39 switch ($this->next_step) {
40 case 1:
41 // Add 'type' column to the 'admin_columns' DB table
42 $this->update_database();
43
44 $this
45 ->update_next_step(2)
46 ->apply_update();
47 break;
48 case 2:
49 // Update renamed column types and specific settings
50 $this->update_columns();
51
52 $this
53 ->update_next_step(3)
54 ->apply_update();
55 break;
56 case 3:
57 // Move the stored default columns to a new location
58 $this->update_default_columns();
59
60 // Delete obsolete default sortables
61 $this->delete_default_sortables();
62 $this->flush_help_transient();
63
64 $this->clear_next_step();
65 break;
66 }
67 }
68
69 private function flush_help_transient(): void
70 {
71 $cache = new Transient('ac-deprecated-message-count');
72 $cache->delete();
73 }
74
75 private function delete_default_sortables(): void
76 {
77 global $wpdb;
78
79 $wpdb->query(
80 "DELETE FROM $wpdb->options WHERE option_name LIKE 'ac_sorting_%_default'"
81 );
82 }
83
84 private function update_default_columns(): void
85 {
86 global $wpdb;
87
88 $results = $wpdb->get_results(
89 "SELECT * FROM $wpdb->options WHERE option_name LIKE 'cpac_options_%__default' AND option_value != ''"
90 );
91
92 if (! $results) {
93 return;
94 }
95
96 foreach ($results as $item) {
97 if (! isset($item->option_name, $item->option_value)) {
98 continue;
99 }
100
101 $list_key = Helper\Strings::create()->remove_prefix($item->option_name, 'cpac_options_');
102 $list_key = Helper\Strings::create()->remove_suffix($list_key, '__default');
103
104 if (! $list_key) {
105 continue;
106 }
107
108 $data = unserialize($item->option_value, ['allowed_classes' => false]);
109
110 if (! $data || ! is_array($data)) {
111 continue;
112 }
113
114 $option_name = "_ac_columns_default_" . $list_key;
115
116 $exists = $wpdb->get_var(
117 $wpdb->prepare("SELECT option_name FROM $wpdb->options WHERE option_name = %s", $option_name)
118 );
119
120 // Skip when exists
121 if ($exists) {
122 continue;
123 }
124
125 $updated = [];
126
127 foreach ($data as $column_name => $label) {
128 if ($column_name === 'cb') {
129 continue;
130 }
131
132 $updated[$column_name] = [
133 'label' => $label,
134 ];
135 }
136
137 $wpdb->insert(
138 $wpdb->options,
139 [
140 'option_name' => $option_name,
141 'option_value' => $updated ? serialize($updated) : '',
142 'autoload' => 'off',
143 ]
144 );
145 }
146
147 // Delete
148 $wpdb->query(
149 "DELETE FROM $wpdb->options WHERE option_name LIKE 'cpac_options_%__default'"
150 );
151 }
152
153 private function update_columns(): void
154 {
155 global $wpdb;
156
157 $views = $wpdb->get_results("SELECT id, list_id, columns FROM {$wpdb->prefix}admin_columns");
158
159 if (! $views) {
160 return;
161 }
162
163 $updates = [];
164
165 foreach ($views as $view) {
166 if (! $view->columns) {
167 continue;
168 }
169
170 $columns = unserialize($view->columns, ['allowed_classes' => false]);
171
172 if (! $columns || ! is_array($columns)) {
173 continue;
174 }
175
176 $has_changed_columns = false;
177
178 foreach ($columns as $i => $column) {
179 // invalid data
180 if (! is_array($column) || ! $column) {
181 continue;
182 }
183
184 $updated_column = $this->modify_column_options($column);
185
186 if ($updated_column) {
187 $columns[$i] = $updated_column;
188 $has_changed_columns = true;
189 }
190 }
191
192 if ($has_changed_columns) {
193 $updates[$view->id] = serialize($columns);
194 }
195 }
196
197 foreach ($updates as $id => $columns) {
198 $wpdb->query(
199 $wpdb->prepare("UPDATE {$wpdb->prefix}admin_columns SET columns = %s WHERE id = %d", $columns, $id)
200 );
201 }
202 }
203
204 private function modify_column_options(array $column): ?array
205 {
206 if (! isset($column['type'])) {
207 return null;
208 }
209
210 // User column: `column-user_posts` has been replaced with `column-user_postcount`
211 if ($column['type'] === 'column-user_posts') {
212 $column['type'] = 'column-user_postcount';
213
214 return $column;
215 }
216
217 // The column setting 'character_limit' has been renamed to 'excerpt_length'
218 if (! empty($column['character_limit'])) {
219 $column['excerpt_length'] = $column['character_limit'];
220 unset($column['character_limit']);
221
222 return $column;
223 }
224
225 // The column "Media ID (column-mediaid)" is replace by "Post ID" (column-postid)
226 if ($column['type'] === 'column-mediaid') {
227 $column['type'] = 'column-postid';
228
229 return $column;
230 }
231
232 // The column gravatar has a new image size setting
233 if ($column['type'] === 'column-gravatar') {
234 $column['gravatar_size'] = $column['image_size_w'] ?? 60;
235
236 unset($column['image_size'], $column['image_size_w'], $column['image_size_h']);
237
238 return $column;
239 }
240
241 return null;
242 }
243
244 private function get_next_step(): int
245 {
246 return (int)get_option(self::PROGRESS_KEY, 1);
247 }
248
249 private function update_next_step(int $step): self
250 {
251 $this->next_step = $step;
252
253 update_option(self::PROGRESS_KEY, $this->next_step, false);
254
255 return $this;
256 }
257
258 private function clear_next_step(): void
259 {
260 delete_option(self::PROGRESS_KEY);
261 }
262
263 private function update_database(): void
264 {
265 $this->database->install();
266 }
267
268 }
269