changeset 9 | 177826044cd9 |
parent 7 | cf61fcea0001 |
child 16 | a86126ab1dd4 |
8:c7c34916027a | 9:177826044cd9 |
---|---|
12 * @since 2.0.0 |
12 * @since 2.0.0 |
13 * |
13 * |
14 * @return bool |
14 * @return bool |
15 */ |
15 */ |
16 function got_mod_rewrite() { |
16 function got_mod_rewrite() { |
17 $got_rewrite = apache_mod_loaded('mod_rewrite', true); |
17 $got_rewrite = apache_mod_loaded( 'mod_rewrite', true ); |
18 |
18 |
19 /** |
19 /** |
20 * Filters whether Apache and mod_rewrite are present. |
20 * Filters whether Apache and mod_rewrite are present. |
21 * |
21 * |
22 * This filter was previously used to force URL rewriting for other servers, |
22 * This filter was previously used to force URL rewriting for other servers, |
63 * @param string $filename |
63 * @param string $filename |
64 * @param string $marker |
64 * @param string $marker |
65 * @return array An array of strings from a file (.htaccess ) from between BEGIN and END markers. |
65 * @return array An array of strings from a file (.htaccess ) from between BEGIN and END markers. |
66 */ |
66 */ |
67 function extract_from_markers( $filename, $marker ) { |
67 function extract_from_markers( $filename, $marker ) { |
68 $result = array (); |
68 $result = array(); |
69 |
69 |
70 if ( ! file_exists( $filename ) ) { |
70 if ( ! file_exists( $filename ) ) { |
71 return $result; |
71 return $result; |
72 } |
72 } |
73 |
73 |
134 while ( ! feof( $fp ) ) { |
134 while ( ! feof( $fp ) ) { |
135 $lines[] = rtrim( fgets( $fp ), "\r\n" ); |
135 $lines[] = rtrim( fgets( $fp ), "\r\n" ); |
136 } |
136 } |
137 |
137 |
138 // Split out the existing file into the preceding lines, and those that appear after the marker |
138 // Split out the existing file into the preceding lines, and those that appear after the marker |
139 $pre_lines = $post_lines = $existing_lines = array(); |
139 $pre_lines = $post_lines = $existing_lines = array(); |
140 $found_marker = $found_end_marker = false; |
140 $found_marker = $found_end_marker = false; |
141 foreach ( $lines as $line ) { |
141 foreach ( $lines as $line ) { |
142 if ( ! $found_marker && false !== strpos( $line, $start_marker ) ) { |
142 if ( ! $found_marker && false !== strpos( $line, $start_marker ) ) { |
143 $found_marker = true; |
143 $found_marker = true; |
144 continue; |
144 continue; |
162 |
162 |
163 return true; |
163 return true; |
164 } |
164 } |
165 |
165 |
166 // Generate the new file data |
166 // Generate the new file data |
167 $new_file_data = implode( "\n", array_merge( |
167 $new_file_data = implode( |
168 $pre_lines, |
168 "\n", |
169 array( $start_marker ), |
169 array_merge( |
170 $insertion, |
170 $pre_lines, |
171 array( $end_marker ), |
171 array( $start_marker ), |
172 $post_lines |
172 $insertion, |
173 ) ); |
173 array( $end_marker ), |
174 $post_lines |
|
175 ) |
|
176 ); |
|
174 |
177 |
175 // Write to the start of the file, and truncate it to that length |
178 // Write to the start of the file, and truncate it to that length |
176 fseek( $fp, 0 ); |
179 fseek( $fp, 0 ); |
177 $bytes = fwrite( $fp, $new_file_data ); |
180 $bytes = fwrite( $fp, $new_file_data ); |
178 if ( $bytes ) { |
181 if ( $bytes ) { |
196 * @global WP_Rewrite $wp_rewrite |
199 * @global WP_Rewrite $wp_rewrite |
197 * |
200 * |
198 * @return bool|null True on write success, false on failure. Null in multisite. |
201 * @return bool|null True on write success, false on failure. Null in multisite. |
199 */ |
202 */ |
200 function save_mod_rewrite_rules() { |
203 function save_mod_rewrite_rules() { |
201 if ( is_multisite() ) |
204 if ( is_multisite() ) { |
202 return; |
205 return; |
206 } |
|
203 |
207 |
204 global $wp_rewrite; |
208 global $wp_rewrite; |
205 |
209 |
206 // Ensure get_home_path() is declared. |
210 // Ensure get_home_path() is declared. |
207 require_once( ABSPATH . 'wp-admin/includes/file.php' ); |
211 require_once( ABSPATH . 'wp-admin/includes/file.php' ); |
211 |
215 |
212 /* |
216 /* |
213 * If the file doesn't already exist check for write access to the directory |
217 * If the file doesn't already exist check for write access to the directory |
214 * and whether we have some rules. Else check for write access to the file. |
218 * and whether we have some rules. Else check for write access to the file. |
215 */ |
219 */ |
216 if ((!file_exists($htaccess_file) && is_writable($home_path) && $wp_rewrite->using_mod_rewrite_permalinks()) || is_writable($htaccess_file)) { |
220 if ( ( ! file_exists( $htaccess_file ) && is_writable( $home_path ) && $wp_rewrite->using_mod_rewrite_permalinks() ) || is_writable( $htaccess_file ) ) { |
217 if ( got_mod_rewrite() ) { |
221 if ( got_mod_rewrite() ) { |
218 $rules = explode( "\n", $wp_rewrite->mod_rewrite_rules() ); |
222 $rules = explode( "\n", $wp_rewrite->mod_rewrite_rules() ); |
219 return insert_with_markers( $htaccess_file, 'WordPress', $rules ); |
223 return insert_with_markers( $htaccess_file, 'WordPress', $rules ); |
220 } |
224 } |
221 } |
225 } |
231 * |
235 * |
232 * @global WP_Rewrite $wp_rewrite |
236 * @global WP_Rewrite $wp_rewrite |
233 * |
237 * |
234 * @return bool|null True on write success, false on failure. Null in multisite. |
238 * @return bool|null True on write success, false on failure. Null in multisite. |
235 */ |
239 */ |
236 function iis7_save_url_rewrite_rules(){ |
240 function iis7_save_url_rewrite_rules() { |
237 if ( is_multisite() ) |
241 if ( is_multisite() ) { |
238 return; |
242 return; |
243 } |
|
239 |
244 |
240 global $wp_rewrite; |
245 global $wp_rewrite; |
241 |
246 |
242 // Ensure get_home_path() is declared. |
247 // Ensure get_home_path() is declared. |
243 require_once( ABSPATH . 'wp-admin/includes/file.php' ); |
248 require_once( ABSPATH . 'wp-admin/includes/file.php' ); |
244 |
249 |
245 $home_path = get_home_path(); |
250 $home_path = get_home_path(); |
246 $web_config_file = $home_path . 'web.config'; |
251 $web_config_file = $home_path . 'web.config'; |
247 |
252 |
248 // Using win_is_writable() instead of is_writable() because of a bug in Windows PHP |
253 // Using win_is_writable() instead of is_writable() because of a bug in Windows PHP |
249 if ( iis7_supports_permalinks() && ( ( ! file_exists($web_config_file) && win_is_writable($home_path) && $wp_rewrite->using_mod_rewrite_permalinks() ) || win_is_writable($web_config_file) ) ) { |
254 if ( iis7_supports_permalinks() && ( ( ! file_exists( $web_config_file ) && win_is_writable( $home_path ) && $wp_rewrite->using_mod_rewrite_permalinks() ) || win_is_writable( $web_config_file ) ) ) { |
250 $rule = $wp_rewrite->iis7_url_rewrite_rules(false, '', ''); |
255 $rule = $wp_rewrite->iis7_url_rewrite_rules( false ); |
251 if ( ! empty($rule) ) { |
256 if ( ! empty( $rule ) ) { |
252 return iis7_add_rewrite_rule($web_config_file, $rule); |
257 return iis7_add_rewrite_rule( $web_config_file, $rule ); |
253 } else { |
258 } else { |
254 return iis7_delete_rewrite_rule($web_config_file); |
259 return iis7_delete_rewrite_rule( $web_config_file ); |
255 } |
260 } |
256 } |
261 } |
257 return false; |
262 return false; |
258 } |
263 } |
259 |
264 |
263 * @since 1.5.0 |
268 * @since 1.5.0 |
264 * |
269 * |
265 * @param string $file |
270 * @param string $file |
266 */ |
271 */ |
267 function update_recently_edited( $file ) { |
272 function update_recently_edited( $file ) { |
268 $oldfiles = (array ) get_option( 'recently_edited' ); |
273 $oldfiles = (array) get_option( 'recently_edited' ); |
269 if ( $oldfiles ) { |
274 if ( $oldfiles ) { |
270 $oldfiles = array_reverse( $oldfiles ); |
275 $oldfiles = array_reverse( $oldfiles ); |
271 $oldfiles[] = $file; |
276 $oldfiles[] = $file; |
272 $oldfiles = array_reverse( $oldfiles ); |
277 $oldfiles = array_reverse( $oldfiles ); |
273 $oldfiles = array_unique( $oldfiles ); |
278 $oldfiles = array_unique( $oldfiles ); |
274 if ( 5 < count( $oldfiles )) |
279 if ( 5 < count( $oldfiles ) ) { |
275 array_pop( $oldfiles ); |
280 array_pop( $oldfiles ); |
281 } |
|
276 } else { |
282 } else { |
277 $oldfiles[] = $file; |
283 $oldfiles[] = $file; |
278 } |
284 } |
279 update_option( 'recently_edited', $oldfiles ); |
285 update_option( 'recently_edited', $oldfiles ); |
280 } |
286 } |
281 |
287 |
282 /** |
288 /** |
283 * Makes a tree structure for the Theme Editor's file list. |
289 * Makes a tree structure for the theme editor's file list. |
284 * |
290 * |
285 * @since 4.9.0 |
291 * @since 4.9.0 |
286 * @access private |
292 * @access private |
287 * |
293 * |
288 * @param array $allowed_files List of theme file paths. |
294 * @param array $allowed_files List of theme file paths. |
289 * @return array Tree structure for listing theme files. |
295 * @return array Tree structure for listing theme files. |
290 */ |
296 */ |
291 function wp_make_theme_file_tree( $allowed_files ) { |
297 function wp_make_theme_file_tree( $allowed_files ) { |
292 $tree_list = array(); |
298 $tree_list = array(); |
293 foreach ( $allowed_files as $file_name => $absolute_filename ) { |
299 foreach ( $allowed_files as $file_name => $absolute_filename ) { |
294 $list = explode( '/', $file_name ); |
300 $list = explode( '/', $file_name ); |
295 $last_dir = &$tree_list; |
301 $last_dir = &$tree_list; |
296 foreach ( $list as $dir ) { |
302 foreach ( $list as $dir ) { |
297 $last_dir =& $last_dir[ $dir ]; |
303 $last_dir =& $last_dir[ $dir ]; |
298 } |
304 } |
299 $last_dir = $file_name; |
305 $last_dir = $file_name; |
300 } |
306 } |
301 return $tree_list; |
307 return $tree_list; |
302 } |
308 } |
303 |
309 |
304 /** |
310 /** |
305 * Outputs the formatted file list for the Theme Editor. |
311 * Outputs the formatted file list for the theme editor. |
306 * |
312 * |
307 * @since 4.9.0 |
313 * @since 4.9.0 |
308 * @access private |
314 * @access private |
315 * |
|
316 * @global string $relative_file Name of the file being edited relative to the |
|
317 * theme directory. |
|
318 * @global string $stylesheet The stylesheet name of the theme being edited. |
|
309 * |
319 * |
310 * @param array|string $tree List of file/folder paths, or filename. |
320 * @param array|string $tree List of file/folder paths, or filename. |
311 * @param int $level The aria-level for the current iteration. |
321 * @param int $level The aria-level for the current iteration. |
312 * @param int $size The aria-setsize for the current iteration. |
322 * @param int $size The aria-setsize for the current iteration. |
313 * @param int $index The aria-posinset for the current iteration. |
323 * @param int $index The aria-posinset for the current iteration. |
315 function wp_print_theme_file_tree( $tree, $level = 2, $size = 1, $index = 1 ) { |
325 function wp_print_theme_file_tree( $tree, $level = 2, $size = 1, $index = 1 ) { |
316 global $relative_file, $stylesheet; |
326 global $relative_file, $stylesheet; |
317 |
327 |
318 if ( is_array( $tree ) ) { |
328 if ( is_array( $tree ) ) { |
319 $index = 0; |
329 $index = 0; |
320 $size = count( $tree ); |
330 $size = count( $tree ); |
321 foreach ( $tree as $label => $theme_file ) : |
331 foreach ( $tree as $label => $theme_file ) : |
322 $index++; |
332 $index++; |
323 if ( ! is_array( $theme_file ) ) { |
333 if ( ! is_array( $theme_file ) ) { |
324 wp_print_theme_file_tree( $theme_file, $level, $index, $size ); |
334 wp_print_theme_file_tree( $theme_file, $level, $index, $size ); |
325 continue; |
335 continue; |
334 </li> |
344 </li> |
335 <?php |
345 <?php |
336 endforeach; |
346 endforeach; |
337 } else { |
347 } else { |
338 $filename = $tree; |
348 $filename = $tree; |
339 $url = add_query_arg( |
349 $url = add_query_arg( |
340 array( |
350 array( |
341 'file' => rawurlencode( $tree ), |
351 'file' => rawurlencode( $tree ), |
342 'theme' => rawurlencode( $stylesheet ), |
352 'theme' => rawurlencode( $stylesheet ), |
343 ), |
353 ), |
344 self_admin_url( 'theme-editor.php' ) |
354 self_admin_url( 'theme-editor.php' ) |
345 ); |
355 ); |
346 ?> |
356 ?> |
350 aria-level="<?php echo esc_attr( $level ); ?>" |
360 aria-level="<?php echo esc_attr( $level ); ?>" |
351 aria-setsize="<?php echo esc_attr( $size ); ?>" |
361 aria-setsize="<?php echo esc_attr( $size ); ?>" |
352 aria-posinset="<?php echo esc_attr( $index ); ?>"> |
362 aria-posinset="<?php echo esc_attr( $index ); ?>"> |
353 <?php |
363 <?php |
354 $file_description = esc_html( get_file_description( $filename ) ); |
364 $file_description = esc_html( get_file_description( $filename ) ); |
355 if ( $file_description !== $filename && basename( $filename ) !== $file_description ) { |
365 if ( $file_description !== $filename && wp_basename( $filename ) !== $file_description ) { |
356 $file_description .= '<br /><span class="nonessential">(' . esc_html( $filename ) . ')</span>'; |
366 $file_description .= '<br /><span class="nonessential">(' . esc_html( $filename ) . ')</span>'; |
357 } |
367 } |
358 |
368 |
359 if ( $relative_file === $filename ) { |
369 if ( $relative_file === $filename ) { |
360 echo '<span class="notice notice-info">' . $file_description . '</span>'; |
370 echo '<span class="notice notice-info">' . $file_description . '</span>'; |
367 <?php |
377 <?php |
368 } |
378 } |
369 } |
379 } |
370 |
380 |
371 /** |
381 /** |
372 * Makes a tree structure for the Plugin Editor's file list. |
382 * Makes a tree structure for the plugin editor's file list. |
373 * |
383 * |
374 * @since 4.9.0 |
384 * @since 4.9.0 |
375 * @access private |
385 * @access private |
376 * |
386 * |
377 * @param string $plugin_editable_files List of plugin file paths. |
387 * @param array $plugin_editable_files List of plugin file paths. |
378 * @return array Tree structure for listing plugin files. |
388 * @return array Tree structure for listing plugin files. |
379 */ |
389 */ |
380 function wp_make_plugin_file_tree( $plugin_editable_files ) { |
390 function wp_make_plugin_file_tree( $plugin_editable_files ) { |
381 $tree_list = array(); |
391 $tree_list = array(); |
382 foreach ( $plugin_editable_files as $plugin_file ) { |
392 foreach ( $plugin_editable_files as $plugin_file ) { |
383 $list = explode( '/', preg_replace( '#^.+?/#', '', $plugin_file ) ); |
393 $list = explode( '/', preg_replace( '#^.+?/#', '', $plugin_file ) ); |
384 $last_dir = &$tree_list; |
394 $last_dir = &$tree_list; |
385 foreach ( $list as $dir ) { |
395 foreach ( $list as $dir ) { |
386 $last_dir =& $last_dir[ $dir ]; |
396 $last_dir =& $last_dir[ $dir ]; |
387 } |
397 } |
388 $last_dir = $plugin_file; |
398 $last_dir = $plugin_file; |
389 } |
399 } |
390 return $tree_list; |
400 return $tree_list; |
391 } |
401 } |
392 |
402 |
393 /** |
403 /** |
394 * Outputs the formatted file list for the Plugin Editor. |
404 * Outputs the formatted file list for the plugin editor. |
395 * |
405 * |
396 * @since 4.9.0 |
406 * @since 4.9.0 |
397 * @access private |
407 * @access private |
398 * |
408 * |
399 * @param array|string $tree List of file/folder paths, or filename. |
409 * @param array|string $tree List of file/folder paths, or filename. |
404 */ |
414 */ |
405 function wp_print_plugin_file_tree( $tree, $label = '', $level = 2, $size = 1, $index = 1 ) { |
415 function wp_print_plugin_file_tree( $tree, $label = '', $level = 2, $size = 1, $index = 1 ) { |
406 global $file, $plugin; |
416 global $file, $plugin; |
407 if ( is_array( $tree ) ) { |
417 if ( is_array( $tree ) ) { |
408 $index = 0; |
418 $index = 0; |
409 $size = count( $tree ); |
419 $size = count( $tree ); |
410 foreach ( $tree as $label => $plugin_file ) : |
420 foreach ( $tree as $label => $plugin_file ) : |
411 $index++; |
421 $index++; |
412 if ( ! is_array( $plugin_file ) ) { |
422 if ( ! is_array( $plugin_file ) ) { |
413 wp_print_plugin_file_tree( $plugin_file, $label, $level, $index, $size ); |
423 wp_print_plugin_file_tree( $plugin_file, $label, $level, $index, $size ); |
414 continue; |
424 continue; |
424 <?php |
434 <?php |
425 endforeach; |
435 endforeach; |
426 } else { |
436 } else { |
427 $url = add_query_arg( |
437 $url = add_query_arg( |
428 array( |
438 array( |
429 'file' => rawurlencode( $tree ), |
439 'file' => rawurlencode( $tree ), |
430 'plugin' => rawurlencode( $plugin ), |
440 'plugin' => rawurlencode( $plugin ), |
431 ), |
441 ), |
432 self_admin_url( 'plugin-editor.php' ) |
442 self_admin_url( 'plugin-editor.php' ) |
433 ); |
443 ); |
434 ?> |
444 ?> |
458 * |
468 * |
459 * @param string $old_value |
469 * @param string $old_value |
460 * @param string $value |
470 * @param string $value |
461 */ |
471 */ |
462 function update_home_siteurl( $old_value, $value ) { |
472 function update_home_siteurl( $old_value, $value ) { |
463 if ( wp_installing() ) |
473 if ( wp_installing() ) { |
464 return; |
474 return; |
475 } |
|
465 |
476 |
466 if ( is_multisite() && ms_is_switched() ) { |
477 if ( is_multisite() && ms_is_switched() ) { |
467 delete_option( 'rewrite_rules' ); |
478 delete_option( 'rewrite_rules' ); |
468 } else { |
479 } else { |
469 flush_rewrite_rules(); |
480 flush_rewrite_rules(); |
501 * |
512 * |
502 * @since 2.1.0 |
513 * @since 2.1.0 |
503 * |
514 * |
504 * @param string|WP_Error $message |
515 * @param string|WP_Error $message |
505 */ |
516 */ |
506 function show_message($message) { |
517 function show_message( $message ) { |
507 if ( is_wp_error($message) ){ |
518 if ( is_wp_error( $message ) ) { |
508 if ( $message->get_error_data() && is_string( $message->get_error_data() ) ) |
519 if ( $message->get_error_data() && is_string( $message->get_error_data() ) ) { |
509 $message = $message->get_error_message() . ': ' . $message->get_error_data(); |
520 $message = $message->get_error_message() . ': ' . $message->get_error_data(); |
510 else |
521 } else { |
511 $message = $message->get_error_message(); |
522 $message = $message->get_error_message(); |
523 } |
|
512 } |
524 } |
513 echo "<p>$message</p>\n"; |
525 echo "<p>$message</p>\n"; |
514 wp_ob_end_flush_all(); |
526 wp_ob_end_flush_all(); |
515 flush(); |
527 flush(); |
516 } |
528 } |
520 * |
532 * |
521 * @param string $content |
533 * @param string $content |
522 * @return array |
534 * @return array |
523 */ |
535 */ |
524 function wp_doc_link_parse( $content ) { |
536 function wp_doc_link_parse( $content ) { |
525 if ( !is_string( $content ) || empty( $content ) ) |
537 if ( ! is_string( $content ) || empty( $content ) ) { |
526 return array(); |
538 return array(); |
527 |
539 } |
528 if ( !function_exists('token_get_all') ) |
540 |
541 if ( ! function_exists( 'token_get_all' ) ) { |
|
529 return array(); |
542 return array(); |
530 |
543 } |
531 $tokens = token_get_all( $content ); |
544 |
532 $count = count( $tokens ); |
545 $tokens = token_get_all( $content ); |
533 $functions = array(); |
546 $count = count( $tokens ); |
547 $functions = array(); |
|
534 $ignore_functions = array(); |
548 $ignore_functions = array(); |
535 for ( $t = 0; $t < $count - 2; $t++ ) { |
549 for ( $t = 0; $t < $count - 2; $t++ ) { |
536 if ( ! is_array( $tokens[ $t ] ) ) { |
550 if ( ! is_array( $tokens[ $t ] ) ) { |
537 continue; |
551 continue; |
538 } |
552 } |
539 |
553 |
540 if ( T_STRING == $tokens[ $t ][0] && ( '(' == $tokens[ $t + 1 ] || '(' == $tokens[ $t + 2 ] ) ) { |
554 if ( T_STRING == $tokens[ $t ][0] && ( '(' == $tokens[ $t + 1 ] || '(' == $tokens[ $t + 2 ] ) ) { |
541 // If it's a function or class defined locally, there's not going to be any docs available |
555 // If it's a function or class defined locally, there's not going to be any docs available |
542 if ( ( isset( $tokens[ $t - 2 ][1] ) && in_array( $tokens[ $t - 2 ][1], array( 'function', 'class' ) ) ) || ( isset( $tokens[ $t - 2 ][0] ) && T_OBJECT_OPERATOR == $tokens[ $t - 1 ][0] ) ) { |
556 if ( ( isset( $tokens[ $t - 2 ][1] ) && in_array( $tokens[ $t - 2 ][1], array( 'function', 'class' ) ) ) || ( isset( $tokens[ $t - 2 ][0] ) && T_OBJECT_OPERATOR == $tokens[ $t - 1 ][0] ) ) { |
543 $ignore_functions[] = $tokens[$t][1]; |
557 $ignore_functions[] = $tokens[ $t ][1]; |
544 } |
558 } |
545 // Add this to our stack of unique references |
559 // Add this to our stack of unique references |
546 $functions[] = $tokens[$t][1]; |
560 $functions[] = $tokens[ $t ][1]; |
547 } |
561 } |
548 } |
562 } |
549 |
563 |
550 $functions = array_unique( $functions ); |
564 $functions = array_unique( $functions ); |
551 sort( $functions ); |
565 sort( $functions ); |
553 /** |
567 /** |
554 * Filters the list of functions and classes to be ignored from the documentation lookup. |
568 * Filters the list of functions and classes to be ignored from the documentation lookup. |
555 * |
569 * |
556 * @since 2.8.0 |
570 * @since 2.8.0 |
557 * |
571 * |
558 * @param array $ignore_functions Functions and classes to be ignored. |
572 * @param string[] $ignore_functions Array of names of functions and classes to be ignored. |
559 */ |
573 */ |
560 $ignore_functions = apply_filters( 'documentation_ignore_functions', $ignore_functions ); |
574 $ignore_functions = apply_filters( 'documentation_ignore_functions', $ignore_functions ); |
561 |
575 |
562 $ignore_functions = array_unique( $ignore_functions ); |
576 $ignore_functions = array_unique( $ignore_functions ); |
563 |
577 |
564 $out = array(); |
578 $out = array(); |
565 foreach ( $functions as $function ) { |
579 foreach ( $functions as $function ) { |
566 if ( in_array( $function, $ignore_functions ) ) |
580 if ( in_array( $function, $ignore_functions ) ) { |
567 continue; |
581 continue; |
582 } |
|
568 $out[] = $function; |
583 $out[] = $function; |
569 } |
584 } |
570 |
585 |
571 return $out; |
586 return $out; |
572 } |
587 } |
576 * |
591 * |
577 * @since 2.8.0 |
592 * @since 2.8.0 |
578 */ |
593 */ |
579 function set_screen_options() { |
594 function set_screen_options() { |
580 |
595 |
581 if ( isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options']) ) { |
596 if ( isset( $_POST['wp_screen_options'] ) && is_array( $_POST['wp_screen_options'] ) ) { |
582 check_admin_referer( 'screen-options-nonce', 'screenoptionnonce' ); |
597 check_admin_referer( 'screen-options-nonce', 'screenoptionnonce' ); |
583 |
598 |
584 if ( !$user = wp_get_current_user() ) |
599 if ( ! $user = wp_get_current_user() ) { |
585 return; |
600 return; |
601 } |
|
586 $option = $_POST['wp_screen_options']['option']; |
602 $option = $_POST['wp_screen_options']['option']; |
587 $value = $_POST['wp_screen_options']['value']; |
603 $value = $_POST['wp_screen_options']['value']; |
588 |
604 |
589 if ( $option != sanitize_key( $option ) ) |
605 if ( $option != sanitize_key( $option ) ) { |
590 return; |
606 return; |
607 } |
|
591 |
608 |
592 $map_option = $option; |
609 $map_option = $option; |
593 $type = str_replace('edit_', '', $map_option); |
610 $type = str_replace( 'edit_', '', $map_option ); |
594 $type = str_replace('_per_page', '', $type); |
611 $type = str_replace( '_per_page', '', $type ); |
595 if ( in_array( $type, get_taxonomies() ) ) |
612 if ( in_array( $type, get_taxonomies() ) ) { |
596 $map_option = 'edit_tags_per_page'; |
613 $map_option = 'edit_tags_per_page'; |
597 elseif ( in_array( $type, get_post_types() ) ) |
614 } elseif ( in_array( $type, get_post_types() ) ) { |
598 $map_option = 'edit_per_page'; |
615 $map_option = 'edit_per_page'; |
599 else |
616 } else { |
600 $option = str_replace('-', '_', $option); |
617 $option = str_replace( '-', '_', $option ); |
618 } |
|
601 |
619 |
602 switch ( $map_option ) { |
620 switch ( $map_option ) { |
603 case 'edit_per_page': |
621 case 'edit_per_page': |
604 case 'users_per_page': |
622 case 'users_per_page': |
605 case 'edit_comments_per_page': |
623 case 'edit_comments_per_page': |
606 case 'upload_per_page': |
624 case 'upload_per_page': |
607 case 'edit_tags_per_page': |
625 case 'edit_tags_per_page': |
608 case 'plugins_per_page': |
626 case 'plugins_per_page': |
609 case 'export_personal_data_requests_per_page': |
627 case 'export_personal_data_requests_per_page': |
610 case 'remove_personal_data_requests_per_page': |
628 case 'remove_personal_data_requests_per_page': |
611 // Network admin |
629 // Network admin |
612 case 'sites_network_per_page': |
630 case 'sites_network_per_page': |
613 case 'users_network_per_page': |
631 case 'users_network_per_page': |
614 case 'site_users_network_per_page': |
632 case 'site_users_network_per_page': |
615 case 'plugins_network_per_page': |
633 case 'plugins_network_per_page': |
616 case 'themes_network_per_page': |
634 case 'themes_network_per_page': |
617 case 'site_themes_network_per_page': |
635 case 'site_themes_network_per_page': |
618 $value = (int) $value; |
636 $value = (int) $value; |
619 if ( $value < 1 || $value > 999 ) |
637 if ( $value < 1 || $value > 999 ) { |
620 return; |
638 return; |
639 } |
|
621 break; |
640 break; |
622 default: |
641 default: |
623 |
|
624 /** |
642 /** |
625 * Filters a screen option value before it is set. |
643 * Filters a screen option value before it is set. |
626 * |
644 * |
627 * The filter can also be used to modify non-standard [items]_per_page |
645 * The filter can also be used to modify non-standard [items]_per_page |
628 * settings. See the parent function for a full list of standard options. |
646 * settings. See the parent function for a full list of standard options. |
631 * |
649 * |
632 * @since 2.8.0 |
650 * @since 2.8.0 |
633 * |
651 * |
634 * @see set_screen_options() |
652 * @see set_screen_options() |
635 * |
653 * |
636 * @param bool|int $value Screen option value. Default false to skip. |
654 * @param bool $keep Whether to save or skip saving the screen option value. Default false. |
637 * @param string $option The option name. |
655 * @param string $option The option name. |
638 * @param int $value The number of rows to use. |
656 * @param int $value The number of rows to use. |
639 */ |
657 */ |
640 $value = apply_filters( 'set-screen-option', false, $option, $value ); |
658 $value = apply_filters( 'set-screen-option', false, $option, $value ); |
641 |
659 |
642 if ( false === $value ) |
660 if ( false === $value ) { |
643 return; |
661 return; |
662 } |
|
644 break; |
663 break; |
645 } |
664 } |
646 |
665 |
647 update_user_meta($user->ID, $option, $value); |
666 update_user_meta( $user->ID, $option, $value ); |
648 |
667 |
649 $url = remove_query_arg( array( 'pagenum', 'apage', 'paged' ), wp_get_referer() ); |
668 $url = remove_query_arg( array( 'pagenum', 'apage', 'paged' ), wp_get_referer() ); |
650 if ( isset( $_POST['mode'] ) ) { |
669 if ( isset( $_POST['mode'] ) ) { |
651 $url = add_query_arg( array( 'mode' => $_POST['mode'] ), $url ); |
670 $url = add_query_arg( array( 'mode' => $_POST['mode'] ), $url ); |
652 } |
671 } |
662 * @since 2.8.0 |
681 * @since 2.8.0 |
663 * |
682 * |
664 * @return bool |
683 * @return bool |
665 * @param string $filename The file path to the configuration file |
684 * @param string $filename The file path to the configuration file |
666 */ |
685 */ |
667 function iis7_rewrite_rule_exists($filename) { |
686 function iis7_rewrite_rule_exists( $filename ) { |
668 if ( ! file_exists($filename) ) |
687 if ( ! file_exists( $filename ) ) { |
669 return false; |
688 return false; |
689 } |
|
670 if ( ! class_exists( 'DOMDocument', false ) ) { |
690 if ( ! class_exists( 'DOMDocument', false ) ) { |
671 return false; |
691 return false; |
672 } |
692 } |
673 |
693 |
674 $doc = new DOMDocument(); |
694 $doc = new DOMDocument(); |
675 if ( $doc->load($filename) === false ) |
695 if ( $doc->load( $filename ) === false ) { |
676 return false; |
696 return false; |
677 $xpath = new DOMXPath($doc); |
697 } |
678 $rules = $xpath->query('/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')] | /configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WordPress\')]'); |
698 $xpath = new DOMXPath( $doc ); |
679 if ( $rules->length == 0 ) |
699 $rules = $xpath->query( '/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')] | /configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WordPress\')]' ); |
700 if ( $rules->length == 0 ) { |
|
680 return false; |
701 return false; |
681 else |
702 } else { |
682 return true; |
703 return true; |
704 } |
|
683 } |
705 } |
684 |
706 |
685 /** |
707 /** |
686 * Delete WordPress rewrite rule from web.config file if it exists there |
708 * Delete WordPress rewrite rule from web.config file if it exists there |
687 * |
709 * |
688 * @since 2.8.0 |
710 * @since 2.8.0 |
689 * |
711 * |
690 * @param string $filename Name of the configuration file |
712 * @param string $filename Name of the configuration file |
691 * @return bool |
713 * @return bool |
692 */ |
714 */ |
693 function iis7_delete_rewrite_rule($filename) { |
715 function iis7_delete_rewrite_rule( $filename ) { |
694 // If configuration file does not exist then rules also do not exist so there is nothing to delete |
716 // If configuration file does not exist then rules also do not exist so there is nothing to delete |
695 if ( ! file_exists($filename) ) |
717 if ( ! file_exists( $filename ) ) { |
696 return true; |
718 return true; |
719 } |
|
697 |
720 |
698 if ( ! class_exists( 'DOMDocument', false ) ) { |
721 if ( ! class_exists( 'DOMDocument', false ) ) { |
699 return false; |
722 return false; |
700 } |
723 } |
701 |
724 |
702 $doc = new DOMDocument(); |
725 $doc = new DOMDocument(); |
703 $doc->preserveWhiteSpace = false; |
726 $doc->preserveWhiteSpace = false; |
704 |
727 |
705 if ( $doc -> load($filename) === false ) |
728 if ( $doc->load( $filename ) === false ) { |
706 return false; |
729 return false; |
707 $xpath = new DOMXPath($doc); |
730 } |
708 $rules = $xpath->query('/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')] | /configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WordPress\')]'); |
731 $xpath = new DOMXPath( $doc ); |
732 $rules = $xpath->query( '/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')] | /configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WordPress\')]' ); |
|
709 if ( $rules->length > 0 ) { |
733 if ( $rules->length > 0 ) { |
710 $child = $rules->item(0); |
734 $child = $rules->item( 0 ); |
711 $parent = $child->parentNode; |
735 $parent = $child->parentNode; |
712 $parent->removeChild($child); |
736 $parent->removeChild( $child ); |
713 $doc->formatOutput = true; |
737 $doc->formatOutput = true; |
714 saveDomDocument($doc, $filename); |
738 saveDomDocument( $doc, $filename ); |
715 } |
739 } |
716 return true; |
740 return true; |
717 } |
741 } |
718 |
742 |
719 /** |
743 /** |
723 * |
747 * |
724 * @param string $filename The file path to the configuration file |
748 * @param string $filename The file path to the configuration file |
725 * @param string $rewrite_rule The XML fragment with URL Rewrite rule |
749 * @param string $rewrite_rule The XML fragment with URL Rewrite rule |
726 * @return bool |
750 * @return bool |
727 */ |
751 */ |
728 function iis7_add_rewrite_rule($filename, $rewrite_rule) { |
752 function iis7_add_rewrite_rule( $filename, $rewrite_rule ) { |
729 if ( ! class_exists( 'DOMDocument', false ) ) { |
753 if ( ! class_exists( 'DOMDocument', false ) ) { |
730 return false; |
754 return false; |
731 } |
755 } |
732 |
756 |
733 // If configuration file does not exist then we create one. |
757 // If configuration file does not exist then we create one. |
734 if ( ! file_exists($filename) ) { |
758 if ( ! file_exists( $filename ) ) { |
735 $fp = fopen( $filename, 'w'); |
759 $fp = fopen( $filename, 'w' ); |
736 fwrite($fp, '<configuration/>'); |
760 fwrite( $fp, '<configuration/>' ); |
737 fclose($fp); |
761 fclose( $fp ); |
738 } |
762 } |
739 |
763 |
740 $doc = new DOMDocument(); |
764 $doc = new DOMDocument(); |
741 $doc->preserveWhiteSpace = false; |
765 $doc->preserveWhiteSpace = false; |
742 |
766 |
743 if ( $doc->load($filename) === false ) |
767 if ( $doc->load( $filename ) === false ) { |
744 return false; |
768 return false; |
745 |
769 } |
746 $xpath = new DOMXPath($doc); |
770 |
771 $xpath = new DOMXPath( $doc ); |
|
747 |
772 |
748 // First check if the rule already exists as in that case there is no need to re-add it |
773 // First check if the rule already exists as in that case there is no need to re-add it |
749 $wordpress_rules = $xpath->query('/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')] | /configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WordPress\')]'); |
774 $wordpress_rules = $xpath->query( '/configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'wordpress\')] | /configuration/system.webServer/rewrite/rules/rule[starts-with(@name,\'WordPress\')]' ); |
750 if ( $wordpress_rules->length > 0 ) |
775 if ( $wordpress_rules->length > 0 ) { |
751 return true; |
776 return true; |
777 } |
|
752 |
778 |
753 // Check the XPath to the rewrite rule and create XML nodes if they do not exist |
779 // Check the XPath to the rewrite rule and create XML nodes if they do not exist |
754 $xmlnodes = $xpath->query('/configuration/system.webServer/rewrite/rules'); |
780 $xmlnodes = $xpath->query( '/configuration/system.webServer/rewrite/rules' ); |
755 if ( $xmlnodes->length > 0 ) { |
781 if ( $xmlnodes->length > 0 ) { |
756 $rules_node = $xmlnodes->item(0); |
782 $rules_node = $xmlnodes->item( 0 ); |
757 } else { |
783 } else { |
758 $rules_node = $doc->createElement('rules'); |
784 $rules_node = $doc->createElement( 'rules' ); |
759 |
785 |
760 $xmlnodes = $xpath->query('/configuration/system.webServer/rewrite'); |
786 $xmlnodes = $xpath->query( '/configuration/system.webServer/rewrite' ); |
761 if ( $xmlnodes->length > 0 ) { |
787 if ( $xmlnodes->length > 0 ) { |
762 $rewrite_node = $xmlnodes->item(0); |
788 $rewrite_node = $xmlnodes->item( 0 ); |
763 $rewrite_node->appendChild($rules_node); |
789 $rewrite_node->appendChild( $rules_node ); |
764 } else { |
790 } else { |
765 $rewrite_node = $doc->createElement('rewrite'); |
791 $rewrite_node = $doc->createElement( 'rewrite' ); |
766 $rewrite_node->appendChild($rules_node); |
792 $rewrite_node->appendChild( $rules_node ); |
767 |
793 |
768 $xmlnodes = $xpath->query('/configuration/system.webServer'); |
794 $xmlnodes = $xpath->query( '/configuration/system.webServer' ); |
769 if ( $xmlnodes->length > 0 ) { |
795 if ( $xmlnodes->length > 0 ) { |
770 $system_webServer_node = $xmlnodes->item(0); |
796 $system_webServer_node = $xmlnodes->item( 0 ); |
771 $system_webServer_node->appendChild($rewrite_node); |
797 $system_webServer_node->appendChild( $rewrite_node ); |
772 } else { |
798 } else { |
773 $system_webServer_node = $doc->createElement('system.webServer'); |
799 $system_webServer_node = $doc->createElement( 'system.webServer' ); |
774 $system_webServer_node->appendChild($rewrite_node); |
800 $system_webServer_node->appendChild( $rewrite_node ); |
775 |
801 |
776 $xmlnodes = $xpath->query('/configuration'); |
802 $xmlnodes = $xpath->query( '/configuration' ); |
777 if ( $xmlnodes->length > 0 ) { |
803 if ( $xmlnodes->length > 0 ) { |
778 $config_node = $xmlnodes->item(0); |
804 $config_node = $xmlnodes->item( 0 ); |
779 $config_node->appendChild($system_webServer_node); |
805 $config_node->appendChild( $system_webServer_node ); |
780 } else { |
806 } else { |
781 $config_node = $doc->createElement('configuration'); |
807 $config_node = $doc->createElement( 'configuration' ); |
782 $doc->appendChild($config_node); |
808 $doc->appendChild( $config_node ); |
783 $config_node->appendChild($system_webServer_node); |
809 $config_node->appendChild( $system_webServer_node ); |
784 } |
810 } |
785 } |
811 } |
786 } |
812 } |
787 } |
813 } |
788 |
814 |
789 $rule_fragment = $doc->createDocumentFragment(); |
815 $rule_fragment = $doc->createDocumentFragment(); |
790 $rule_fragment->appendXML($rewrite_rule); |
816 $rule_fragment->appendXML( $rewrite_rule ); |
791 $rules_node->appendChild($rule_fragment); |
817 $rules_node->appendChild( $rule_fragment ); |
792 |
818 |
793 $doc->encoding = "UTF-8"; |
819 $doc->encoding = 'UTF-8'; |
794 $doc->formatOutput = true; |
820 $doc->formatOutput = true; |
795 saveDomDocument($doc, $filename); |
821 saveDomDocument( $doc, $filename ); |
796 |
822 |
797 return true; |
823 return true; |
798 } |
824 } |
799 |
825 |
800 /** |
826 /** |
803 * @since 2.8.0 |
829 * @since 2.8.0 |
804 * |
830 * |
805 * @param DOMDocument $doc |
831 * @param DOMDocument $doc |
806 * @param string $filename |
832 * @param string $filename |
807 */ |
833 */ |
808 function saveDomDocument($doc, $filename) { |
834 function saveDomDocument( $doc, $filename ) { |
809 $config = $doc->saveXML(); |
835 $config = $doc->saveXML(); |
810 $config = preg_replace("/([^\r])\n/", "$1\r\n", $config); |
836 $config = preg_replace( "/([^\r])\n/", "$1\r\n", $config ); |
811 $fp = fopen($filename, 'w'); |
837 $fp = fopen( $filename, 'w' ); |
812 fwrite($fp, $config); |
838 fwrite( $fp, $config ); |
813 fclose($fp); |
839 fclose( $fp ); |
814 } |
840 } |
815 |
841 |
816 /** |
842 /** |
817 * Display the default admin color scheme picker (Used in user-edit.php) |
843 * Display the default admin color scheme picker (Used in user-edit.php) |
818 * |
844 * |
827 |
853 |
828 ksort( $_wp_admin_css_colors ); |
854 ksort( $_wp_admin_css_colors ); |
829 |
855 |
830 if ( isset( $_wp_admin_css_colors['fresh'] ) ) { |
856 if ( isset( $_wp_admin_css_colors['fresh'] ) ) { |
831 // Set Default ('fresh') and Light should go first. |
857 // Set Default ('fresh') and Light should go first. |
832 $_wp_admin_css_colors = array_filter( array_merge( array( 'fresh' => '', 'light' => '' ), $_wp_admin_css_colors ) ); |
858 $_wp_admin_css_colors = array_filter( |
859 array_merge( |
|
860 array( |
|
861 'fresh' => '', |
|
862 'light' => '', |
|
863 ), |
|
864 $_wp_admin_css_colors |
|
865 ) |
|
866 ); |
|
833 } |
867 } |
834 |
868 |
835 $current_color = get_user_option( 'admin_color', $user_id ); |
869 $current_color = get_user_option( 'admin_color', $user_id ); |
836 |
870 |
837 if ( empty( $current_color ) || ! isset( $_wp_admin_css_colors[ $current_color ] ) ) { |
871 if ( empty( $current_color ) || ! isset( $_wp_admin_css_colors[ $current_color ] ) ) { |
867 </div> |
901 </div> |
868 <?php |
902 <?php |
869 |
903 |
870 endforeach; |
904 endforeach; |
871 |
905 |
872 ?> |
906 ?> |
873 </fieldset> |
907 </fieldset> |
874 <?php |
908 <?php |
875 } |
909 } |
876 |
910 |
877 /** |
911 /** |
892 $icon_colors = $_wp_admin_css_colors[ $color_scheme ]->icon_colors; |
926 $icon_colors = $_wp_admin_css_colors[ $color_scheme ]->icon_colors; |
893 } elseif ( ! empty( $_wp_admin_css_colors['fresh']->icon_colors ) ) { |
927 } elseif ( ! empty( $_wp_admin_css_colors['fresh']->icon_colors ) ) { |
894 $icon_colors = $_wp_admin_css_colors['fresh']->icon_colors; |
928 $icon_colors = $_wp_admin_css_colors['fresh']->icon_colors; |
895 } else { |
929 } else { |
896 // Fall back to the default set of icon colors if the default scheme is missing. |
930 // Fall back to the default set of icon colors if the default scheme is missing. |
897 $icon_colors = array( 'base' => '#82878c', 'focus' => '#00a0d2', 'current' => '#fff' ); |
931 $icon_colors = array( |
932 'base' => '#a0a5aa', |
|
933 'focus' => '#00a0d2', |
|
934 'current' => '#fff', |
|
935 ); |
|
898 } |
936 } |
899 |
937 |
900 echo '<script type="text/javascript">var _wpColorScheme = ' . wp_json_encode( array( 'icons' => $icon_colors ) ) . ";</script>\n"; |
938 echo '<script type="text/javascript">var _wpColorScheme = ' . wp_json_encode( array( 'icons' => $icon_colors ) ) . ";</script>\n"; |
901 } |
939 } |
902 |
940 |
924 function wp_check_locked_posts( $response, $data, $screen_id ) { |
962 function wp_check_locked_posts( $response, $data, $screen_id ) { |
925 $checked = array(); |
963 $checked = array(); |
926 |
964 |
927 if ( array_key_exists( 'wp-check-locked-posts', $data ) && is_array( $data['wp-check-locked-posts'] ) ) { |
965 if ( array_key_exists( 'wp-check-locked-posts', $data ) && is_array( $data['wp-check-locked-posts'] ) ) { |
928 foreach ( $data['wp-check-locked-posts'] as $key ) { |
966 foreach ( $data['wp-check-locked-posts'] as $key ) { |
929 if ( ! $post_id = absint( substr( $key, 5 ) ) ) |
967 if ( ! $post_id = absint( substr( $key, 5 ) ) ) { |
930 continue; |
968 continue; |
969 } |
|
931 |
970 |
932 if ( ( $user_id = wp_check_post_lock( $post_id ) ) && ( $user = get_userdata( $user_id ) ) && current_user_can( 'edit_post', $post_id ) ) { |
971 if ( ( $user_id = wp_check_post_lock( $post_id ) ) && ( $user = get_userdata( $user_id ) ) && current_user_can( 'edit_post', $post_id ) ) { |
933 $send = array( 'text' => sprintf( __( '%s is currently editing' ), $user->display_name ) ); |
972 $send = array( 'text' => sprintf( __( '%s is currently editing' ), $user->display_name ) ); |
934 |
973 |
935 if ( ( $avatar = get_avatar( $user->ID, 18 ) ) && preg_match( "|src='([^']+)'|", $avatar, $matches ) ) |
974 if ( ( $avatar = get_avatar( $user->ID, 18 ) ) && preg_match( "|src='([^']+)'|", $avatar, $matches ) ) { |
936 $send['avatar_src'] = $matches[1]; |
975 $send['avatar_src'] = $matches[1]; |
937 |
976 } |
938 $checked[$key] = $send; |
977 |
978 $checked[ $key ] = $send; |
|
939 } |
979 } |
940 } |
980 } |
941 } |
981 } |
942 |
982 |
943 if ( ! empty( $checked ) ) |
983 if ( ! empty( $checked ) ) { |
944 $response['wp-check-locked-posts'] = $checked; |
984 $response['wp-check-locked-posts'] = $checked; |
985 } |
|
945 |
986 |
946 return $response; |
987 return $response; |
947 } |
988 } |
948 |
989 |
949 /** |
990 /** |
957 * @return array The Heartbeat response. |
998 * @return array The Heartbeat response. |
958 */ |
999 */ |
959 function wp_refresh_post_lock( $response, $data, $screen_id ) { |
1000 function wp_refresh_post_lock( $response, $data, $screen_id ) { |
960 if ( array_key_exists( 'wp-refresh-post-lock', $data ) ) { |
1001 if ( array_key_exists( 'wp-refresh-post-lock', $data ) ) { |
961 $received = $data['wp-refresh-post-lock']; |
1002 $received = $data['wp-refresh-post-lock']; |
962 $send = array(); |
1003 $send = array(); |
963 |
1004 |
964 if ( ! $post_id = absint( $received['post_id'] ) ) |
1005 if ( ! $post_id = absint( $received['post_id'] ) ) { |
965 return $response; |
1006 return $response; |
966 |
1007 } |
967 if ( ! current_user_can('edit_post', $post_id) ) |
1008 |
1009 if ( ! current_user_can( 'edit_post', $post_id ) ) { |
|
968 return $response; |
1010 return $response; |
1011 } |
|
969 |
1012 |
970 if ( ( $user_id = wp_check_post_lock( $post_id ) ) && ( $user = get_userdata( $user_id ) ) ) { |
1013 if ( ( $user_id = wp_check_post_lock( $post_id ) ) && ( $user = get_userdata( $user_id ) ) ) { |
971 $error = array( |
1014 $error = array( |
972 'text' => sprintf( __( '%s has taken over and is currently editing.' ), $user->display_name ) |
1015 'text' => sprintf( __( '%s has taken over and is currently editing.' ), $user->display_name ), |
973 ); |
1016 ); |
974 |
1017 |
975 if ( $avatar = get_avatar( $user->ID, 64 ) ) { |
1018 if ( $avatar = get_avatar( $user->ID, 64 ) ) { |
976 if ( preg_match( "|src='([^']+)'|", $avatar, $matches ) ) |
1019 if ( preg_match( "|src='([^']+)'|", $avatar, $matches ) ) { |
977 $error['avatar_src'] = $matches[1]; |
1020 $error['avatar_src'] = $matches[1]; |
1021 } |
|
978 } |
1022 } |
979 |
1023 |
980 $send['lock_error'] = $error; |
1024 $send['lock_error'] = $error; |
981 } else { |
1025 } else { |
982 if ( $new_lock = wp_set_post_lock( $post_id ) ) |
1026 if ( $new_lock = wp_set_post_lock( $post_id ) ) { |
983 $send['new_lock'] = implode( ':', $new_lock ); |
1027 $send['new_lock'] = implode( ':', $new_lock ); |
1028 } |
|
984 } |
1029 } |
985 |
1030 |
986 $response['wp-refresh-post-lock'] = $send; |
1031 $response['wp-refresh-post-lock'] = $send; |
987 } |
1032 } |
988 |
1033 |
999 * @param string $screen_id The screen id. |
1044 * @param string $screen_id The screen id. |
1000 * @return array The Heartbeat response. |
1045 * @return array The Heartbeat response. |
1001 */ |
1046 */ |
1002 function wp_refresh_post_nonces( $response, $data, $screen_id ) { |
1047 function wp_refresh_post_nonces( $response, $data, $screen_id ) { |
1003 if ( array_key_exists( 'wp-refresh-post-nonces', $data ) ) { |
1048 if ( array_key_exists( 'wp-refresh-post-nonces', $data ) ) { |
1004 $received = $data['wp-refresh-post-nonces']; |
1049 $received = $data['wp-refresh-post-nonces']; |
1005 $response['wp-refresh-post-nonces'] = array( 'check' => 1 ); |
1050 $response['wp-refresh-post-nonces'] = array( 'check' => 1 ); |
1006 |
1051 |
1007 if ( ! $post_id = absint( $received['post_id'] ) ) { |
1052 if ( ! $post_id = absint( $received['post_id'] ) ) { |
1008 return $response; |
1053 return $response; |
1009 } |
1054 } |
1012 return $response; |
1057 return $response; |
1013 } |
1058 } |
1014 |
1059 |
1015 $response['wp-refresh-post-nonces'] = array( |
1060 $response['wp-refresh-post-nonces'] = array( |
1016 'replace' => array( |
1061 'replace' => array( |
1017 'getpermalinknonce' => wp_create_nonce('getpermalink'), |
1062 'getpermalinknonce' => wp_create_nonce( 'getpermalink' ), |
1018 'samplepermalinknonce' => wp_create_nonce('samplepermalink'), |
1063 'samplepermalinknonce' => wp_create_nonce( 'samplepermalink' ), |
1019 'closedpostboxesnonce' => wp_create_nonce('closedpostboxes'), |
1064 'closedpostboxesnonce' => wp_create_nonce( 'closedpostboxes' ), |
1020 '_ajax_linking_nonce' => wp_create_nonce( 'internal-linking' ), |
1065 '_ajax_linking_nonce' => wp_create_nonce( 'internal-linking' ), |
1021 '_wpnonce' => wp_create_nonce( 'update-post_' . $post_id ), |
1066 '_wpnonce' => wp_create_nonce( 'update-post_' . $post_id ), |
1022 ), |
1067 ), |
1023 'heartbeatNonce' => wp_create_nonce( 'heartbeat-nonce' ), |
|
1024 ); |
1068 ); |
1025 } |
1069 } |
1026 |
1070 |
1071 return $response; |
|
1072 } |
|
1073 |
|
1074 /** |
|
1075 * Add the latest Heartbeat and REST-API nonce to the Heartbeat response. |
|
1076 * |
|
1077 * @since 5.0.0 |
|
1078 * |
|
1079 * @param array $response The Heartbeat response. |
|
1080 * @return array The Heartbeat response. |
|
1081 */ |
|
1082 function wp_refresh_heartbeat_nonces( $response ) { |
|
1083 // Refresh the Rest API nonce. |
|
1084 $response['rest_nonce'] = wp_create_nonce( 'wp_rest' ); |
|
1085 |
|
1086 // Refresh the Heartbeat nonce. |
|
1087 $response['heartbeat_nonce'] = wp_create_nonce( 'heartbeat-nonce' ); |
|
1027 return $response; |
1088 return $response; |
1028 } |
1089 } |
1029 |
1090 |
1030 /** |
1091 /** |
1031 * Disable suspension of Heartbeat on the Add/Edit Post screens. |
1092 * Disable suspension of Heartbeat on the Add/Edit Post screens. |
1059 function heartbeat_autosave( $response, $data ) { |
1120 function heartbeat_autosave( $response, $data ) { |
1060 if ( ! empty( $data['wp_autosave'] ) ) { |
1121 if ( ! empty( $data['wp_autosave'] ) ) { |
1061 $saved = wp_autosave( $data['wp_autosave'] ); |
1122 $saved = wp_autosave( $data['wp_autosave'] ); |
1062 |
1123 |
1063 if ( is_wp_error( $saved ) ) { |
1124 if ( is_wp_error( $saved ) ) { |
1064 $response['wp_autosave'] = array( 'success' => false, 'message' => $saved->get_error_message() ); |
1125 $response['wp_autosave'] = array( |
1126 'success' => false, |
|
1127 'message' => $saved->get_error_message(), |
|
1128 ); |
|
1065 } elseif ( empty( $saved ) ) { |
1129 } elseif ( empty( $saved ) ) { |
1066 $response['wp_autosave'] = array( 'success' => false, 'message' => __( 'Error while saving.' ) ); |
1130 $response['wp_autosave'] = array( |
1131 'success' => false, |
|
1132 'message' => __( 'Error while saving.' ), |
|
1133 ); |
|
1067 } else { |
1134 } else { |
1068 /* translators: draft saved date format, see https://secure.php.net/date */ |
1135 /* translators: draft saved date format, see https://secure.php.net/date */ |
1069 $draft_saved_date_format = __( 'g:i:s a' ); |
1136 $draft_saved_date_format = __( 'g:i:s a' ); |
1070 /* translators: %s: date and time */ |
1137 /* translators: %s: date and time */ |
1071 $response['wp_autosave'] = array( 'success' => true, 'message' => sprintf( __( 'Draft saved at %s.' ), date_i18n( $draft_saved_date_format ) ) ); |
1138 $response['wp_autosave'] = array( |
1139 'success' => true, |
|
1140 'message' => sprintf( __( 'Draft saved at %s.' ), date_i18n( $draft_saved_date_format ) ), |
|
1141 ); |
|
1072 } |
1142 } |
1073 } |
1143 } |
1074 |
1144 |
1075 return $response; |
1145 return $response; |
1076 } |
1146 } |
1098 <script> |
1168 <script> |
1099 if ( window.history.replaceState ) { |
1169 if ( window.history.replaceState ) { |
1100 window.history.replaceState( null, null, document.getElementById( 'wp-admin-canonical' ).href + window.location.hash ); |
1170 window.history.replaceState( null, null, document.getElementById( 'wp-admin-canonical' ).href + window.location.hash ); |
1101 } |
1171 } |
1102 </script> |
1172 </script> |
1103 <?php |
1173 <?php |
1104 } |
1174 } |
1105 |
1175 |
1106 /** |
1176 /** |
1107 * Send a referrer policy header so referrers are not sent externally from administration screens. |
1177 * Send a referrer policy header so referrers are not sent externally from administration screens. |
1108 * |
1178 * |
1158 function update_option_new_admin_email( $old_value, $value ) { |
1228 function update_option_new_admin_email( $old_value, $value ) { |
1159 if ( $value == get_option( 'admin_email' ) || ! is_email( $value ) ) { |
1229 if ( $value == get_option( 'admin_email' ) || ! is_email( $value ) ) { |
1160 return; |
1230 return; |
1161 } |
1231 } |
1162 |
1232 |
1163 $hash = md5( $value . time() . wp_rand() ); |
1233 $hash = md5( $value . time() . wp_rand() ); |
1164 $new_admin_email = array( |
1234 $new_admin_email = array( |
1165 'hash' => $hash, |
1235 'hash' => $hash, |
1166 'newemail' => $value, |
1236 'newemail' => $value, |
1167 ); |
1237 ); |
1168 update_option( 'adminhash', $new_admin_email ); |
1238 update_option( 'adminhash', $new_admin_email ); |
1169 |
1239 |
1170 $switched_locale = switch_to_locale( get_user_locale() ); |
1240 $switched_locale = switch_to_locale( get_user_locale() ); |
1171 |
1241 |
1172 /* translators: Do not translate USERNAME, ADMIN_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */ |
1242 /* translators: Do not translate USERNAME, ADMIN_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */ |
1173 $email_text = __( 'Howdy ###USERNAME###, |
1243 $email_text = __( |
1244 'Howdy ###USERNAME###, |
|
1174 |
1245 |
1175 You recently requested to have the administration email address on |
1246 You recently requested to have the administration email address on |
1176 your site changed. |
1247 your site changed. |
1177 |
1248 |
1178 If this is correct, please click on the following link to change it: |
1249 If this is correct, please click on the following link to change it: |
1183 |
1254 |
1184 This email has been sent to ###EMAIL### |
1255 This email has been sent to ###EMAIL### |
1185 |
1256 |
1186 Regards, |
1257 Regards, |
1187 All at ###SITENAME### |
1258 All at ###SITENAME### |
1188 ###SITEURL###' ); |
1259 ###SITEURL###' |
1260 ); |
|
1189 |
1261 |
1190 /** |
1262 /** |
1191 * Filters the text of the email sent when a change of site admin email address is attempted. |
1263 * Filters the text of the email sent when a change of site admin email address is attempted. |
1192 * |
1264 * |
1193 * The following strings have a special meaning and will get replaced dynamically: |
1265 * The following strings have a special meaning and will get replaced dynamically: |
1209 * } |
1281 * } |
1210 */ |
1282 */ |
1211 $content = apply_filters( 'new_admin_email_content', $email_text, $new_admin_email ); |
1283 $content = apply_filters( 'new_admin_email_content', $email_text, $new_admin_email ); |
1212 |
1284 |
1213 $current_user = wp_get_current_user(); |
1285 $current_user = wp_get_current_user(); |
1214 $content = str_replace( '###USERNAME###', $current_user->user_login, $content ); |
1286 $content = str_replace( '###USERNAME###', $current_user->user_login, $content ); |
1215 $content = str_replace( '###ADMIN_URL###', esc_url( self_admin_url( 'options.php?adminhash=' . $hash ) ), $content ); |
1287 $content = str_replace( '###ADMIN_URL###', esc_url( self_admin_url( 'options.php?adminhash=' . $hash ) ), $content ); |
1216 $content = str_replace( '###EMAIL###', $value, $content ); |
1288 $content = str_replace( '###EMAIL###', $value, $content ); |
1217 $content = str_replace( '###SITENAME###', wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), $content ); |
1289 $content = str_replace( '###SITENAME###', wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), $content ); |
1218 $content = str_replace( '###SITEURL###', home_url(), $content ); |
1290 $content = str_replace( '###SITEURL###', home_url(), $content ); |
1219 |
1291 |
1292 /* translators: New admin email address notification email subject. %s: Site title */ |
|
1220 wp_mail( $value, sprintf( __( '[%s] New Admin Email Address' ), wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) ), $content ); |
1293 wp_mail( $value, sprintf( __( '[%s] New Admin Email Address' ), wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) ), $content ); |
1221 |
1294 |
1222 if ( $switched_locale ) { |
1295 if ( $switched_locale ) { |
1223 restore_previous_locale(); |
1296 restore_previous_locale(); |
1224 } |
1297 } |
1269 * The suggested text should contain information about any functionality that affects user privacy, |
1342 * The suggested text should contain information about any functionality that affects user privacy, |
1270 * and will be shown in the Suggested Privacy Policy Content postbox. |
1343 * and will be shown in the Suggested Privacy Policy Content postbox. |
1271 * |
1344 * |
1272 * Intended for use from `wp_add_privacy_policy_content()`. |
1345 * Intended for use from `wp_add_privacy_policy_content()`. |
1273 * |
1346 * |
1274 * $since 4.9.6 |
1347 * @since 4.9.6 |
1275 * |
1348 * |
1276 * @param string $plugin_name The name of the plugin or theme that is suggesting content for the site's privacy policy. |
1349 * @param string $plugin_name The name of the plugin or theme that is suggesting content for the site's privacy policy. |
1277 * @param string $policy_text The suggested content for inclusion in the policy. |
1350 * @param string $policy_text The suggested content for inclusion in the policy. |
1278 */ |
1351 */ |
1279 public static function add( $plugin_name, $policy_text ) { |
1352 public static function add( $plugin_name, $policy_text ) { |
1379 return; |
1452 return; |
1380 } |
1453 } |
1381 |
1454 |
1382 ?> |
1455 ?> |
1383 <div class="policy-text-updated notice notice-warning is-dismissible"> |
1456 <div class="policy-text-updated notice notice-warning is-dismissible"> |
1384 <p><?php |
1457 <p> |
1458 <?php |
|
1385 printf( |
1459 printf( |
1386 /* translators: %s: Privacy Policy Guide URL */ |
1460 /* translators: %s: Privacy Policy Guide URL */ |
1387 __( 'The suggested privacy policy text has changed. Please <a href="%s">review the guide</a> and update your privacy policy.' ), |
1461 __( 'The suggested privacy policy text has changed. Please <a href="%s">review the guide</a> and update your privacy policy.' ), |
1388 esc_url( admin_url( 'tools.php?wp-privacy-policy-guide=1' ) ) |
1462 esc_url( admin_url( 'tools.php?wp-privacy-policy-guide=1' ) ) |
1389 ); |
1463 ); |
1390 ?></p> |
1464 ?> |
1465 </p> |
|
1391 </div> |
1466 </div> |
1392 <?php |
1467 <?php |
1393 } |
1468 } |
1394 |
1469 |
1395 /** |
1470 /** |
1404 if ( ! $policy_page_id || $policy_page_id !== (int) $post_id ) { |
1479 if ( ! $policy_page_id || $policy_page_id !== (int) $post_id ) { |
1405 return; |
1480 return; |
1406 } |
1481 } |
1407 |
1482 |
1408 // Remove updated|removed status. |
1483 // Remove updated|removed status. |
1409 $old = (array) get_post_meta( $policy_page_id, '_wp_suggested_privacy_policy_content' ); |
1484 $old = (array) get_post_meta( $policy_page_id, '_wp_suggested_privacy_policy_content' ); |
1410 $done = array(); |
1485 $done = array(); |
1411 $update_cache = false; |
1486 $update_cache = false; |
1412 |
1487 |
1413 foreach ( $old as $old_key => $old_data ) { |
1488 foreach ( $old as $old_key => $old_data ) { |
1414 if ( ! empty( $old_data['removed'] ) ) { |
1489 if ( ! empty( $old_data['removed'] ) ) { |
1415 // Remove the old policy text. |
1490 // Remove the old policy text. |
1417 continue; |
1492 continue; |
1418 } |
1493 } |
1419 |
1494 |
1420 if ( ! empty( $old_data['updated'] ) ) { |
1495 if ( ! empty( $old_data['updated'] ) ) { |
1421 // 'updated' is now 'added'. |
1496 // 'updated' is now 'added'. |
1422 $done[] = array( |
1497 $done[] = array( |
1423 'plugin_name' => $old_data['plugin_name'], |
1498 'plugin_name' => $old_data['plugin_name'], |
1424 'policy_text' => $old_data['policy_text'], |
1499 'policy_text' => $old_data['policy_text'], |
1425 'added' => $old_data['updated'], |
1500 'added' => $old_data['updated'], |
1426 ); |
1501 ); |
1427 $update_cache = true; |
1502 $update_cache = true; |
1448 * |
1523 * |
1449 * @return array The privacy policy text/informtion added by core and plugins. |
1524 * @return array The privacy policy text/informtion added by core and plugins. |
1450 */ |
1525 */ |
1451 public static function get_suggested_policy_text() { |
1526 public static function get_suggested_policy_text() { |
1452 $policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' ); |
1527 $policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' ); |
1453 $checked = array(); |
1528 $checked = array(); |
1454 $time = time(); |
1529 $time = time(); |
1455 $update_cache = false; |
1530 $update_cache = false; |
1456 $new = self::$policy_content; |
1531 $new = self::$policy_content; |
1457 $old = array(); |
1532 $old = array(); |
1458 |
1533 |
1459 if ( $policy_page_id ) { |
1534 if ( $policy_page_id ) { |
1460 $old = (array) get_post_meta( $policy_page_id, '_wp_suggested_privacy_policy_content' ); |
1535 $old = (array) get_post_meta( $policy_page_id, '_wp_suggested_privacy_policy_content' ); |
1461 } |
1536 } |
1462 |
1537 |
1467 |
1542 |
1468 if ( $new_data['policy_text'] === $old_data['policy_text'] ) { |
1543 if ( $new_data['policy_text'] === $old_data['policy_text'] ) { |
1469 // Use the new plugin name in case it was changed, translated, etc. |
1544 // Use the new plugin name in case it was changed, translated, etc. |
1470 if ( $old_data['plugin_name'] !== $new_data['plugin_name'] ) { |
1545 if ( $old_data['plugin_name'] !== $new_data['plugin_name'] ) { |
1471 $old_data['plugin_name'] = $new_data['plugin_name']; |
1546 $old_data['plugin_name'] = $new_data['plugin_name']; |
1472 $update_cache = true; |
1547 $update_cache = true; |
1473 } |
1548 } |
1474 |
1549 |
1475 // A plugin was re-activated. |
1550 // A plugin was re-activated. |
1476 if ( ! empty( $old_data['removed'] ) ) { |
1551 if ( ! empty( $old_data['removed'] ) ) { |
1477 unset( $old_data['removed'] ); |
1552 unset( $old_data['removed'] ); |
1478 $old_data['added'] = $time; |
1553 $old_data['added'] = $time; |
1479 $update_cache = true; |
1554 $update_cache = true; |
1480 } |
1555 } |
1481 |
1556 |
1482 $checked[] = $old_data; |
1557 $checked[] = $old_data; |
1483 $found = true; |
1558 $found = true; |
1484 } elseif ( $new_data['plugin_name'] === $old_data['plugin_name'] ) { |
1559 } elseif ( $new_data['plugin_name'] === $old_data['plugin_name'] ) { |
1485 // The info for the policy was updated. |
1560 // The info for the policy was updated. |
1486 $checked[] = array( |
1561 $checked[] = array( |
1487 'plugin_name' => $new_data['plugin_name'], |
1562 'plugin_name' => $new_data['plugin_name'], |
1488 'policy_text' => $new_data['policy_text'], |
1563 'policy_text' => $new_data['policy_text'], |
1489 'updated' => $time, |
1564 'updated' => $time, |
1490 ); |
1565 ); |
1491 $found = $update_cache = true; |
1566 $found = $update_cache = true; |
1492 } |
1567 } |
1493 |
1568 |
1494 if ( $found ) { |
1569 if ( $found ) { |
1495 unset( $new[ $new_key ], $old[ $old_key ] ); |
1570 unset( $new[ $new_key ], $old[ $old_key ] ); |
1496 continue 2; |
1571 continue 2; |
1538 |
1613 |
1539 /** |
1614 /** |
1540 * Add a notice with a link to the guide when editing the privacy policy page. |
1615 * Add a notice with a link to the guide when editing the privacy policy page. |
1541 * |
1616 * |
1542 * @since 4.9.6 |
1617 * @since 4.9.6 |
1543 * |
1618 * @since 5.0.0 The $post parameter is now optional. |
1544 * @param $post WP_Post The currently edited post. |
1619 * |
1620 * @param WP_Post|null $post The currently edited post. Default null. |
|
1545 */ |
1621 */ |
1546 public static function notice( $post ) { |
1622 public static function notice( $post = null ) { |
1623 if ( is_null( $post ) ) { |
|
1624 global $post; |
|
1625 } else { |
|
1626 $post = get_post( $post ); |
|
1627 } |
|
1628 |
|
1547 if ( ! ( $post instanceof WP_Post ) ) { |
1629 if ( ! ( $post instanceof WP_Post ) ) { |
1548 return; |
1630 return; |
1549 } |
1631 } |
1550 |
1632 |
1551 if ( ! current_user_can( 'manage_privacy_options' ) ) { |
1633 if ( ! current_user_can( 'manage_privacy_options' ) ) { |
1552 return; |
1634 return; |
1553 } |
1635 } |
1554 |
1636 |
1555 $policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' ); |
1637 $policy_page_id = (int) get_option( 'wp_page_for_privacy_policy' ); |
1556 |
1638 |
1557 if ( ! $policy_page_id || $policy_page_id != $post->ID ) { |
1639 if ( ! $policy_page_id || $policy_page_id !== $post->ID ) { |
1558 return; |
1640 return; |
1559 } |
1641 } |
1560 |
1642 |
1561 ?> |
1643 $message = __( 'Need help putting together your new Privacy Policy page? Check out our guide for recommendations on what content to include, along with policies suggested by your plugins and theme.' ); |
1562 <div class="notice notice-warning inline wp-pp-notice"> |
1644 $url = esc_url( admin_url( 'tools.php?wp-privacy-policy-guide=1' ) ); |
1563 <p> |
1645 $label = __( 'View Privacy Policy Guide.' ); |
1564 <?php |
1646 |
1565 /* translators: 1: Privacy Policy guide URL, 2: additional link attributes, 3: accessibility text */ |
1647 if ( get_current_screen()->is_block_editor() ) { |
1566 printf( |
1648 wp_enqueue_script( 'wp-notices' ); |
1567 __( 'Need help putting together your new Privacy Policy page? <a href="%1$s" %2$s>Check out our guide%3$s</a> for recommendations on what content to include, along with policies suggested by your plugins and theme.' ), |
1649 $action = array( |
1568 admin_url( 'tools.php?wp-privacy-policy-guide=1' ), |
1650 'url' => $url, |
1569 'target="_blank"', |
1651 'label' => $label, |
1652 ); |
|
1653 wp_add_inline_script( |
|
1654 'wp-notices', |
|
1570 sprintf( |
1655 sprintf( |
1571 '<span class="screen-reader-text"> %s</span>', |
1656 'wp.data.dispatch( "core/notices" ).createWarningNotice( "%s", { actions: [ %s ], isDismissible: false } )', |
1657 $message, |
|
1658 wp_json_encode( $action ) |
|
1659 ), |
|
1660 'after' |
|
1661 ); |
|
1662 } else { |
|
1663 ?> |
|
1664 <div class="notice notice-warning inline wp-pp-notice"> |
|
1665 <p> |
|
1666 <?php |
|
1667 echo $message; |
|
1668 printf( |
|
1669 ' <a href="%s" target="_blank">%s <span class="screen-reader-text">%s</span></a>', |
|
1670 $url, |
|
1671 $label, |
|
1572 /* translators: accessibility text */ |
1672 /* translators: accessibility text */ |
1573 __( '(opens in a new tab)' ) |
1673 __( '(opens in a new tab)' ) |
1574 ) |
1674 ); |
1575 ); |
1675 ?> |
1576 ?> |
1676 </p> |
1577 </p> |
1677 </div> |
1578 </div> |
1678 <?php |
1579 <?php |
1679 } |
1580 |
|
1581 } |
1680 } |
1582 |
1681 |
1583 /** |
1682 /** |
1584 * Output the privacy policy guide together with content from the theme and plugins. |
1683 * Output the privacy policy guide together with content from the theme and plugins. |
1585 * |
1684 * |
1587 */ |
1686 */ |
1588 public static function privacy_policy_guide() { |
1687 public static function privacy_policy_guide() { |
1589 |
1688 |
1590 $content_array = self::get_suggested_policy_text(); |
1689 $content_array = self::get_suggested_policy_text(); |
1591 |
1690 |
1592 $content = ''; |
1691 $content = ''; |
1593 $toc = array( '<li><a href="#wp-privacy-policy-guide-introduction">' . __( 'Introduction' ) . '</a></li>' ); |
1692 $toc = array( '<li><a href="#wp-privacy-policy-guide-introduction">' . __( 'Introduction' ) . '</a></li>' ); |
1594 $date_format = __( 'F j, Y' ); |
1693 $date_format = __( 'F j, Y' ); |
1595 $copy = __( 'Copy' ); |
1694 $copy = __( 'Copy this section to clipboard' ); |
1596 $return_to_top = '<a href="#" class="return-to-top">' . __( '↑ Return to Top' ) . '</a>'; |
1695 $return_to_top = '<a href="#" class="return-to-top">' . __( '↑ Return to Top' ) . '</a>'; |
1597 |
1696 |
1598 foreach ( $content_array as $section ) { |
1697 foreach ( $content_array as $section ) { |
1599 $class = $meta = $removed = ''; |
1698 $class = $meta = $removed = ''; |
1600 |
1699 |
1601 if ( ! empty( $section['removed'] ) ) { |
1700 if ( ! empty( $section['removed'] ) ) { |
1602 $class = ' text-removed'; |
1701 $class = ' text-removed'; |
1603 $date = date_i18n( $date_format, $section['removed'] ); |
1702 $date = date_i18n( $date_format, $section['removed'] ); |
1604 $meta = sprintf( __( 'Removed %s.' ), $date ); |
1703 $meta = sprintf( __( 'Removed %s.' ), $date ); |
1605 |
1704 |
1606 $removed = __( 'You deactivated this plugin on %s and may no longer need this policy.' ); |
1705 $removed = __( 'You deactivated this plugin on %s and may no longer need this policy.' ); |
1607 $removed = '<div class="error inline"><p>' . sprintf( $removed, $date ) . '</p></div>'; |
1706 $removed = '<div class="error inline"><p>' . sprintf( $removed, $date ) . '</p></div>'; |
1608 } elseif ( ! empty( $section['updated'] ) ) { |
1707 } elseif ( ! empty( $section['updated'] ) ) { |
1609 $class = ' text-updated'; |
1708 $class = ' text-updated'; |
1610 $date = date_i18n( $date_format, $section['updated'] ); |
1709 $date = date_i18n( $date_format, $section['updated'] ); |
1611 $meta = sprintf( __( 'Updated %s.' ), $date ); |
1710 $meta = sprintf( __( 'Updated %s.' ), $date ); |
1612 } |
1711 } |
1613 |
1712 |
1614 if ( $meta ) { |
1713 if ( $meta ) { |
1615 $meta = '<br><span class="privacy-text-meta">' . $meta . '</span>'; |
1714 $meta = '<br><span class="privacy-text-meta">' . $meta . '</span>'; |
1616 } |
1715 } |
1617 |
1716 |
1618 $plugin_name = esc_html( $section['plugin_name'] ); |
1717 $plugin_name = esc_html( $section['plugin_name'] ); |
1619 $toc_id = 'wp-privacy-policy-guide-' . sanitize_title( $plugin_name ); |
1718 $toc_id = 'wp-privacy-policy-guide-' . sanitize_title( $plugin_name ); |
1620 $toc[] = sprintf( '<li><a href="#%1$s">%2$s</a>' . $meta . '</li>', $toc_id, $plugin_name ); |
1719 $toc[] = sprintf( '<li><a href="#%1$s">%2$s</a>' . $meta . '</li>', $toc_id, $plugin_name ); |
1621 |
1720 |
1622 $content .= '<div class="privacy-text-section' . $class . '">'; |
1721 $content .= '<div class="privacy-text-section' . $class . '">'; |
1623 $content .= '<a id="' . $toc_id . '"> </a>'; |
1722 $content .= '<a id="' . $toc_id . '"> </a>'; |
1624 /* translators: %s: plugin name */ |
1723 /* translators: %s: plugin name */ |
1625 $content .= '<h2>' . sprintf( __( 'Source: %s' ), $plugin_name ) . '</h2>'; |
1724 $content .= '<h2>' . sprintf( __( 'Source: %s' ), $plugin_name ) . '</h2>'; |
1627 |
1726 |
1628 $content .= '<div class="policy-text">' . $section['policy_text'] . '</div>'; |
1727 $content .= '<div class="policy-text">' . $section['policy_text'] . '</div>'; |
1629 $content .= $return_to_top; |
1728 $content .= $return_to_top; |
1630 |
1729 |
1631 if ( empty( $section['removed'] ) ) { |
1730 if ( empty( $section['removed'] ) ) { |
1632 $content .= '<div class="privacy-text-actions">'; |
1731 $content .= '<div class="privacy-text-actions">'; |
1633 $content .= '<button type="button" class="privacy-text-copy button">'; |
1732 $content .= '<button type="button" class="privacy-text-copy button">'; |
1634 $content .= $copy; |
1733 $content .= $copy; |
1635 $content .= '<span class="screen-reader-text">' . sprintf( __( 'Copy suggested policy text from %s.' ), $plugin_name ) . '</span>'; |
1734 $content .= '<span class="screen-reader-text">' . sprintf( __( 'Copy suggested policy text from %s.' ), $plugin_name ) . '</span>'; |
1636 $content .= '</button>'; |
1735 $content .= '</button>'; |
1637 $content .= '</div>'; |
1736 $content .= '</div>'; |
1638 } |
1737 } |
1639 |
1738 |
1640 $content .= "</div>\n"; // End of .privacy-text-section. |
1739 $content .= "</div>\n"; // End of .privacy-text-section. |
1641 } |
1740 } |
1642 |
1741 |
1672 |
1771 |
1673 /** |
1772 /** |
1674 * Return the default suggested privacy policy content. |
1773 * Return the default suggested privacy policy content. |
1675 * |
1774 * |
1676 * @since 4.9.6 |
1775 * @since 4.9.6 |
1677 * |
1776 * @since 5.0.0 Added the `$blocks` parameter. |
1678 * @param bool $descr Whether to include the descriptions under the section headings. Default false. |
1777 * |
1778 * @param bool $description Whether to include the descriptions under the section headings. Default false. |
|
1779 * @param bool $blocks Whether to format the content for the block editor. Default true. |
|
1679 * @return string The default policy content. |
1780 * @return string The default policy content. |
1680 */ |
1781 */ |
1681 public static function get_default_content( $descr = false ) { |
1782 public static function get_default_content( $description = false, $blocks = true ) { |
1682 $suggested_text = $descr ? '<strong class="privacy-policy-tutorial">' . __( 'Suggested text:' ) . ' </strong>' : ''; |
1783 $suggested_text = $description ? '<strong class="privacy-policy-tutorial">' . __( 'Suggested text:' ) . ' </strong>' : ''; |
1683 $content = ''; |
1784 $content = ''; |
1785 $strings = array(); |
|
1684 |
1786 |
1685 // Start of the suggested privacy policy text. |
1787 // Start of the suggested privacy policy text. |
1686 $descr && $content .= |
1788 if ( $description ) { |
1687 '<div class="wp-suggested-text">'; |
1789 $strings[] = '<div class="wp-suggested-text">'; |
1688 $content .= |
1790 } |
1689 '<h2>' . __( 'Who we are' ) . '</h2>'; |
1791 |
1690 $descr && $content .= |
1792 /* translators: default privacy policy heading. */ |
1691 '<p class="privacy-policy-tutorial">' . __( 'In this section you should note your site URL, as well as the name of the company, organization, or individual behind it, and some accurate contact information.' ) . '</p>' . |
1793 $strings[] = '<h2>' . __( 'Who we are' ) . '</h2>'; |
1692 '<p class="privacy-policy-tutorial">' . __( 'The amount of information you may be required to show will vary depending on your local or national business regulations. You may, for example, be required to display a physical address, a registered address, or your company registration number.' ) . '</p>'; |
1794 |
1693 $content .= |
1795 if ( $description ) { |
1694 /* translators: %s Site URL */ |
1796 /* translators: privacy policy tutorial. */ |
1695 '<p>' . $suggested_text . sprintf( __( 'Our website address is: %s.' ), get_bloginfo( 'url', 'display' ) ) . '</p>' . |
1797 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this section you should note your site URL, as well as the name of the company, organization, or individual behind it, and some accurate contact information.' ) . '</p>'; |
1696 |
1798 /* translators: privacy policy tutorial. */ |
1697 '<h2>' . __( 'What personal data we collect and why we collect it' ) . '</h2>'; |
1799 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'The amount of information you may be required to show will vary depending on your local or national business regulations. You may, for example, be required to display a physical address, a registered address, or your company registration number.' ) . '</p>'; |
1698 $descr && $content .= |
1800 } |
1699 '<p class="privacy-policy-tutorial">' . __( 'In this section you should note what personal data you collect from users and site visitors. This may include personal data, such as name, email address, personal account preferences; transactional data, such as purchase information; and technical data, such as information about cookies.' ) . '</p>' . |
1801 |
1700 '<p class="privacy-policy-tutorial">' . __( 'You should also note any collection and retention of sensitive personal data, such as data concerning health.' ) . '</p>' . |
1802 /* translators: default privacy policy text, %s Site URL. */ |
1701 '<p class="privacy-policy-tutorial">' . __( 'In addition to listing what personal data you collect, you need to note why you collect it. These explanations must note either the legal basis for your data collection and retention or the active consent the user has given.' ) . '</p>' . |
1803 $strings[] = '<p>' . $suggested_text . sprintf( __( 'Our website address is: %s.' ), get_bloginfo( 'url', 'display' ) ) . '</p>'; |
1702 '<p class="privacy-policy-tutorial">' . __( 'Personal data is not just created by a user’s interactions with your site. Personal data is also generated from technical processes such as contact forms, comments, cookies, analytics, and third party embeds.' ) . '</p>' . |
1804 |
1703 '<p class="privacy-policy-tutorial">' . __( 'By default WordPress does not collect any personal data about visitors, and only collects the data shown on the User Profile screen from registered users. However some of your plugins may collect personal data. You should add the relevant information below.' ) . '</p>'; |
1805 /* translators: default privacy policy heading. */ |
1704 |
1806 $strings[] = '<h2>' . __( 'What personal data we collect and why we collect it' ) . '</h2>'; |
1705 $content .= |
1807 |
1706 '<h3>' . __( 'Comments' ) . '</h3>'; |
1808 if ( $description ) { |
1707 $descr && $content .= |
1809 /* translators: privacy policy tutorial. */ |
1708 '<p class="privacy-policy-tutorial">' . __( 'In this subsection you should note what information is captured through comments. We have noted the data which WordPress collects by default.' ) . '</p>'; |
1810 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this section you should note what personal data you collect from users and site visitors. This may include personal data, such as name, email address, personal account preferences; transactional data, such as purchase information; and technical data, such as information about cookies.' ) . '</p>'; |
1709 $content .= |
1811 /* translators: privacy policy tutorial. */ |
1710 '<p>' . $suggested_text . __( 'When visitors leave comments on the site we collect the data shown in the comments form, and also the visitor’s IP address and browser user agent string to help spam detection.' ) . '</p>' . |
1812 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'You should also note any collection and retention of sensitive personal data, such as data concerning health.' ) . '</p>'; |
1711 '<p>' . __( 'An anonymized string created from your email address (also called a hash) may be provided to the Gravatar service to see if you are using it. The Gravatar service privacy policy is available here: https://automattic.com/privacy/. After approval of your comment, your profile picture is visible to the public in the context of your comment.' ) . '</p>' . |
1813 /* translators: privacy policy tutorial. */ |
1712 |
1814 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In addition to listing what personal data you collect, you need to note why you collect it. These explanations must note either the legal basis for your data collection and retention or the active consent the user has given.' ) . '</p>'; |
1713 '<h3>' . __( 'Media' ) . '</h3>'; |
1815 /* translators: privacy policy tutorial. */ |
1714 $descr && $content .= |
1816 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'Personal data is not just created by a user’s interactions with your site. Personal data is also generated from technical processes such as contact forms, comments, cookies, analytics, and third party embeds.' ) . '</p>'; |
1715 '<p class="privacy-policy-tutorial">' . __( 'In this subsection you should note what information may be disclosed by users who can upload media files. All uploaded files are usually publicly accessible.' ) . '</p>'; |
1817 /* translators: privacy policy tutorial. */ |
1716 $content .= |
1818 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'By default WordPress does not collect any personal data about visitors, and only collects the data shown on the User Profile screen from registered users. However some of your plugins may collect personal data. You should add the relevant information below.' ) . '</p>'; |
1717 '<p>' . $suggested_text . __( 'If you upload images to the website, you should avoid uploading images with embedded location data (EXIF GPS) included. Visitors to the website can download and extract any location data from images on the website.' ) . '</p>' . |
1819 } |
1718 |
1820 |
1719 '<h3>' . __( 'Contact forms' ) . '</h3>'; |
1821 /* translators: default privacy policy heading. */ |
1720 $descr && $content .= |
1822 $strings[] = '<h3>' . __( 'Comments' ) . '</h3>'; |
1721 '<p class="privacy-policy-tutorial">' . __( 'By default, WordPress does not include a contact form. If you use a contact form plugin, use this subsection to note what personal data is captured when someone submits a contact form, and how long you keep it. For example, you may note that you keep contact form submissions for a certain period for customer service purposes, but you do not use the information submitted through them for marketing purposes.' ) . '</p>'; |
1823 |
1722 |
1824 if ( $description ) { |
1723 $content .= |
1825 /* translators: privacy policy tutorial. */ |
1724 '<h3>' . __( 'Cookies' ) . '</h3>'; |
1826 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this subsection you should note what information is captured through comments. We have noted the data which WordPress collects by default.' ) . '</p>'; |
1725 $descr && $content .= |
1827 } |
1726 '<p class="privacy-policy-tutorial">' . __( 'In this subsection you should list the cookies your web site uses, including those set by your plugins, social media, and analytics. We have provided the cookies which WordPress installs by default.' ) . '</p>'; |
1828 |
1727 $content .= |
1829 /* translators: default privacy policy text. */ |
1728 '<p>' . $suggested_text . __( 'If you leave a comment on our site you may opt-in to saving your name, email address and website in cookies. These are for your convenience so that you do not have to fill in your details again when you leave another comment. These cookies will last for one year.' ) . '</p>' . |
1830 $strings[] = '<p>' . $suggested_text . __( 'When visitors leave comments on the site we collect the data shown in the comments form, and also the visitor’s IP address and browser user agent string to help spam detection.' ) . '</p>'; |
1729 '<p>' . __( 'If you have an account and you log in to this site, we will set a temporary cookie to determine if your browser accepts cookies. This cookie contains no personal data and is discarded when you close your browser.' ) . '</p>' . |
1831 /* translators: default privacy policy text. */ |
1730 '<p>' . __( 'When you log in, we will also set up several cookies to save your login information and your screen display choices. Login cookies last for two days, and screen options cookies last for a year. If you select "Remember Me", your login will persist for two weeks. If you log out of your account, the login cookies will be removed.' ) . '</p>' . |
1832 $strings[] = '<p>' . __( 'An anonymized string created from your email address (also called a hash) may be provided to the Gravatar service to see if you are using it. The Gravatar service privacy policy is available here: https://automattic.com/privacy/. After approval of your comment, your profile picture is visible to the public in the context of your comment.' ) . '</p>'; |
1731 '<p>' . __( 'If you edit or publish an article, an additional cookie will be saved in your browser. This cookie includes no personal data and simply indicates the post ID of the article you just edited. It expires after 1 day.' ) . '</p>' . |
1833 |
1732 |
1834 /* translators: default privacy policy heading. */ |
1733 '<h3>' . __( 'Embedded content from other websites' ) . '</h3>' . |
1835 $strings[] = '<h3>' . __( 'Media' ) . '</h3>'; |
1734 '<p>' . $suggested_text . __( 'Articles on this site may include embedded content (e.g. videos, images, articles, etc.). Embedded content from other websites behaves in the exact same way as if the visitor has visited the other website.' ) . '</p>' . |
1836 |
1735 '<p>' . __( 'These websites may collect data about you, use cookies, embed additional third-party tracking, and monitor your interaction with that embedded content, including tracking your interaction with the embedded content if you have an account and are logged in to that website.' ) . '</p>' . |
1837 if ( $description ) { |
1736 |
1838 /* translators: privacy policy tutorial. */ |
1737 '<h3>' . __( 'Analytics' ) . '</h3>'; |
1839 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this subsection you should note what information may be disclosed by users who can upload media files. All uploaded files are usually publicly accessible.' ) . '</p>'; |
1738 $descr && $content .= |
1840 } |
1739 '<p class="privacy-policy-tutorial">' . __( 'In this subsection you should note what analytics package you use, how users can opt out of analytics tracking, and a link to your analytics provider’s privacy policy, if any.' ) . '</p>' . |
1841 |
1740 '<p class="privacy-policy-tutorial">' . __( 'By default WordPress does not collect any analytics data. However, many web hosting accounts collect some anonymous analytics data. You may also have installed a WordPress plugin that provides analytics services. In that case, add information from that plugin here.' ) . '</p>'; |
1842 /* translators: default privacy policy text. */ |
1741 |
1843 $strings[] = '<p>' . $suggested_text . __( 'If you upload images to the website, you should avoid uploading images with embedded location data (EXIF GPS) included. Visitors to the website can download and extract any location data from images on the website.' ) . '</p>'; |
1742 $content .= |
1844 |
1743 '<h2>' . __( 'Who we share your data with' ) . '</h2>'; |
1845 /* translators: default privacy policy heading. */ |
1744 $descr && $content .= |
1846 $strings[] = '<h3>' . __( 'Contact forms' ) . '</h3>'; |
1745 '<p class="privacy-policy-tutorial">' . __( 'In this section you should name and list all third party providers with whom you share site data, including partners, cloud-based services, payment processors, and third party service providers, and note what data you share with them and why. Link to their own privacy policies if possible.' ) . '</p>' . |
1847 |
1746 '<p class="privacy-policy-tutorial">' . __( 'By default WordPress does not share any personal data with anyone.' ) . '</p>'; |
1848 if ( $description ) { |
1747 |
1849 /* translators: privacy policy tutorial. */ |
1748 $content .= |
1850 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'By default, WordPress does not include a contact form. If you use a contact form plugin, use this subsection to note what personal data is captured when someone submits a contact form, and how long you keep it. For example, you may note that you keep contact form submissions for a certain period for customer service purposes, but you do not use the information submitted through them for marketing purposes.' ) . '</p>'; |
1749 '<h2>' . __( 'How long we retain your data' ) . '</h2>'; |
1851 } |
1750 $descr && $content .= |
1852 |
1751 '<p class="privacy-policy-tutorial">' . __( 'In this section you should explain how long you retain personal data collected or processed by the web site. While it is your responsibility to come up with the schedule of how long you keep each dataset for and why you keep it, that information does need to be listed here. For example, you may want to say that you keep contact form entries for six months, analytics records for a year, and customer purchase records for ten years.' ) . '</p>'; |
1853 /* translators: default privacy policy heading. */ |
1752 $content .= |
1854 $strings[] = '<h3>' . __( 'Cookies' ) . '</h3>'; |
1753 '<p>' . $suggested_text . __( 'If you leave a comment, the comment and its metadata are retained indefinitely. This is so we can recognize and approve any follow-up comments automatically instead of holding them in a moderation queue.' ) . '</p>' . |
1855 |
1754 '<p>' . __( 'For users that register on our website (if any), we also store the personal information they provide in their user profile. All users can see, edit, or delete their personal information at any time (except they cannot change their username). Website administrators can also see and edit that information.' ) . '</p>' . |
1856 if ( $description ) { |
1755 |
1857 /* translators: privacy policy tutorial. */ |
1756 '<h2>' . __( 'What rights you have over your data' ) . '</h2>'; |
1858 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this subsection you should list the cookies your web site uses, including those set by your plugins, social media, and analytics. We have provided the cookies which WordPress installs by default.' ) . '</p>'; |
1757 $descr && $content .= |
1859 } |
1758 '<p class="privacy-policy-tutorial">' . __( 'In this section you should explain what rights your users have over their data and how they can invoke those rights.' ) . '</p>'; |
1860 |
1759 $content .= |
1861 /* translators: default privacy policy text. */ |
1760 '<p>' . $suggested_text . __( 'If you have an account on this site, or have left comments, you can request to receive an exported file of the personal data we hold about you, including any data you have provided to us. You can also request that we erase any personal data we hold about you. This does not include any data we are obliged to keep for administrative, legal, or security purposes.' ) . '</p>' . |
1862 $strings[] = '<p>' . $suggested_text . __( 'If you leave a comment on our site you may opt-in to saving your name, email address and website in cookies. These are for your convenience so that you do not have to fill in your details again when you leave another comment. These cookies will last for one year.' ) . '</p>'; |
1761 |
1863 /* translators: default privacy policy text. */ |
1762 '<h2>' . __( 'Where we send your data' ) . '</h2>'; |
1864 $strings[] = '<p>' . __( 'If you visit our login page, we will set a temporary cookie to determine if your browser accepts cookies. This cookie contains no personal data and is discarded when you close your browser.' ) . '</p>'; |
1763 $descr && $content .= |
1865 /* translators: default privacy policy text. */ |
1764 '<p class="privacy-policy-tutorial">' . __( 'In this section you should list all transfers of your site data outside the European Union and describe the means by which that data is safeguarded to European data protection standards. This could include your web hosting, cloud storage, or other third party services.' ) . '</p>' . |
1866 $strings[] = '<p>' . __( 'When you log in, we will also set up several cookies to save your login information and your screen display choices. Login cookies last for two days, and screen options cookies last for a year. If you select "Remember Me", your login will persist for two weeks. If you log out of your account, the login cookies will be removed.' ) . '</p>'; |
1765 '<p class="privacy-policy-tutorial">' . __( 'European data protection law requires data about European residents which is transferred outside the European Union to be safeguarded to the same standards as if the data was in Europe. So in addition to listing where data goes, you should describe how you ensure that these standards are met either by yourself or by your third party providers, whether that is through an agreement such as Privacy Shield, model clauses in your contracts, or binding corporate rules.' ) . '</p>'; |
1867 /* translators: default privacy policy text. */ |
1766 $content .= |
1868 $strings[] = '<p>' . __( 'If you edit or publish an article, an additional cookie will be saved in your browser. This cookie includes no personal data and simply indicates the post ID of the article you just edited. It expires after 1 day.' ) . '</p>'; |
1767 '<p>' . $suggested_text . __( 'Visitor comments may be checked through an automated spam detection service.' ) . '</p>' . |
1869 |
1768 |
1870 /* translators: default privacy policy heading. */ |
1769 '<h2>' . __( 'Your contact information' ) . '</h2>'; |
1871 $strings[] = '<h3>' . __( 'Embedded content from other websites' ) . '</h3>'; |
1770 $descr && $content .= |
1872 /* translators: default privacy policy text. */ |
1771 '<p class="privacy-policy-tutorial">' . __( 'In this section you should provide a contact method for privacy-specific concerns. If you are required to have a Data Protection Officer, list their name and full contact details here as well.' ) . '</p>'; |
1873 $strings[] = '<p>' . $suggested_text . __( 'Articles on this site may include embedded content (e.g. videos, images, articles, etc.). Embedded content from other websites behaves in the exact same way as if the visitor has visited the other website.' ) . '</p>'; |
1772 |
1874 /* translators: default privacy policy text. */ |
1773 $content .= |
1875 $strings[] = '<p>' . __( 'These websites may collect data about you, use cookies, embed additional third-party tracking, and monitor your interaction with that embedded content, including tracking your interaction with the embedded content if you have an account and are logged in to that website.' ) . '</p>'; |
1774 '<h2>' . __( 'Additional information' ) . '</h2>'; |
1876 |
1775 $descr && $content .= |
1877 /* translators: default privacy policy heading. */ |
1776 '<p class="privacy-policy-tutorial">' . __( 'If you use your site for commercial purposes and you engage in more complex collection or processing of personal data, you should note the following information in your privacy policy in addition to the information we have already discussed.' ) . '</p>'; |
1878 $strings[] = '<h3>' . __( 'Analytics' ) . '</h3>'; |
1777 |
1879 |
1778 $content .= |
1880 if ( $description ) { |
1779 '<h3>' . __( 'How we protect your data' ) . '</h3>'; |
1881 /* translators: privacy policy tutorial. */ |
1780 $descr && $content .= |
1882 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this subsection you should note what analytics package you use, how users can opt out of analytics tracking, and a link to your analytics provider’s privacy policy, if any.' ) . '</p>'; |
1781 '<p class="privacy-policy-tutorial">' . __( 'In this section you should explain what measures you have taken to protect your users’ data. This could include technical measures such as encryption; security measures such as two factor authentication; and measures such as staff training in data protection. If you have carried out a Privacy Impact Assessment, you can mention it here too.' ) . '</p>'; |
1883 /* translators: privacy policy tutorial. */ |
1782 |
1884 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'By default WordPress does not collect any analytics data. However, many web hosting accounts collect some anonymous analytics data. You may also have installed a WordPress plugin that provides analytics services. In that case, add information from that plugin here.' ) . '</p>'; |
1783 $content .= |
1885 } |
1784 '<h3>' . __( 'What data breach procedures we have in place' ) . '</h3>'; |
1886 |
1785 $descr && $content .= |
1887 /* translators: default privacy policy heading. */ |
1786 '<p class="privacy-policy-tutorial">' . __( 'In this section you should explain what procedures you have in place to deal with data breaches, either potential or real, such as internal reporting systems, contact mechanisms, or bug bounties.' ) . '</p>'; |
1888 $strings[] = '<h2>' . __( 'Who we share your data with' ) . '</h2>'; |
1787 |
1889 |
1788 $content .= |
1890 if ( $description ) { |
1789 '<h3>' . __( 'What third parties we receive data from' ) . '</h3>'; |
1891 /* translators: privacy policy tutorial. */ |
1790 $descr && $content .= |
1892 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this section you should name and list all third party providers with whom you share site data, including partners, cloud-based services, payment processors, and third party service providers, and note what data you share with them and why. Link to their own privacy policies if possible.' ) . '</p>'; |
1791 '<p class="privacy-policy-tutorial">' . __( 'If your web site receives data about users from third parties, including advertisers, this information must be included within the section of your privacy policy dealing with third party data.' ) . '</p>'; |
1893 /* translators: privacy policy tutorial. */ |
1792 |
1894 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'By default WordPress does not share any personal data with anyone.' ) . '</p>'; |
1793 $content .= |
1895 } |
1794 '<h3>' . __( 'What automated decision making and/or profiling we do with user data' ) . '</h3>'; |
1896 |
1795 $descr && $content .= |
1897 /* translators: default privacy policy heading. */ |
1796 '<p class="privacy-policy-tutorial">' . __( 'If your web site provides a service which includes automated decision making - for example, allowing customers to apply for credit, or aggregating their data into an advertising profile - you must note that this is taking place, and include information about how that information is used, what decisions are made with that aggregated data, and what rights users have over decisions made without human intervention.' ) . '</p>'; |
1898 $strings[] = '<h2>' . __( 'How long we retain your data' ) . '</h2>'; |
1797 |
1899 |
1798 $content .= |
1900 if ( $description ) { |
1799 '<h3>' . __( 'Industry regulatory disclosure requirements' ) . '</h3>'; |
1901 /* translators: privacy policy tutorial. */ |
1800 $descr && $content .= |
1902 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this section you should explain how long you retain personal data collected or processed by the web site. While it is your responsibility to come up with the schedule of how long you keep each dataset for and why you keep it, that information does need to be listed here. For example, you may want to say that you keep contact form entries for six months, analytics records for a year, and customer purchase records for ten years.' ) . '</p>'; |
1801 '<p class="privacy-policy-tutorial">' . __( 'If you are a member of a regulated industry, or if you are subject to additional privacy laws, you may be required to disclose that information here.' ) . '</p>' . |
1903 } |
1802 '</div>'; |
1904 |
1905 /* translators: default privacy policy text. */ |
|
1906 $strings[] = '<p>' . $suggested_text . __( 'If you leave a comment, the comment and its metadata are retained indefinitely. This is so we can recognize and approve any follow-up comments automatically instead of holding them in a moderation queue.' ) . '</p>'; |
|
1907 /* translators: default privacy policy text. */ |
|
1908 $strings[] = '<p>' . __( 'For users that register on our website (if any), we also store the personal information they provide in their user profile. All users can see, edit, or delete their personal information at any time (except they cannot change their username). Website administrators can also see and edit that information.' ) . '</p>'; |
|
1909 |
|
1910 /* translators: default privacy policy heading. */ |
|
1911 $strings[] = '<h2>' . __( 'What rights you have over your data' ) . '</h2>'; |
|
1912 |
|
1913 if ( $description ) { |
|
1914 /* translators: privacy policy tutorial. */ |
|
1915 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this section you should explain what rights your users have over their data and how they can invoke those rights.' ) . '</p>'; |
|
1916 } |
|
1917 |
|
1918 /* translators: default privacy policy text. */ |
|
1919 $strings[] = '<p>' . $suggested_text . __( 'If you have an account on this site, or have left comments, you can request to receive an exported file of the personal data we hold about you, including any data you have provided to us. You can also request that we erase any personal data we hold about you. This does not include any data we are obliged to keep for administrative, legal, or security purposes.' ) . '</p>'; |
|
1920 |
|
1921 /* translators: default privacy policy heading. */ |
|
1922 $strings[] = '<h2>' . __( 'Where we send your data' ) . '</h2>'; |
|
1923 |
|
1924 if ( $description ) { |
|
1925 /* translators: privacy policy tutorial. */ |
|
1926 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this section you should list all transfers of your site data outside the European Union and describe the means by which that data is safeguarded to European data protection standards. This could include your web hosting, cloud storage, or other third party services.' ) . '</p>'; |
|
1927 /* translators: privacy policy tutorial. */ |
|
1928 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'European data protection law requires data about European residents which is transferred outside the European Union to be safeguarded to the same standards as if the data was in Europe. So in addition to listing where data goes, you should describe how you ensure that these standards are met either by yourself or by your third party providers, whether that is through an agreement such as Privacy Shield, model clauses in your contracts, or binding corporate rules.' ) . '</p>'; |
|
1929 } |
|
1930 |
|
1931 /* translators: default privacy policy text. */ |
|
1932 $strings[] = '<p>' . $suggested_text . __( 'Visitor comments may be checked through an automated spam detection service.' ) . '</p>'; |
|
1933 |
|
1934 /* translators: default privacy policy heading. */ |
|
1935 $strings[] = '<h2>' . __( 'Your contact information' ) . '</h2>'; |
|
1936 |
|
1937 if ( $description ) { |
|
1938 /* translators: privacy policy tutorial. */ |
|
1939 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this section you should provide a contact method for privacy-specific concerns. If you are required to have a Data Protection Officer, list their name and full contact details here as well.' ) . '</p>'; |
|
1940 } |
|
1941 |
|
1942 /* translators: default privacy policy heading. */ |
|
1943 $strings[] = '<h2>' . __( 'Additional information' ) . '</h2>'; |
|
1944 |
|
1945 if ( $description ) { |
|
1946 /* translators: privacy policy tutorial. */ |
|
1947 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'If you use your site for commercial purposes and you engage in more complex collection or processing of personal data, you should note the following information in your privacy policy in addition to the information we have already discussed.' ) . '</p>'; |
|
1948 } |
|
1949 |
|
1950 /* translators: default privacy policy heading. */ |
|
1951 $strings[] = '<h3>' . __( 'How we protect your data' ) . '</h3>'; |
|
1952 |
|
1953 if ( $description ) { |
|
1954 /* translators: privacy policy tutorial. */ |
|
1955 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this section you should explain what measures you have taken to protect your users’ data. This could include technical measures such as encryption; security measures such as two factor authentication; and measures such as staff training in data protection. If you have carried out a Privacy Impact Assessment, you can mention it here too.' ) . '</p>'; |
|
1956 } |
|
1957 |
|
1958 /* translators: default privacy policy heading. */ |
|
1959 $strings[] = '<h3>' . __( 'What data breach procedures we have in place' ) . '</h3>'; |
|
1960 |
|
1961 if ( $description ) { |
|
1962 /* translators: privacy policy tutorial. */ |
|
1963 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'In this section you should explain what procedures you have in place to deal with data breaches, either potential or real, such as internal reporting systems, contact mechanisms, or bug bounties.' ) . '</p>'; |
|
1964 } |
|
1965 |
|
1966 /* translators: default privacy policy heading. */ |
|
1967 $strings[] = '<h3>' . __( 'What third parties we receive data from' ) . '</h3>'; |
|
1968 |
|
1969 if ( $description ) { |
|
1970 /* translators: privacy policy tutorial. */ |
|
1971 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'If your web site receives data about users from third parties, including advertisers, this information must be included within the section of your privacy policy dealing with third party data.' ) . '</p>'; |
|
1972 } |
|
1973 |
|
1974 /* translators: default privacy policy heading. */ |
|
1975 $strings[] = '<h3>' . __( 'What automated decision making and/or profiling we do with user data' ) . '</h3>'; |
|
1976 |
|
1977 if ( $description ) { |
|
1978 /* translators: privacy policy tutorial. */ |
|
1979 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'If your web site provides a service which includes automated decision making - for example, allowing customers to apply for credit, or aggregating their data into an advertising profile - you must note that this is taking place, and include information about how that information is used, what decisions are made with that aggregated data, and what rights users have over decisions made without human intervention.' ) . '</p>'; |
|
1980 } |
|
1981 |
|
1982 /* translators: default privacy policy heading. */ |
|
1983 $strings[] = '<h3>' . __( 'Industry regulatory disclosure requirements' ) . '</h3>'; |
|
1984 |
|
1985 if ( $description ) { |
|
1986 /* translators: privacy policy tutorial. */ |
|
1987 $strings[] = '<p class="privacy-policy-tutorial">' . __( 'If you are a member of a regulated industry, or if you are subject to additional privacy laws, you may be required to disclose that information here.' ) . '</p>'; |
|
1988 $strings[] = '</div>'; |
|
1989 } |
|
1990 |
|
1991 if ( $blocks ) { |
|
1992 foreach ( $strings as $key => $string ) { |
|
1993 if ( 0 === strpos( $string, '<p>' ) ) { |
|
1994 $strings[ $key ] = '<!-- wp:paragraph -->' . $string . '<!-- /wp:paragraph -->'; |
|
1995 } |
|
1996 |
|
1997 if ( 0 === strpos( $string, '<h2>' ) ) { |
|
1998 $strings[ $key ] = '<!-- wp:heading -->' . $string . '<!-- /wp:heading -->'; |
|
1999 } |
|
2000 |
|
2001 if ( 0 === strpos( $string, '<h3>' ) ) { |
|
2002 $strings[ $key ] = '<!-- wp:heading {"level":3} -->' . $string . '<!-- /wp:heading -->'; |
|
2003 } |
|
2004 } |
|
2005 } |
|
2006 |
|
2007 $content = implode( '', $strings ); |
|
1803 // End of the suggested privacy policy text. |
2008 // End of the suggested privacy policy text. |
1804 |
2009 |
1805 /** |
2010 /** |
1806 * Filters the default content suggested for inclusion in a privacy policy. |
2011 * Filters the default content suggested for inclusion in a privacy policy. |
1807 * |
2012 * |
1808 * @since 4.9.6 |
2013 * @since 4.9.6 |
2014 * @since 5.0.0 Added the `$strings`, `$description`, and `$blocks` parameters. |
|
1809 * |
2015 * |
1810 * @param $content string The default policy content. |
2016 * @param string $content The default policy content. |
2017 * @param array $strings An array of privacy policy content strings. |
|
2018 * @param bool $description Whether policy descriptions should be included. |
|
2019 * @param bool $blocks Whether the content should be formatted for the block editor. |
|
1811 */ |
2020 */ |
1812 return apply_filters( 'wp_get_default_privacy_policy_content', $content ); |
2021 return apply_filters( 'wp_get_default_privacy_policy_content', $content, $strings, $description, $blocks ); |
1813 } |
2022 } |
1814 |
2023 |
1815 /** |
2024 /** |
1816 * Add the suggested privacy policy text to the policy postbox. |
2025 * Add the suggested privacy policy text to the policy postbox. |
1817 * |
2026 * |
1818 * @since 4.9.6 |
2027 * @since 4.9.6 |
1819 */ |
2028 */ |
1820 public static function add_suggested_content() { |
2029 public static function add_suggested_content() { |
1821 $content = self::get_default_content( true ); |
2030 $content = self::get_default_content( true, false ); |
1822 wp_add_privacy_policy_content( __( 'WordPress' ), $content ); |
2031 wp_add_privacy_policy_content( __( 'WordPress' ), $content ); |
1823 } |
2032 } |
1824 } |
2033 } |
2034 |
|
2035 /** |
|
2036 * Checks if the user needs to update PHP. |
|
2037 * |
|
2038 * @since 5.1.0 |
|
2039 * @since 5.1.1 Added the {@see 'wp_is_php_version_acceptable'} filter. |
|
2040 * |
|
2041 * @return array|false $response Array of PHP version data. False on failure. |
|
2042 */ |
|
2043 function wp_check_php_version() { |
|
2044 $version = phpversion(); |
|
2045 $key = md5( $version ); |
|
2046 |
|
2047 $response = get_site_transient( 'php_check_' . $key ); |
|
2048 if ( false === $response ) { |
|
2049 $url = 'http://api.wordpress.org/core/serve-happy/1.0/'; |
|
2050 if ( wp_http_supports( array( 'ssl' ) ) ) { |
|
2051 $url = set_url_scheme( $url, 'https' ); |
|
2052 } |
|
2053 |
|
2054 $url = add_query_arg( 'php_version', $version, $url ); |
|
2055 |
|
2056 $response = wp_remote_get( $url ); |
|
2057 |
|
2058 if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { |
|
2059 return false; |
|
2060 } |
|
2061 |
|
2062 /** |
|
2063 * Response should be an array with: |
|
2064 * 'recommended_version' - string - The PHP version recommended by WordPress. |
|
2065 * 'is_supported' - boolean - Whether the PHP version is actively supported. |
|
2066 * 'is_secure' - boolean - Whether the PHP version receives security updates. |
|
2067 * 'is_acceptable' - boolean - Whether the PHP version is still acceptable for WordPress. |
|
2068 */ |
|
2069 $response = json_decode( wp_remote_retrieve_body( $response ), true ); |
|
2070 |
|
2071 if ( ! is_array( $response ) ) { |
|
2072 return false; |
|
2073 } |
|
2074 |
|
2075 set_site_transient( 'php_check_' . $key, $response, WEEK_IN_SECONDS ); |
|
2076 } |
|
2077 |
|
2078 if ( isset( $response['is_acceptable'] ) && $response['is_acceptable'] ) { |
|
2079 /** |
|
2080 * Filters whether the active PHP version is considered acceptable by WordPress. |
|
2081 * |
|
2082 * Returning false will trigger a PHP version warning to show up in the admin dashboard to administrators. |
|
2083 * |
|
2084 * This filter is only run if the wordpress.org Serve Happy API considers the PHP version acceptable, ensuring |
|
2085 * that this filter can only make this check stricter, but not loosen it. |
|
2086 * |
|
2087 * @since 5.1.1 |
|
2088 * |
|
2089 * @param bool $is_acceptable Whether the PHP version is considered acceptable. Default true. |
|
2090 * @param string $version PHP version checked. |
|
2091 */ |
|
2092 $response['is_acceptable'] = (bool) apply_filters( 'wp_is_php_version_acceptable', true, $version ); |
|
2093 } |
|
2094 |
|
2095 return $response; |
|
2096 } |