| 1 |
<?php |
| 2 |
/** |
| 3 |
* Site Health Integration for Friends Plugin |
| 4 |
* |
| 5 |
* This class handles all Site Health related functionality including |
| 6 |
* migration status checks and post tag cleanup diagnostics. |
| 7 |
* |
| 8 |
* @package Friends |
| 9 |
*/ |
| 10 |
|
| 11 |
namespace Friends; |
| 12 |
|
| 13 |
/** |
| 14 |
* Site Health integration class |
| 15 |
*/ |
| 16 |
class Site_Health { |
| 17 |
|
| 18 |
/** |
| 19 |
* Constructor |
| 20 |
*/ |
| 21 |
public function __construct() { |
| 22 |
add_filter( 'site_status_tests', array( $this, 'add_tests' ) ); |
| 23 |
add_filter( 'debug_information', array( $this, 'site_health_debug' ) ); |
| 24 |
add_action( 'wp_ajax_friends_restart_migration', array( $this, 'ajax_restart_migration' ) ); |
| 25 |
add_action( 'wp_ajax_friends_cleanup_post_tags', array( $this, 'ajax_cleanup_post_tags' ) ); |
| 26 |
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); |
| 27 |
} |
| 28 |
|
| 29 |
/** |
| 30 |
* Add Site Health tests. |
| 31 |
* |
| 32 |
* @param array $tests Existing tests. |
| 33 |
* @return array Modified tests. |
| 34 |
*/ |
| 35 |
public function add_tests( $tests ) { |
| 36 |
$tests['direct']['friends_migration'] = array( |
| 37 |
'label' => __( 'Friends Post Tag Migration', 'friends' ), |
| 38 |
'test' => array( $this, 'test_migration' ), |
| 39 |
); |
| 40 |
|
| 41 |
$tests['direct']['friends_orphaned_post_tags'] = array( |
| 42 |
'label' => __( 'Friends Orphaned Post Tags', 'friends' ), |
| 43 |
'test' => array( $this, 'test_post_tag_cleanup' ), |
| 44 |
); |
| 45 |
|
| 46 |
$tests['direct']['friends-roles'] = array( |
| 47 |
'label' => __( 'Friend roles were created', 'friends' ), |
| 48 |
'test' => array( $this, 'friend_roles_test' ), |
| 49 |
); |
| 50 |
|
| 51 |
$tests['direct']['friends-cron'] = array( |
| 52 |
'label' => __( 'Friends cron job is enabled', 'friends' ), |
| 53 |
'test' => array( $this, 'friends_cron_test' ), |
| 54 |
); |
| 55 |
|
| 56 |
$tests['direct']['friends-delete-cron'] = array( |
| 57 |
'label' => __( 'Friends delete old posts cron job is enabled', 'friends' ), |
| 58 |
'test' => array( $this, 'friends_cron_delete_test' ), |
| 59 |
); |
| 60 |
|
| 61 |
return $tests; |
| 62 |
} |
| 63 |
|
| 64 |
/** |
| 65 |
* Site Health test for post tag migration status. |
| 66 |
* |
| 67 |
* @return array Site Health test result. |
| 68 |
*/ |
| 69 |
public function test_migration() { |
| 70 |
require_once __DIR__ . '/class-migration.php'; |
| 71 |
$status = Migration::get_migration_status(); |
| 72 |
|
| 73 |
if ( $status['completed'] ) { |
| 74 |
$result = array( |
| 75 |
'label' => __( 'Post tag migration completed', 'friends' ), |
| 76 |
'status' => 'good', |
| 77 |
'badge' => array( |
| 78 |
'label' => __( 'Friends', 'friends' ), |
| 79 |
'color' => 'green', |
| 80 |
), |
| 81 |
'description' => sprintf( |
| 82 |
'<p>%s</p>', |
| 83 |
$status['completed_time'] ? sprintf( |
| 84 |
/* translators: %s: completion time */ |
| 85 |
__( 'The post tag migration was completed on %s.', 'friends' ), |
| 86 |
$status['completed_time'] |
| 87 |
) : __( 'The post tag migration has been completed.', 'friends' ) |
| 88 |
), |
| 89 |
'test' => 'friends_migration', |
| 90 |
); |
| 91 |
} elseif ( $status['in_progress'] ) { |
| 92 |
$result = array( |
| 93 |
'label' => __( 'Post tag migration in progress', 'friends' ), |
| 94 |
'status' => 'recommended', |
| 95 |
'badge' => array( |
| 96 |
'label' => __( 'Friends', 'friends' ), |
| 97 |
'color' => 'orange', |
| 98 |
), |
| 99 |
'description' => sprintf( |
| 100 |
'<p>%s</p><p>%s</p>', |
| 101 |
sprintf( |
| 102 |
/* translators: %1$d: migrated count, %2$d: total count */ |
| 103 |
__( 'Migration progress: %1$d/%2$d posts processed.', 'friends' ), |
| 104 |
isset( $status['migrated'] ) ? $status['migrated'] : 0, |
| 105 |
isset( $status['total'] ) ? $status['total'] : 0 |
| 106 |
), |
| 107 |
__( 'The migration will continue automatically in the background.', 'friends' ) |
| 108 |
), |
| 109 |
'test' => 'friends_migration', |
| 110 |
); |
| 111 |
} else { |
| 112 |
// No migration status options are set, check the database to see current state |
| 113 |
global $wpdb; |
| 114 |
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery |
| 115 |
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching |
| 116 |
$friends_posts_with_post_tags = $wpdb->get_var( |
| 117 |
$wpdb->prepare( |
| 118 |
"SELECT COUNT(DISTINCT p.ID) |
| 119 |
FROM {$wpdb->posts} p |
| 120 |
INNER JOIN {$wpdb->term_relationships} tr ON p.ID = tr.object_id |
| 121 |
INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id |
| 122 |
WHERE p.post_type = %s |
| 123 |
AND tt.taxonomy = 'post_tag' |
| 124 |
AND p.post_status IN ('publish', 'private')", |
| 125 |
Friends::CPT |
| 126 |
) |
| 127 |
); |
| 128 |
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery |
| 129 |
// phpcs:enable WordPress.DB.DirectDatabaseQuery.NoCaching |
| 130 |
|
| 131 |
if ( $friends_posts_with_post_tags > 0 ) { |
| 132 |
$result = array( |
| 133 |
'label' => __( 'Friends posts need tag migration', 'friends' ), |
| 134 |
'status' => 'recommended', |
| 135 |
'badge' => array( |
| 136 |
'label' => __( 'Friends', 'friends' ), |
| 137 |
'color' => 'orange', |
| 138 |
), |
| 139 |
'description' => sprintf( |
| 140 |
'<p>%s</p><p><button type="button" class="button button-primary" onclick="friendsRestartMigration(this)">%s</button></p>', |
| 141 |
sprintf( |
| 142 |
/* translators: %d: number of posts */ |
| 143 |
_n( |
| 144 |
'%d Friends post is still using the post_tag taxonomy. A migration to the friend_tag taxonomy is recommended for better organization.', |
| 145 |
'%d Friends posts are still using the post_tag taxonomy. A migration to the friend_tag taxonomy is recommended for better organization.', |
| 146 |
$friends_posts_with_post_tags, |
| 147 |
'friends' |
| 148 |
), |
| 149 |
$friends_posts_with_post_tags |
| 150 |
), |
| 151 |
__( 'Start Migration', 'friends' ) |
| 152 |
), |
| 153 |
'test' => 'friends_migration', |
| 154 |
); |
| 155 |
} else { |
| 156 |
$result = array( |
| 157 |
'label' => __( 'No Friends tag migration needed', 'friends' ), |
| 158 |
'status' => 'good', |
| 159 |
'badge' => array( |
| 160 |
'label' => __( 'Friends', 'friends' ), |
| 161 |
'color' => 'green', |
| 162 |
), |
| 163 |
'description' => sprintf( |
| 164 |
'<p>%s</p>', |
| 165 |
__( 'No Friends posts are using the post_tag taxonomy. All Friends posts are properly using the friend_tag taxonomy.', 'friends' ) |
| 166 |
), |
| 167 |
'test' => 'friends_migration', |
| 168 |
); |
| 169 |
} |
| 170 |
} |
| 171 |
|
| 172 |
return $result; |
| 173 |
} |
| 174 |
|
| 175 |
/** |
| 176 |
* Site Health test for orphaned post tags cleanup. |
| 177 |
* |
| 178 |
* @return array Site Health test result. |
| 179 |
*/ |
| 180 |
public function test_post_tag_cleanup() { |
| 181 |
require_once __DIR__ . '/class-migration.php'; |
| 182 |
|
| 183 |
global $wpdb; |
| 184 |
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery |
| 185 |
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching |
| 186 |
|
| 187 |
// Count ALL post_tag terms that have no actual post associations from supported post types. |
| 188 |
|
| 189 |
// Get post types that support the post_tag taxonomy |
| 190 |
$post_types = get_post_types_by_support( array(), 'and' ); |
| 191 |
$post_tag_post_types = array(); |
| 192 |
foreach ( $post_types as $post_type ) { |
| 193 |
if ( is_object_in_taxonomy( $post_type, 'post_tag' ) ) { |
| 194 |
$post_tag_post_types[] = $post_type; |
| 195 |
} |
| 196 |
} |
| 197 |
|
| 198 |
if ( empty( $post_tag_post_types ) ) { |
| 199 |
$orphaned_tags = $wpdb->get_results( |
| 200 |
"SELECT t.term_id, t.name, t.slug |
| 201 |
FROM {$wpdb->terms} t |
| 202 |
INNER JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id |
| 203 |
WHERE tt.taxonomy = 'post_tag' |
| 204 |
ORDER BY t.name ASC" |
| 205 |
); |
| 206 |
} else { |
| 207 |
$placeholders = implode( ',', array_fill( 0, count( $post_tag_post_types ), '%s' ) ); |
| 208 |
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 209 |
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare |
| 210 |
$orphaned_tags = $wpdb->get_results( |
| 211 |
$wpdb->prepare( |
| 212 |
"SELECT t.term_id, t.name, t.slug |
| 213 |
FROM {$wpdb->terms} t |
| 214 |
INNER JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id |
| 215 |
LEFT JOIN ( |
| 216 |
SELECT DISTINCT tt2.term_id |
| 217 |
FROM {$wpdb->term_relationships} tr |
| 218 |
INNER JOIN {$wpdb->term_taxonomy} tt2 ON tr.term_taxonomy_id = tt2.term_taxonomy_id |
| 219 |
INNER JOIN {$wpdb->posts} p ON tr.object_id = p.ID |
| 220 |
WHERE tt2.taxonomy = 'post_tag' |
| 221 |
AND p.post_status IN ('publish', 'private') |
| 222 |
AND p.post_type IN ($placeholders) |
| 223 |
) used_terms ON t.term_id = used_terms.term_id |
| 224 |
WHERE tt.taxonomy = 'post_tag' AND used_terms.term_id IS NULL |
| 225 |
ORDER BY t.name ASC", |
| 226 |
$post_tag_post_types |
| 227 |
) |
| 228 |
); |
| 229 |
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 230 |
// phpcs:enable WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare |
| 231 |
} |
| 232 |
|
| 233 |
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery |
| 234 |
// phpcs:enable WordPress.DB.DirectDatabaseQuery.NoCaching |
| 235 |
|
| 236 |
$orphaned_count = count( $orphaned_tags ); |
| 237 |
|
| 238 |
if ( $orphaned_count > 0 ) { |
| 239 |
$description = sprintf( |
| 240 |
/* translators: %d: number of orphaned tags */ |
| 241 |
_n( |
| 242 |
'%d orphaned post_tag term was found with no associated posts. These tags may have been created by Friends posts before migration or other sources and can be safely removed to keep your tag cloud clean.', |
| 243 |
'%d orphaned post_tag terms were found with no associated posts. These tags may have been created by Friends posts before migration or other sources and can be safely removed to keep your tag cloud clean.', |
| 244 |
$orphaned_count, |
| 245 |
'friends' |
| 246 |
), |
| 247 |
$orphaned_count |
| 248 |
); |
| 249 |
|
| 250 |
$tag_list_limit = 15; |
| 251 |
if ( $orphaned_count <= $tag_list_limit ) { |
| 252 |
$tag_names = array_map( |
| 253 |
function ( $tag ) { |
| 254 |
return '<code>' . esc_html( $tag->name ) . '</code>'; |
| 255 |
}, |
| 256 |
$orphaned_tags |
| 257 |
); |
| 258 |
$description .= '<br><br><strong>' . __( 'Tags to be deleted:', 'friends' ) . '</strong> ' . implode( ', ', $tag_names ); |
| 259 |
} else { |
| 260 |
$shown_tags = array_slice( $orphaned_tags, 0, $tag_list_limit ); |
| 261 |
$tag_names = array_map( |
| 262 |
function ( $tag ) { |
| 263 |
return '<code>' . esc_html( $tag->name ) . '</code>'; |
| 264 |
}, |
| 265 |
$shown_tags |
| 266 |
); |
| 267 |
$remaining = $orphaned_count - $tag_list_limit; |
| 268 |
$description .= '<br><br><strong>' . __( 'Tags to be deleted:', 'friends' ) . '</strong> ' . implode( ', ', $tag_names ) . sprintf( |
| 269 |
/* translators: %d: number of additional tags */ |
| 270 |
_n( ' and %d more', ' and %d more', $remaining, 'friends' ), |
| 271 |
$remaining |
| 272 |
); |
| 273 |
} |
| 274 |
|
| 275 |
$result = array( |
| 276 |
'label' => __( 'Orphaned post tags found', 'friends' ), |
| 277 |
'status' => 'recommended', |
| 278 |
'badge' => array( |
| 279 |
'label' => __( 'Friends', 'friends' ), |
| 280 |
'color' => 'orange', |
| 281 |
), |
| 282 |
'description' => sprintf( |
| 283 |
'<p>%s</p><p><button type="button" class="button button-primary" onclick="friendsCleanupPostTags(this)">%s</button></p>', |
| 284 |
$description, |
| 285 |
__( 'Clean Up Orphaned Tags', 'friends' ) |
| 286 |
), |
| 287 |
'test' => 'friends_orphaned_post_tags', |
| 288 |
); |
| 289 |
} else { |
| 290 |
$result = array( |
| 291 |
'label' => __( 'No orphaned post tags found', 'friends' ), |
| 292 |
'status' => 'good', |
| 293 |
'badge' => array( |
| 294 |
'label' => __( 'Friends', 'friends' ), |
| 295 |
'color' => 'green', |
| 296 |
), |
| 297 |
'description' => sprintf( |
| 298 |
'<p>%s</p>', |
| 299 |
__( 'All post_tag terms have associated posts. Your tag system is clean.', 'friends' ) |
| 300 |
), |
| 301 |
'test' => 'friends_orphaned_post_tags', |
| 302 |
); |
| 303 |
} |
| 304 |
|
| 305 |
return $result; |
| 306 |
} |
| 307 |
|
| 308 |
/** |
| 309 |
* Get missing Friends plugin roles. |
| 310 |
* |
| 311 |
* @return array Missing role names. |
| 312 |
*/ |
| 313 |
public function get_missing_friends_plugin_roles() { |
| 314 |
$missing = Friends::get_friends_plugin_roles(); |
| 315 |
$roles = new \WP_Roles(); |
| 316 |
foreach ( $roles->roles as $role => $data ) { |
| 317 |
if ( isset( $data['capabilities']['friends_plugin'] ) ) { |
| 318 |
foreach ( $missing as $k => $cap ) { |
| 319 |
if ( isset( $data['capabilities'][ $cap ] ) ) { |
| 320 |
unset( $missing[ $k ] ); |
| 321 |
break; |
| 322 |
} |
| 323 |
} |
| 324 |
} |
| 325 |
} |
| 326 |
|
| 327 |
return array_values( $missing ); |
| 328 |
} |
| 329 |
|
| 330 |
/** |
| 331 |
* Site Health test for friend roles. |
| 332 |
* |
| 333 |
* @return array Site Health test result. |
| 334 |
*/ |
| 335 |
public function friend_roles_test() { |
| 336 |
$result = array( |
| 337 |
'label' => __( 'The friend roles have been installed', 'friends' ), |
| 338 |
'status' => 'good', |
| 339 |
'badge' => array( |
| 340 |
'label' => __( 'Friends', 'friends' ), |
| 341 |
'color' => 'green', |
| 342 |
), |
| 343 |
'description' => |
| 344 |
'<p>' . |
| 345 |
__( 'The Friends Plugin uses users and user roles to determine friendship status between sites.', 'friends' ) . |
| 346 |
'</p>' . |
| 347 |
'<p>' . |
| 348 |
sprintf( |
| 349 |
/* translators: %s is a list of roles. */ |
| 350 |
__( 'These are the roles required for the friends plugin: %s', 'friends' ), |
| 351 |
implode( ', ', Friends::get_friends_plugin_roles() ) |
| 352 |
) . |
| 353 |
'</p>', |
| 354 |
'test' => 'friends-roles', |
| 355 |
); |
| 356 |
|
| 357 |
$missing_friend_roles = $this->get_missing_friends_plugin_roles(); |
| 358 |
if ( ! empty( $missing_friend_roles ) ) { |
| 359 |
|
| 360 |
$result['label'] = sprintf( |
| 361 |
/* translators: %s is a list of missing roles. */ |
| 362 |
__( 'Not all friend roles have been installed. Missing: %s', 'friends' ), |
| 363 |
implode( ', ', $missing_friend_roles ) |
| 364 |
); |
| 365 |
$result['badge']['color'] = 'red'; |
| 366 |
$result['status'] = 'critical'; |
| 367 |
$result['description'] .= '<p>'; |
| 368 |
$result['description'] .= wp_kses_post( |
| 369 |
sprintf( |
| 370 |
/* translators: %s is a URL. */ |
| 371 |
__( '<strong>To fix this:</strong> <a href="%s">Re-run activation of the Friends plugin</a>.', 'friends' ), |
| 372 |
esc_url( wp_nonce_url( add_query_arg( '_wp_http_referer', remove_query_arg( '_wp_http_referer' ), admin_url( 'admin.php?page=friends-settings&rerun-activate' ) ), 'friends-settings' ) ) |
| 373 |
) |
| 374 |
); |
| 375 |
$result['description'] .= '</p>'; |
| 376 |
} |
| 377 |
|
| 378 |
return $result; |
| 379 |
} |
| 380 |
|
| 381 |
/** |
| 382 |
* Site Health test for Friends cron job. |
| 383 |
* |
| 384 |
* @return array Site Health test result. |
| 385 |
*/ |
| 386 |
public function friends_cron_test() { |
| 387 |
$result = array( |
| 388 |
'label' => __( 'The refresh cron job is enabled', 'friends' ), |
| 389 |
'status' => 'good', |
| 390 |
'badge' => array( |
| 391 |
'label' => __( 'Friends', 'friends' ), |
| 392 |
'color' => 'green', |
| 393 |
), |
| 394 |
'description' => |
| 395 |
'<p>' . |
| 396 |
__( 'The Friends Plugin uses a cron job to fetch your friends\' feeds.', 'friends' ) . |
| 397 |
'</p>', |
| 398 |
'test' => 'friends-cron', |
| 399 |
); |
| 400 |
if ( ! wp_next_scheduled( 'cron_friends_refresh_feeds' ) ) { |
| 401 |
$result['label'] = __( 'The refresh cron job is not enabled', 'friends' ); |
| 402 |
$result['badge']['color'] = 'red'; |
| 403 |
$result['status'] = 'critical'; |
| 404 |
$result['description'] .= '<p>'; |
| 405 |
$result['description'] .= wp_kses_post( |
| 406 |
sprintf( |
| 407 |
/* translators: %s is a URL. */ |
| 408 |
__( '<strong>To fix this:</strong> <a href="%s">Enable the Friends cron job</a>.', 'friends' ), |
| 409 |
esc_url( wp_nonce_url( add_query_arg( '_wp_http_referer', remove_query_arg( '_wp_http_referer' ), admin_url( 'admin.php?page=friends-settings&rerun-activate' ) ), 'friends-settings' ) ) |
| 410 |
) |
| 411 |
); |
| 412 |
$result['description'] .= '</p>'; |
| 413 |
} |
| 414 |
|
| 415 |
return $result; |
| 416 |
} |
| 417 |
|
| 418 |
/** |
| 419 |
* Site Health test for Friends delete old posts cron job. |
| 420 |
* |
| 421 |
* @return array Site Health test result. |
| 422 |
*/ |
| 423 |
public function friends_cron_delete_test() { |
| 424 |
$result = array( |
| 425 |
'label' => __( 'The cron job to delete old posts is enabled', 'friends' ), |
| 426 |
'status' => 'good', |
| 427 |
'badge' => array( |
| 428 |
'label' => __( 'Friends', 'friends' ), |
| 429 |
'color' => 'green', |
| 430 |
), |
| 431 |
'description' => |
| 432 |
'<p>' . |
| 433 |
__( 'The Friends Plugin uses a cron job to delete old posts your friends.', 'friends' ) . |
| 434 |
'</p>', |
| 435 |
'test' => 'friends-delete-cron', |
| 436 |
); |
| 437 |
|
| 438 |
if ( ! wp_next_scheduled( 'cron_friends_delete_old_posts' ) ) { |
| 439 |
$result['label'] = __( 'The cron job to delete old posts is not enabled', 'friends' ); |
| 440 |
$result['badge']['color'] = 'orange'; |
| 441 |
$result['status'] = 'recommended'; |
| 442 |
$result['description'] .= '<p>'; |
| 443 |
$result['description'] .= wp_kses_post( |
| 444 |
sprintf( |
| 445 |
/* translators: %s is a URL. */ |
| 446 |
__( '<strong>To fix this:</strong> <a href="%s">Enable the Friends cron job</a>.', 'friends' ), |
| 447 |
esc_url( wp_nonce_url( add_query_arg( '_wp_http_referer', remove_query_arg( '_wp_http_referer' ), admin_url( 'admin.php?page=friends-settings&rerun-activate' ) ), 'friends-settings' ) ) |
| 448 |
) |
| 449 |
); |
| 450 |
$result['description'] .= '</p>'; |
| 451 |
} |
| 452 |
|
| 453 |
return $result; |
| 454 |
} |
| 455 |
|
| 456 |
/** |
| 457 |
* Add debug information to Site Health. |
| 458 |
* |
| 459 |
* @param array $debug_info Debug information array. |
| 460 |
* @return array Modified debug information. |
| 461 |
*/ |
| 462 |
public function site_health_debug( $debug_info ) { |
| 463 |
$missing_friend_roles = $this->get_missing_friends_plugin_roles(); |
| 464 |
$debug_info['friends'] = array( |
| 465 |
'label' => __( 'Friends', 'friends' ), |
| 466 |
'fields' => array( |
| 467 |
'version' => array( |
| 468 |
'label' => __( 'Friends Version', 'friends' ), |
| 469 |
'value' => Friends::VERSION, |
| 470 |
), |
| 471 |
'mbstring' => array( |
| 472 |
'label' => __( 'mbstring is available', 'friends' ), |
| 473 |
'value' => function_exists( 'mb_check_encoding' ) ? __( 'Yes' ) : __( 'No' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain |
| 474 |
), |
| 475 |
'roles' => array( |
| 476 |
'label' => __( 'Friend roles missing', 'friends' ), |
| 477 |
'value' => empty( $missing_friend_roles ) ? sprintf( |
| 478 |
/* translators: %s is a list of roles. */ |
| 479 |
__( 'All roles found: %s', 'friends' ), |
| 480 |
implode( ', ', Friends::get_friends_plugin_roles() ) |
| 481 |
) : implode( ', ', $missing_friend_roles ), |
| 482 |
), |
| 483 |
'main_user' => array( |
| 484 |
'label' => __( 'Main Friend User', 'friends' ), |
| 485 |
'value' => $this->human_readable_main_user(), |
| 486 |
), |
| 487 |
'parsers' => array( |
| 488 |
'label' => __( 'Registered Parsers', 'friends' ), |
| 489 |
'value' => wp_strip_all_tags( implode( ', ', Friends::get_instance()->feed->get_registered_parsers() ) ), |
| 490 |
), |
| 491 |
), |
| 492 |
); |
| 493 |
|
| 494 |
return $debug_info; |
| 495 |
} |
| 496 |
|
| 497 |
/** |
| 498 |
* Returns a human readable string for which user is the main user. |
| 499 |
* |
| 500 |
* @return string |
| 501 |
*/ |
| 502 |
private function human_readable_main_user() { |
| 503 |
$main_user = Friends::get_main_friend_user_id(); |
| 504 |
|
| 505 |
if ( ! $main_user ) { |
| 506 |
/* translators: %d is the number of users. */ |
| 507 |
return esc_html( sprintf( __( 'No main user set. Admin users: %d', 'friends' ), User_Query::all_admin_users()->get_total() ) ); |
| 508 |
} |
| 509 |
|
| 510 |
$user = new \WP_User( $main_user ); |
| 511 |
|
| 512 |
if ( ! $user->exists() ) { |
| 513 |
/* translators: %d is the user ID. */ |
| 514 |
return esc_html( sprintf( __( 'Main user ID %d does not exist', 'friends' ), $main_user ) ); |
| 515 |
} |
| 516 |
|
| 517 |
/* translators: %1$s is the user login, %2$d is the user ID. */ |
| 518 |
return esc_html( sprintf( __( '%1$s (#%2$d)', 'friends' ), $user->user_login, $main_user ) ); |
| 519 |
} |
| 520 |
|
| 521 |
/** |
| 522 |
* AJAX handler for restarting migration. |
| 523 |
*/ |
| 524 |
public function ajax_restart_migration() { |
| 525 |
check_ajax_referer( 'friends_restart_migration', 'nonce' ); |
| 526 |
|
| 527 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 528 |
wp_die( __( 'You do not have permission to perform this action.', 'friends' ) ); |
| 529 |
} |
| 530 |
|
| 531 |
require_once __DIR__ . '/class-migration.php'; |
| 532 |
Migration::trigger_migration_manually(); |
| 533 |
|
| 534 |
wp_send_json_success( array( 'message' => __( 'Migration restarted successfully.', 'friends' ) ) ); |
| 535 |
} |
| 536 |
|
| 537 |
/** |
| 538 |
* AJAX handler for cleaning up orphaned post tags. |
| 539 |
*/ |
| 540 |
public function ajax_cleanup_post_tags() { |
| 541 |
check_ajax_referer( 'friends_cleanup_post_tags', 'nonce' ); |
| 542 |
|
| 543 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 544 |
wp_die( __( 'You do not have permission to perform this action.', 'friends' ) ); |
| 545 |
} |
| 546 |
|
| 547 |
require_once __DIR__ . '/class-migration.php'; |
| 548 |
$results = Migration::cleanup_orphaned_post_tags(); |
| 549 |
|
| 550 |
if ( $results['deleted'] > 0 ) { |
| 551 |
wp_send_json_success( |
| 552 |
array( |
| 553 |
'message' => sprintf( |
| 554 |
/* translators: %d: number of deleted tags */ |
| 555 |
_n( |
| 556 |
'Successfully deleted %d orphaned post tag.', |
| 557 |
'Successfully deleted %d orphaned post tags.', |
| 558 |
$results['deleted'], |
| 559 |
'friends' |
| 560 |
), |
| 561 |
$results['deleted'] |
| 562 |
), |
| 563 |
) |
| 564 |
); |
| 565 |
} else { |
| 566 |
wp_send_json_success( array( 'message' => __( 'No orphaned post_tags were found to clean up.', 'friends' ) ) ); |
| 567 |
} |
| 568 |
} |
| 569 |
|
| 570 |
/** |
| 571 |
* Enqueue scripts for Site Health pages. |
| 572 |
* |
| 573 |
* @param string $hook Current admin page. |
| 574 |
*/ |
| 575 |
public function enqueue_scripts( $hook ) { |
| 576 |
if ( 'site-health.php' !== $hook ) { |
| 577 |
return; |
| 578 |
} |
| 579 |
|
| 580 |
wp_enqueue_script( |
| 581 |
'friends-site-health', |
| 582 |
plugins_url( 'site-health.js', __DIR__ ), |
| 583 |
array( 'jquery' ), |
| 584 |
filemtime( plugin_dir_path( __DIR__ ) . 'site-health.js' ), |
| 585 |
true |
| 586 |
); |
| 587 |
|
| 588 |
wp_localize_script( |
| 589 |
'friends-site-health', |
| 590 |
'friendsSiteHealth', |
| 591 |
array( |
| 592 |
'restartMigrationNonce' => wp_create_nonce( 'friends_restart_migration' ), |
| 593 |
'cleanupPostTagsNonce' => wp_create_nonce( 'friends_cleanup_post_tags' ), |
| 594 |
'ajaxUrl' => admin_url( 'admin-ajax.php' ), |
| 595 |
'confirmRestart' => __( 'This will restart the migration process. Any posts that were previously migrated will be re-processed. Continue?', 'friends' ), |
| 596 |
'confirmCleanup' => __( 'This will clean up orphaned post_tag terms that were created by Friends posts. Only unused tags will be deleted. Continue?', 'friends' ), |
| 597 |
) |
| 598 |
); |
| 599 |
} |
| 600 |
} |
| 601 |
|