Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
62.50% |
20 / 32 |
|
83.33% |
5 / 6 |
CRAP | n/a |
0 / 0 |
|
| wpcomsh_is_staging_site_get_atomic_persistent_data | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
| wpcomsh_disable_outgoing_pings_in_non_production_envs | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
| wpcomsh_disable_incoming_pings_in_non_production_envs | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
| wpcomsh_force_pingback_flag_off_on_staging | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
| wpcomsh_force_ping_status_closed_on_staging | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
| wpcomsh_disable_pingback_ui_on_staging | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Customizations for the staging sites. |
| 4 | * |
| 5 | * @package wpcomsh |
| 6 | */ |
| 7 | |
| 8 | /** |
| 9 | * Returns Atomic persistent data value for wpcom_is_staging_site. |
| 10 | * |
| 11 | * @param string $wpcom_is_staging_site Value for the preview links option. |
| 12 | * |
| 13 | * @return string The value of WPCOM_IS_STAGING_SITE if set, otherwise the option value. |
| 14 | */ |
| 15 | function wpcomsh_is_staging_site_get_atomic_persistent_data( $wpcom_is_staging_site ) { |
| 16 | $persistent_data = new Atomic_Persistent_Data(); |
| 17 | $persistent_data_is_staging_site_value = $persistent_data->WPCOM_IS_STAGING_SITE; // phpcs:ignore WordPress.NamingConventions.ValidVariableName |
| 18 | |
| 19 | if ( $persistent_data_is_staging_site_value !== null ) { |
| 20 | return json_decode( $persistent_data_is_staging_site_value ); |
| 21 | } |
| 22 | |
| 23 | return $wpcom_is_staging_site; |
| 24 | } |
| 25 | // need to hook to default_option_* too because if this option doesn't exist, the hook wouldn't run. |
| 26 | add_filter( 'default_option_wpcom_is_staging_site', 'wpcomsh_is_staging_site_get_atomic_persistent_data' ); |
| 27 | add_filter( 'option_wpcom_is_staging_site', 'wpcomsh_is_staging_site_get_atomic_persistent_data' ); |
| 28 | |
| 29 | /** |
| 30 | * Disables outgoing pingbacks/trackbacks in staging environments. |
| 31 | * |
| 32 | * Prevents the dispatch of pingbacks when the environment type is 'staging' |
| 33 | * by clearing the list of URLs to ping. The `pre_ping` action passes |
| 34 | * `$post_links` by reference, so emptying it prevents all outgoing pings. |
| 35 | * |
| 36 | * This can be removed once WordPress core addresses the issue. |
| 37 | * |
| 38 | * @see https://core.trac.wordpress.org/ticket/64837 |
| 39 | * |
| 40 | * @param string[] $post_links Array of URLs to ping (passed by reference). |
| 41 | */ |
| 42 | function wpcomsh_disable_outgoing_pings_in_non_production_envs( &$post_links ) { |
| 43 | if ( 'staging' === wp_get_environment_type() ) { |
| 44 | $post_links = array(); |
| 45 | } |
| 46 | } |
| 47 | add_action( 'pre_ping', 'wpcomsh_disable_outgoing_pings_in_non_production_envs' ); |
| 48 | |
| 49 | /** |
| 50 | * Disables incoming pingbacks in staging environments by removing |
| 51 | * the 'pingback.ping' XML-RPC method. |
| 52 | * |
| 53 | * Prevents WordPress from processing incoming pingbacks when the environment |
| 54 | * type is 'staging'. This can be removed once WordPress core addresses the issue. |
| 55 | * |
| 56 | * @see https://core.trac.wordpress.org/ticket/64837 |
| 57 | * |
| 58 | * @param array<string, callable> $methods Associative array of XML-RPC methods. |
| 59 | * @return array<string, callable> Modified associative array of XML-RPC methods. |
| 60 | */ |
| 61 | function wpcomsh_disable_incoming_pings_in_non_production_envs( $methods ) { |
| 62 | if ( 'staging' === wp_get_environment_type() ) { |
| 63 | unset( $methods['pingback.ping'] ); |
| 64 | } |
| 65 | |
| 66 | return $methods; |
| 67 | } |
| 68 | add_filter( 'xmlrpc_methods', 'wpcomsh_disable_incoming_pings_in_non_production_envs' ); |
| 69 | |
| 70 | /** |
| 71 | * Forces the default_pingback_flag option to '0' on staging sites so the |
| 72 | * Discussion Settings UI reflects that outgoing pingbacks are disabled. |
| 73 | * |
| 74 | * @return string|false '0' on staging sites, false to allow normal behavior otherwise. |
| 75 | */ |
| 76 | function wpcomsh_force_pingback_flag_off_on_staging() { |
| 77 | if ( 'staging' === wp_get_environment_type() ) { |
| 78 | return '0'; |
| 79 | } |
| 80 | |
| 81 | return false; |
| 82 | } |
| 83 | add_filter( 'pre_option_default_pingback_flag', 'wpcomsh_force_pingback_flag_off_on_staging' ); |
| 84 | |
| 85 | /** |
| 86 | * Forces the default_ping_status option to 'closed' on staging sites so the |
| 87 | * Discussion Settings UI reflects that incoming pingbacks are disabled. |
| 88 | * |
| 89 | * @return string|false 'closed' on staging sites, false to allow normal behavior otherwise. |
| 90 | */ |
| 91 | function wpcomsh_force_ping_status_closed_on_staging() { |
| 92 | if ( 'staging' === wp_get_environment_type() ) { |
| 93 | return 'closed'; |
| 94 | } |
| 95 | |
| 96 | return false; |
| 97 | } |
| 98 | add_filter( 'pre_option_default_ping_status', 'wpcomsh_force_ping_status_closed_on_staging' ); |
| 99 | |
| 100 | /** |
| 101 | * Disables pingback checkboxes and adds an explanation on the Discussion |
| 102 | * Settings page for staging sites. |
| 103 | */ |
| 104 | function wpcomsh_disable_pingback_ui_on_staging() { |
| 105 | if ( 'staging' !== wp_get_environment_type() ) { |
| 106 | return; |
| 107 | } |
| 108 | |
| 109 | $screen = get_current_screen(); |
| 110 | if ( ! $screen || 'options-discussion' !== $screen->id ) { |
| 111 | return; |
| 112 | } |
| 113 | |
| 114 | ?> |
| 115 | <script> |
| 116 | ( function() { |
| 117 | var ids = [ 'default_pingback_flag', 'default_ping_status' ]; |
| 118 | var message = ' — ' + <?php echo wp_json_encode( __( 'Pingbacks are disabled on staging sites to prevent unintended outbound requests.', 'wpcomsh' ), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ); ?>; |
| 119 | ids.forEach( function( id ) { |
| 120 | var checkbox = document.getElementById( id ); |
| 121 | if ( checkbox ) { |
| 122 | checkbox.disabled = true; |
| 123 | var note = document.createElement( 'em' ); |
| 124 | note.textContent = message; |
| 125 | checkbox.parentNode.appendChild( note ); |
| 126 | } |
| 127 | } ); |
| 128 | } )(); |
| 129 | </script> |
| 130 | <?php |
| 131 | } |
| 132 | add_action( 'admin_print_footer_scripts', 'wpcomsh_disable_pingback_ui_on_staging' ); |