diff --git src/wp-admin/css/forms.css src/wp-admin/css/forms.css
index ab0a1cfc6e..e9774e9277 100644
|
|
table.form-table td .updated p { |
1089 | 1089 | } |
1090 | 1090 | |
1091 | 1091 | .tools-privacy-edit { |
1092 | | margin: 2.3em 0; |
| 1092 | margin: 1.5em 0; |
1093 | 1093 | } |
1094 | 1094 | |
1095 | 1095 | .tools-privacy-policy-page span { |
diff --git src/wp-admin/includes/admin-filters.php src/wp-admin/includes/admin-filters.php
index 68592b6d41..233f40f6dd 100644
|
|
add_filter( 'wp_privacy_personal_data_export_page', 'wp_privacy_process_personal |
138 | 138 | add_action( 'wp_privacy_personal_data_export_file', 'wp_privacy_generate_personal_data_export_file', 10 ); |
139 | 139 | |
140 | 140 | // Privacy policy text changes check. |
141 | | add_action( 'admin_init', array( 'WP_Privacy_Policy_Content', 'text_change_check' ), 20 ); |
| 141 | add_action( 'admin_init', array( 'WP_Privacy_Policy_Content', 'text_change_check' ), 100 ); |
142 | 142 | |
143 | 143 | // Show a "postbox" with the text suggestions for a privacy policy. |
144 | 144 | add_action( 'edit_form_after_title', array( 'WP_Privacy_Policy_Content', 'notice' ) ); |
… |
… |
add_action( 'edit_form_after_title', array( 'WP_Privacy_Policy_Content', 'notice |
146 | 146 | // Add the suggested policy text from WordPress. |
147 | 147 | add_action( 'admin_init', array( 'WP_Privacy_Policy_Content', 'add_suggested_content' ), 1 ); |
148 | 148 | |
149 | | // Stop checking for text changes after the policy page is updated. |
| 149 | // Update the cached policy info when the policy page is updated. |
150 | 150 | add_action( 'post_updated', array( 'WP_Privacy_Policy_Content', '_policy_page_updated' ) ); |
diff --git src/wp-admin/includes/misc.php src/wp-admin/includes/misc.php
index ff8e78a98e..75539c6494 100644
|
|
final class WP_Privacy_Policy_Content { |
1320 | 1320 | |
1321 | 1321 | // The site doesn't have a privacy policy. |
1322 | 1322 | if ( empty( $policy_page_id ) ) { |
1323 | | return; |
| 1323 | return false; |
1324 | 1324 | } |
1325 | 1325 | |
1326 | 1326 | if ( ! current_user_can( 'edit_post', $policy_page_id ) ) { |
1327 | | return; |
| 1327 | return false; |
1328 | 1328 | } |
1329 | 1329 | |
1330 | | // Also run when the option doesn't exist yet. |
1331 | | if ( get_option( '_wp_privacy_text_change_check' ) === 'no-check' ) { |
1332 | | return; |
| 1330 | $old = (array) get_post_meta( $policy_page_id, '_wp_suggested_privacy_policy_content' ); |
| 1331 | |
| 1332 | // Updates are not relevant if the user has not reviewed any suggestions yet. |
| 1333 | if ( empty( $old ) ) { |
| 1334 | return false; |
| 1335 | } |
| 1336 | |
| 1337 | $cached = get_option( '_wp_suggested_policy_text_has_changed' ); |
| 1338 | |
| 1339 | /* |
| 1340 | * When this function is called before `admin_init`, `self::$policy_content` |
| 1341 | * has not been populated yet, so use the cached result from the last |
| 1342 | * execution instead. |
| 1343 | */ |
| 1344 | if ( ! did_action( 'admin_init' ) ) { |
| 1345 | return 'changed' === $cached; |
1333 | 1346 | } |
1334 | 1347 | |
1335 | | $old = (array) get_post_meta( $policy_page_id, '_wp_suggested_privacy_policy_content' ); |
1336 | 1348 | $new = self::$policy_content; |
1337 | 1349 | |
1338 | 1350 | // Remove the extra values added to the meta. |
1339 | 1351 | foreach ( $old as $key => $data ) { |
| 1352 | if ( ! empty( $data['removed'] ) ) { |
| 1353 | unset( $old[ $key ] ); |
| 1354 | continue; |
| 1355 | } |
| 1356 | |
1340 | 1357 | $old[ $key ] = array( |
1341 | 1358 | 'plugin_name' => $data['plugin_name'], |
1342 | 1359 | 'policy_text' => $data['policy_text'], |
… |
… |
final class WP_Privacy_Policy_Content { |
1347 | 1364 | // See http://php.net/manual/en/language.operators.array.php |
1348 | 1365 | if ( $new != $old ) { |
1349 | 1366 | // A plugin was activated or deactivated, or some policy text has changed. |
1350 | | // Show a notice on all screens in wp-admin. |
| 1367 | // Show a notice on the relevant screens to inform the admin. |
1351 | 1368 | add_action( 'admin_notices', array( 'WP_Privacy_Policy_Content', 'policy_text_changed_notice' ) ); |
| 1369 | $state = 'changed'; |
1352 | 1370 | } else { |
1353 | | // Stop checking. |
1354 | | update_option( '_wp_privacy_text_change_check', 'no-check' ); |
| 1371 | $state = 'not-changed'; |
| 1372 | } |
| 1373 | |
| 1374 | // Cache the result for use before `admin_init` (see above). |
| 1375 | if ( $cached !== $state ) { |
| 1376 | update_option( '_wp_suggested_policy_text_has_changed', $state ); |
1355 | 1377 | } |
| 1378 | |
| 1379 | return 'changed' === $state; |
1356 | 1380 | } |
1357 | 1381 | |
1358 | 1382 | /** |
1359 | | * Output an admin notice when some privacy info has changed. |
| 1383 | * Output a warning when some privacy info has changed. |
1360 | 1384 | * |
1361 | 1385 | * @since 4.9.6 |
1362 | 1386 | */ |
1363 | 1387 | public static function policy_text_changed_notice() { |
1364 | 1388 | global $post; |
1365 | | $policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' ); |
| 1389 | |
| 1390 | $screen = get_current_screen()->id; |
| 1391 | $policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' ); |
| 1392 | $editing_privacy_page = 'page' === $screen && ! empty( $post->ID ) && (int) $post->ID === $policy_page_id; |
| 1393 | |
| 1394 | if ( 'privacy' !== $screen && ! $editing_privacy_page ) { |
| 1395 | return; |
| 1396 | } |
1366 | 1397 | |
1367 | 1398 | ?> |
1368 | 1399 | <div class="policy-text-updated notice notice-warning is-dismissible"> |
1369 | 1400 | <p><?php |
1370 | | |
1371 | | _e( 'The suggested privacy policy text has changed.' ); |
1372 | | |
1373 | | if ( empty( $post ) || $post->ID != $policy_page_id ) { |
1374 | | ?> |
1375 | | <a href="<?php echo get_edit_post_link( $policy_page_id ); ?>"><?php _e( 'Edit the privacy policy.' ); ?></a> |
1376 | | <?php |
1377 | | } |
1378 | | |
| 1401 | _e( 'The suggested privacy policy text has changed. Please update your privacy policy.' ); |
1379 | 1402 | ?></p> |
1380 | 1403 | </div> |
1381 | 1404 | <?php |
1382 | 1405 | } |
1383 | 1406 | |
1384 | 1407 | /** |
1385 | | * Stop checking for changed privacy info when the policy page is updated. |
| 1408 | * Update the cached policy info when the policy page is updated. |
1386 | 1409 | * |
1387 | 1410 | * @since 4.9.6 |
1388 | 1411 | * @access private |
… |
… |
final class WP_Privacy_Policy_Content { |
1394 | 1417 | return; |
1395 | 1418 | } |
1396 | 1419 | |
1397 | | // The policy page was updated. |
1398 | | // Stop checking for text changes. |
1399 | | update_option( '_wp_privacy_text_change_check', 'no-check' ); |
1400 | | |
1401 | 1420 | // Remove updated|removed status. |
1402 | 1421 | $old = (array) get_post_meta( $policy_page_id, '_wp_suggested_privacy_policy_content' ); |
1403 | 1422 | $done = array(); |
… |
… |
final class WP_Privacy_Policy_Content { |
1496 | 1515 | foreach ( $new as $new_data ) { |
1497 | 1516 | if ( ! empty( $new_data['plugin_name'] ) && ! empty( $new_data['policy_text'] ) ) { |
1498 | 1517 | $new_data['added'] = $time; |
1499 | | array_unshift( $checked, $new_data ); |
| 1518 | $checked[] = $new_data; |
1500 | 1519 | } |
1501 | 1520 | } |
1502 | 1521 | $update_cache = true; |
… |
… |
final class WP_Privacy_Policy_Content { |
1511 | 1530 | 'policy_text' => $old_data['policy_text'], |
1512 | 1531 | 'removed' => $time, |
1513 | 1532 | ); |
1514 | | array_unshift( $checked, $data ); |
| 1533 | |
| 1534 | $checked[] = $data; |
1515 | 1535 | } |
1516 | 1536 | } |
1517 | 1537 | $update_cache = true; |
… |
… |
final class WP_Privacy_Policy_Content { |
1525 | 1545 | } |
1526 | 1546 | } |
1527 | 1547 | |
1528 | | // Stop checking for changes after the page has been loaded. |
1529 | | if ( get_option( '_wp_privacy_text_change_check' ) !== 'no-check' ) { |
1530 | | update_option( '_wp_privacy_text_change_check', 'no-check' ); |
1531 | | } |
1532 | | |
1533 | 1548 | return $checked; |
1534 | 1549 | } |
1535 | 1550 | |
diff --git src/wp-admin/menu.php src/wp-admin/menu.php
index 0ad302ebda..bf9eb72abb 100644
|
|
if ( ! is_multisite() && defined( 'WP_ALLOW_MULTISITE' ) && WP_ALLOW_MULTISITE ) |
263 | 263 | $submenu['tools.php'][50] = array( __( 'Network Setup' ), 'setup_network', 'network.php' ); |
264 | 264 | } |
265 | 265 | |
266 | | $menu[80] = array( __( 'Settings' ), 'manage_options', 'options-general.php', '', 'menu-top menu-icon-settings', 'menu-settings', 'dashicons-admin-settings' ); |
| 266 | $change_notice = ''; |
| 267 | if ( current_user_can( 'manage_privacy_options' ) && WP_Privacy_Policy_Content::text_change_check() ) { |
| 268 | $change_notice = ' <span class="update-plugins 1"><span class="plugin-count">' . number_format_i18n( 1 ) . '</span></span>'; |
| 269 | } |
| 270 | |
| 271 | // translators: %s is the update notification bubble, if updates are available. |
| 272 | $menu[80] = array( sprintf( __( 'Settings %s' ), $change_notice ), 'manage_options', 'options-general.php', '', 'menu-top menu-icon-settings', 'menu-settings', 'dashicons-admin-settings' ); |
267 | 273 | $submenu['options-general.php'][10] = array( _x( 'General', 'settings screen' ), 'manage_options', 'options-general.php' ); |
268 | 274 | $submenu['options-general.php'][15] = array( __( 'Writing' ), 'manage_options', 'options-writing.php' ); |
269 | 275 | $submenu['options-general.php'][20] = array( __( 'Reading' ), 'manage_options', 'options-reading.php' ); |
270 | 276 | $submenu['options-general.php'][25] = array( __( 'Discussion' ), 'manage_options', 'options-discussion.php' ); |
271 | 277 | $submenu['options-general.php'][30] = array( __( 'Media' ), 'manage_options', 'options-media.php' ); |
272 | 278 | $submenu['options-general.php'][40] = array( __( 'Permalinks' ), 'manage_options', 'options-permalink.php' ); |
273 | | $submenu['options-general.php'][45] = array( __( 'Privacy' ), 'manage_privacy_options', 'privacy.php' ); |
| 279 | // translators: %s is the update notification bubble, if updates are available. |
| 280 | $submenu['options-general.php'][45] = array( sprintf( __( 'Privacy %s' ), $change_notice ), 'manage_privacy_options', 'privacy.php' ); |
274 | 281 | |
275 | 282 | $_wp_last_utility_menu = 80; // The index of the last top-level menu in the utility menu group |
276 | 283 | |
diff --git src/wp-includes/default-filters.php src/wp-includes/default-filters.php
index 7ecff3ade1..61c45e6231 100644
|
|
add_filter( 'pre_oembed_result', 'wp_filter_pre_oembed_result', 10, 3 ); |
562 | 562 | // Capabilities |
563 | 563 | add_filter( 'user_has_cap', 'wp_maybe_grant_install_languages_cap', 1 ); |
564 | 564 | |
565 | | // Trigger the check for policy text changes after active plugins change. |
566 | | add_action( 'update_site_option_active_sitewide_plugins', '_wp_privacy_active_plugins_change' ); |
567 | | add_action( 'update_option_active_plugins', '_wp_privacy_active_plugins_change' ); |
568 | | |
569 | 565 | unset( $filter, $action ); |
diff --git src/wp-includes/functions.php src/wp-includes/functions.php
index 341a1746d9..763b98df28 100644
|
|
function wp_privacy_anonymize_data( $type, $data = '' ) { |
6248 | 6248 | return apply_filters( 'wp_privacy_anonymize_data', $anonymous, $type, $data ); |
6249 | 6249 | } |
6250 | 6250 | |
6251 | | /** |
6252 | | * Trigger the check for policy text changes. |
6253 | | * |
6254 | | * @since 4.9.6 |
6255 | | * @access private |
6256 | | */ |
6257 | | function _wp_privacy_active_plugins_change() { |
6258 | | update_option( '_wp_privacy_text_change_check', 'check' ); |
6259 | | } |
6260 | | |
6261 | 6251 | /** |
6262 | 6252 | * Schedule a `WP_Cron` job to delete expired export files. |
6263 | 6253 | * |