PluginProbe
Friends / 4.3.2
Friends v4.3.2
4.3.2 4.3.1 4.3.0 4.2.2 4.2.1 4.2.0 4.1.0 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.0 2.9.1 All 88 releases
friends / templates / admin / migrations.php

migrations.php in Friends 4.3.2, at templates/admin/migrations.php

308 lines 11.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * This template contains the admin migrations page.
4 *
5 * @package Friends
6 */
7
8 namespace Friends;
9
10 ?>
11 <h2><?php esc_html_e( 'Migrations', 'friends' ); ?></h2>
12 <p class="description">
13 <?php esc_html_e( 'This page shows all migrations and allows you to run them manually if needed.', 'friends' ); ?>
14 <?php esc_html_e( 'Migrations run automatically when upgrading from a version lower than the one shown.', 'friends' ); ?>
15 </p>
16
17 <table class="wp-list-table widefat fixed striped" id="friends-migrations-table">
18 <thead>
19 <tr>
20 <th style="width: 15%;"><?php esc_html_e( 'Runs when upgrading to', 'friends' ); ?></th>
21 <th style="width: 25%;"><?php esc_html_e( 'Migration', 'friends' ); ?></th>
22 <th style="width: 35%;"><?php esc_html_e( 'Description', 'friends' ); ?></th>
23 <th style="width: 15%;"><?php esc_html_e( 'Status', 'friends' ); ?></th>
24 <th style="width: 10%;"><?php esc_html_e( 'Actions', 'friends' ); ?></th>
25 </tr>
26 </thead>
27 <tbody>
28 <?php foreach ( $args['statuses'] as $migration_id => $migration_status ) : ?>
29 <tr data-migration-id="<?php echo esc_attr( $migration_id ); ?>">
30 <td><code><?php echo esc_html( $migration_status['version'] ); ?></code></td>
31 <td>
32 <strong><?php echo esc_html( $migration_status['title'] ); ?></strong>
33 <?php if ( $migration_status['batched'] ) : ?>
34 <span class="dashicons dashicons-database" title="<?php esc_attr_e( 'Batched migration', 'friends' ); ?>"></span>
35 <?php endif; ?>
36 </td>
37 <td><?php echo esc_html( $migration_status['description'] ); ?></td>
38 <td class="migration-status">
39 <?php Migration::render_status_badge( $migration_status ); ?>
40 </td>
41 <td>
42 <?php if ( ! empty( $migration_status['in_progress'] ) ) : ?>
43 <button type="button" class="button button-primary process-batch" data-migration-id="<?php echo esc_attr( $migration_id ); ?>">
44 <?php esc_html_e( 'Process Batch Now', 'friends' ); ?>
45 </button>
46 <?php else : ?>
47 <button type="button" class="button button-secondary run-migration" data-migration-id="<?php echo esc_attr( $migration_id ); ?>">
48 <?php esc_html_e( 'Run', 'friends' ); ?>
49 </button>
50 <?php endif; ?>
51 <?php if ( ! empty( $migration_status['completed'] ) && Migration::can_undo_migration( $migration_id ) ) : ?>
52 <button type="button" class="button button-small undo-migration" data-migration-id="<?php echo esc_attr( $migration_id ); ?>">
53 <?php esc_html_e( 'Undo', 'friends' ); ?>
54 </button>
55 <?php endif; ?>
56 <?php if ( has_action( 'friends_migration_debug_' . $migration_id ) ) : ?>
57 <button type="button" class="button button-small toggle-debug" data-migration-id="<?php echo esc_attr( $migration_id ); ?>">
58 <?php esc_html_e( 'Debug', 'friends' ); ?>
59 </button>
60 <?php endif; ?>
61 </td>
62 </tr>
63 <tr class="migration-debug-row" data-migration-id="<?php echo esc_attr( $migration_id ); ?>" style="display: none;">
64 <td colspan="5" style="padding: 0;"></td>
65 </tr>
66 <?php endforeach; ?>
67 </tbody>
68 </table>
69
70 <h2><?php esc_html_e( 'Plugin Information', 'friends' ); ?></h2>
71 <form method="post" id="friends-version-form">
72 <?php wp_nonce_field( 'friends-update-version' ); ?>
73 <table class="form-table">
74 <tr>
75 <th><?php esc_html_e( 'Plugin Version', 'friends' ); ?></th>
76 <td><code><?php echo esc_html( Friends::VERSION ); ?></code></td>
77 </tr>
78 <tr>
79 <th><label for="stored_version"><?php esc_html_e( 'Stored Version', 'friends' ); ?></label></th>
80 <td>
81 <input type="text" name="stored_version" id="stored_version" value="<?php echo esc_attr( get_option( 'friends_plugin_version', '' ) ); ?>" class="regular-text" />
82 <p class="description">
83 <?php esc_html_e( 'This is the version the plugin thinks it was last upgraded to.', 'friends' ); ?>
84 <?php esc_html_e( 'Set to a lower version (e.g., "4.0.0") to re-run migrations for newer versions.', 'friends' ); ?>
85 <?php esc_html_e( 'Clear it to run all migrations on next page load.', 'friends' ); ?>
86 </p>
87 </td>
88 </tr>
89 </table>
90 <p class="submit">
91 <input type="submit" name="update_version" class="button button-primary" value="<?php esc_attr_e( 'Update Stored Version', 'friends' ); ?>" />
92 <button type="button" class="button button-secondary" id="reset-to-current"><?php esc_html_e( 'Reset to Current', 'friends' ); ?></button>
93 <button type="button" class="button button-secondary" id="clear-version"><?php esc_html_e( 'Clear (Force All Migrations)', 'friends' ); ?></button>
94 </p>
95 </form>
96
97 <?php
98 /**
99 * Hook to add debug information to the migrations page.
100 * Used by friends-debugger to show detailed migration diagnostics.
101 *
102 * @param array $statuses All migration statuses.
103 */
104 do_action( 'friends_migrations_debug', $args['statuses'] );
105 ?>
106
107 <script>
108 jQuery(document).ready(function($) {
109 $('#reset-to-current').on('click', function() {
110 $('#stored_version').val('<?php echo esc_js( Friends::VERSION ); ?>');
111 });
112
113 $('#clear-version').on('click', function() {
114 $('#stored_version').val('');
115 });
116
117 $('.toggle-debug').on('click', function() {
118 var $button = $(this);
119 var migrationId = $button.data('migration-id');
120 var $debugRow = $('.migration-debug-row[data-migration-id="' + migrationId + '"]');
121
122 if ($debugRow.is(':visible')) {
123 $debugRow.hide().find('td').html('');
124 $button.text('<?php echo esc_js( __( 'Debug', 'friends' ) ); ?>');
125 return;
126 }
127
128 $button.prop('disabled', true).text('<?php echo esc_js( __( 'Loading...', 'friends' ) ); ?>');
129
130 $.post(ajaxurl, {
131 action: 'friends_get_migration_debug',
132 migration_id: migrationId,
133 _wpnonce: '<?php echo esc_js( wp_create_nonce( 'friends-migration-debug' ) ); ?>'
134 }, function(response) {
135 if (response.success) {
136 $debugRow.find('td').html(response.data.html);
137 $debugRow.show();
138 $button.text('<?php echo esc_js( __( 'Hide Debug', 'friends' ) ); ?>');
139 } else {
140 alert(response.data.message || '<?php echo esc_js( __( 'Failed to load debug info.', 'friends' ) ); ?>');
141 }
142 $button.prop('disabled', false);
143 }).fail(function() {
144 alert('<?php echo esc_js( __( 'Request failed.', 'friends' ) ); ?>');
145 $button.prop('disabled', false).text('<?php echo esc_js( __( 'Debug', 'friends' ) ); ?>');
146 });
147 });
148
149 $('.process-batch').on('click', function() {
150 var $button = $(this);
151 var $row = $button.closest('tr');
152 var migrationId = $button.data('migration-id');
153
154 $button.prop('disabled', true).text('<?php echo esc_js( __( 'Processing...', 'friends' ) ); ?>');
155
156 $.post(ajaxurl, {
157 action: 'friends_process_migration_batch',
158 migration_id: migrationId,
159 _wpnonce: '<?php echo esc_js( wp_create_nonce( 'friends-process-batch' ) ); ?>'
160 }, function(response) {
161 if (response.success) {
162 $row.find('.migration-status').html(response.data.html);
163 if (response.data.in_progress) {
164 $button.prop('disabled', false).text('<?php echo esc_js( __( 'Process Batch Now', 'friends' ) ); ?>');
165 } else {
166 $button.removeClass('button-primary process-batch').addClass('button-secondary run-migration')
167 .prop('disabled', false).text('<?php echo esc_js( __( 'Run', 'friends' ) ); ?>');
168 }
169 } else {
170 alert(response.data.message || '<?php echo esc_js( __( 'Processing failed.', 'friends' ) ); ?>');
171 $button.prop('disabled', false).text('<?php echo esc_js( __( 'Process Batch Now', 'friends' ) ); ?>');
172 }
173 }).fail(function() {
174 alert('<?php echo esc_js( __( 'Request failed.', 'friends' ) ); ?>');
175 $button.prop('disabled', false).text('<?php echo esc_js( __( 'Process Batch Now', 'friends' ) ); ?>');
176 });
177 });
178
179 $(document).on('click', '.undo-migration', function() {
180 var $button = $(this);
181 var $row = $button.closest('tr');
182 var migrationId = $button.data('migration-id');
183
184 if (!confirm('<?php echo esc_js( __( 'Are you sure you want to undo this migration?', 'friends' ) ); ?>')) {
185 return;
186 }
187
188 $button.prop('disabled', true).text('<?php echo esc_js( __( 'Undoing...', 'friends' ) ); ?>');
189
190 $.post(ajaxurl, {
191 action: 'friends_undo_migration',
192 migration_id: migrationId,
193 _wpnonce: '<?php echo esc_js( wp_create_nonce( 'friends-undo-migration' ) ); ?>'
194 }, function(response) {
195 if (response.success) {
196 $row.find('.migration-status').html(response.data.html);
197 $button.remove();
198 } else {
199 alert(response.data.message || '<?php echo esc_js( __( 'Undo failed.', 'friends' ) ); ?>');
200 $button.prop('disabled', false).text('<?php echo esc_js( __( 'Undo', 'friends' ) ); ?>');
201 }
202 }).fail(function() {
203 alert('<?php echo esc_js( __( 'Request failed.', 'friends' ) ); ?>');
204 $button.prop('disabled', false).text('<?php echo esc_js( __( 'Undo', 'friends' ) ); ?>');
205 });
206 });
207
208 $('.run-migration').on('click', function() {
209 var $button = $(this);
210 var $row = $button.closest('tr');
211 var migrationId = $button.data('migration-id');
212
213 $button.prop('disabled', true).text('<?php echo esc_js( __( 'Running...', 'friends' ) ); ?>');
214
215 $.post(ajaxurl, {
216 action: 'friends_run_migration',
217 migration_id: migrationId,
218 _wpnonce: '<?php echo esc_js( wp_create_nonce( 'friends-run-migration' ) ); ?>'
219 }, function(response) {
220 if (response.success) {
221 if (response.data.batched) {
222 pollMigrationStatus(migrationId, $row, $button);
223 } else {
224 refreshMigrationStatus(migrationId, $row, $button);
225 }
226 } else {
227 alert(response.data.message || '<?php echo esc_js( __( 'Migration failed.', 'friends' ) ); ?>');
228 $button.prop('disabled', false).text('<?php echo esc_js( __( 'Run', 'friends' ) ); ?>');
229 }
230 }).fail(function() {
231 alert('<?php echo esc_js( __( 'Request failed.', 'friends' ) ); ?>');
232 $button.prop('disabled', false).text('<?php echo esc_js( __( 'Run', 'friends' ) ); ?>');
233 });
234 });
235
236 function pollMigrationStatus(migrationId, $row, $button) {
237 $.post(ajaxurl, {
238 action: 'friends_get_migration_status',
239 migration_id: migrationId,
240 _wpnonce: '<?php echo esc_js( wp_create_nonce( 'friends-migration-status' ) ); ?>'
241 }, function(response) {
242 if (response.success) {
243 $row.find('.migration-status').html(response.data.html);
244 if (response.data.in_progress) {
245 setTimeout(function() {
246 pollMigrationStatus(migrationId, $row, $button);
247 }, 2000);
248 } else {
249 $button.prop('disabled', false).text('<?php echo esc_js( __( 'Run', 'friends' ) ); ?>');
250 }
251 }
252 });
253 }
254
255 function refreshMigrationStatus(migrationId, $row, $button) {
256 $.post(ajaxurl, {
257 action: 'friends_get_migration_status',
258 migration_id: migrationId,
259 _wpnonce: '<?php echo esc_js( wp_create_nonce( 'friends-migration-status' ) ); ?>'
260 }, function(response) {
261 if (response.success) {
262 $row.find('.migration-status').html(response.data.html);
263 }
264 $button.prop('disabled', false).text('<?php echo esc_js( __( 'Run', 'friends' ) ); ?>');
265 });
266 }
267 });
268 </script>
269
270 <style>
271 #friends-migrations-table .status-badge {
272 display: inline-block;
273 padding: 3px 8px;
274 border-radius: 3px;
275 font-size: 12px;
276 font-weight: 600;
277 }
278 #friends-migrations-table .status-completed {
279 background: #d4edda;
280 color: #155724;
281 }
282 #friends-migrations-table .status-pending {
283 background: #fff3cd;
284 color: #856404;
285 }
286 #friends-migrations-table .status-in-progress {
287 background: #cce5ff;
288 color: #004085;
289 }
290 #friends-migrations-table .status-no-tracking {
291 background: #e2e3e5;
292 color: #383d41;
293 }
294 #friends-migrations-table .progress-bar {
295 width: 100%;
296 height: 8px;
297 background: #e0e0e0;
298 border-radius: 4px;
299 margin-top: 5px;
300 overflow: hidden;
301 }
302 #friends-migrations-table .progress-bar-fill {
303 height: 100%;
304 background: #0073aa;
305 transition: width 0.3s ease;
306 }
307 </style>
308