Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
75.34% |
55 / 73 |
|
66.67% |
4 / 6 |
CRAP | |
0.00% |
0 / 1 |
| Settings_Page | |
75.34% |
55 / 73 |
|
66.67% |
4 / 6 |
21.33 | |
0.00% |
0 / 1 |
| init | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| register_menu | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
2 | |||
| render_sections | |
100.00% |
24 / 24 |
|
100.00% |
1 / 1 |
7 | |||
| render_saved_notice | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
4 | |||
| render_multibyte_warning | |
10.53% |
2 / 19 |
|
0.00% |
0 / 1 |
4.87 | |||
| render | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
1 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * The Settings > Sharing screen. |
| 4 | * |
| 5 | * @package automattic/jetpack-sharing-likes |
| 6 | */ |
| 7 | |
| 8 | declare( strict_types = 1 ); |
| 9 | |
| 10 | namespace Automattic\Jetpack\Sharing_Likes\Settings; |
| 11 | |
| 12 | /** |
| 13 | * Registers Settings > Sharing and renders its sections. |
| 14 | * |
| 15 | * Registration does not depend on any module being active, so the screen and |
| 16 | * every section on it exist whatever the site is running, as long as it can |
| 17 | * run them at all: see `Environment::settings_screen_supported()`. |
| 18 | */ |
| 19 | final class Settings_Page { |
| 20 | |
| 21 | /** |
| 22 | * Submenu slug. Unchanged from when sharedaddy registered this screen, so |
| 23 | * existing links and bookmarks keep working. |
| 24 | */ |
| 25 | public const SLUG = 'sharing'; |
| 26 | |
| 27 | /** |
| 28 | * Query argument a save adds when the Comment Likes switch did not take. |
| 29 | */ |
| 30 | public const COMMENT_LIKES_UNCHANGED = 'comment-likes-unchanged'; |
| 31 | |
| 32 | /** |
| 33 | * Hook the screen up. |
| 34 | */ |
| 35 | public static function init(): void { |
| 36 | add_action( 'admin_menu', array( __CLASS__, 'register_menu' ) ); |
| 37 | } |
| 38 | |
| 39 | /** |
| 40 | * Add the submenu entry under Settings. |
| 41 | */ |
| 42 | public static function register_menu(): void { |
| 43 | if ( ! Environment::settings_screen_supported() ) { |
| 44 | return; |
| 45 | } |
| 46 | |
| 47 | add_submenu_page( |
| 48 | 'options-general.php', |
| 49 | __( 'Sharing Settings', 'jetpack-sharing-likes' ), |
| 50 | __( 'Sharing', 'jetpack-sharing-likes' ), |
| 51 | 'manage_options', |
| 52 | self::SLUG, |
| 53 | array( __CLASS__, 'render' ) |
| 54 | ); |
| 55 | } |
| 56 | |
| 57 | /** |
| 58 | * Render whichever sections apply, ruled off from one another, then the |
| 59 | * one Save button that covers them all. |
| 60 | */ |
| 61 | private static function render_sections(): void { |
| 62 | // The submenu registers against this too. Repeated here because the sections |
| 63 | // mint the nonces that authorise every save, and the screen is public API. |
| 64 | if ( ! current_user_can( 'manage_options' ) ) { |
| 65 | return; |
| 66 | } |
| 67 | |
| 68 | $sections = array( |
| 69 | array( Sharing_Section::class, 'render' ), |
| 70 | array( Likes_Section::class, 'render' ), |
| 71 | array( Comment_Likes_Section::class, 'render' ), |
| 72 | ); |
| 73 | |
| 74 | $sharing_state = Sharing_Section::state(); |
| 75 | |
| 76 | if ( Section_State::shows_placement( $sharing_state, Likes_Section::state(), Environment::comment_likes_follow_likes_settings() ) ) { |
| 77 | $sections[] = array( Placement_Section::class, 'render' ); |
| 78 | } |
| 79 | |
| 80 | if ( ! Section_State::configures( $sharing_state ) ) { |
| 81 | $sections[] = array( Extras_Section::class, 'render' ); |
| 82 | } |
| 83 | |
| 84 | $rendered = 0; |
| 85 | |
| 86 | foreach ( $sections as $section ) { |
| 87 | ob_start(); |
| 88 | call_user_func( $section ); |
| 89 | $markup = trim( (string) ob_get_clean() ); |
| 90 | |
| 91 | // A section can decline to render, and a rule with nothing after it is worse than no rule. |
| 92 | if ( '' === $markup ) { |
| 93 | continue; |
| 94 | } |
| 95 | |
| 96 | if ( $rendered > 0 ) { |
| 97 | echo '<hr />'; |
| 98 | } |
| 99 | |
| 100 | echo $markup; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- each section escapes its own output. |
| 101 | ++$rendered; |
| 102 | } |
| 103 | |
| 104 | Settings_Form::render(); |
| 105 | } |
| 106 | |
| 107 | /** |
| 108 | * Confirm a save, when one just happened. |
| 109 | */ |
| 110 | private static function render_saved_notice(): void { |
| 111 | // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- only decides whether to print a confirmation. |
| 112 | if ( ! isset( $_GET['update'] ) || 'saved' !== $_GET['update'] ) { |
| 113 | return; |
| 114 | } |
| 115 | |
| 116 | printf( |
| 117 | '<div class="updated"><p>%s</p></div>', |
| 118 | esc_html__( 'Settings have been saved', 'jetpack-sharing-likes' ) |
| 119 | ); |
| 120 | |
| 121 | // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- only decides whether to print a warning. |
| 122 | if ( isset( $_GET[ self::COMMENT_LIKES_UNCHANGED ] ) ) { |
| 123 | printf( |
| 124 | '<div class="error"><p>%s</p></div>', |
| 125 | esc_html__( 'Comment Likes could not be switched on or off on this site.', 'jetpack-sharing-likes' ) |
| 126 | ); |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | /** |
| 131 | * Warn when PHP has no mbstring extension. |
| 132 | * |
| 133 | * Sharing sources fall back to byte-wise string functions without it, which |
| 134 | * can cut multibyte text mid-character when a service truncates it. |
| 135 | */ |
| 136 | private static function render_multibyte_warning(): void { |
| 137 | if ( function_exists( 'mb_stripos' ) ) { |
| 138 | return; |
| 139 | } |
| 140 | |
| 141 | printf( |
| 142 | '<div class="notice notice-warning"><p><strong>%1$s</strong></p><p>%2$s</p></div>', |
| 143 | esc_html__( 'Warning! Multibyte support missing!', 'jetpack-sharing-likes' ), |
| 144 | wp_kses( |
| 145 | sprintf( |
| 146 | /* translators: placeholder is a link to a PHP support document. */ |
| 147 | __( 'This plugin will work without it, but multibyte support is used <a href="%s" rel="noopener noreferrer" target="_blank">if available</a>. You may see minor problems with Tweets and other sharing services.', 'jetpack-sharing-likes' ), |
| 148 | 'https://www.php.net/manual/en/mbstring.installation.php' |
| 149 | ), |
| 150 | array( |
| 151 | 'a' => array( |
| 152 | 'href' => array(), |
| 153 | 'rel' => array(), |
| 154 | 'target' => array(), |
| 155 | ), |
| 156 | ) |
| 157 | ) |
| 158 | ); |
| 159 | } |
| 160 | |
| 161 | /** |
| 162 | * Render the screen. |
| 163 | */ |
| 164 | public static function render(): void { |
| 165 | ?> |
| 166 | <div class="wrap"> |
| 167 | <h1><?php esc_html_e( 'Sharing Settings', 'jetpack-sharing-likes' ); ?></h1> |
| 168 | <?php |
| 169 | self::render_multibyte_warning(); |
| 170 | self::render_saved_notice(); |
| 171 | |
| 172 | /** |
| 173 | * Fires at the top of the admin sharing settings screen. |
| 174 | * |
| 175 | * @module sharedaddy |
| 176 | * |
| 177 | * @since jetpack-1.6.0 |
| 178 | */ |
| 179 | do_action( 'pre_admin_screen_sharing' ); |
| 180 | |
| 181 | self::render_sections(); |
| 182 | ?> |
| 183 | </div> |
| 184 | <?php |
| 185 | } |
| 186 | } |