080600
This commit is contained in:
@@ -1,174 +1,174 @@
|
||||
<?php
|
||||
/**
|
||||
* Administration API: Default admin hooks
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.3.0
|
||||
*/
|
||||
|
||||
// Bookmark hooks.
|
||||
add_action( 'admin_page_access_denied', 'wp_link_manager_disabled_message' );
|
||||
|
||||
// Dashboard hooks.
|
||||
add_action( 'activity_box_end', 'wp_dashboard_quota' );
|
||||
add_action( 'welcome_panel', 'wp_welcome_panel' );
|
||||
|
||||
// Media hooks.
|
||||
add_action( 'attachment_submitbox_misc_actions', 'attachment_submitbox_metadata' );
|
||||
add_filter( 'plupload_init', 'wp_show_heic_upload_error' );
|
||||
|
||||
add_action( 'media_upload_image', 'wp_media_upload_handler' );
|
||||
add_action( 'media_upload_audio', 'wp_media_upload_handler' );
|
||||
add_action( 'media_upload_video', 'wp_media_upload_handler' );
|
||||
add_action( 'media_upload_file', 'wp_media_upload_handler' );
|
||||
|
||||
add_action( 'post-plupload-upload-ui', 'media_upload_flash_bypass' );
|
||||
|
||||
add_action( 'post-html-upload-ui', 'media_upload_html_bypass' );
|
||||
|
||||
add_filter( 'async_upload_image', 'get_media_item', 10, 2 );
|
||||
add_filter( 'async_upload_audio', 'get_media_item', 10, 2 );
|
||||
add_filter( 'async_upload_video', 'get_media_item', 10, 2 );
|
||||
add_filter( 'async_upload_file', 'get_media_item', 10, 2 );
|
||||
|
||||
add_filter( 'media_upload_gallery', 'media_upload_gallery' );
|
||||
add_filter( 'media_upload_library', 'media_upload_library' );
|
||||
|
||||
add_filter( 'media_upload_tabs', 'update_gallery_tab' );
|
||||
|
||||
// Admin color schemes.
|
||||
add_action( 'admin_init', 'register_admin_color_schemes', 1 );
|
||||
add_action( 'admin_head', 'wp_color_scheme_settings' );
|
||||
add_action( 'admin_color_scheme_picker', 'admin_color_scheme_picker' );
|
||||
|
||||
// Misc hooks.
|
||||
add_action( 'admin_init', 'wp_admin_headers' );
|
||||
add_action( 'login_init', 'wp_admin_headers' );
|
||||
add_action( 'admin_init', 'send_frame_options_header', 10, 0 );
|
||||
add_action( 'admin_head', 'wp_admin_canonical_url' );
|
||||
add_action( 'admin_head', 'wp_site_icon' );
|
||||
add_action( 'admin_head', 'wp_admin_viewport_meta' );
|
||||
add_action( 'customize_controls_head', 'wp_admin_viewport_meta' );
|
||||
add_filter( 'nav_menu_meta_box_object', '_wp_nav_menu_meta_box_object' );
|
||||
|
||||
// Prerendering.
|
||||
if ( ! is_customize_preview() ) {
|
||||
add_filter( 'admin_print_styles', 'wp_resource_hints', 1 );
|
||||
}
|
||||
|
||||
add_action( 'admin_print_scripts', 'print_emoji_detection_script' );
|
||||
add_action( 'admin_print_scripts', 'print_head_scripts', 20 );
|
||||
add_action( 'admin_print_footer_scripts', '_wp_footer_scripts' );
|
||||
add_action( 'admin_enqueue_scripts', 'wp_enqueue_emoji_styles' );
|
||||
add_action( 'admin_print_styles', 'print_emoji_styles' ); // Retained for backwards-compatibility. Unhooked by wp_enqueue_emoji_styles().
|
||||
add_action( 'admin_print_styles', 'print_admin_styles', 20 );
|
||||
|
||||
add_action( 'admin_print_scripts-index.php', 'wp_localize_community_events' );
|
||||
add_action( 'admin_print_scripts-post.php', 'wp_page_reload_on_back_button_js' );
|
||||
add_action( 'admin_print_scripts-post-new.php', 'wp_page_reload_on_back_button_js' );
|
||||
|
||||
add_action( 'update_option_home', 'update_home_siteurl', 10, 2 );
|
||||
add_action( 'update_option_siteurl', 'update_home_siteurl', 10, 2 );
|
||||
add_action( 'update_option_page_on_front', 'update_home_siteurl', 10, 2 );
|
||||
add_action( 'update_option_admin_email', 'wp_site_admin_email_change_notification', 10, 3 );
|
||||
|
||||
add_action( 'add_option_new_admin_email', 'update_option_new_admin_email', 10, 2 );
|
||||
add_action( 'update_option_new_admin_email', 'update_option_new_admin_email', 10, 2 );
|
||||
|
||||
add_filter( 'heartbeat_received', 'wp_check_locked_posts', 10, 3 );
|
||||
add_filter( 'heartbeat_received', 'wp_refresh_post_lock', 10, 3 );
|
||||
add_filter( 'heartbeat_received', 'heartbeat_autosave', 500, 2 );
|
||||
|
||||
add_filter( 'wp_refresh_nonces', 'wp_refresh_post_nonces', 10, 3 );
|
||||
add_filter( 'wp_refresh_nonces', 'wp_refresh_metabox_loader_nonces', 10, 2 );
|
||||
add_filter( 'wp_refresh_nonces', 'wp_refresh_heartbeat_nonces' );
|
||||
|
||||
add_filter( 'heartbeat_settings', 'wp_heartbeat_set_suspension' );
|
||||
|
||||
add_action( 'use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2 );
|
||||
add_action( 'edit_form_after_title', '_disable_content_editor_for_navigation_post_type' );
|
||||
add_action( 'edit_form_after_editor', '_enable_content_editor_for_navigation_post_type' );
|
||||
|
||||
// Nav Menu hooks.
|
||||
add_action( 'admin_head-nav-menus.php', '_wp_delete_orphaned_draft_menu_items' );
|
||||
|
||||
// Plugin hooks.
|
||||
add_filter( 'allowed_options', 'option_update_filter' );
|
||||
|
||||
// Plugin Install hooks.
|
||||
add_action( 'install_plugins_featured', 'install_dashboard' );
|
||||
add_action( 'install_plugins_upload', 'install_plugins_upload' );
|
||||
add_action( 'install_plugins_search', 'display_plugins_table' );
|
||||
add_action( 'install_plugins_popular', 'display_plugins_table' );
|
||||
add_action( 'install_plugins_recommended', 'display_plugins_table' );
|
||||
add_action( 'install_plugins_new', 'display_plugins_table' );
|
||||
add_action( 'install_plugins_beta', 'display_plugins_table' );
|
||||
add_action( 'install_plugins_favorites', 'display_plugins_table' );
|
||||
add_action( 'install_plugins_pre_plugin-information', 'install_plugin_information' );
|
||||
|
||||
// Template hooks.
|
||||
add_action( 'admin_enqueue_scripts', array( 'WP_Internal_Pointers', 'enqueue_scripts' ) );
|
||||
add_action( 'user_register', array( 'WP_Internal_Pointers', 'dismiss_pointers_for_new_users' ) );
|
||||
|
||||
// Theme hooks.
|
||||
add_action( 'customize_controls_print_footer_scripts', 'customize_themes_print_templates' );
|
||||
|
||||
// Theme Install hooks.
|
||||
add_action( 'install_themes_pre_theme-information', 'install_theme_information' );
|
||||
|
||||
// User hooks.
|
||||
add_action( 'admin_init', 'default_password_nag_handler' );
|
||||
|
||||
add_action( 'admin_notices', 'default_password_nag' );
|
||||
add_action( 'admin_notices', 'new_user_email_admin_notice' );
|
||||
|
||||
add_action( 'profile_update', 'default_password_nag_edit_user', 10, 2 );
|
||||
|
||||
add_action( 'personal_options_update', 'send_confirmation_on_profile_email' );
|
||||
|
||||
// Update hooks.
|
||||
add_action( 'load-plugins.php', 'wp_plugin_update_rows', 20 ); // After wp_update_plugins() is called.
|
||||
add_action( 'load-themes.php', 'wp_theme_update_rows', 20 ); // After wp_update_themes() is called.
|
||||
|
||||
add_action( 'admin_notices', 'update_nag', 3 );
|
||||
add_action( 'admin_notices', 'deactivated_plugins_notice', 5 );
|
||||
add_action( 'admin_notices', 'paused_plugins_notice', 5 );
|
||||
add_action( 'admin_notices', 'paused_themes_notice', 5 );
|
||||
add_action( 'admin_notices', 'maintenance_nag', 10 );
|
||||
add_action( 'admin_notices', 'wp_recovery_mode_nag', 1 );
|
||||
|
||||
add_filter( 'update_footer', 'core_update_footer' );
|
||||
|
||||
// Update Core hooks.
|
||||
add_action( '_core_updated_successfully', '_redirect_to_about_wordpress' );
|
||||
|
||||
// Upgrade hooks.
|
||||
add_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
|
||||
add_action( 'upgrader_process_complete', 'wp_version_check', 10, 0 );
|
||||
add_action( 'upgrader_process_complete', 'wp_update_plugins', 10, 0 );
|
||||
add_action( 'upgrader_process_complete', 'wp_update_themes', 10, 0 );
|
||||
|
||||
// Privacy hooks.
|
||||
add_filter( 'wp_privacy_personal_data_erasure_page', 'wp_privacy_process_personal_data_erasure_page', 10, 5 );
|
||||
add_filter( 'wp_privacy_personal_data_export_page', 'wp_privacy_process_personal_data_export_page', 10, 7 );
|
||||
add_action( 'wp_privacy_personal_data_export_file', 'wp_privacy_generate_personal_data_export_file', 10 );
|
||||
add_action( 'wp_privacy_personal_data_erased', '_wp_privacy_send_erasure_fulfillment_notification', 10 );
|
||||
|
||||
// Privacy policy text changes check.
|
||||
add_action( 'admin_init', array( 'WP_Privacy_Policy_Content', 'text_change_check' ), 100 );
|
||||
|
||||
// Show a "postbox" with the text suggestions for a privacy policy.
|
||||
add_action( 'admin_notices', array( 'WP_Privacy_Policy_Content', 'notice' ) );
|
||||
|
||||
// Add the suggested policy text from WordPress.
|
||||
add_action( 'admin_init', array( 'WP_Privacy_Policy_Content', 'add_suggested_content' ), 1 );
|
||||
|
||||
// Update the cached policy info when the policy page is updated.
|
||||
add_action( 'post_updated', array( 'WP_Privacy_Policy_Content', '_policy_page_updated' ) );
|
||||
|
||||
// Append '(Draft)' to draft page titles in the privacy page dropdown.
|
||||
add_filter( 'list_pages', '_wp_privacy_settings_filter_draft_page_titles', 10, 2 );
|
||||
|
||||
// Font management.
|
||||
add_action( 'admin_print_styles', 'wp_print_font_faces', 50 );
|
||||
<?php
|
||||
/**
|
||||
* Administration API: Default admin hooks
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.3.0
|
||||
*/
|
||||
|
||||
// Bookmark hooks.
|
||||
add_action( 'admin_page_access_denied', 'wp_link_manager_disabled_message' );
|
||||
|
||||
// Dashboard hooks.
|
||||
add_action( 'activity_box_end', 'wp_dashboard_quota' );
|
||||
add_action( 'welcome_panel', 'wp_welcome_panel' );
|
||||
|
||||
// Media hooks.
|
||||
add_action( 'attachment_submitbox_misc_actions', 'attachment_submitbox_metadata' );
|
||||
add_filter( 'plupload_init', 'wp_show_heic_upload_error' );
|
||||
|
||||
add_action( 'media_upload_image', 'wp_media_upload_handler' );
|
||||
add_action( 'media_upload_audio', 'wp_media_upload_handler' );
|
||||
add_action( 'media_upload_video', 'wp_media_upload_handler' );
|
||||
add_action( 'media_upload_file', 'wp_media_upload_handler' );
|
||||
|
||||
add_action( 'post-plupload-upload-ui', 'media_upload_flash_bypass' );
|
||||
|
||||
add_action( 'post-html-upload-ui', 'media_upload_html_bypass' );
|
||||
|
||||
add_filter( 'async_upload_image', 'get_media_item', 10, 2 );
|
||||
add_filter( 'async_upload_audio', 'get_media_item', 10, 2 );
|
||||
add_filter( 'async_upload_video', 'get_media_item', 10, 2 );
|
||||
add_filter( 'async_upload_file', 'get_media_item', 10, 2 );
|
||||
|
||||
add_filter( 'media_upload_gallery', 'media_upload_gallery' );
|
||||
add_filter( 'media_upload_library', 'media_upload_library' );
|
||||
|
||||
add_filter( 'media_upload_tabs', 'update_gallery_tab' );
|
||||
|
||||
// Admin color schemes.
|
||||
add_action( 'admin_init', 'register_admin_color_schemes', 1 );
|
||||
add_action( 'admin_head', 'wp_color_scheme_settings' );
|
||||
add_action( 'admin_color_scheme_picker', 'admin_color_scheme_picker' );
|
||||
|
||||
// Misc hooks.
|
||||
add_action( 'admin_init', 'wp_admin_headers' );
|
||||
add_action( 'login_init', 'wp_admin_headers' );
|
||||
add_action( 'admin_init', 'send_frame_options_header', 10, 0 );
|
||||
add_action( 'admin_head', 'wp_admin_canonical_url' );
|
||||
add_action( 'admin_head', 'wp_site_icon' );
|
||||
add_action( 'admin_head', 'wp_admin_viewport_meta' );
|
||||
add_action( 'customize_controls_head', 'wp_admin_viewport_meta' );
|
||||
add_filter( 'nav_menu_meta_box_object', '_wp_nav_menu_meta_box_object' );
|
||||
|
||||
// Prerendering.
|
||||
if ( ! is_customize_preview() ) {
|
||||
add_filter( 'admin_print_styles', 'wp_resource_hints', 1 );
|
||||
}
|
||||
|
||||
add_action( 'admin_print_scripts', 'print_emoji_detection_script' );
|
||||
add_action( 'admin_print_scripts', 'print_head_scripts', 20 );
|
||||
add_action( 'admin_print_footer_scripts', '_wp_footer_scripts' );
|
||||
add_action( 'admin_enqueue_scripts', 'wp_enqueue_emoji_styles' );
|
||||
add_action( 'admin_print_styles', 'print_emoji_styles' ); // Retained for backwards-compatibility. Unhooked by wp_enqueue_emoji_styles().
|
||||
add_action( 'admin_print_styles', 'print_admin_styles', 20 );
|
||||
|
||||
add_action( 'admin_print_scripts-index.php', 'wp_localize_community_events' );
|
||||
add_action( 'admin_print_scripts-post.php', 'wp_page_reload_on_back_button_js' );
|
||||
add_action( 'admin_print_scripts-post-new.php', 'wp_page_reload_on_back_button_js' );
|
||||
|
||||
add_action( 'update_option_home', 'update_home_siteurl', 10, 2 );
|
||||
add_action( 'update_option_siteurl', 'update_home_siteurl', 10, 2 );
|
||||
add_action( 'update_option_page_on_front', 'update_home_siteurl', 10, 2 );
|
||||
add_action( 'update_option_admin_email', 'wp_site_admin_email_change_notification', 10, 3 );
|
||||
|
||||
add_action( 'add_option_new_admin_email', 'update_option_new_admin_email', 10, 2 );
|
||||
add_action( 'update_option_new_admin_email', 'update_option_new_admin_email', 10, 2 );
|
||||
|
||||
add_filter( 'heartbeat_received', 'wp_check_locked_posts', 10, 3 );
|
||||
add_filter( 'heartbeat_received', 'wp_refresh_post_lock', 10, 3 );
|
||||
add_filter( 'heartbeat_received', 'heartbeat_autosave', 500, 2 );
|
||||
|
||||
add_filter( 'wp_refresh_nonces', 'wp_refresh_post_nonces', 10, 3 );
|
||||
add_filter( 'wp_refresh_nonces', 'wp_refresh_metabox_loader_nonces', 10, 2 );
|
||||
add_filter( 'wp_refresh_nonces', 'wp_refresh_heartbeat_nonces' );
|
||||
|
||||
add_filter( 'heartbeat_settings', 'wp_heartbeat_set_suspension' );
|
||||
|
||||
add_action( 'use_block_editor_for_post_type', '_disable_block_editor_for_navigation_post_type', 10, 2 );
|
||||
add_action( 'edit_form_after_title', '_disable_content_editor_for_navigation_post_type' );
|
||||
add_action( 'edit_form_after_editor', '_enable_content_editor_for_navigation_post_type' );
|
||||
|
||||
// Nav Menu hooks.
|
||||
add_action( 'admin_head-nav-menus.php', '_wp_delete_orphaned_draft_menu_items' );
|
||||
|
||||
// Plugin hooks.
|
||||
add_filter( 'allowed_options', 'option_update_filter' );
|
||||
|
||||
// Plugin Install hooks.
|
||||
add_action( 'install_plugins_featured', 'install_dashboard' );
|
||||
add_action( 'install_plugins_upload', 'install_plugins_upload' );
|
||||
add_action( 'install_plugins_search', 'display_plugins_table' );
|
||||
add_action( 'install_plugins_popular', 'display_plugins_table' );
|
||||
add_action( 'install_plugins_recommended', 'display_plugins_table' );
|
||||
add_action( 'install_plugins_new', 'display_plugins_table' );
|
||||
add_action( 'install_plugins_beta', 'display_plugins_table' );
|
||||
add_action( 'install_plugins_favorites', 'display_plugins_table' );
|
||||
add_action( 'install_plugins_pre_plugin-information', 'install_plugin_information' );
|
||||
|
||||
// Template hooks.
|
||||
add_action( 'admin_enqueue_scripts', array( 'WP_Internal_Pointers', 'enqueue_scripts' ) );
|
||||
add_action( 'user_register', array( 'WP_Internal_Pointers', 'dismiss_pointers_for_new_users' ) );
|
||||
|
||||
// Theme hooks.
|
||||
add_action( 'customize_controls_print_footer_scripts', 'customize_themes_print_templates' );
|
||||
|
||||
// Theme Install hooks.
|
||||
add_action( 'install_themes_pre_theme-information', 'install_theme_information' );
|
||||
|
||||
// User hooks.
|
||||
add_action( 'admin_init', 'default_password_nag_handler' );
|
||||
|
||||
add_action( 'admin_notices', 'default_password_nag' );
|
||||
add_action( 'admin_notices', 'new_user_email_admin_notice' );
|
||||
|
||||
add_action( 'profile_update', 'default_password_nag_edit_user', 10, 2 );
|
||||
|
||||
add_action( 'personal_options_update', 'send_confirmation_on_profile_email' );
|
||||
|
||||
// Update hooks.
|
||||
add_action( 'load-plugins.php', 'wp_plugin_update_rows', 20 ); // After wp_update_plugins() is called.
|
||||
add_action( 'load-themes.php', 'wp_theme_update_rows', 20 ); // After wp_update_themes() is called.
|
||||
|
||||
add_action( 'admin_notices', 'update_nag', 3 );
|
||||
add_action( 'admin_notices', 'deactivated_plugins_notice', 5 );
|
||||
add_action( 'admin_notices', 'paused_plugins_notice', 5 );
|
||||
add_action( 'admin_notices', 'paused_themes_notice', 5 );
|
||||
add_action( 'admin_notices', 'maintenance_nag', 10 );
|
||||
add_action( 'admin_notices', 'wp_recovery_mode_nag', 1 );
|
||||
|
||||
add_filter( 'update_footer', 'core_update_footer' );
|
||||
|
||||
// Update Core hooks.
|
||||
add_action( '_core_updated_successfully', '_redirect_to_about_wordpress' );
|
||||
|
||||
// Upgrade hooks.
|
||||
add_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
|
||||
add_action( 'upgrader_process_complete', 'wp_version_check', 10, 0 );
|
||||
add_action( 'upgrader_process_complete', 'wp_update_plugins', 10, 0 );
|
||||
add_action( 'upgrader_process_complete', 'wp_update_themes', 10, 0 );
|
||||
|
||||
// Privacy hooks.
|
||||
add_filter( 'wp_privacy_personal_data_erasure_page', 'wp_privacy_process_personal_data_erasure_page', 10, 5 );
|
||||
add_filter( 'wp_privacy_personal_data_export_page', 'wp_privacy_process_personal_data_export_page', 10, 7 );
|
||||
add_action( 'wp_privacy_personal_data_export_file', 'wp_privacy_generate_personal_data_export_file', 10 );
|
||||
add_action( 'wp_privacy_personal_data_erased', '_wp_privacy_send_erasure_fulfillment_notification', 10 );
|
||||
|
||||
// Privacy policy text changes check.
|
||||
add_action( 'admin_init', array( 'WP_Privacy_Policy_Content', 'text_change_check' ), 100 );
|
||||
|
||||
// Show a "postbox" with the text suggestions for a privacy policy.
|
||||
add_action( 'admin_notices', array( 'WP_Privacy_Policy_Content', 'notice' ) );
|
||||
|
||||
// Add the suggested policy text from WordPress.
|
||||
add_action( 'admin_init', array( 'WP_Privacy_Policy_Content', 'add_suggested_content' ), 1 );
|
||||
|
||||
// Update the cached policy info when the policy page is updated.
|
||||
add_action( 'post_updated', array( 'WP_Privacy_Policy_Content', '_policy_page_updated' ) );
|
||||
|
||||
// Append '(Draft)' to draft page titles in the privacy page dropdown.
|
||||
add_filter( 'list_pages', '_wp_privacy_settings_filter_draft_page_titles', 10, 2 );
|
||||
|
||||
// Font management.
|
||||
add_action( 'admin_print_styles', 'wp_print_font_faces', 50 );
|
||||
|
||||
@@ -1,101 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* Core Administration API
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 2.3.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WP_ADMIN' ) ) {
|
||||
/*
|
||||
* This file is being included from a file other than wp-admin/admin.php, so
|
||||
* some setup was skipped. Make sure the admin message catalog is loaded since
|
||||
* load_default_textdomain() will not have done so in this context.
|
||||
*/
|
||||
$admin_locale = get_locale();
|
||||
load_textdomain( 'default', WP_LANG_DIR . '/admin-' . $admin_locale . '.mo', $admin_locale );
|
||||
unset( $admin_locale );
|
||||
}
|
||||
|
||||
/** WordPress Administration Hooks */
|
||||
require_once ABSPATH . 'wp-admin/includes/admin-filters.php';
|
||||
|
||||
/** WordPress Bookmark Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/bookmark.php';
|
||||
|
||||
/** WordPress Comment Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/comment.php';
|
||||
|
||||
/** WordPress Administration File API */
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
|
||||
/** WordPress Image Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
|
||||
/** WordPress Media Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/media.php';
|
||||
|
||||
/** WordPress Import Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/import.php';
|
||||
|
||||
/** WordPress Misc Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/misc.php';
|
||||
|
||||
/** WordPress Misc Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-policy-content.php';
|
||||
|
||||
/** WordPress Options Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/options.php';
|
||||
|
||||
/** WordPress Plugin Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
|
||||
/** WordPress Post Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/post.php';
|
||||
|
||||
/** WordPress Administration Screen API */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-screen.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/screen.php';
|
||||
|
||||
/** WordPress Taxonomy Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/taxonomy.php';
|
||||
|
||||
/** WordPress Template Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/template.php';
|
||||
|
||||
/** WordPress List Table Administration API and base class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table-compat.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/list-table.php';
|
||||
|
||||
/** WordPress Theme Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/theme.php';
|
||||
|
||||
/** WordPress Privacy Functions */
|
||||
require_once ABSPATH . 'wp-admin/includes/privacy-tools.php';
|
||||
|
||||
/** WordPress Privacy List Table classes. */
|
||||
// Previously in wp-admin/includes/user.php. Need to be loaded for backward compatibility.
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-requests-table.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-data-export-requests-list-table.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-data-removal-requests-list-table.php';
|
||||
|
||||
/** WordPress User Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/user.php';
|
||||
|
||||
/** WordPress Site Icon API */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-site-icon.php';
|
||||
|
||||
/** WordPress Update Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/update.php';
|
||||
|
||||
/** WordPress Deprecated Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/deprecated.php';
|
||||
|
||||
/** WordPress Multisite support API */
|
||||
if ( is_multisite() ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/ms-admin-filters.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/ms.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/ms-deprecated.php';
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Core Administration API
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 2.3.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'WP_ADMIN' ) ) {
|
||||
/*
|
||||
* This file is being included from a file other than wp-admin/admin.php, so
|
||||
* some setup was skipped. Make sure the admin message catalog is loaded since
|
||||
* load_default_textdomain() will not have done so in this context.
|
||||
*/
|
||||
$admin_locale = get_locale();
|
||||
load_textdomain( 'default', WP_LANG_DIR . '/admin-' . $admin_locale . '.mo', $admin_locale );
|
||||
unset( $admin_locale );
|
||||
}
|
||||
|
||||
/** WordPress Administration Hooks */
|
||||
require_once ABSPATH . 'wp-admin/includes/admin-filters.php';
|
||||
|
||||
/** WordPress Bookmark Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/bookmark.php';
|
||||
|
||||
/** WordPress Comment Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/comment.php';
|
||||
|
||||
/** WordPress Administration File API */
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
|
||||
/** WordPress Image Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
|
||||
/** WordPress Media Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/media.php';
|
||||
|
||||
/** WordPress Import Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/import.php';
|
||||
|
||||
/** WordPress Misc Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/misc.php';
|
||||
|
||||
/** WordPress Misc Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-policy-content.php';
|
||||
|
||||
/** WordPress Options Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/options.php';
|
||||
|
||||
/** WordPress Plugin Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
|
||||
/** WordPress Post Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/post.php';
|
||||
|
||||
/** WordPress Administration Screen API */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-screen.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/screen.php';
|
||||
|
||||
/** WordPress Taxonomy Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/taxonomy.php';
|
||||
|
||||
/** WordPress Template Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/template.php';
|
||||
|
||||
/** WordPress List Table Administration API and base class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table-compat.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/list-table.php';
|
||||
|
||||
/** WordPress Theme Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/theme.php';
|
||||
|
||||
/** WordPress Privacy Functions */
|
||||
require_once ABSPATH . 'wp-admin/includes/privacy-tools.php';
|
||||
|
||||
/** WordPress Privacy List Table classes. */
|
||||
// Previously in wp-admin/includes/user.php. Need to be loaded for backward compatibility.
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-requests-table.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-data-export-requests-list-table.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-data-removal-requests-list-table.php';
|
||||
|
||||
/** WordPress User Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/user.php';
|
||||
|
||||
/** WordPress Site Icon API */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-site-icon.php';
|
||||
|
||||
/** WordPress Update Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/update.php';
|
||||
|
||||
/** WordPress Deprecated Administration API */
|
||||
require_once ABSPATH . 'wp-admin/includes/deprecated.php';
|
||||
|
||||
/** WordPress Multisite support API */
|
||||
if ( is_multisite() ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/ms-admin-filters.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/ms.php';
|
||||
require_once ABSPATH . 'wp-admin/includes/ms-deprecated.php';
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,379 +1,379 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Bookmark Administration API
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds a link using values provided in $_POST.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return int|WP_Error Value 0 or WP_Error on failure. The link ID on success.
|
||||
*/
|
||||
function add_link() {
|
||||
return edit_link();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates or inserts a link using values provided in $_POST.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $link_id Optional. ID of the link to edit. Default 0.
|
||||
* @return int|WP_Error Value 0 or WP_Error on failure. The link ID on success.
|
||||
*/
|
||||
function edit_link( $link_id = 0 ) {
|
||||
if ( ! current_user_can( 'manage_links' ) ) {
|
||||
wp_die(
|
||||
'<h1>' . __( 'You need a higher level of permission.' ) . '</h1>' .
|
||||
'<p>' . __( 'Sorry, you are not allowed to edit the links for this site.' ) . '</p>',
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
$_POST['link_url'] = esc_url( $_POST['link_url'] );
|
||||
$_POST['link_name'] = esc_html( $_POST['link_name'] );
|
||||
$_POST['link_image'] = esc_html( $_POST['link_image'] );
|
||||
$_POST['link_rss'] = esc_url( $_POST['link_rss'] );
|
||||
if ( ! isset( $_POST['link_visible'] ) || 'N' !== $_POST['link_visible'] ) {
|
||||
$_POST['link_visible'] = 'Y';
|
||||
}
|
||||
|
||||
if ( ! empty( $link_id ) ) {
|
||||
$_POST['link_id'] = $link_id;
|
||||
return wp_update_link( $_POST );
|
||||
} else {
|
||||
return wp_insert_link( $_POST );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the default link for editing.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return stdClass Default link object.
|
||||
*/
|
||||
function get_default_link_to_edit() {
|
||||
$link = new stdClass();
|
||||
if ( isset( $_GET['linkurl'] ) ) {
|
||||
$link->link_url = esc_url( wp_unslash( $_GET['linkurl'] ) );
|
||||
} else {
|
||||
$link->link_url = '';
|
||||
}
|
||||
|
||||
if ( isset( $_GET['name'] ) ) {
|
||||
$link->link_name = esc_attr( wp_unslash( $_GET['name'] ) );
|
||||
} else {
|
||||
$link->link_name = '';
|
||||
}
|
||||
|
||||
$link->link_visible = 'Y';
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a specified link from the database.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param int $link_id ID of the link to delete.
|
||||
* @return true Always true.
|
||||
*/
|
||||
function wp_delete_link( $link_id ) {
|
||||
global $wpdb;
|
||||
/**
|
||||
* Fires before a link is deleted.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $link_id ID of the link to delete.
|
||||
*/
|
||||
do_action( 'delete_link', $link_id );
|
||||
|
||||
wp_delete_object_term_relationships( $link_id, 'link_category' );
|
||||
|
||||
$wpdb->delete( $wpdb->links, array( 'link_id' => $link_id ) );
|
||||
|
||||
/**
|
||||
* Fires after a link has been deleted.
|
||||
*
|
||||
* @since 2.2.0
|
||||
*
|
||||
* @param int $link_id ID of the deleted link.
|
||||
*/
|
||||
do_action( 'deleted_link', $link_id );
|
||||
|
||||
clean_bookmark_cache( $link_id );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the link category IDs associated with the link specified.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int $link_id Link ID to look up.
|
||||
* @return int[] The IDs of the requested link's categories.
|
||||
*/
|
||||
function wp_get_link_cats( $link_id = 0 ) {
|
||||
$cats = wp_get_object_terms( $link_id, 'link_category', array( 'fields' => 'ids' ) );
|
||||
return array_unique( $cats );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves link data based on its ID.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int|stdClass $link Link ID or object to retrieve.
|
||||
* @return object Link object for editing.
|
||||
*/
|
||||
function get_link_to_edit( $link ) {
|
||||
return get_bookmark( $link, OBJECT, 'edit' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a link into the database, or updates an existing link.
|
||||
*
|
||||
* Runs all the necessary sanitizing, provides default values if arguments are missing,
|
||||
* and finally saves the link.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param array $linkdata {
|
||||
* Elements that make up the link to insert.
|
||||
*
|
||||
* @type int $link_id Optional. The ID of the existing link if updating.
|
||||
* @type string $link_url The URL the link points to.
|
||||
* @type string $link_name The title of the link.
|
||||
* @type string $link_image Optional. A URL of an image.
|
||||
* @type string $link_target Optional. The target element for the anchor tag.
|
||||
* @type string $link_description Optional. A short description of the link.
|
||||
* @type string $link_visible Optional. 'Y' means visible, anything else means not.
|
||||
* @type int $link_owner Optional. A user ID.
|
||||
* @type int $link_rating Optional. A rating for the link.
|
||||
* @type string $link_rel Optional. A relationship of the link to you.
|
||||
* @type string $link_notes Optional. An extended description of or notes on the link.
|
||||
* @type string $link_rss Optional. A URL of an associated RSS feed.
|
||||
* @type int $link_category Optional. The term ID of the link category.
|
||||
* If empty, uses default link category.
|
||||
* }
|
||||
* @param bool $wp_error Optional. Whether to return a WP_Error object on failure. Default false.
|
||||
* @return int|WP_Error Value 0 or WP_Error on failure. The link ID on success.
|
||||
*/
|
||||
function wp_insert_link( $linkdata, $wp_error = false ) {
|
||||
global $wpdb;
|
||||
|
||||
$defaults = array(
|
||||
'link_id' => 0,
|
||||
'link_name' => '',
|
||||
'link_url' => '',
|
||||
'link_rating' => 0,
|
||||
);
|
||||
|
||||
$parsed_args = wp_parse_args( $linkdata, $defaults );
|
||||
$parsed_args = wp_unslash( sanitize_bookmark( $parsed_args, 'db' ) );
|
||||
|
||||
$link_id = $parsed_args['link_id'];
|
||||
$link_name = $parsed_args['link_name'];
|
||||
$link_url = $parsed_args['link_url'];
|
||||
|
||||
$update = false;
|
||||
if ( ! empty( $link_id ) ) {
|
||||
$update = true;
|
||||
}
|
||||
|
||||
if ( '' === trim( $link_name ) ) {
|
||||
if ( '' !== trim( $link_url ) ) {
|
||||
$link_name = $link_url;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( '' === trim( $link_url ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$link_rating = ( ! empty( $parsed_args['link_rating'] ) ) ? $parsed_args['link_rating'] : 0;
|
||||
$link_image = ( ! empty( $parsed_args['link_image'] ) ) ? $parsed_args['link_image'] : '';
|
||||
$link_target = ( ! empty( $parsed_args['link_target'] ) ) ? $parsed_args['link_target'] : '';
|
||||
$link_visible = ( ! empty( $parsed_args['link_visible'] ) ) ? $parsed_args['link_visible'] : 'Y';
|
||||
$link_owner = ( ! empty( $parsed_args['link_owner'] ) ) ? $parsed_args['link_owner'] : get_current_user_id();
|
||||
$link_notes = ( ! empty( $parsed_args['link_notes'] ) ) ? $parsed_args['link_notes'] : '';
|
||||
$link_description = ( ! empty( $parsed_args['link_description'] ) ) ? $parsed_args['link_description'] : '';
|
||||
$link_rss = ( ! empty( $parsed_args['link_rss'] ) ) ? $parsed_args['link_rss'] : '';
|
||||
$link_rel = ( ! empty( $parsed_args['link_rel'] ) ) ? $parsed_args['link_rel'] : '';
|
||||
$link_category = ( ! empty( $parsed_args['link_category'] ) ) ? $parsed_args['link_category'] : array();
|
||||
|
||||
// Make sure we set a valid category.
|
||||
if ( ! is_array( $link_category ) || 0 === count( $link_category ) ) {
|
||||
$link_category = array( get_option( 'default_link_category' ) );
|
||||
}
|
||||
|
||||
if ( $update ) {
|
||||
if ( false === $wpdb->update( $wpdb->links, compact( 'link_url', 'link_name', 'link_image', 'link_target', 'link_description', 'link_visible', 'link_owner', 'link_rating', 'link_rel', 'link_notes', 'link_rss' ), compact( 'link_id' ) ) ) {
|
||||
if ( $wp_error ) {
|
||||
return new WP_Error( 'db_update_error', __( 'Could not update link in the database.' ), $wpdb->last_error );
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( false === $wpdb->insert( $wpdb->links, compact( 'link_url', 'link_name', 'link_image', 'link_target', 'link_description', 'link_visible', 'link_owner', 'link_rating', 'link_rel', 'link_notes', 'link_rss' ) ) ) {
|
||||
if ( $wp_error ) {
|
||||
return new WP_Error( 'db_insert_error', __( 'Could not insert link into the database.' ), $wpdb->last_error );
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
$link_id = (int) $wpdb->insert_id;
|
||||
}
|
||||
|
||||
wp_set_link_cats( $link_id, $link_category );
|
||||
|
||||
if ( $update ) {
|
||||
/**
|
||||
* Fires after a link was updated in the database.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $link_id ID of the link that was updated.
|
||||
*/
|
||||
do_action( 'edit_link', $link_id );
|
||||
} else {
|
||||
/**
|
||||
* Fires after a link was added to the database.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $link_id ID of the link that was added.
|
||||
*/
|
||||
do_action( 'add_link', $link_id );
|
||||
}
|
||||
clean_bookmark_cache( $link_id );
|
||||
|
||||
return $link_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates link with the specified link categories.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int $link_id ID of the link to update.
|
||||
* @param int[] $link_categories Array of link category IDs to add the link to.
|
||||
*/
|
||||
function wp_set_link_cats( $link_id = 0, $link_categories = array() ) {
|
||||
// If $link_categories isn't already an array, make it one:
|
||||
if ( ! is_array( $link_categories ) || 0 === count( $link_categories ) ) {
|
||||
$link_categories = array( get_option( 'default_link_category' ) );
|
||||
}
|
||||
|
||||
$link_categories = array_map( 'intval', $link_categories );
|
||||
$link_categories = array_unique( $link_categories );
|
||||
|
||||
wp_set_object_terms( $link_id, $link_categories, 'link_category' );
|
||||
|
||||
clean_bookmark_cache( $link_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a link in the database.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $linkdata Link data to update. See wp_insert_link() for accepted arguments.
|
||||
* @return int|WP_Error Value 0 or WP_Error on failure. The updated link ID on success.
|
||||
*/
|
||||
function wp_update_link( $linkdata ) {
|
||||
$link_id = (int) $linkdata['link_id'];
|
||||
|
||||
$link = get_bookmark( $link_id, ARRAY_A );
|
||||
|
||||
// Escape data pulled from DB.
|
||||
$link = wp_slash( $link );
|
||||
|
||||
// Passed link category list overwrites existing category list if not empty.
|
||||
if ( isset( $linkdata['link_category'] ) && is_array( $linkdata['link_category'] )
|
||||
&& count( $linkdata['link_category'] ) > 0
|
||||
) {
|
||||
$link_cats = $linkdata['link_category'];
|
||||
} else {
|
||||
$link_cats = $link['link_category'];
|
||||
}
|
||||
|
||||
// Merge old and new fields with new fields overwriting old ones.
|
||||
$linkdata = array_merge( $link, $linkdata );
|
||||
$linkdata['link_category'] = $link_cats;
|
||||
|
||||
return wp_insert_link( $linkdata );
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the 'disabled' message for the WordPress Link Manager.
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @access private
|
||||
*
|
||||
* @global string $pagenow The filename of the current screen.
|
||||
*/
|
||||
function wp_link_manager_disabled_message() {
|
||||
global $pagenow;
|
||||
|
||||
if ( ! in_array( $pagenow, array( 'link-manager.php', 'link-add.php', 'link.php' ), true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_filter( 'pre_option_link_manager_enabled', '__return_true', 100 );
|
||||
$really_can_manage_links = current_user_can( 'manage_links' );
|
||||
remove_filter( 'pre_option_link_manager_enabled', '__return_true', 100 );
|
||||
|
||||
if ( $really_can_manage_links ) {
|
||||
$plugins = get_plugins();
|
||||
|
||||
if ( empty( $plugins['link-manager/link-manager.php'] ) ) {
|
||||
if ( current_user_can( 'install_plugins' ) ) {
|
||||
$install_url = wp_nonce_url(
|
||||
self_admin_url( 'update.php?action=install-plugin&plugin=link-manager' ),
|
||||
'install-plugin_link-manager'
|
||||
);
|
||||
|
||||
wp_die(
|
||||
sprintf(
|
||||
/* translators: %s: A link to install the Link Manager plugin. */
|
||||
__( 'If you are looking to use the link manager, please install the <a href="%s">Link Manager plugin</a>.' ),
|
||||
esc_url( $install_url )
|
||||
)
|
||||
);
|
||||
}
|
||||
} elseif ( is_plugin_inactive( 'link-manager/link-manager.php' ) ) {
|
||||
if ( current_user_can( 'activate_plugins' ) ) {
|
||||
$activate_url = wp_nonce_url(
|
||||
self_admin_url( 'plugins.php?action=activate&plugin=link-manager/link-manager.php' ),
|
||||
'activate-plugin_link-manager/link-manager.php'
|
||||
);
|
||||
|
||||
wp_die(
|
||||
sprintf(
|
||||
/* translators: %s: A link to activate the Link Manager plugin. */
|
||||
__( 'Please activate the <a href="%s">Link Manager plugin</a> to use the link manager.' ),
|
||||
esc_url( $activate_url )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wp_die( __( 'Sorry, you are not allowed to edit the links for this site.' ) );
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* WordPress Bookmark Administration API
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds a link using values provided in $_POST.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return int|WP_Error Value 0 or WP_Error on failure. The link ID on success.
|
||||
*/
|
||||
function add_link() {
|
||||
return edit_link();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates or inserts a link using values provided in $_POST.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $link_id Optional. ID of the link to edit. Default 0.
|
||||
* @return int|WP_Error Value 0 or WP_Error on failure. The link ID on success.
|
||||
*/
|
||||
function edit_link( $link_id = 0 ) {
|
||||
if ( ! current_user_can( 'manage_links' ) ) {
|
||||
wp_die(
|
||||
'<h1>' . __( 'You need a higher level of permission.' ) . '</h1>' .
|
||||
'<p>' . __( 'Sorry, you are not allowed to edit the links for this site.' ) . '</p>',
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
$_POST['link_url'] = esc_url( $_POST['link_url'] );
|
||||
$_POST['link_name'] = esc_html( $_POST['link_name'] );
|
||||
$_POST['link_image'] = esc_html( $_POST['link_image'] );
|
||||
$_POST['link_rss'] = esc_url( $_POST['link_rss'] );
|
||||
if ( ! isset( $_POST['link_visible'] ) || 'N' !== $_POST['link_visible'] ) {
|
||||
$_POST['link_visible'] = 'Y';
|
||||
}
|
||||
|
||||
if ( ! empty( $link_id ) ) {
|
||||
$_POST['link_id'] = $link_id;
|
||||
return wp_update_link( $_POST );
|
||||
} else {
|
||||
return wp_insert_link( $_POST );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the default link for editing.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return stdClass Default link object.
|
||||
*/
|
||||
function get_default_link_to_edit() {
|
||||
$link = new stdClass();
|
||||
if ( isset( $_GET['linkurl'] ) ) {
|
||||
$link->link_url = esc_url( wp_unslash( $_GET['linkurl'] ) );
|
||||
} else {
|
||||
$link->link_url = '';
|
||||
}
|
||||
|
||||
if ( isset( $_GET['name'] ) ) {
|
||||
$link->link_name = esc_attr( wp_unslash( $_GET['name'] ) );
|
||||
} else {
|
||||
$link->link_name = '';
|
||||
}
|
||||
|
||||
$link->link_visible = 'Y';
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a specified link from the database.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param int $link_id ID of the link to delete.
|
||||
* @return true Always true.
|
||||
*/
|
||||
function wp_delete_link( $link_id ) {
|
||||
global $wpdb;
|
||||
/**
|
||||
* Fires before a link is deleted.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $link_id ID of the link to delete.
|
||||
*/
|
||||
do_action( 'delete_link', $link_id );
|
||||
|
||||
wp_delete_object_term_relationships( $link_id, 'link_category' );
|
||||
|
||||
$wpdb->delete( $wpdb->links, array( 'link_id' => $link_id ) );
|
||||
|
||||
/**
|
||||
* Fires after a link has been deleted.
|
||||
*
|
||||
* @since 2.2.0
|
||||
*
|
||||
* @param int $link_id ID of the deleted link.
|
||||
*/
|
||||
do_action( 'deleted_link', $link_id );
|
||||
|
||||
clean_bookmark_cache( $link_id );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the link category IDs associated with the link specified.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int $link_id Link ID to look up.
|
||||
* @return int[] The IDs of the requested link's categories.
|
||||
*/
|
||||
function wp_get_link_cats( $link_id = 0 ) {
|
||||
$cats = wp_get_object_terms( $link_id, 'link_category', array( 'fields' => 'ids' ) );
|
||||
return array_unique( $cats );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves link data based on its ID.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int|stdClass $link Link ID or object to retrieve.
|
||||
* @return object Link object for editing.
|
||||
*/
|
||||
function get_link_to_edit( $link ) {
|
||||
return get_bookmark( $link, OBJECT, 'edit' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a link into the database, or updates an existing link.
|
||||
*
|
||||
* Runs all the necessary sanitizing, provides default values if arguments are missing,
|
||||
* and finally saves the link.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param array $linkdata {
|
||||
* Elements that make up the link to insert.
|
||||
*
|
||||
* @type int $link_id Optional. The ID of the existing link if updating.
|
||||
* @type string $link_url The URL the link points to.
|
||||
* @type string $link_name The title of the link.
|
||||
* @type string $link_image Optional. A URL of an image.
|
||||
* @type string $link_target Optional. The target element for the anchor tag.
|
||||
* @type string $link_description Optional. A short description of the link.
|
||||
* @type string $link_visible Optional. 'Y' means visible, anything else means not.
|
||||
* @type int $link_owner Optional. A user ID.
|
||||
* @type int $link_rating Optional. A rating for the link.
|
||||
* @type string $link_rel Optional. A relationship of the link to you.
|
||||
* @type string $link_notes Optional. An extended description of or notes on the link.
|
||||
* @type string $link_rss Optional. A URL of an associated RSS feed.
|
||||
* @type int $link_category Optional. The term ID of the link category.
|
||||
* If empty, uses default link category.
|
||||
* }
|
||||
* @param bool $wp_error Optional. Whether to return a WP_Error object on failure. Default false.
|
||||
* @return int|WP_Error Value 0 or WP_Error on failure. The link ID on success.
|
||||
*/
|
||||
function wp_insert_link( $linkdata, $wp_error = false ) {
|
||||
global $wpdb;
|
||||
|
||||
$defaults = array(
|
||||
'link_id' => 0,
|
||||
'link_name' => '',
|
||||
'link_url' => '',
|
||||
'link_rating' => 0,
|
||||
);
|
||||
|
||||
$parsed_args = wp_parse_args( $linkdata, $defaults );
|
||||
$parsed_args = wp_unslash( sanitize_bookmark( $parsed_args, 'db' ) );
|
||||
|
||||
$link_id = $parsed_args['link_id'];
|
||||
$link_name = $parsed_args['link_name'];
|
||||
$link_url = $parsed_args['link_url'];
|
||||
|
||||
$update = false;
|
||||
if ( ! empty( $link_id ) ) {
|
||||
$update = true;
|
||||
}
|
||||
|
||||
if ( '' === trim( $link_name ) ) {
|
||||
if ( '' !== trim( $link_url ) ) {
|
||||
$link_name = $link_url;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( '' === trim( $link_url ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$link_rating = ( ! empty( $parsed_args['link_rating'] ) ) ? $parsed_args['link_rating'] : 0;
|
||||
$link_image = ( ! empty( $parsed_args['link_image'] ) ) ? $parsed_args['link_image'] : '';
|
||||
$link_target = ( ! empty( $parsed_args['link_target'] ) ) ? $parsed_args['link_target'] : '';
|
||||
$link_visible = ( ! empty( $parsed_args['link_visible'] ) ) ? $parsed_args['link_visible'] : 'Y';
|
||||
$link_owner = ( ! empty( $parsed_args['link_owner'] ) ) ? $parsed_args['link_owner'] : get_current_user_id();
|
||||
$link_notes = ( ! empty( $parsed_args['link_notes'] ) ) ? $parsed_args['link_notes'] : '';
|
||||
$link_description = ( ! empty( $parsed_args['link_description'] ) ) ? $parsed_args['link_description'] : '';
|
||||
$link_rss = ( ! empty( $parsed_args['link_rss'] ) ) ? $parsed_args['link_rss'] : '';
|
||||
$link_rel = ( ! empty( $parsed_args['link_rel'] ) ) ? $parsed_args['link_rel'] : '';
|
||||
$link_category = ( ! empty( $parsed_args['link_category'] ) ) ? $parsed_args['link_category'] : array();
|
||||
|
||||
// Make sure we set a valid category.
|
||||
if ( ! is_array( $link_category ) || 0 === count( $link_category ) ) {
|
||||
$link_category = array( get_option( 'default_link_category' ) );
|
||||
}
|
||||
|
||||
if ( $update ) {
|
||||
if ( false === $wpdb->update( $wpdb->links, compact( 'link_url', 'link_name', 'link_image', 'link_target', 'link_description', 'link_visible', 'link_owner', 'link_rating', 'link_rel', 'link_notes', 'link_rss' ), compact( 'link_id' ) ) ) {
|
||||
if ( $wp_error ) {
|
||||
return new WP_Error( 'db_update_error', __( 'Could not update link in the database.' ), $wpdb->last_error );
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( false === $wpdb->insert( $wpdb->links, compact( 'link_url', 'link_name', 'link_image', 'link_target', 'link_description', 'link_visible', 'link_owner', 'link_rating', 'link_rel', 'link_notes', 'link_rss' ) ) ) {
|
||||
if ( $wp_error ) {
|
||||
return new WP_Error( 'db_insert_error', __( 'Could not insert link into the database.' ), $wpdb->last_error );
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
$link_id = (int) $wpdb->insert_id;
|
||||
}
|
||||
|
||||
wp_set_link_cats( $link_id, $link_category );
|
||||
|
||||
if ( $update ) {
|
||||
/**
|
||||
* Fires after a link was updated in the database.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $link_id ID of the link that was updated.
|
||||
*/
|
||||
do_action( 'edit_link', $link_id );
|
||||
} else {
|
||||
/**
|
||||
* Fires after a link was added to the database.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $link_id ID of the link that was added.
|
||||
*/
|
||||
do_action( 'add_link', $link_id );
|
||||
}
|
||||
clean_bookmark_cache( $link_id );
|
||||
|
||||
return $link_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates link with the specified link categories.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int $link_id ID of the link to update.
|
||||
* @param int[] $link_categories Array of link category IDs to add the link to.
|
||||
*/
|
||||
function wp_set_link_cats( $link_id = 0, $link_categories = array() ) {
|
||||
// If $link_categories isn't already an array, make it one:
|
||||
if ( ! is_array( $link_categories ) || 0 === count( $link_categories ) ) {
|
||||
$link_categories = array( get_option( 'default_link_category' ) );
|
||||
}
|
||||
|
||||
$link_categories = array_map( 'intval', $link_categories );
|
||||
$link_categories = array_unique( $link_categories );
|
||||
|
||||
wp_set_object_terms( $link_id, $link_categories, 'link_category' );
|
||||
|
||||
clean_bookmark_cache( $link_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a link in the database.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $linkdata Link data to update. See wp_insert_link() for accepted arguments.
|
||||
* @return int|WP_Error Value 0 or WP_Error on failure. The updated link ID on success.
|
||||
*/
|
||||
function wp_update_link( $linkdata ) {
|
||||
$link_id = (int) $linkdata['link_id'];
|
||||
|
||||
$link = get_bookmark( $link_id, ARRAY_A );
|
||||
|
||||
// Escape data pulled from DB.
|
||||
$link = wp_slash( $link );
|
||||
|
||||
// Passed link category list overwrites existing category list if not empty.
|
||||
if ( isset( $linkdata['link_category'] ) && is_array( $linkdata['link_category'] )
|
||||
&& count( $linkdata['link_category'] ) > 0
|
||||
) {
|
||||
$link_cats = $linkdata['link_category'];
|
||||
} else {
|
||||
$link_cats = $link['link_category'];
|
||||
}
|
||||
|
||||
// Merge old and new fields with new fields overwriting old ones.
|
||||
$linkdata = array_merge( $link, $linkdata );
|
||||
$linkdata['link_category'] = $link_cats;
|
||||
|
||||
return wp_insert_link( $linkdata );
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the 'disabled' message for the WordPress Link Manager.
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @access private
|
||||
*
|
||||
* @global string $pagenow The filename of the current screen.
|
||||
*/
|
||||
function wp_link_manager_disabled_message() {
|
||||
global $pagenow;
|
||||
|
||||
if ( ! in_array( $pagenow, array( 'link-manager.php', 'link-add.php', 'link.php' ), true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_filter( 'pre_option_link_manager_enabled', '__return_true', 100 );
|
||||
$really_can_manage_links = current_user_can( 'manage_links' );
|
||||
remove_filter( 'pre_option_link_manager_enabled', '__return_true', 100 );
|
||||
|
||||
if ( $really_can_manage_links ) {
|
||||
$plugins = get_plugins();
|
||||
|
||||
if ( empty( $plugins['link-manager/link-manager.php'] ) ) {
|
||||
if ( current_user_can( 'install_plugins' ) ) {
|
||||
$install_url = wp_nonce_url(
|
||||
self_admin_url( 'update.php?action=install-plugin&plugin=link-manager' ),
|
||||
'install-plugin_link-manager'
|
||||
);
|
||||
|
||||
wp_die(
|
||||
sprintf(
|
||||
/* translators: %s: A link to install the Link Manager plugin. */
|
||||
__( 'If you are looking to use the link manager, please install the <a href="%s">Link Manager plugin</a>.' ),
|
||||
esc_url( $install_url )
|
||||
)
|
||||
);
|
||||
}
|
||||
} elseif ( is_plugin_inactive( 'link-manager/link-manager.php' ) ) {
|
||||
if ( current_user_can( 'activate_plugins' ) ) {
|
||||
$activate_url = wp_nonce_url(
|
||||
self_admin_url( 'plugins.php?action=activate&plugin=link-manager/link-manager.php' ),
|
||||
'activate-plugin_link-manager/link-manager.php'
|
||||
);
|
||||
|
||||
wp_die(
|
||||
sprintf(
|
||||
/* translators: %s: A link to activate the Link Manager plugin. */
|
||||
__( 'Please activate the <a href="%s">Link Manager plugin</a> to use the link manager.' ),
|
||||
esc_url( $activate_url )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wp_die( __( 'Sorry, you are not allowed to edit the links for this site.' ) );
|
||||
}
|
||||
|
||||
@@ -1,135 +1,135 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Automatic_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Upgrader Skin for Automatic WordPress Upgrades.
|
||||
*
|
||||
* This skin is designed to be used when no output is intended, all output
|
||||
* is captured and stored for the caller to process and log/email/discard.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see Bulk_Upgrader_Skin
|
||||
*/
|
||||
class Automatic_Upgrader_Skin extends WP_Upgrader_Skin {
|
||||
protected $messages = array();
|
||||
|
||||
/**
|
||||
* Determines whether the upgrader needs FTP/SSH details in order to connect
|
||||
* to the filesystem.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @since 4.6.0 The `$context` parameter default changed from `false` to an empty string.
|
||||
*
|
||||
* @see request_filesystem_credentials()
|
||||
*
|
||||
* @param bool|WP_Error $error Optional. Whether the current request has failed to connect,
|
||||
* or an error object. Default false.
|
||||
* @param string $context Optional. Full path to the directory that is tested
|
||||
* for being writable. Default empty.
|
||||
* @param bool $allow_relaxed_file_ownership Optional. Whether to allow Group/World writable. Default false.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
|
||||
if ( $context ) {
|
||||
$this->options['context'] = $context;
|
||||
}
|
||||
/*
|
||||
* TODO: Fix up request_filesystem_credentials(), or split it, to allow us to request a no-output version.
|
||||
* This will output a credentials form in event of failure. We don't want that, so just hide with a buffer.
|
||||
*/
|
||||
ob_start();
|
||||
$result = parent::request_filesystem_credentials( $error, $context, $allow_relaxed_file_ownership );
|
||||
ob_end_clean();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the upgrade messages.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @return string[] Messages during an upgrade.
|
||||
*/
|
||||
public function get_upgrade_messages() {
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a message about the upgrade.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @since 5.9.0 Renamed `$data` to `$feedback` for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string|array|WP_Error $feedback Message data.
|
||||
* @param mixed ...$args Optional text replacements.
|
||||
*/
|
||||
public function feedback( $feedback, ...$args ) {
|
||||
if ( is_wp_error( $feedback ) ) {
|
||||
$string = $feedback->get_error_message();
|
||||
} elseif ( is_array( $feedback ) ) {
|
||||
return;
|
||||
} else {
|
||||
$string = $feedback;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->upgrader->strings[ $string ] ) ) {
|
||||
$string = $this->upgrader->strings[ $string ];
|
||||
}
|
||||
|
||||
if ( str_contains( $string, '%' ) ) {
|
||||
if ( ! empty( $args ) ) {
|
||||
$string = vsprintf( $string, $args );
|
||||
}
|
||||
}
|
||||
|
||||
$string = trim( $string );
|
||||
|
||||
// Only allow basic HTML in the messages, as it'll be used in emails/logs rather than direct browser output.
|
||||
$string = wp_kses(
|
||||
$string,
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => true,
|
||||
),
|
||||
'br' => true,
|
||||
'em' => true,
|
||||
'strong' => true,
|
||||
)
|
||||
);
|
||||
|
||||
if ( empty( $string ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->messages[] = $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new output buffer.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function header() {
|
||||
ob_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the buffered content, deletes the buffer, and processes the output.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function footer() {
|
||||
$output = ob_get_clean();
|
||||
if ( ! empty( $output ) ) {
|
||||
$this->feedback( $output );
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Automatic_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Upgrader Skin for Automatic WordPress Upgrades.
|
||||
*
|
||||
* This skin is designed to be used when no output is intended, all output
|
||||
* is captured and stored for the caller to process and log/email/discard.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see Bulk_Upgrader_Skin
|
||||
*/
|
||||
class Automatic_Upgrader_Skin extends WP_Upgrader_Skin {
|
||||
protected $messages = array();
|
||||
|
||||
/**
|
||||
* Determines whether the upgrader needs FTP/SSH details in order to connect
|
||||
* to the filesystem.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @since 4.6.0 The `$context` parameter default changed from `false` to an empty string.
|
||||
*
|
||||
* @see request_filesystem_credentials()
|
||||
*
|
||||
* @param bool|WP_Error $error Optional. Whether the current request has failed to connect,
|
||||
* or an error object. Default false.
|
||||
* @param string $context Optional. Full path to the directory that is tested
|
||||
* for being writable. Default empty.
|
||||
* @param bool $allow_relaxed_file_ownership Optional. Whether to allow Group/World writable. Default false.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
|
||||
if ( $context ) {
|
||||
$this->options['context'] = $context;
|
||||
}
|
||||
/*
|
||||
* TODO: Fix up request_filesystem_credentials(), or split it, to allow us to request a no-output version.
|
||||
* This will output a credentials form in event of failure. We don't want that, so just hide with a buffer.
|
||||
*/
|
||||
ob_start();
|
||||
$result = parent::request_filesystem_credentials( $error, $context, $allow_relaxed_file_ownership );
|
||||
ob_end_clean();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the upgrade messages.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @return string[] Messages during an upgrade.
|
||||
*/
|
||||
public function get_upgrade_messages() {
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a message about the upgrade.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @since 5.9.0 Renamed `$data` to `$feedback` for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string|array|WP_Error $feedback Message data.
|
||||
* @param mixed ...$args Optional text replacements.
|
||||
*/
|
||||
public function feedback( $feedback, ...$args ) {
|
||||
if ( is_wp_error( $feedback ) ) {
|
||||
$string = $feedback->get_error_message();
|
||||
} elseif ( is_array( $feedback ) ) {
|
||||
return;
|
||||
} else {
|
||||
$string = $feedback;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->upgrader->strings[ $string ] ) ) {
|
||||
$string = $this->upgrader->strings[ $string ];
|
||||
}
|
||||
|
||||
if ( str_contains( $string, '%' ) ) {
|
||||
if ( ! empty( $args ) ) {
|
||||
$string = vsprintf( $string, $args );
|
||||
}
|
||||
}
|
||||
|
||||
$string = trim( $string );
|
||||
|
||||
// Only allow basic HTML in the messages, as it'll be used in emails/logs rather than direct browser output.
|
||||
$string = wp_kses(
|
||||
$string,
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => true,
|
||||
),
|
||||
'br' => true,
|
||||
'em' => true,
|
||||
'strong' => true,
|
||||
)
|
||||
);
|
||||
|
||||
if ( empty( $string ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->messages[] = $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new output buffer.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function header() {
|
||||
ob_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the buffered content, deletes the buffer, and processes the output.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function footer() {
|
||||
$output = ob_get_clean();
|
||||
if ( ! empty( $output ) ) {
|
||||
$this->feedback( $output );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,87 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Bulk_Plugin_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bulk Plugin Upgrader Skin for WordPress Plugin Upgrades.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see Bulk_Upgrader_Skin
|
||||
*/
|
||||
class Bulk_Plugin_Upgrader_Skin extends Bulk_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Plugin info.
|
||||
*
|
||||
* The Plugin_Upgrader::bulk_upgrade() method will fill this in
|
||||
* with info retrieved from the get_plugin_data() function.
|
||||
*
|
||||
* @var array Plugin data. Values will be empty if not supplied by the plugin.
|
||||
*/
|
||||
public $plugin_info = array();
|
||||
|
||||
public function add_strings() {
|
||||
parent::add_strings();
|
||||
/* translators: 1: Plugin name, 2: Number of the plugin, 3: Total number of plugins being updated. */
|
||||
$this->upgrader->strings['skin_before_update_header'] = __( 'Updating Plugin %1$s (%2$d/%3$d)' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function before( $title = '' ) {
|
||||
parent::before( $this->plugin_info['Title'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function after( $title = '' ) {
|
||||
parent::after( $this->plugin_info['Title'] );
|
||||
$this->decrement_update_count( 'plugin' );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function bulk_footer() {
|
||||
parent::bulk_footer();
|
||||
|
||||
$update_actions = array(
|
||||
'plugins_page' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'plugins.php' ),
|
||||
__( 'Go to Plugins page' )
|
||||
),
|
||||
'updates_page' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'update-core.php' ),
|
||||
__( 'Go to WordPress Updates page' )
|
||||
),
|
||||
);
|
||||
|
||||
if ( ! current_user_can( 'activate_plugins' ) ) {
|
||||
unset( $update_actions['plugins_page'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following bulk plugin updates.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string[] $update_actions Array of plugin action links.
|
||||
* @param array $plugin_info Array of information for the last-updated plugin.
|
||||
*/
|
||||
$update_actions = apply_filters( 'update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info );
|
||||
|
||||
if ( ! empty( $update_actions ) ) {
|
||||
$this->feedback( implode( ' | ', (array) $update_actions ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Bulk_Plugin_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bulk Plugin Upgrader Skin for WordPress Plugin Upgrades.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see Bulk_Upgrader_Skin
|
||||
*/
|
||||
class Bulk_Plugin_Upgrader_Skin extends Bulk_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Plugin info.
|
||||
*
|
||||
* The Plugin_Upgrader::bulk_upgrade() method will fill this in
|
||||
* with info retrieved from the get_plugin_data() function.
|
||||
*
|
||||
* @var array Plugin data. Values will be empty if not supplied by the plugin.
|
||||
*/
|
||||
public $plugin_info = array();
|
||||
|
||||
public function add_strings() {
|
||||
parent::add_strings();
|
||||
/* translators: 1: Plugin name, 2: Number of the plugin, 3: Total number of plugins being updated. */
|
||||
$this->upgrader->strings['skin_before_update_header'] = __( 'Updating Plugin %1$s (%2$d/%3$d)' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function before( $title = '' ) {
|
||||
parent::before( $this->plugin_info['Title'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function after( $title = '' ) {
|
||||
parent::after( $this->plugin_info['Title'] );
|
||||
$this->decrement_update_count( 'plugin' );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function bulk_footer() {
|
||||
parent::bulk_footer();
|
||||
|
||||
$update_actions = array(
|
||||
'plugins_page' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'plugins.php' ),
|
||||
__( 'Go to Plugins page' )
|
||||
),
|
||||
'updates_page' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'update-core.php' ),
|
||||
__( 'Go to WordPress Updates page' )
|
||||
),
|
||||
);
|
||||
|
||||
if ( ! current_user_can( 'activate_plugins' ) ) {
|
||||
unset( $update_actions['plugins_page'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following bulk plugin updates.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string[] $update_actions Array of plugin action links.
|
||||
* @param array $plugin_info Array of information for the last-updated plugin.
|
||||
*/
|
||||
$update_actions = apply_filters( 'update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info );
|
||||
|
||||
if ( ! empty( $update_actions ) ) {
|
||||
$this->feedback( implode( ' | ', (array) $update_actions ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Bulk_Plugin_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bulk Theme Upgrader Skin for WordPress Theme Upgrades.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see Bulk_Upgrader_Skin
|
||||
*/
|
||||
class Bulk_Theme_Upgrader_Skin extends Bulk_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Theme info.
|
||||
*
|
||||
* The Theme_Upgrader::bulk_upgrade() method will fill this in
|
||||
* with info retrieved from the Theme_Upgrader::theme_info() method,
|
||||
* which in turn calls the wp_get_theme() function.
|
||||
*
|
||||
* @var WP_Theme|false The theme's info object, or false.
|
||||
*/
|
||||
public $theme_info = false;
|
||||
|
||||
public function add_strings() {
|
||||
parent::add_strings();
|
||||
/* translators: 1: Theme name, 2: Number of the theme, 3: Total number of themes being updated. */
|
||||
$this->upgrader->strings['skin_before_update_header'] = __( 'Updating Theme %1$s (%2$d/%3$d)' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function before( $title = '' ) {
|
||||
parent::before( $this->theme_info->display( 'Name' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function after( $title = '' ) {
|
||||
parent::after( $this->theme_info->display( 'Name' ) );
|
||||
$this->decrement_update_count( 'theme' );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function bulk_footer() {
|
||||
parent::bulk_footer();
|
||||
|
||||
$update_actions = array(
|
||||
'themes_page' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'themes.php' ),
|
||||
__( 'Go to Themes page' )
|
||||
),
|
||||
'updates_page' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'update-core.php' ),
|
||||
__( 'Go to WordPress Updates page' )
|
||||
),
|
||||
);
|
||||
|
||||
if ( ! current_user_can( 'switch_themes' ) && ! current_user_can( 'edit_theme_options' ) ) {
|
||||
unset( $update_actions['themes_page'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following bulk theme updates.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string[] $update_actions Array of theme action links.
|
||||
* @param WP_Theme $theme_info Theme object for the last-updated theme.
|
||||
*/
|
||||
$update_actions = apply_filters( 'update_bulk_theme_complete_actions', $update_actions, $this->theme_info );
|
||||
|
||||
if ( ! empty( $update_actions ) ) {
|
||||
$this->feedback( implode( ' | ', (array) $update_actions ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Bulk_Plugin_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bulk Theme Upgrader Skin for WordPress Theme Upgrades.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see Bulk_Upgrader_Skin
|
||||
*/
|
||||
class Bulk_Theme_Upgrader_Skin extends Bulk_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Theme info.
|
||||
*
|
||||
* The Theme_Upgrader::bulk_upgrade() method will fill this in
|
||||
* with info retrieved from the Theme_Upgrader::theme_info() method,
|
||||
* which in turn calls the wp_get_theme() function.
|
||||
*
|
||||
* @var WP_Theme|false The theme's info object, or false.
|
||||
*/
|
||||
public $theme_info = false;
|
||||
|
||||
public function add_strings() {
|
||||
parent::add_strings();
|
||||
/* translators: 1: Theme name, 2: Number of the theme, 3: Total number of themes being updated. */
|
||||
$this->upgrader->strings['skin_before_update_header'] = __( 'Updating Theme %1$s (%2$d/%3$d)' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function before( $title = '' ) {
|
||||
parent::before( $this->theme_info->display( 'Name' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function after( $title = '' ) {
|
||||
parent::after( $this->theme_info->display( 'Name' ) );
|
||||
$this->decrement_update_count( 'theme' );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function bulk_footer() {
|
||||
parent::bulk_footer();
|
||||
|
||||
$update_actions = array(
|
||||
'themes_page' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'themes.php' ),
|
||||
__( 'Go to Themes page' )
|
||||
),
|
||||
'updates_page' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'update-core.php' ),
|
||||
__( 'Go to WordPress Updates page' )
|
||||
),
|
||||
);
|
||||
|
||||
if ( ! current_user_can( 'switch_themes' ) && ! current_user_can( 'edit_theme_options' ) ) {
|
||||
unset( $update_actions['themes_page'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following bulk theme updates.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string[] $update_actions Array of theme action links.
|
||||
* @param WP_Theme $theme_info Theme object for the last-updated theme.
|
||||
*/
|
||||
$update_actions = apply_filters( 'update_bulk_theme_complete_actions', $update_actions, $this->theme_info );
|
||||
|
||||
if ( ! empty( $update_actions ) ) {
|
||||
$this->feedback( implode( ' | ', (array) $update_actions ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,187 +1,187 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Bulk_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generic Bulk Upgrader Skin for WordPress Upgrades.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see WP_Upgrader_Skin
|
||||
*/
|
||||
class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
|
||||
public $in_loop = false;
|
||||
/**
|
||||
* @var string|false
|
||||
*/
|
||||
public $error = false;
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'url' => '',
|
||||
'nonce' => '',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
parent::__construct( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function add_strings() {
|
||||
$this->upgrader->strings['skin_upgrade_start'] = __( 'The update process is starting. This process may take a while on some hosts, so please be patient.' );
|
||||
/* translators: 1: Title of an update, 2: Error message. */
|
||||
$this->upgrader->strings['skin_update_failed_error'] = __( 'An error occurred while updating %1$s: %2$s' );
|
||||
/* translators: %s: Title of an update. */
|
||||
$this->upgrader->strings['skin_update_failed'] = __( 'The update of %s failed.' );
|
||||
/* translators: %s: Title of an update. */
|
||||
$this->upgrader->strings['skin_update_successful'] = __( '%s updated successfully.' );
|
||||
$this->upgrader->strings['skin_upgrade_end'] = __( 'All updates have been completed.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.9.0 Renamed `$string` (a PHP reserved keyword) to `$feedback` for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string $feedback Message data.
|
||||
* @param mixed ...$args Optional text replacements.
|
||||
*/
|
||||
public function feedback( $feedback, ...$args ) {
|
||||
if ( isset( $this->upgrader->strings[ $feedback ] ) ) {
|
||||
$feedback = $this->upgrader->strings[ $feedback ];
|
||||
}
|
||||
|
||||
if ( str_contains( $feedback, '%' ) ) {
|
||||
if ( $args ) {
|
||||
$args = array_map( 'strip_tags', $args );
|
||||
$args = array_map( 'esc_html', $args );
|
||||
$feedback = vsprintf( $feedback, $args );
|
||||
}
|
||||
}
|
||||
if ( empty( $feedback ) ) {
|
||||
return;
|
||||
}
|
||||
if ( $this->in_loop ) {
|
||||
echo "$feedback<br />\n";
|
||||
} else {
|
||||
echo "<p>$feedback</p>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function header() {
|
||||
// Nothing. This will be displayed within an iframe.
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function footer() {
|
||||
// Nothing. This will be displayed within an iframe.
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.9.0 Renamed `$error` to `$errors` for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string|WP_Error $errors Errors.
|
||||
*/
|
||||
public function error( $errors ) {
|
||||
if ( is_string( $errors ) && isset( $this->upgrader->strings[ $errors ] ) ) {
|
||||
$this->error = $this->upgrader->strings[ $errors ];
|
||||
}
|
||||
|
||||
if ( is_wp_error( $errors ) ) {
|
||||
$messages = array();
|
||||
foreach ( $errors->get_error_messages() as $emessage ) {
|
||||
if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) ) {
|
||||
$messages[] = $emessage . ' ' . esc_html( strip_tags( $errors->get_error_data() ) );
|
||||
} else {
|
||||
$messages[] = $emessage;
|
||||
}
|
||||
}
|
||||
$this->error = implode( ', ', $messages );
|
||||
}
|
||||
echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js( $this->upgrader->update_current ) . '\').hide();</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function bulk_header() {
|
||||
$this->feedback( 'skin_upgrade_start' );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function bulk_footer() {
|
||||
$this->feedback( 'skin_upgrade_end' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function before( $title = '' ) {
|
||||
$this->in_loop = true;
|
||||
printf( '<h2>' . $this->upgrader->strings['skin_before_update_header'] . ' <span class="spinner waiting-' . $this->upgrader->update_current . '"></span></h2>', $title, $this->upgrader->update_current, $this->upgrader->update_count );
|
||||
echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js( $this->upgrader->update_current ) . '\').css("display", "inline-block");</script>';
|
||||
// This progress messages div gets moved via JavaScript when clicking on "More details.".
|
||||
echo '<div class="update-messages hide-if-js" id="progress-' . esc_attr( $this->upgrader->update_current ) . '"><p>';
|
||||
$this->flush_output();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function after( $title = '' ) {
|
||||
echo '</p></div>';
|
||||
if ( $this->error || ! $this->result ) {
|
||||
if ( $this->error ) {
|
||||
$after_error_message = sprintf( $this->upgrader->strings['skin_update_failed_error'], $title, '<strong>' . $this->error . '</strong>' );
|
||||
} else {
|
||||
$after_error_message = sprintf( $this->upgrader->strings['skin_update_failed'], $title );
|
||||
}
|
||||
wp_admin_notice(
|
||||
$after_error_message,
|
||||
array(
|
||||
'additional_classes' => array( 'error' ),
|
||||
)
|
||||
);
|
||||
|
||||
echo '<script type="text/javascript">jQuery(\'#progress-' . esc_js( $this->upgrader->update_current ) . '\').show();</script>';
|
||||
}
|
||||
if ( $this->result && ! is_wp_error( $this->result ) ) {
|
||||
if ( ! $this->error ) {
|
||||
echo '<div class="updated js-update-details" data-update-details="progress-' . esc_attr( $this->upgrader->update_current ) . '">' .
|
||||
'<p>' . sprintf( $this->upgrader->strings['skin_update_successful'], $title ) .
|
||||
' <button type="button" class="hide-if-no-js button-link js-update-details-toggle" aria-expanded="false">' . __( 'More details.' ) . '<span class="dashicons dashicons-arrow-down" aria-hidden="true"></span></button>' .
|
||||
'</p></div>';
|
||||
}
|
||||
|
||||
echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js( $this->upgrader->update_current ) . '\').hide();</script>';
|
||||
}
|
||||
|
||||
$this->reset();
|
||||
$this->flush_output();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function reset() {
|
||||
$this->in_loop = false;
|
||||
$this->error = false;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function flush_output() {
|
||||
wp_ob_end_flush_all();
|
||||
flush();
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Bulk_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generic Bulk Upgrader Skin for WordPress Upgrades.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see WP_Upgrader_Skin
|
||||
*/
|
||||
class Bulk_Upgrader_Skin extends WP_Upgrader_Skin {
|
||||
public $in_loop = false;
|
||||
/**
|
||||
* @var string|false
|
||||
*/
|
||||
public $error = false;
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'url' => '',
|
||||
'nonce' => '',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
parent::__construct( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function add_strings() {
|
||||
$this->upgrader->strings['skin_upgrade_start'] = __( 'The update process is starting. This process may take a while on some hosts, so please be patient.' );
|
||||
/* translators: 1: Title of an update, 2: Error message. */
|
||||
$this->upgrader->strings['skin_update_failed_error'] = __( 'An error occurred while updating %1$s: %2$s' );
|
||||
/* translators: %s: Title of an update. */
|
||||
$this->upgrader->strings['skin_update_failed'] = __( 'The update of %s failed.' );
|
||||
/* translators: %s: Title of an update. */
|
||||
$this->upgrader->strings['skin_update_successful'] = __( '%s updated successfully.' );
|
||||
$this->upgrader->strings['skin_upgrade_end'] = __( 'All updates have been completed.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.9.0 Renamed `$string` (a PHP reserved keyword) to `$feedback` for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string $feedback Message data.
|
||||
* @param mixed ...$args Optional text replacements.
|
||||
*/
|
||||
public function feedback( $feedback, ...$args ) {
|
||||
if ( isset( $this->upgrader->strings[ $feedback ] ) ) {
|
||||
$feedback = $this->upgrader->strings[ $feedback ];
|
||||
}
|
||||
|
||||
if ( str_contains( $feedback, '%' ) ) {
|
||||
if ( $args ) {
|
||||
$args = array_map( 'strip_tags', $args );
|
||||
$args = array_map( 'esc_html', $args );
|
||||
$feedback = vsprintf( $feedback, $args );
|
||||
}
|
||||
}
|
||||
if ( empty( $feedback ) ) {
|
||||
return;
|
||||
}
|
||||
if ( $this->in_loop ) {
|
||||
echo "$feedback<br />\n";
|
||||
} else {
|
||||
echo "<p>$feedback</p>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function header() {
|
||||
// Nothing. This will be displayed within an iframe.
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function footer() {
|
||||
// Nothing. This will be displayed within an iframe.
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.9.0 Renamed `$error` to `$errors` for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string|WP_Error $errors Errors.
|
||||
*/
|
||||
public function error( $errors ) {
|
||||
if ( is_string( $errors ) && isset( $this->upgrader->strings[ $errors ] ) ) {
|
||||
$this->error = $this->upgrader->strings[ $errors ];
|
||||
}
|
||||
|
||||
if ( is_wp_error( $errors ) ) {
|
||||
$messages = array();
|
||||
foreach ( $errors->get_error_messages() as $emessage ) {
|
||||
if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) ) {
|
||||
$messages[] = $emessage . ' ' . esc_html( strip_tags( $errors->get_error_data() ) );
|
||||
} else {
|
||||
$messages[] = $emessage;
|
||||
}
|
||||
}
|
||||
$this->error = implode( ', ', $messages );
|
||||
}
|
||||
echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js( $this->upgrader->update_current ) . '\').hide();</script>';
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function bulk_header() {
|
||||
$this->feedback( 'skin_upgrade_start' );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function bulk_footer() {
|
||||
$this->feedback( 'skin_upgrade_end' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function before( $title = '' ) {
|
||||
$this->in_loop = true;
|
||||
printf( '<h2>' . $this->upgrader->strings['skin_before_update_header'] . ' <span class="spinner waiting-' . $this->upgrader->update_current . '"></span></h2>', $title, $this->upgrader->update_current, $this->upgrader->update_count );
|
||||
echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js( $this->upgrader->update_current ) . '\').css("display", "inline-block");</script>';
|
||||
// This progress messages div gets moved via JavaScript when clicking on "More details.".
|
||||
echo '<div class="update-messages hide-if-js" id="progress-' . esc_attr( $this->upgrader->update_current ) . '"><p>';
|
||||
$this->flush_output();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function after( $title = '' ) {
|
||||
echo '</p></div>';
|
||||
if ( $this->error || ! $this->result ) {
|
||||
if ( $this->error ) {
|
||||
$after_error_message = sprintf( $this->upgrader->strings['skin_update_failed_error'], $title, '<strong>' . $this->error . '</strong>' );
|
||||
} else {
|
||||
$after_error_message = sprintf( $this->upgrader->strings['skin_update_failed'], $title );
|
||||
}
|
||||
wp_admin_notice(
|
||||
$after_error_message,
|
||||
array(
|
||||
'additional_classes' => array( 'error' ),
|
||||
)
|
||||
);
|
||||
|
||||
echo '<script type="text/javascript">jQuery(\'#progress-' . esc_js( $this->upgrader->update_current ) . '\').show();</script>';
|
||||
}
|
||||
if ( $this->result && ! is_wp_error( $this->result ) ) {
|
||||
if ( ! $this->error ) {
|
||||
echo '<div class="updated js-update-details" data-update-details="progress-' . esc_attr( $this->upgrader->update_current ) . '">' .
|
||||
'<p>' . sprintf( $this->upgrader->strings['skin_update_successful'], $title ) .
|
||||
' <button type="button" class="hide-if-no-js button-link js-update-details-toggle" aria-expanded="false">' . __( 'More details.' ) . '<span class="dashicons dashicons-arrow-down" aria-hidden="true"></span></button>' .
|
||||
'</p></div>';
|
||||
}
|
||||
|
||||
echo '<script type="text/javascript">jQuery(\'.waiting-' . esc_js( $this->upgrader->update_current ) . '\').hide();</script>';
|
||||
}
|
||||
|
||||
$this->reset();
|
||||
$this->flush_output();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function reset() {
|
||||
$this->in_loop = false;
|
||||
$this->error = false;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function flush_output() {
|
||||
wp_ob_end_flush_all();
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,420 +1,420 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrade API: Core_Upgrader class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used for updating core.
|
||||
*
|
||||
* It allows for WordPress to upgrade itself in combination with
|
||||
* the wp-admin/includes/update-core.php file.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader.php.
|
||||
*
|
||||
* @see WP_Upgrader
|
||||
*/
|
||||
class Core_Upgrader extends WP_Upgrader {
|
||||
|
||||
/**
|
||||
* Initializes the upgrade strings.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function upgrade_strings() {
|
||||
$this->strings['up_to_date'] = __( 'WordPress is at the latest version.' );
|
||||
$this->strings['locked'] = __( 'Another update is currently in progress.' );
|
||||
$this->strings['no_package'] = __( 'Update package not available.' );
|
||||
/* translators: %s: Package URL. */
|
||||
$this->strings['downloading_package'] = sprintf( __( 'Downloading update from %s…' ), '<span class="code pre">%s</span>' );
|
||||
$this->strings['unpack_package'] = __( 'Unpacking the update…' );
|
||||
$this->strings['copy_failed'] = __( 'Could not copy files.' );
|
||||
$this->strings['copy_failed_space'] = __( 'Could not copy files. You may have run out of disk space.' );
|
||||
$this->strings['start_rollback'] = __( 'Attempting to restore the previous version.' );
|
||||
$this->strings['rollback_was_required'] = __( 'Due to an error during updating, WordPress has been restored to your previous version.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades WordPress core.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
* @global callable $_wp_filesystem_direct_method
|
||||
*
|
||||
* @param object $current Response object for whether WordPress is current.
|
||||
* @param array $args {
|
||||
* Optional. Arguments for upgrading WordPress core. Default empty array.
|
||||
*
|
||||
* @type bool $pre_check_md5 Whether to check the file checksums before
|
||||
* attempting the upgrade. Default true.
|
||||
* @type bool $attempt_rollback Whether to attempt to rollback the chances if
|
||||
* there is a problem. Default false.
|
||||
* @type bool $do_rollback Whether to perform this "upgrade" as a rollback.
|
||||
* Default false.
|
||||
* }
|
||||
* @return string|false|WP_Error New WordPress version on success, false or WP_Error on failure.
|
||||
*/
|
||||
public function upgrade( $current, $args = array() ) {
|
||||
global $wp_filesystem;
|
||||
|
||||
require ABSPATH . WPINC . '/version.php'; // $wp_version;
|
||||
|
||||
$start_time = time();
|
||||
|
||||
$defaults = array(
|
||||
'pre_check_md5' => true,
|
||||
'attempt_rollback' => false,
|
||||
'do_rollback' => false,
|
||||
'allow_relaxed_file_ownership' => false,
|
||||
);
|
||||
$parsed_args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$this->init();
|
||||
$this->upgrade_strings();
|
||||
|
||||
// Is an update available?
|
||||
if ( ! isset( $current->response ) || 'latest' === $current->response ) {
|
||||
return new WP_Error( 'up_to_date', $this->strings['up_to_date'] );
|
||||
}
|
||||
|
||||
$res = $this->fs_connect( array( ABSPATH, WP_CONTENT_DIR ), $parsed_args['allow_relaxed_file_ownership'] );
|
||||
if ( ! $res || is_wp_error( $res ) ) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
$wp_dir = trailingslashit( $wp_filesystem->abspath() );
|
||||
|
||||
$partial = true;
|
||||
if ( $parsed_args['do_rollback'] ) {
|
||||
$partial = false;
|
||||
} elseif ( $parsed_args['pre_check_md5'] && ! $this->check_files() ) {
|
||||
$partial = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If partial update is returned from the API, use that, unless we're doing
|
||||
* a reinstallation. If we cross the new_bundled version number, then use
|
||||
* the new_bundled zip. Don't though if the constant is set to skip bundled items.
|
||||
* If the API returns a no_content zip, go with it. Finally, default to the full zip.
|
||||
*/
|
||||
if ( $parsed_args['do_rollback'] && $current->packages->rollback ) {
|
||||
$to_download = 'rollback';
|
||||
} elseif ( $current->packages->partial && 'reinstall' !== $current->response && $wp_version === $current->partial_version && $partial ) {
|
||||
$to_download = 'partial';
|
||||
} elseif ( $current->packages->new_bundled && version_compare( $wp_version, $current->new_bundled, '<' )
|
||||
&& ( ! defined( 'CORE_UPGRADE_SKIP_NEW_BUNDLED' ) || ! CORE_UPGRADE_SKIP_NEW_BUNDLED ) ) {
|
||||
$to_download = 'new_bundled';
|
||||
} elseif ( $current->packages->no_content ) {
|
||||
$to_download = 'no_content';
|
||||
} else {
|
||||
$to_download = 'full';
|
||||
}
|
||||
|
||||
// Lock to prevent multiple Core Updates occurring.
|
||||
$lock = WP_Upgrader::create_lock( 'core_updater', 15 * MINUTE_IN_SECONDS );
|
||||
if ( ! $lock ) {
|
||||
return new WP_Error( 'locked', $this->strings['locked'] );
|
||||
}
|
||||
|
||||
$download = $this->download_package( $current->packages->$to_download, true );
|
||||
|
||||
/*
|
||||
* Allow for signature soft-fail.
|
||||
* WARNING: This may be removed in the future.
|
||||
*/
|
||||
if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) {
|
||||
// Output the failure error as a normal feedback, and not as an error:
|
||||
/** This filter is documented in wp-admin/includes/update-core.php */
|
||||
apply_filters( 'update_feedback', $download->get_error_message() );
|
||||
|
||||
// Report this failure back to WordPress.org for debugging purposes.
|
||||
wp_version_check(
|
||||
array(
|
||||
'signature_failure_code' => $download->get_error_code(),
|
||||
'signature_failure_data' => $download->get_error_data(),
|
||||
)
|
||||
);
|
||||
|
||||
// Pretend this error didn't happen.
|
||||
$download = $download->get_error_data( 'softfail-filename' );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $download ) ) {
|
||||
WP_Upgrader::release_lock( 'core_updater' );
|
||||
return $download;
|
||||
}
|
||||
|
||||
$working_dir = $this->unpack_package( $download );
|
||||
if ( is_wp_error( $working_dir ) ) {
|
||||
WP_Upgrader::release_lock( 'core_updater' );
|
||||
return $working_dir;
|
||||
}
|
||||
|
||||
// Copy update-core.php from the new version into place.
|
||||
if ( ! $wp_filesystem->copy( $working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true ) ) {
|
||||
$wp_filesystem->delete( $working_dir, true );
|
||||
WP_Upgrader::release_lock( 'core_updater' );
|
||||
return new WP_Error( 'copy_failed_for_update_core_file', __( 'The update cannot be installed because some files could not be copied. This is usually due to inconsistent file permissions.' ), 'wp-admin/includes/update-core.php' );
|
||||
}
|
||||
$wp_filesystem->chmod( $wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE );
|
||||
|
||||
wp_opcache_invalidate( ABSPATH . 'wp-admin/includes/update-core.php' );
|
||||
require_once ABSPATH . 'wp-admin/includes/update-core.php';
|
||||
|
||||
if ( ! function_exists( 'update_core' ) ) {
|
||||
WP_Upgrader::release_lock( 'core_updater' );
|
||||
return new WP_Error( 'copy_failed_space', $this->strings['copy_failed_space'] );
|
||||
}
|
||||
|
||||
$result = update_core( $working_dir, $wp_dir );
|
||||
|
||||
// In the event of an issue, we may be able to roll back.
|
||||
if ( $parsed_args['attempt_rollback'] && $current->packages->rollback && ! $parsed_args['do_rollback'] ) {
|
||||
$try_rollback = false;
|
||||
if ( is_wp_error( $result ) ) {
|
||||
$error_code = $result->get_error_code();
|
||||
/*
|
||||
* Not all errors are equal. These codes are critical: copy_failed__copy_dir,
|
||||
* mkdir_failed__copy_dir, copy_failed__copy_dir_retry, and disk_full.
|
||||
* do_rollback allows for update_core() to trigger a rollback if needed.
|
||||
*/
|
||||
if ( str_contains( $error_code, 'do_rollback' ) ) {
|
||||
$try_rollback = true;
|
||||
} elseif ( str_contains( $error_code, '__copy_dir' ) ) {
|
||||
$try_rollback = true;
|
||||
} elseif ( 'disk_full' === $error_code ) {
|
||||
$try_rollback = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $try_rollback ) {
|
||||
/** This filter is documented in wp-admin/includes/update-core.php */
|
||||
apply_filters( 'update_feedback', $result );
|
||||
|
||||
/** This filter is documented in wp-admin/includes/update-core.php */
|
||||
apply_filters( 'update_feedback', $this->strings['start_rollback'] );
|
||||
|
||||
$rollback_result = $this->upgrade( $current, array_merge( $parsed_args, array( 'do_rollback' => true ) ) );
|
||||
|
||||
$original_result = $result;
|
||||
$result = new WP_Error(
|
||||
'rollback_was_required',
|
||||
$this->strings['rollback_was_required'],
|
||||
(object) array(
|
||||
'update' => $original_result,
|
||||
'rollback' => $rollback_result,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/** This action is documented in wp-admin/includes/class-wp-upgrader.php */
|
||||
do_action(
|
||||
'upgrader_process_complete',
|
||||
$this,
|
||||
array(
|
||||
'action' => 'update',
|
||||
'type' => 'core',
|
||||
)
|
||||
);
|
||||
|
||||
// Clear the current updates.
|
||||
delete_site_transient( 'update_core' );
|
||||
|
||||
if ( ! $parsed_args['do_rollback'] ) {
|
||||
$stats = array(
|
||||
'update_type' => $current->response,
|
||||
'success' => true,
|
||||
'fs_method' => $wp_filesystem->method,
|
||||
'fs_method_forced' => defined( 'FS_METHOD' ) || has_filter( 'filesystem_method' ),
|
||||
'fs_method_direct' => ! empty( $GLOBALS['_wp_filesystem_direct_method'] ) ? $GLOBALS['_wp_filesystem_direct_method'] : '',
|
||||
'time_taken' => time() - $start_time,
|
||||
'reported' => $wp_version,
|
||||
'attempted' => $current->version,
|
||||
);
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
$stats['success'] = false;
|
||||
// Did a rollback occur?
|
||||
if ( ! empty( $try_rollback ) ) {
|
||||
$stats['error_code'] = $original_result->get_error_code();
|
||||
$stats['error_data'] = $original_result->get_error_data();
|
||||
// Was the rollback successful? If not, collect its error too.
|
||||
$stats['rollback'] = ! is_wp_error( $rollback_result );
|
||||
if ( is_wp_error( $rollback_result ) ) {
|
||||
$stats['rollback_code'] = $rollback_result->get_error_code();
|
||||
$stats['rollback_data'] = $rollback_result->get_error_data();
|
||||
}
|
||||
} else {
|
||||
$stats['error_code'] = $result->get_error_code();
|
||||
$stats['error_data'] = $result->get_error_data();
|
||||
}
|
||||
}
|
||||
|
||||
wp_version_check( $stats );
|
||||
}
|
||||
|
||||
WP_Upgrader::release_lock( 'core_updater' );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this WordPress Core version should update to an offered version or not.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string $offered_ver The offered version, of the format x.y.z.
|
||||
* @return bool True if we should update to the offered version, otherwise false.
|
||||
*/
|
||||
public static function should_update_to_version( $offered_ver ) {
|
||||
require ABSPATH . WPINC . '/version.php'; // $wp_version; // x.y.z
|
||||
|
||||
$current_branch = implode( '.', array_slice( preg_split( '/[.-]/', $wp_version ), 0, 2 ) ); // x.y
|
||||
$new_branch = implode( '.', array_slice( preg_split( '/[.-]/', $offered_ver ), 0, 2 ) ); // x.y
|
||||
|
||||
$current_is_development_version = (bool) strpos( $wp_version, '-' );
|
||||
|
||||
// Defaults:
|
||||
$upgrade_dev = get_site_option( 'auto_update_core_dev', 'enabled' ) === 'enabled';
|
||||
$upgrade_minor = get_site_option( 'auto_update_core_minor', 'enabled' ) === 'enabled';
|
||||
$upgrade_major = get_site_option( 'auto_update_core_major', 'unset' ) === 'enabled';
|
||||
|
||||
// WP_AUTO_UPDATE_CORE = true (all), 'beta', 'rc', 'development', 'branch-development', 'minor', false.
|
||||
if ( defined( 'WP_AUTO_UPDATE_CORE' ) ) {
|
||||
if ( false === WP_AUTO_UPDATE_CORE ) {
|
||||
// Defaults to turned off, unless a filter allows it.
|
||||
$upgrade_dev = false;
|
||||
$upgrade_minor = false;
|
||||
$upgrade_major = false;
|
||||
} elseif ( true === WP_AUTO_UPDATE_CORE
|
||||
|| in_array( WP_AUTO_UPDATE_CORE, array( 'beta', 'rc', 'development', 'branch-development' ), true )
|
||||
) {
|
||||
// ALL updates for core.
|
||||
$upgrade_dev = true;
|
||||
$upgrade_minor = true;
|
||||
$upgrade_major = true;
|
||||
} elseif ( 'minor' === WP_AUTO_UPDATE_CORE ) {
|
||||
// Only minor updates for core.
|
||||
$upgrade_dev = false;
|
||||
$upgrade_minor = true;
|
||||
$upgrade_major = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 1: If we're already on that version, not much point in updating?
|
||||
if ( $offered_ver === $wp_version ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2: If we're running a newer version, that's a nope.
|
||||
if ( version_compare( $wp_version, $offered_ver, '>' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$failure_data = get_site_option( 'auto_core_update_failed' );
|
||||
if ( $failure_data ) {
|
||||
// If this was a critical update failure, cannot update.
|
||||
if ( ! empty( $failure_data['critical'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't claim we can update on update-core.php if we have a non-critical failure logged.
|
||||
if ( $wp_version === $failure_data['current'] && str_contains( $offered_ver, '.1.next.minor' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cannot update if we're retrying the same A to B update that caused a non-critical failure.
|
||||
* Some non-critical failures do allow retries, like download_failed.
|
||||
* 3.7.1 => 3.7.2 resulted in files_not_writable, if we are still on 3.7.1 and still trying to update to 3.7.2.
|
||||
*/
|
||||
if ( empty( $failure_data['retry'] ) && $wp_version === $failure_data['current'] && $offered_ver === $failure_data['attempted'] ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 3: 3.7-alpha-25000 -> 3.7-alpha-25678 -> 3.7-beta1 -> 3.7-beta2.
|
||||
if ( $current_is_development_version ) {
|
||||
|
||||
/**
|
||||
* Filters whether to enable automatic core updates for development versions.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param bool $upgrade_dev Whether to enable automatic updates for
|
||||
* development versions.
|
||||
*/
|
||||
if ( ! apply_filters( 'allow_dev_auto_core_updates', $upgrade_dev ) ) {
|
||||
return false;
|
||||
}
|
||||
// Else fall through to minor + major branches below.
|
||||
}
|
||||
|
||||
// 4: Minor in-branch updates (3.7.0 -> 3.7.1 -> 3.7.2 -> 3.7.4).
|
||||
if ( $current_branch === $new_branch ) {
|
||||
|
||||
/**
|
||||
* Filters whether to enable minor automatic core updates.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param bool $upgrade_minor Whether to enable minor automatic core updates.
|
||||
*/
|
||||
return apply_filters( 'allow_minor_auto_core_updates', $upgrade_minor );
|
||||
}
|
||||
|
||||
// 5: Major version updates (3.7.0 -> 3.8.0 -> 3.9.1).
|
||||
if ( version_compare( $new_branch, $current_branch, '>' ) ) {
|
||||
|
||||
/**
|
||||
* Filters whether to enable major automatic core updates.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param bool $upgrade_major Whether to enable major automatic core updates.
|
||||
*/
|
||||
return apply_filters( 'allow_major_auto_core_updates', $upgrade_major );
|
||||
}
|
||||
|
||||
// If we're not sure, we don't want it.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the disk file checksums against the expected checksums.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @global string $wp_version The WordPress version string.
|
||||
* @global string $wp_local_package Locale code of the package.
|
||||
*
|
||||
* @return bool True if the checksums match, otherwise false.
|
||||
*/
|
||||
public function check_files() {
|
||||
global $wp_version, $wp_local_package;
|
||||
|
||||
$checksums = get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' );
|
||||
|
||||
if ( ! is_array( $checksums ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( $checksums as $file => $checksum ) {
|
||||
// Skip files which get updated.
|
||||
if ( str_starts_with( $file, 'wp-content' ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! file_exists( ABSPATH . $file ) || md5_file( ABSPATH . $file ) !== $checksum ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrade API: Core_Upgrader class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used for updating core.
|
||||
*
|
||||
* It allows for WordPress to upgrade itself in combination with
|
||||
* the wp-admin/includes/update-core.php file.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader.php.
|
||||
*
|
||||
* @see WP_Upgrader
|
||||
*/
|
||||
class Core_Upgrader extends WP_Upgrader {
|
||||
|
||||
/**
|
||||
* Initializes the upgrade strings.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function upgrade_strings() {
|
||||
$this->strings['up_to_date'] = __( 'WordPress is at the latest version.' );
|
||||
$this->strings['locked'] = __( 'Another update is currently in progress.' );
|
||||
$this->strings['no_package'] = __( 'Update package not available.' );
|
||||
/* translators: %s: Package URL. */
|
||||
$this->strings['downloading_package'] = sprintf( __( 'Downloading update from %s…' ), '<span class="code pre">%s</span>' );
|
||||
$this->strings['unpack_package'] = __( 'Unpacking the update…' );
|
||||
$this->strings['copy_failed'] = __( 'Could not copy files.' );
|
||||
$this->strings['copy_failed_space'] = __( 'Could not copy files. You may have run out of disk space.' );
|
||||
$this->strings['start_rollback'] = __( 'Attempting to restore the previous version.' );
|
||||
$this->strings['rollback_was_required'] = __( 'Due to an error during updating, WordPress has been restored to your previous version.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades WordPress core.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
* @global callable $_wp_filesystem_direct_method
|
||||
*
|
||||
* @param object $current Response object for whether WordPress is current.
|
||||
* @param array $args {
|
||||
* Optional. Arguments for upgrading WordPress core. Default empty array.
|
||||
*
|
||||
* @type bool $pre_check_md5 Whether to check the file checksums before
|
||||
* attempting the upgrade. Default true.
|
||||
* @type bool $attempt_rollback Whether to attempt to rollback the chances if
|
||||
* there is a problem. Default false.
|
||||
* @type bool $do_rollback Whether to perform this "upgrade" as a rollback.
|
||||
* Default false.
|
||||
* }
|
||||
* @return string|false|WP_Error New WordPress version on success, false or WP_Error on failure.
|
||||
*/
|
||||
public function upgrade( $current, $args = array() ) {
|
||||
global $wp_filesystem;
|
||||
|
||||
require ABSPATH . WPINC . '/version.php'; // $wp_version;
|
||||
|
||||
$start_time = time();
|
||||
|
||||
$defaults = array(
|
||||
'pre_check_md5' => true,
|
||||
'attempt_rollback' => false,
|
||||
'do_rollback' => false,
|
||||
'allow_relaxed_file_ownership' => false,
|
||||
);
|
||||
$parsed_args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$this->init();
|
||||
$this->upgrade_strings();
|
||||
|
||||
// Is an update available?
|
||||
if ( ! isset( $current->response ) || 'latest' === $current->response ) {
|
||||
return new WP_Error( 'up_to_date', $this->strings['up_to_date'] );
|
||||
}
|
||||
|
||||
$res = $this->fs_connect( array( ABSPATH, WP_CONTENT_DIR ), $parsed_args['allow_relaxed_file_ownership'] );
|
||||
if ( ! $res || is_wp_error( $res ) ) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
$wp_dir = trailingslashit( $wp_filesystem->abspath() );
|
||||
|
||||
$partial = true;
|
||||
if ( $parsed_args['do_rollback'] ) {
|
||||
$partial = false;
|
||||
} elseif ( $parsed_args['pre_check_md5'] && ! $this->check_files() ) {
|
||||
$partial = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If partial update is returned from the API, use that, unless we're doing
|
||||
* a reinstallation. If we cross the new_bundled version number, then use
|
||||
* the new_bundled zip. Don't though if the constant is set to skip bundled items.
|
||||
* If the API returns a no_content zip, go with it. Finally, default to the full zip.
|
||||
*/
|
||||
if ( $parsed_args['do_rollback'] && $current->packages->rollback ) {
|
||||
$to_download = 'rollback';
|
||||
} elseif ( $current->packages->partial && 'reinstall' !== $current->response && $wp_version === $current->partial_version && $partial ) {
|
||||
$to_download = 'partial';
|
||||
} elseif ( $current->packages->new_bundled && version_compare( $wp_version, $current->new_bundled, '<' )
|
||||
&& ( ! defined( 'CORE_UPGRADE_SKIP_NEW_BUNDLED' ) || ! CORE_UPGRADE_SKIP_NEW_BUNDLED ) ) {
|
||||
$to_download = 'new_bundled';
|
||||
} elseif ( $current->packages->no_content ) {
|
||||
$to_download = 'no_content';
|
||||
} else {
|
||||
$to_download = 'full';
|
||||
}
|
||||
|
||||
// Lock to prevent multiple Core Updates occurring.
|
||||
$lock = WP_Upgrader::create_lock( 'core_updater', 15 * MINUTE_IN_SECONDS );
|
||||
if ( ! $lock ) {
|
||||
return new WP_Error( 'locked', $this->strings['locked'] );
|
||||
}
|
||||
|
||||
$download = $this->download_package( $current->packages->$to_download, true );
|
||||
|
||||
/*
|
||||
* Allow for signature soft-fail.
|
||||
* WARNING: This may be removed in the future.
|
||||
*/
|
||||
if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) {
|
||||
// Output the failure error as a normal feedback, and not as an error:
|
||||
/** This filter is documented in wp-admin/includes/update-core.php */
|
||||
apply_filters( 'update_feedback', $download->get_error_message() );
|
||||
|
||||
// Report this failure back to WordPress.org for debugging purposes.
|
||||
wp_version_check(
|
||||
array(
|
||||
'signature_failure_code' => $download->get_error_code(),
|
||||
'signature_failure_data' => $download->get_error_data(),
|
||||
)
|
||||
);
|
||||
|
||||
// Pretend this error didn't happen.
|
||||
$download = $download->get_error_data( 'softfail-filename' );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $download ) ) {
|
||||
WP_Upgrader::release_lock( 'core_updater' );
|
||||
return $download;
|
||||
}
|
||||
|
||||
$working_dir = $this->unpack_package( $download );
|
||||
if ( is_wp_error( $working_dir ) ) {
|
||||
WP_Upgrader::release_lock( 'core_updater' );
|
||||
return $working_dir;
|
||||
}
|
||||
|
||||
// Copy update-core.php from the new version into place.
|
||||
if ( ! $wp_filesystem->copy( $working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true ) ) {
|
||||
$wp_filesystem->delete( $working_dir, true );
|
||||
WP_Upgrader::release_lock( 'core_updater' );
|
||||
return new WP_Error( 'copy_failed_for_update_core_file', __( 'The update cannot be installed because some files could not be copied. This is usually due to inconsistent file permissions.' ), 'wp-admin/includes/update-core.php' );
|
||||
}
|
||||
$wp_filesystem->chmod( $wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE );
|
||||
|
||||
wp_opcache_invalidate( ABSPATH . 'wp-admin/includes/update-core.php' );
|
||||
require_once ABSPATH . 'wp-admin/includes/update-core.php';
|
||||
|
||||
if ( ! function_exists( 'update_core' ) ) {
|
||||
WP_Upgrader::release_lock( 'core_updater' );
|
||||
return new WP_Error( 'copy_failed_space', $this->strings['copy_failed_space'] );
|
||||
}
|
||||
|
||||
$result = update_core( $working_dir, $wp_dir );
|
||||
|
||||
// In the event of an issue, we may be able to roll back.
|
||||
if ( $parsed_args['attempt_rollback'] && $current->packages->rollback && ! $parsed_args['do_rollback'] ) {
|
||||
$try_rollback = false;
|
||||
if ( is_wp_error( $result ) ) {
|
||||
$error_code = $result->get_error_code();
|
||||
/*
|
||||
* Not all errors are equal. These codes are critical: copy_failed__copy_dir,
|
||||
* mkdir_failed__copy_dir, copy_failed__copy_dir_retry, and disk_full.
|
||||
* do_rollback allows for update_core() to trigger a rollback if needed.
|
||||
*/
|
||||
if ( str_contains( $error_code, 'do_rollback' ) ) {
|
||||
$try_rollback = true;
|
||||
} elseif ( str_contains( $error_code, '__copy_dir' ) ) {
|
||||
$try_rollback = true;
|
||||
} elseif ( 'disk_full' === $error_code ) {
|
||||
$try_rollback = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $try_rollback ) {
|
||||
/** This filter is documented in wp-admin/includes/update-core.php */
|
||||
apply_filters( 'update_feedback', $result );
|
||||
|
||||
/** This filter is documented in wp-admin/includes/update-core.php */
|
||||
apply_filters( 'update_feedback', $this->strings['start_rollback'] );
|
||||
|
||||
$rollback_result = $this->upgrade( $current, array_merge( $parsed_args, array( 'do_rollback' => true ) ) );
|
||||
|
||||
$original_result = $result;
|
||||
$result = new WP_Error(
|
||||
'rollback_was_required',
|
||||
$this->strings['rollback_was_required'],
|
||||
(object) array(
|
||||
'update' => $original_result,
|
||||
'rollback' => $rollback_result,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/** This action is documented in wp-admin/includes/class-wp-upgrader.php */
|
||||
do_action(
|
||||
'upgrader_process_complete',
|
||||
$this,
|
||||
array(
|
||||
'action' => 'update',
|
||||
'type' => 'core',
|
||||
)
|
||||
);
|
||||
|
||||
// Clear the current updates.
|
||||
delete_site_transient( 'update_core' );
|
||||
|
||||
if ( ! $parsed_args['do_rollback'] ) {
|
||||
$stats = array(
|
||||
'update_type' => $current->response,
|
||||
'success' => true,
|
||||
'fs_method' => $wp_filesystem->method,
|
||||
'fs_method_forced' => defined( 'FS_METHOD' ) || has_filter( 'filesystem_method' ),
|
||||
'fs_method_direct' => ! empty( $GLOBALS['_wp_filesystem_direct_method'] ) ? $GLOBALS['_wp_filesystem_direct_method'] : '',
|
||||
'time_taken' => time() - $start_time,
|
||||
'reported' => $wp_version,
|
||||
'attempted' => $current->version,
|
||||
);
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
$stats['success'] = false;
|
||||
// Did a rollback occur?
|
||||
if ( ! empty( $try_rollback ) ) {
|
||||
$stats['error_code'] = $original_result->get_error_code();
|
||||
$stats['error_data'] = $original_result->get_error_data();
|
||||
// Was the rollback successful? If not, collect its error too.
|
||||
$stats['rollback'] = ! is_wp_error( $rollback_result );
|
||||
if ( is_wp_error( $rollback_result ) ) {
|
||||
$stats['rollback_code'] = $rollback_result->get_error_code();
|
||||
$stats['rollback_data'] = $rollback_result->get_error_data();
|
||||
}
|
||||
} else {
|
||||
$stats['error_code'] = $result->get_error_code();
|
||||
$stats['error_data'] = $result->get_error_data();
|
||||
}
|
||||
}
|
||||
|
||||
wp_version_check( $stats );
|
||||
}
|
||||
|
||||
WP_Upgrader::release_lock( 'core_updater' );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this WordPress Core version should update to an offered version or not.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string $offered_ver The offered version, of the format x.y.z.
|
||||
* @return bool True if we should update to the offered version, otherwise false.
|
||||
*/
|
||||
public static function should_update_to_version( $offered_ver ) {
|
||||
require ABSPATH . WPINC . '/version.php'; // $wp_version; // x.y.z
|
||||
|
||||
$current_branch = implode( '.', array_slice( preg_split( '/[.-]/', $wp_version ), 0, 2 ) ); // x.y
|
||||
$new_branch = implode( '.', array_slice( preg_split( '/[.-]/', $offered_ver ), 0, 2 ) ); // x.y
|
||||
|
||||
$current_is_development_version = (bool) strpos( $wp_version, '-' );
|
||||
|
||||
// Defaults:
|
||||
$upgrade_dev = get_site_option( 'auto_update_core_dev', 'enabled' ) === 'enabled';
|
||||
$upgrade_minor = get_site_option( 'auto_update_core_minor', 'enabled' ) === 'enabled';
|
||||
$upgrade_major = get_site_option( 'auto_update_core_major', 'unset' ) === 'enabled';
|
||||
|
||||
// WP_AUTO_UPDATE_CORE = true (all), 'beta', 'rc', 'development', 'branch-development', 'minor', false.
|
||||
if ( defined( 'WP_AUTO_UPDATE_CORE' ) ) {
|
||||
if ( false === WP_AUTO_UPDATE_CORE ) {
|
||||
// Defaults to turned off, unless a filter allows it.
|
||||
$upgrade_dev = false;
|
||||
$upgrade_minor = false;
|
||||
$upgrade_major = false;
|
||||
} elseif ( true === WP_AUTO_UPDATE_CORE
|
||||
|| in_array( WP_AUTO_UPDATE_CORE, array( 'beta', 'rc', 'development', 'branch-development' ), true )
|
||||
) {
|
||||
// ALL updates for core.
|
||||
$upgrade_dev = true;
|
||||
$upgrade_minor = true;
|
||||
$upgrade_major = true;
|
||||
} elseif ( 'minor' === WP_AUTO_UPDATE_CORE ) {
|
||||
// Only minor updates for core.
|
||||
$upgrade_dev = false;
|
||||
$upgrade_minor = true;
|
||||
$upgrade_major = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 1: If we're already on that version, not much point in updating?
|
||||
if ( $offered_ver === $wp_version ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2: If we're running a newer version, that's a nope.
|
||||
if ( version_compare( $wp_version, $offered_ver, '>' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$failure_data = get_site_option( 'auto_core_update_failed' );
|
||||
if ( $failure_data ) {
|
||||
// If this was a critical update failure, cannot update.
|
||||
if ( ! empty( $failure_data['critical'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't claim we can update on update-core.php if we have a non-critical failure logged.
|
||||
if ( $wp_version === $failure_data['current'] && str_contains( $offered_ver, '.1.next.minor' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cannot update if we're retrying the same A to B update that caused a non-critical failure.
|
||||
* Some non-critical failures do allow retries, like download_failed.
|
||||
* 3.7.1 => 3.7.2 resulted in files_not_writable, if we are still on 3.7.1 and still trying to update to 3.7.2.
|
||||
*/
|
||||
if ( empty( $failure_data['retry'] ) && $wp_version === $failure_data['current'] && $offered_ver === $failure_data['attempted'] ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 3: 3.7-alpha-25000 -> 3.7-alpha-25678 -> 3.7-beta1 -> 3.7-beta2.
|
||||
if ( $current_is_development_version ) {
|
||||
|
||||
/**
|
||||
* Filters whether to enable automatic core updates for development versions.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param bool $upgrade_dev Whether to enable automatic updates for
|
||||
* development versions.
|
||||
*/
|
||||
if ( ! apply_filters( 'allow_dev_auto_core_updates', $upgrade_dev ) ) {
|
||||
return false;
|
||||
}
|
||||
// Else fall through to minor + major branches below.
|
||||
}
|
||||
|
||||
// 4: Minor in-branch updates (3.7.0 -> 3.7.1 -> 3.7.2 -> 3.7.4).
|
||||
if ( $current_branch === $new_branch ) {
|
||||
|
||||
/**
|
||||
* Filters whether to enable minor automatic core updates.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param bool $upgrade_minor Whether to enable minor automatic core updates.
|
||||
*/
|
||||
return apply_filters( 'allow_minor_auto_core_updates', $upgrade_minor );
|
||||
}
|
||||
|
||||
// 5: Major version updates (3.7.0 -> 3.8.0 -> 3.9.1).
|
||||
if ( version_compare( $new_branch, $current_branch, '>' ) ) {
|
||||
|
||||
/**
|
||||
* Filters whether to enable major automatic core updates.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param bool $upgrade_major Whether to enable major automatic core updates.
|
||||
*/
|
||||
return apply_filters( 'allow_major_auto_core_updates', $upgrade_major );
|
||||
}
|
||||
|
||||
// If we're not sure, we don't want it.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the disk file checksums against the expected checksums.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @global string $wp_version The WordPress version string.
|
||||
* @global string $wp_local_package Locale code of the package.
|
||||
*
|
||||
* @return bool True if the checksums match, otherwise false.
|
||||
*/
|
||||
public function check_files() {
|
||||
global $wp_version, $wp_local_package;
|
||||
|
||||
$checksums = get_core_checksums( $wp_version, isset( $wp_local_package ) ? $wp_local_package : 'en_US' );
|
||||
|
||||
if ( ! is_array( $checksums ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( $checksums as $file => $checksum ) {
|
||||
// Skip files which get updated.
|
||||
if ( str_starts_with( $file, 'wp-content' ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! file_exists( ABSPATH . $file ) || md5_file( ABSPATH . $file ) !== $checksum ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,141 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrade API: File_Upload_Upgrader class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used for handling file uploads.
|
||||
*
|
||||
* This class handles the upload process and passes it as if it's a local file
|
||||
* to the Upgrade/Installer functions.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader.php.
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
class File_Upload_Upgrader {
|
||||
|
||||
/**
|
||||
* The full path to the file package.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @var string $package
|
||||
*/
|
||||
public $package;
|
||||
|
||||
/**
|
||||
* The name of the file.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @var string $filename
|
||||
*/
|
||||
public $filename;
|
||||
|
||||
/**
|
||||
* The ID of the attachment post for this file.
|
||||
*
|
||||
* @since 3.3.0
|
||||
* @var int $id
|
||||
*/
|
||||
public $id = 0;
|
||||
|
||||
/**
|
||||
* Construct the upgrader for a form.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string $form The name of the form the file was uploaded from.
|
||||
* @param string $urlholder The name of the `GET` parameter that holds the filename.
|
||||
*/
|
||||
public function __construct( $form, $urlholder ) {
|
||||
|
||||
if ( empty( $_FILES[ $form ]['name'] ) && empty( $_GET[ $urlholder ] ) ) {
|
||||
wp_die( __( 'Please select a file' ) );
|
||||
}
|
||||
|
||||
// Handle a newly uploaded file. Else, assume it's already been uploaded.
|
||||
if ( ! empty( $_FILES ) ) {
|
||||
$overrides = array(
|
||||
'test_form' => false,
|
||||
'test_type' => false,
|
||||
);
|
||||
$file = wp_handle_upload( $_FILES[ $form ], $overrides );
|
||||
|
||||
if ( isset( $file['error'] ) ) {
|
||||
wp_die( $file['error'] );
|
||||
}
|
||||
|
||||
if ( 'pluginzip' === $form || 'themezip' === $form ) {
|
||||
if ( ! wp_zip_file_is_valid( $file['file'] ) ) {
|
||||
wp_delete_file( $file['file'] );
|
||||
wp_die( __( 'Incompatible Archive.' ) );
|
||||
}
|
||||
}
|
||||
|
||||
$this->filename = $_FILES[ $form ]['name'];
|
||||
$this->package = $file['file'];
|
||||
|
||||
// Construct the attachment array.
|
||||
$attachment = array(
|
||||
'post_title' => $this->filename,
|
||||
'post_content' => $file['url'],
|
||||
'post_mime_type' => $file['type'],
|
||||
'guid' => $file['url'],
|
||||
'context' => 'upgrader',
|
||||
'post_status' => 'private',
|
||||
);
|
||||
|
||||
// Save the data.
|
||||
$this->id = wp_insert_attachment( $attachment, $file['file'] );
|
||||
|
||||
// Schedule a cleanup for 2 hours from now in case of failed installation.
|
||||
wp_schedule_single_event( time() + 2 * HOUR_IN_SECONDS, 'upgrader_scheduled_cleanup', array( $this->id ) );
|
||||
|
||||
} elseif ( is_numeric( $_GET[ $urlholder ] ) ) {
|
||||
// Numeric Package = previously uploaded file, see above.
|
||||
$this->id = (int) $_GET[ $urlholder ];
|
||||
$attachment = get_post( $this->id );
|
||||
if ( empty( $attachment ) ) {
|
||||
wp_die( __( 'Please select a file' ) );
|
||||
}
|
||||
|
||||
$this->filename = $attachment->post_title;
|
||||
$this->package = get_attached_file( $attachment->ID );
|
||||
} else {
|
||||
// Else, It's set to something, Back compat for plugins using the old (pre-3.3) File_Uploader handler.
|
||||
$uploads = wp_upload_dir();
|
||||
if ( ! ( $uploads && false === $uploads['error'] ) ) {
|
||||
wp_die( $uploads['error'] );
|
||||
}
|
||||
|
||||
$this->filename = sanitize_file_name( $_GET[ $urlholder ] );
|
||||
$this->package = $uploads['basedir'] . '/' . $this->filename;
|
||||
|
||||
if ( ! str_starts_with( realpath( $this->package ), realpath( $uploads['basedir'] ) ) ) {
|
||||
wp_die( __( 'Please select a file' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the attachment/uploaded file.
|
||||
*
|
||||
* @since 3.2.2
|
||||
*
|
||||
* @return bool Whether the cleanup was successful.
|
||||
*/
|
||||
public function cleanup() {
|
||||
if ( $this->id ) {
|
||||
wp_delete_attachment( $this->id );
|
||||
|
||||
} elseif ( file_exists( $this->package ) ) {
|
||||
return @unlink( $this->package );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrade API: File_Upload_Upgrader class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used for handling file uploads.
|
||||
*
|
||||
* This class handles the upload process and passes it as if it's a local file
|
||||
* to the Upgrade/Installer functions.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader.php.
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
class File_Upload_Upgrader {
|
||||
|
||||
/**
|
||||
* The full path to the file package.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @var string $package
|
||||
*/
|
||||
public $package;
|
||||
|
||||
/**
|
||||
* The name of the file.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @var string $filename
|
||||
*/
|
||||
public $filename;
|
||||
|
||||
/**
|
||||
* The ID of the attachment post for this file.
|
||||
*
|
||||
* @since 3.3.0
|
||||
* @var int $id
|
||||
*/
|
||||
public $id = 0;
|
||||
|
||||
/**
|
||||
* Construct the upgrader for a form.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string $form The name of the form the file was uploaded from.
|
||||
* @param string $urlholder The name of the `GET` parameter that holds the filename.
|
||||
*/
|
||||
public function __construct( $form, $urlholder ) {
|
||||
|
||||
if ( empty( $_FILES[ $form ]['name'] ) && empty( $_GET[ $urlholder ] ) ) {
|
||||
wp_die( __( 'Please select a file' ) );
|
||||
}
|
||||
|
||||
// Handle a newly uploaded file. Else, assume it's already been uploaded.
|
||||
if ( ! empty( $_FILES ) ) {
|
||||
$overrides = array(
|
||||
'test_form' => false,
|
||||
'test_type' => false,
|
||||
);
|
||||
$file = wp_handle_upload( $_FILES[ $form ], $overrides );
|
||||
|
||||
if ( isset( $file['error'] ) ) {
|
||||
wp_die( $file['error'] );
|
||||
}
|
||||
|
||||
if ( 'pluginzip' === $form || 'themezip' === $form ) {
|
||||
if ( ! wp_zip_file_is_valid( $file['file'] ) ) {
|
||||
wp_delete_file( $file['file'] );
|
||||
wp_die( __( 'Incompatible Archive.' ) );
|
||||
}
|
||||
}
|
||||
|
||||
$this->filename = $_FILES[ $form ]['name'];
|
||||
$this->package = $file['file'];
|
||||
|
||||
// Construct the attachment array.
|
||||
$attachment = array(
|
||||
'post_title' => $this->filename,
|
||||
'post_content' => $file['url'],
|
||||
'post_mime_type' => $file['type'],
|
||||
'guid' => $file['url'],
|
||||
'context' => 'upgrader',
|
||||
'post_status' => 'private',
|
||||
);
|
||||
|
||||
// Save the data.
|
||||
$this->id = wp_insert_attachment( $attachment, $file['file'] );
|
||||
|
||||
// Schedule a cleanup for 2 hours from now in case of failed installation.
|
||||
wp_schedule_single_event( time() + 2 * HOUR_IN_SECONDS, 'upgrader_scheduled_cleanup', array( $this->id ) );
|
||||
|
||||
} elseif ( is_numeric( $_GET[ $urlholder ] ) ) {
|
||||
// Numeric Package = previously uploaded file, see above.
|
||||
$this->id = (int) $_GET[ $urlholder ];
|
||||
$attachment = get_post( $this->id );
|
||||
if ( empty( $attachment ) ) {
|
||||
wp_die( __( 'Please select a file' ) );
|
||||
}
|
||||
|
||||
$this->filename = $attachment->post_title;
|
||||
$this->package = get_attached_file( $attachment->ID );
|
||||
} else {
|
||||
// Else, It's set to something, Back compat for plugins using the old (pre-3.3) File_Uploader handler.
|
||||
$uploads = wp_upload_dir();
|
||||
if ( ! ( $uploads && false === $uploads['error'] ) ) {
|
||||
wp_die( $uploads['error'] );
|
||||
}
|
||||
|
||||
$this->filename = sanitize_file_name( $_GET[ $urlholder ] );
|
||||
$this->package = $uploads['basedir'] . '/' . $this->filename;
|
||||
|
||||
if ( ! str_starts_with( realpath( $this->package ), realpath( $uploads['basedir'] ) ) ) {
|
||||
wp_die( __( 'Please select a file' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the attachment/uploaded file.
|
||||
*
|
||||
* @since 3.2.2
|
||||
*
|
||||
* @return bool Whether the cleanup was successful.
|
||||
*/
|
||||
public function cleanup() {
|
||||
if ( $this->id ) {
|
||||
wp_delete_attachment( $this->id );
|
||||
|
||||
} elseif ( file_exists( $this->package ) ) {
|
||||
return @unlink( $this->package );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,186 +1,186 @@
|
||||
<?php
|
||||
/**
|
||||
* PemFTP - An Ftp implementation in pure PHP
|
||||
*
|
||||
* @package PemFTP
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @version 1.0
|
||||
* @copyright Alexey Dotsenko
|
||||
* @author Alexey Dotsenko
|
||||
* @link https://www.phpclasses.org/package/1743-PHP-FTP-client-in-pure-PHP.html
|
||||
* @license LGPL https://opensource.org/licenses/lgpl-license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* FTP implementation using fsockopen to connect.
|
||||
*
|
||||
* @package PemFTP
|
||||
* @subpackage Pure
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @version 1.0
|
||||
* @copyright Alexey Dotsenko
|
||||
* @author Alexey Dotsenko
|
||||
* @link https://www.phpclasses.org/package/1743-PHP-FTP-client-in-pure-PHP.html
|
||||
* @license LGPL https://opensource.org/licenses/lgpl-license.html
|
||||
*/
|
||||
class ftp_pure extends ftp_base {
|
||||
|
||||
function __construct($verb=FALSE, $le=FALSE) {
|
||||
parent::__construct(false, $verb, $le);
|
||||
}
|
||||
|
||||
// <!-- --------------------------------------------------------------------------------------- -->
|
||||
// <!-- Private functions -->
|
||||
// <!-- --------------------------------------------------------------------------------------- -->
|
||||
|
||||
function _settimeout($sock) {
|
||||
if(!@stream_set_timeout($sock, $this->_timeout)) {
|
||||
$this->PushError('_settimeout','socket set send timeout');
|
||||
$this->_quit();
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _connect($host, $port) {
|
||||
$this->SendMSG("Creating socket");
|
||||
$sock = @fsockopen($host, $port, $errno, $errstr, $this->_timeout);
|
||||
if (!$sock) {
|
||||
$this->PushError('_connect','socket connect failed', $errstr." (".$errno.")");
|
||||
return FALSE;
|
||||
}
|
||||
$this->_connected=true;
|
||||
return $sock;
|
||||
}
|
||||
|
||||
function _readmsg($fnction="_readmsg"){
|
||||
if(!$this->_connected) {
|
||||
$this->PushError($fnction, 'Connect first');
|
||||
return FALSE;
|
||||
}
|
||||
$result=true;
|
||||
$this->_message="";
|
||||
$this->_code=0;
|
||||
$go=true;
|
||||
do {
|
||||
$tmp=@fgets($this->_ftp_control_sock, 512);
|
||||
if($tmp===false) {
|
||||
$go=$result=false;
|
||||
$this->PushError($fnction,'Read failed');
|
||||
} else {
|
||||
$this->_message.=$tmp;
|
||||
if(preg_match("/^([0-9]{3})(-(.*[".CRLF."]{1,2})+\\1)? [^".CRLF."]+[".CRLF."]{1,2}$/", $this->_message, $regs)) $go=false;
|
||||
}
|
||||
} while($go);
|
||||
if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF;
|
||||
$this->_code=(int)$regs[1];
|
||||
return $result;
|
||||
}
|
||||
|
||||
function _exec($cmd, $fnction="_exec") {
|
||||
if(!$this->_ready) {
|
||||
$this->PushError($fnction,'Connect first');
|
||||
return FALSE;
|
||||
}
|
||||
if($this->LocalEcho) echo "PUT > ",$cmd,CRLF;
|
||||
$status=@fputs($this->_ftp_control_sock, $cmd.CRLF);
|
||||
if($status===false) {
|
||||
$this->PushError($fnction,'socket write failed');
|
||||
return FALSE;
|
||||
}
|
||||
$this->_lastaction=time();
|
||||
if(!$this->_readmsg($fnction)) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _data_prepare($mode=FTP_ASCII) {
|
||||
if(!$this->_settype($mode)) return FALSE;
|
||||
if($this->_passive) {
|
||||
if(!$this->_exec("PASV", "pasv")) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!$this->_checkCode()) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
$ip_port = explode(",", preg_replace("/^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*$/s", "\\1", $this->_message));
|
||||
$this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3];
|
||||
$this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]);
|
||||
$this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
|
||||
$this->_ftp_data_sock=@fsockopen($this->_datahost, $this->_dataport, $errno, $errstr, $this->_timeout);
|
||||
if(!$this->_ftp_data_sock) {
|
||||
$this->PushError("_data_prepare","fsockopen fails", $errstr." (".$errno.")");
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
else $this->_ftp_data_sock;
|
||||
} else {
|
||||
$this->SendMSG("Only passive connections available!");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _data_read($mode=FTP_ASCII, $fp=NULL) {
|
||||
if(is_resource($fp)) $out=0;
|
||||
else $out="";
|
||||
if(!$this->_passive) {
|
||||
$this->SendMSG("Only passive connections available!");
|
||||
return FALSE;
|
||||
}
|
||||
while (!feof($this->_ftp_data_sock)) {
|
||||
$block=fread($this->_ftp_data_sock, $this->_ftp_buff_size);
|
||||
if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block);
|
||||
if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block));
|
||||
else $out.=$block;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function _data_write($mode=FTP_ASCII, $fp=NULL) {
|
||||
if(is_resource($fp)) $out=0;
|
||||
else $out="";
|
||||
if(!$this->_passive) {
|
||||
$this->SendMSG("Only passive connections available!");
|
||||
return FALSE;
|
||||
}
|
||||
if(is_resource($fp)) {
|
||||
while(!feof($fp)) {
|
||||
$block=fread($fp, $this->_ftp_buff_size);
|
||||
if(!$this->_data_write_block($mode, $block)) return false;
|
||||
}
|
||||
} elseif(!$this->_data_write_block($mode, $fp)) return false;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _data_write_block($mode, $block) {
|
||||
if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block);
|
||||
do {
|
||||
if(($t=@fwrite($this->_ftp_data_sock, $block))===FALSE) {
|
||||
$this->PushError("_data_write","Can't write to socket");
|
||||
return FALSE;
|
||||
}
|
||||
$block=substr($block, $t);
|
||||
} while(!empty($block));
|
||||
return true;
|
||||
}
|
||||
|
||||
function _data_close() {
|
||||
@fclose($this->_ftp_data_sock);
|
||||
$this->SendMSG("Disconnected data from remote host");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _quit($force=FALSE) {
|
||||
if($this->_connected or $force) {
|
||||
@fclose($this->_ftp_control_sock);
|
||||
$this->_connected=false;
|
||||
$this->SendMSG("Socket closed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<?php
|
||||
/**
|
||||
* PemFTP - An Ftp implementation in pure PHP
|
||||
*
|
||||
* @package PemFTP
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @version 1.0
|
||||
* @copyright Alexey Dotsenko
|
||||
* @author Alexey Dotsenko
|
||||
* @link https://www.phpclasses.org/package/1743-PHP-FTP-client-in-pure-PHP.html
|
||||
* @license LGPL https://opensource.org/licenses/lgpl-license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* FTP implementation using fsockopen to connect.
|
||||
*
|
||||
* @package PemFTP
|
||||
* @subpackage Pure
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @version 1.0
|
||||
* @copyright Alexey Dotsenko
|
||||
* @author Alexey Dotsenko
|
||||
* @link https://www.phpclasses.org/package/1743-PHP-FTP-client-in-pure-PHP.html
|
||||
* @license LGPL https://opensource.org/licenses/lgpl-license.html
|
||||
*/
|
||||
class ftp_pure extends ftp_base {
|
||||
|
||||
function __construct($verb=FALSE, $le=FALSE) {
|
||||
parent::__construct(false, $verb, $le);
|
||||
}
|
||||
|
||||
// <!-- --------------------------------------------------------------------------------------- -->
|
||||
// <!-- Private functions -->
|
||||
// <!-- --------------------------------------------------------------------------------------- -->
|
||||
|
||||
function _settimeout($sock) {
|
||||
if(!@stream_set_timeout($sock, $this->_timeout)) {
|
||||
$this->PushError('_settimeout','socket set send timeout');
|
||||
$this->_quit();
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _connect($host, $port) {
|
||||
$this->SendMSG("Creating socket");
|
||||
$sock = @fsockopen($host, $port, $errno, $errstr, $this->_timeout);
|
||||
if (!$sock) {
|
||||
$this->PushError('_connect','socket connect failed', $errstr." (".$errno.")");
|
||||
return FALSE;
|
||||
}
|
||||
$this->_connected=true;
|
||||
return $sock;
|
||||
}
|
||||
|
||||
function _readmsg($fnction="_readmsg"){
|
||||
if(!$this->_connected) {
|
||||
$this->PushError($fnction, 'Connect first');
|
||||
return FALSE;
|
||||
}
|
||||
$result=true;
|
||||
$this->_message="";
|
||||
$this->_code=0;
|
||||
$go=true;
|
||||
do {
|
||||
$tmp=@fgets($this->_ftp_control_sock, 512);
|
||||
if($tmp===false) {
|
||||
$go=$result=false;
|
||||
$this->PushError($fnction,'Read failed');
|
||||
} else {
|
||||
$this->_message.=$tmp;
|
||||
if(preg_match("/^([0-9]{3})(-(.*[".CRLF."]{1,2})+\\1)? [^".CRLF."]+[".CRLF."]{1,2}$/", $this->_message, $regs)) $go=false;
|
||||
}
|
||||
} while($go);
|
||||
if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF;
|
||||
$this->_code=(int)$regs[1];
|
||||
return $result;
|
||||
}
|
||||
|
||||
function _exec($cmd, $fnction="_exec") {
|
||||
if(!$this->_ready) {
|
||||
$this->PushError($fnction,'Connect first');
|
||||
return FALSE;
|
||||
}
|
||||
if($this->LocalEcho) echo "PUT > ",$cmd,CRLF;
|
||||
$status=@fputs($this->_ftp_control_sock, $cmd.CRLF);
|
||||
if($status===false) {
|
||||
$this->PushError($fnction,'socket write failed');
|
||||
return FALSE;
|
||||
}
|
||||
$this->_lastaction=time();
|
||||
if(!$this->_readmsg($fnction)) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _data_prepare($mode=FTP_ASCII) {
|
||||
if(!$this->_settype($mode)) return FALSE;
|
||||
if($this->_passive) {
|
||||
if(!$this->_exec("PASV", "pasv")) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!$this->_checkCode()) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
$ip_port = explode(",", preg_replace("/^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*$/s", "\\1", $this->_message));
|
||||
$this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3];
|
||||
$this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]);
|
||||
$this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
|
||||
$this->_ftp_data_sock=@fsockopen($this->_datahost, $this->_dataport, $errno, $errstr, $this->_timeout);
|
||||
if(!$this->_ftp_data_sock) {
|
||||
$this->PushError("_data_prepare","fsockopen fails", $errstr." (".$errno.")");
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
else $this->_ftp_data_sock;
|
||||
} else {
|
||||
$this->SendMSG("Only passive connections available!");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _data_read($mode=FTP_ASCII, $fp=NULL) {
|
||||
if(is_resource($fp)) $out=0;
|
||||
else $out="";
|
||||
if(!$this->_passive) {
|
||||
$this->SendMSG("Only passive connections available!");
|
||||
return FALSE;
|
||||
}
|
||||
while (!feof($this->_ftp_data_sock)) {
|
||||
$block=fread($this->_ftp_data_sock, $this->_ftp_buff_size);
|
||||
if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block);
|
||||
if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block));
|
||||
else $out.=$block;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function _data_write($mode=FTP_ASCII, $fp=NULL) {
|
||||
if(is_resource($fp)) $out=0;
|
||||
else $out="";
|
||||
if(!$this->_passive) {
|
||||
$this->SendMSG("Only passive connections available!");
|
||||
return FALSE;
|
||||
}
|
||||
if(is_resource($fp)) {
|
||||
while(!feof($fp)) {
|
||||
$block=fread($fp, $this->_ftp_buff_size);
|
||||
if(!$this->_data_write_block($mode, $block)) return false;
|
||||
}
|
||||
} elseif(!$this->_data_write_block($mode, $fp)) return false;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _data_write_block($mode, $block) {
|
||||
if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block);
|
||||
do {
|
||||
if(($t=@fwrite($this->_ftp_data_sock, $block))===FALSE) {
|
||||
$this->PushError("_data_write","Can't write to socket");
|
||||
return FALSE;
|
||||
}
|
||||
$block=substr($block, $t);
|
||||
} while(!empty($block));
|
||||
return true;
|
||||
}
|
||||
|
||||
function _data_close() {
|
||||
@fclose($this->_ftp_data_sock);
|
||||
$this->SendMSG("Disconnected data from remote host");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _quit($force=FALSE) {
|
||||
if($this->_connected or $force) {
|
||||
@fclose($this->_ftp_control_sock);
|
||||
$this->_connected=false;
|
||||
$this->SendMSG("Socket closed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,246 +1,246 @@
|
||||
<?php
|
||||
/**
|
||||
* PemFTP - An Ftp implementation in pure PHP
|
||||
*
|
||||
* @package PemFTP
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @version 1.0
|
||||
* @copyright Alexey Dotsenko
|
||||
* @author Alexey Dotsenko
|
||||
* @link https://www.phpclasses.org/package/1743-PHP-FTP-client-in-pure-PHP.html
|
||||
* @license LGPL https://opensource.org/licenses/lgpl-license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Socket Based FTP implementation
|
||||
*
|
||||
* @package PemFTP
|
||||
* @subpackage Socket
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @version 1.0
|
||||
* @copyright Alexey Dotsenko
|
||||
* @author Alexey Dotsenko
|
||||
* @link https://www.phpclasses.org/package/1743-PHP-FTP-client-in-pure-PHP.html
|
||||
* @license LGPL https://opensource.org/licenses/lgpl-license.html
|
||||
*/
|
||||
class ftp_sockets extends ftp_base {
|
||||
|
||||
function __construct($verb=FALSE, $le=FALSE) {
|
||||
parent::__construct(true, $verb, $le);
|
||||
}
|
||||
|
||||
// <!-- --------------------------------------------------------------------------------------- -->
|
||||
// <!-- Private functions -->
|
||||
// <!-- --------------------------------------------------------------------------------------- -->
|
||||
|
||||
function _settimeout($sock) {
|
||||
if(!@socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) {
|
||||
$this->PushError('_connect','socket set receive timeout',socket_strerror(socket_last_error($sock)));
|
||||
@socket_close($sock);
|
||||
return FALSE;
|
||||
}
|
||||
if(!@socket_set_option($sock, SOL_SOCKET , SO_SNDTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) {
|
||||
$this->PushError('_connect','socket set send timeout',socket_strerror(socket_last_error($sock)));
|
||||
@socket_close($sock);
|
||||
return FALSE;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function _connect($host, $port) {
|
||||
$this->SendMSG("Creating socket");
|
||||
if(!($sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) {
|
||||
$this->PushError('_connect','socket create failed',socket_strerror(socket_last_error($sock)));
|
||||
return FALSE;
|
||||
}
|
||||
if(!$this->_settimeout($sock)) return FALSE;
|
||||
$this->SendMSG("Connecting to \"".$host.":".$port."\"");
|
||||
if (!($res = @socket_connect($sock, $host, $port))) {
|
||||
$this->PushError('_connect','socket connect failed',socket_strerror(socket_last_error($sock)));
|
||||
@socket_close($sock);
|
||||
return FALSE;
|
||||
}
|
||||
$this->_connected=true;
|
||||
return $sock;
|
||||
}
|
||||
|
||||
function _readmsg($fnction="_readmsg"){
|
||||
if(!$this->_connected) {
|
||||
$this->PushError($fnction,'Connect first');
|
||||
return FALSE;
|
||||
}
|
||||
$result=true;
|
||||
$this->_message="";
|
||||
$this->_code=0;
|
||||
$go=true;
|
||||
do {
|
||||
$tmp=@socket_read($this->_ftp_control_sock, 4096, PHP_BINARY_READ);
|
||||
if($tmp===false) {
|
||||
$go=$result=false;
|
||||
$this->PushError($fnction,'Read failed', socket_strerror(socket_last_error($this->_ftp_control_sock)));
|
||||
} else {
|
||||
$this->_message.=$tmp;
|
||||
$go = !preg_match("/^([0-9]{3})(-.+\\1)? [^".CRLF."]+".CRLF."$/Us", $this->_message, $regs);
|
||||
}
|
||||
} while($go);
|
||||
if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF;
|
||||
$this->_code=(int)$regs[1];
|
||||
return $result;
|
||||
}
|
||||
|
||||
function _exec($cmd, $fnction="_exec") {
|
||||
if(!$this->_ready) {
|
||||
$this->PushError($fnction,'Connect first');
|
||||
return FALSE;
|
||||
}
|
||||
if($this->LocalEcho) echo "PUT > ",$cmd,CRLF;
|
||||
$status=@socket_write($this->_ftp_control_sock, $cmd.CRLF);
|
||||
if($status===false) {
|
||||
$this->PushError($fnction,'socket write failed', socket_strerror(socket_last_error($this->stream)));
|
||||
return FALSE;
|
||||
}
|
||||
$this->_lastaction=time();
|
||||
if(!$this->_readmsg($fnction)) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _data_prepare($mode=FTP_ASCII) {
|
||||
if(!$this->_settype($mode)) return FALSE;
|
||||
$this->SendMSG("Creating data socket");
|
||||
$this->_ftp_data_sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
if ($this->_ftp_data_sock < 0) {
|
||||
$this->PushError('_data_prepare','socket create failed',socket_strerror(socket_last_error($this->_ftp_data_sock)));
|
||||
return FALSE;
|
||||
}
|
||||
if(!$this->_settimeout($this->_ftp_data_sock)) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if($this->_passive) {
|
||||
if(!$this->_exec("PASV", "pasv")) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!$this->_checkCode()) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
$ip_port = explode(",", preg_replace("/^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*$/s", "\\1", $this->_message));
|
||||
$this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3];
|
||||
$this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]);
|
||||
$this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
|
||||
if(!@socket_connect($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) {
|
||||
$this->PushError("_data_prepare","socket_connect", socket_strerror(socket_last_error($this->_ftp_data_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
else $this->_ftp_temp_sock=$this->_ftp_data_sock;
|
||||
} else {
|
||||
if(!@socket_getsockname($this->_ftp_control_sock, $addr, $port)) {
|
||||
$this->PushError("_data_prepare","cannot get control socket information", socket_strerror(socket_last_error($this->_ftp_control_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!@socket_bind($this->_ftp_data_sock,$addr)){
|
||||
$this->PushError("_data_prepare","cannot bind data socket", socket_strerror(socket_last_error($this->_ftp_data_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!@socket_listen($this->_ftp_data_sock)) {
|
||||
$this->PushError("_data_prepare","cannot listen data socket", socket_strerror(socket_last_error($this->_ftp_data_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!@socket_getsockname($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) {
|
||||
$this->PushError("_data_prepare","cannot get data socket information", socket_strerror(socket_last_error($this->_ftp_data_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!$this->_exec('PORT '.str_replace('.',',',$this->_datahost.'.'.($this->_dataport>>8).'.'.($this->_dataport&0x00FF)), "_port")) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!$this->_checkCode()) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _data_read($mode=FTP_ASCII, $fp=NULL) {
|
||||
$NewLine=$this->_eol_code[$this->OS_local];
|
||||
if(is_resource($fp)) $out=0;
|
||||
else $out="";
|
||||
if(!$this->_passive) {
|
||||
$this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
|
||||
$this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock);
|
||||
if($this->_ftp_temp_sock===FALSE) {
|
||||
$this->PushError("_data_read","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
while(($block=@socket_read($this->_ftp_temp_sock, $this->_ftp_buff_size, PHP_BINARY_READ))!==false) {
|
||||
if($block==="") break;
|
||||
if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block);
|
||||
if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block));
|
||||
else $out.=$block;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function _data_write($mode=FTP_ASCII, $fp=NULL) {
|
||||
$NewLine=$this->_eol_code[$this->OS_local];
|
||||
if(is_resource($fp)) $out=0;
|
||||
else $out="";
|
||||
if(!$this->_passive) {
|
||||
$this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
|
||||
$this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock);
|
||||
if($this->_ftp_temp_sock===FALSE) {
|
||||
$this->PushError("_data_write","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
|
||||
$this->_data_close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(is_resource($fp)) {
|
||||
while(!feof($fp)) {
|
||||
$block=fread($fp, $this->_ftp_buff_size);
|
||||
if(!$this->_data_write_block($mode, $block)) return false;
|
||||
}
|
||||
} elseif(!$this->_data_write_block($mode, $fp)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function _data_write_block($mode, $block) {
|
||||
if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block);
|
||||
do {
|
||||
if(($t=@socket_write($this->_ftp_temp_sock, $block))===FALSE) {
|
||||
$this->PushError("_data_write","socket_write", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
$block=substr($block, $t);
|
||||
} while(!empty($block));
|
||||
return true;
|
||||
}
|
||||
|
||||
function _data_close() {
|
||||
@socket_close($this->_ftp_temp_sock);
|
||||
@socket_close($this->_ftp_data_sock);
|
||||
$this->SendMSG("Disconnected data from remote host");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _quit() {
|
||||
if($this->_connected) {
|
||||
@socket_close($this->_ftp_control_sock);
|
||||
$this->_connected=false;
|
||||
$this->SendMSG("Socket closed");
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
/**
|
||||
* PemFTP - An Ftp implementation in pure PHP
|
||||
*
|
||||
* @package PemFTP
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @version 1.0
|
||||
* @copyright Alexey Dotsenko
|
||||
* @author Alexey Dotsenko
|
||||
* @link https://www.phpclasses.org/package/1743-PHP-FTP-client-in-pure-PHP.html
|
||||
* @license LGPL https://opensource.org/licenses/lgpl-license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Socket Based FTP implementation
|
||||
*
|
||||
* @package PemFTP
|
||||
* @subpackage Socket
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @version 1.0
|
||||
* @copyright Alexey Dotsenko
|
||||
* @author Alexey Dotsenko
|
||||
* @link https://www.phpclasses.org/package/1743-PHP-FTP-client-in-pure-PHP.html
|
||||
* @license LGPL https://opensource.org/licenses/lgpl-license.html
|
||||
*/
|
||||
class ftp_sockets extends ftp_base {
|
||||
|
||||
function __construct($verb=FALSE, $le=FALSE) {
|
||||
parent::__construct(true, $verb, $le);
|
||||
}
|
||||
|
||||
// <!-- --------------------------------------------------------------------------------------- -->
|
||||
// <!-- Private functions -->
|
||||
// <!-- --------------------------------------------------------------------------------------- -->
|
||||
|
||||
function _settimeout($sock) {
|
||||
if(!@socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) {
|
||||
$this->PushError('_connect','socket set receive timeout',socket_strerror(socket_last_error($sock)));
|
||||
@socket_close($sock);
|
||||
return FALSE;
|
||||
}
|
||||
if(!@socket_set_option($sock, SOL_SOCKET , SO_SNDTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) {
|
||||
$this->PushError('_connect','socket set send timeout',socket_strerror(socket_last_error($sock)));
|
||||
@socket_close($sock);
|
||||
return FALSE;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function _connect($host, $port) {
|
||||
$this->SendMSG("Creating socket");
|
||||
if(!($sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) {
|
||||
$this->PushError('_connect','socket create failed',socket_strerror(socket_last_error($sock)));
|
||||
return FALSE;
|
||||
}
|
||||
if(!$this->_settimeout($sock)) return FALSE;
|
||||
$this->SendMSG("Connecting to \"".$host.":".$port."\"");
|
||||
if (!($res = @socket_connect($sock, $host, $port))) {
|
||||
$this->PushError('_connect','socket connect failed',socket_strerror(socket_last_error($sock)));
|
||||
@socket_close($sock);
|
||||
return FALSE;
|
||||
}
|
||||
$this->_connected=true;
|
||||
return $sock;
|
||||
}
|
||||
|
||||
function _readmsg($fnction="_readmsg"){
|
||||
if(!$this->_connected) {
|
||||
$this->PushError($fnction,'Connect first');
|
||||
return FALSE;
|
||||
}
|
||||
$result=true;
|
||||
$this->_message="";
|
||||
$this->_code=0;
|
||||
$go=true;
|
||||
do {
|
||||
$tmp=@socket_read($this->_ftp_control_sock, 4096, PHP_BINARY_READ);
|
||||
if($tmp===false) {
|
||||
$go=$result=false;
|
||||
$this->PushError($fnction,'Read failed', socket_strerror(socket_last_error($this->_ftp_control_sock)));
|
||||
} else {
|
||||
$this->_message.=$tmp;
|
||||
$go = !preg_match("/^([0-9]{3})(-.+\\1)? [^".CRLF."]+".CRLF."$/Us", $this->_message, $regs);
|
||||
}
|
||||
} while($go);
|
||||
if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF;
|
||||
$this->_code=(int)$regs[1];
|
||||
return $result;
|
||||
}
|
||||
|
||||
function _exec($cmd, $fnction="_exec") {
|
||||
if(!$this->_ready) {
|
||||
$this->PushError($fnction,'Connect first');
|
||||
return FALSE;
|
||||
}
|
||||
if($this->LocalEcho) echo "PUT > ",$cmd,CRLF;
|
||||
$status=@socket_write($this->_ftp_control_sock, $cmd.CRLF);
|
||||
if($status===false) {
|
||||
$this->PushError($fnction,'socket write failed', socket_strerror(socket_last_error($this->stream)));
|
||||
return FALSE;
|
||||
}
|
||||
$this->_lastaction=time();
|
||||
if(!$this->_readmsg($fnction)) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _data_prepare($mode=FTP_ASCII) {
|
||||
if(!$this->_settype($mode)) return FALSE;
|
||||
$this->SendMSG("Creating data socket");
|
||||
$this->_ftp_data_sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
if ($this->_ftp_data_sock < 0) {
|
||||
$this->PushError('_data_prepare','socket create failed',socket_strerror(socket_last_error($this->_ftp_data_sock)));
|
||||
return FALSE;
|
||||
}
|
||||
if(!$this->_settimeout($this->_ftp_data_sock)) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if($this->_passive) {
|
||||
if(!$this->_exec("PASV", "pasv")) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!$this->_checkCode()) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
$ip_port = explode(",", preg_replace("/^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*$/s", "\\1", $this->_message));
|
||||
$this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3];
|
||||
$this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]);
|
||||
$this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
|
||||
if(!@socket_connect($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) {
|
||||
$this->PushError("_data_prepare","socket_connect", socket_strerror(socket_last_error($this->_ftp_data_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
else $this->_ftp_temp_sock=$this->_ftp_data_sock;
|
||||
} else {
|
||||
if(!@socket_getsockname($this->_ftp_control_sock, $addr, $port)) {
|
||||
$this->PushError("_data_prepare","cannot get control socket information", socket_strerror(socket_last_error($this->_ftp_control_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!@socket_bind($this->_ftp_data_sock,$addr)){
|
||||
$this->PushError("_data_prepare","cannot bind data socket", socket_strerror(socket_last_error($this->_ftp_data_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!@socket_listen($this->_ftp_data_sock)) {
|
||||
$this->PushError("_data_prepare","cannot listen data socket", socket_strerror(socket_last_error($this->_ftp_data_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!@socket_getsockname($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) {
|
||||
$this->PushError("_data_prepare","cannot get data socket information", socket_strerror(socket_last_error($this->_ftp_data_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!$this->_exec('PORT '.str_replace('.',',',$this->_datahost.'.'.($this->_dataport>>8).'.'.($this->_dataport&0x00FF)), "_port")) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
if(!$this->_checkCode()) {
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _data_read($mode=FTP_ASCII, $fp=NULL) {
|
||||
$NewLine=$this->_eol_code[$this->OS_local];
|
||||
if(is_resource($fp)) $out=0;
|
||||
else $out="";
|
||||
if(!$this->_passive) {
|
||||
$this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
|
||||
$this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock);
|
||||
if($this->_ftp_temp_sock===FALSE) {
|
||||
$this->PushError("_data_read","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
while(($block=@socket_read($this->_ftp_temp_sock, $this->_ftp_buff_size, PHP_BINARY_READ))!==false) {
|
||||
if($block==="") break;
|
||||
if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block);
|
||||
if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block));
|
||||
else $out.=$block;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function _data_write($mode=FTP_ASCII, $fp=NULL) {
|
||||
$NewLine=$this->_eol_code[$this->OS_local];
|
||||
if(is_resource($fp)) $out=0;
|
||||
else $out="";
|
||||
if(!$this->_passive) {
|
||||
$this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
|
||||
$this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock);
|
||||
if($this->_ftp_temp_sock===FALSE) {
|
||||
$this->PushError("_data_write","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
|
||||
$this->_data_close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(is_resource($fp)) {
|
||||
while(!feof($fp)) {
|
||||
$block=fread($fp, $this->_ftp_buff_size);
|
||||
if(!$this->_data_write_block($mode, $block)) return false;
|
||||
}
|
||||
} elseif(!$this->_data_write_block($mode, $fp)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function _data_write_block($mode, $block) {
|
||||
if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block);
|
||||
do {
|
||||
if(($t=@socket_write($this->_ftp_temp_sock, $block))===FALSE) {
|
||||
$this->PushError("_data_write","socket_write", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
|
||||
$this->_data_close();
|
||||
return FALSE;
|
||||
}
|
||||
$block=substr($block, $t);
|
||||
} while(!empty($block));
|
||||
return true;
|
||||
}
|
||||
|
||||
function _data_close() {
|
||||
@socket_close($this->_ftp_temp_sock);
|
||||
@socket_close($this->_ftp_data_sock);
|
||||
$this->SendMSG("Disconnected data from remote host");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function _quit() {
|
||||
if($this->_connected) {
|
||||
@socket_close($this->_ftp_control_sock);
|
||||
$this->_connected=false;
|
||||
$this->SendMSG("Socket closed");
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,97 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Language_Pack_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Translation Upgrader Skin for WordPress Translation Upgrades.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see WP_Upgrader_Skin
|
||||
*/
|
||||
class Language_Pack_Upgrader_Skin extends WP_Upgrader_Skin {
|
||||
public $language_update = null;
|
||||
public $done_header = false;
|
||||
public $done_footer = false;
|
||||
public $display_footer_actions = true;
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'url' => '',
|
||||
'nonce' => '',
|
||||
'title' => __( 'Update Translations' ),
|
||||
'skip_header_footer' => false,
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
if ( $args['skip_header_footer'] ) {
|
||||
$this->done_header = true;
|
||||
$this->done_footer = true;
|
||||
$this->display_footer_actions = false;
|
||||
}
|
||||
parent::__construct( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function before() {
|
||||
$name = $this->upgrader->get_name_for_update( $this->language_update );
|
||||
|
||||
echo '<div class="update-messages lp-show-latest">';
|
||||
|
||||
/* translators: 1: Project name (plugin, theme, or WordPress), 2: Language. */
|
||||
printf( '<h2>' . __( 'Updating translations for %1$s (%2$s)…' ) . '</h2>', $name, $this->language_update->language );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.9.0 Renamed `$error` to `$errors` for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string|WP_Error $errors Errors.
|
||||
*/
|
||||
public function error( $errors ) {
|
||||
echo '<div class="lp-error">';
|
||||
parent::error( $errors );
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function after() {
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function bulk_footer() {
|
||||
$this->decrement_update_count( 'translation' );
|
||||
|
||||
$update_actions = array(
|
||||
'updates_page' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'update-core.php' ),
|
||||
__( 'Go to WordPress Updates page' )
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a translations update.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string[] $update_actions Array of translations update links.
|
||||
*/
|
||||
$update_actions = apply_filters( 'update_translations_complete_actions', $update_actions );
|
||||
|
||||
if ( $update_actions && $this->display_footer_actions ) {
|
||||
$this->feedback( implode( ' | ', $update_actions ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Language_Pack_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Translation Upgrader Skin for WordPress Translation Upgrades.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see WP_Upgrader_Skin
|
||||
*/
|
||||
class Language_Pack_Upgrader_Skin extends WP_Upgrader_Skin {
|
||||
public $language_update = null;
|
||||
public $done_header = false;
|
||||
public $done_footer = false;
|
||||
public $display_footer_actions = true;
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'url' => '',
|
||||
'nonce' => '',
|
||||
'title' => __( 'Update Translations' ),
|
||||
'skip_header_footer' => false,
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
if ( $args['skip_header_footer'] ) {
|
||||
$this->done_header = true;
|
||||
$this->done_footer = true;
|
||||
$this->display_footer_actions = false;
|
||||
}
|
||||
parent::__construct( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function before() {
|
||||
$name = $this->upgrader->get_name_for_update( $this->language_update );
|
||||
|
||||
echo '<div class="update-messages lp-show-latest">';
|
||||
|
||||
/* translators: 1: Project name (plugin, theme, or WordPress), 2: Language. */
|
||||
printf( '<h2>' . __( 'Updating translations for %1$s (%2$s)…' ) . '</h2>', $name, $this->language_update->language );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.9.0 Renamed `$error` to `$errors` for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string|WP_Error $errors Errors.
|
||||
*/
|
||||
public function error( $errors ) {
|
||||
echo '<div class="lp-error">';
|
||||
parent::error( $errors );
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function after() {
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function bulk_footer() {
|
||||
$this->decrement_update_count( 'translation' );
|
||||
|
||||
$update_actions = array(
|
||||
'updates_page' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'update-core.php' ),
|
||||
__( 'Go to WordPress Updates page' )
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a translations update.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string[] $update_actions Array of translations update links.
|
||||
*/
|
||||
$update_actions = apply_filters( 'update_translations_complete_actions', $update_actions );
|
||||
|
||||
if ( $update_actions && $this->display_footer_actions ) {
|
||||
$this->feedback( implode( ' | ', $update_actions ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,479 +1,479 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrade API: Language_Pack_Upgrader class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used for updating/installing language packs (translations)
|
||||
* for plugins, themes, and core.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader.php.
|
||||
*
|
||||
* @see WP_Upgrader
|
||||
*/
|
||||
class Language_Pack_Upgrader extends WP_Upgrader {
|
||||
|
||||
/**
|
||||
* Result of the language pack upgrade.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @var array|WP_Error $result
|
||||
* @see WP_Upgrader::$result
|
||||
*/
|
||||
public $result;
|
||||
|
||||
/**
|
||||
* Whether a bulk upgrade/installation is being performed.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @var bool $bulk
|
||||
*/
|
||||
public $bulk = true;
|
||||
|
||||
/**
|
||||
* Asynchronously upgrades language packs after other upgrades have been made.
|
||||
*
|
||||
* Hooked to the {@see 'upgrader_process_complete'} action by default.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param false|WP_Upgrader $upgrader Optional. WP_Upgrader instance or false. If `$upgrader` is
|
||||
* a Language_Pack_Upgrader instance, the method will bail to
|
||||
* avoid recursion. Otherwise unused. Default false.
|
||||
*/
|
||||
public static function async_upgrade( $upgrader = false ) {
|
||||
// Avoid recursion.
|
||||
if ( $upgrader && $upgrader instanceof Language_Pack_Upgrader ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Nothing to do?
|
||||
$language_updates = wp_get_translation_updates();
|
||||
if ( ! $language_updates ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Avoid messing with VCS installations, at least for now.
|
||||
* Noted: this is not the ideal way to accomplish this.
|
||||
*/
|
||||
$check_vcs = new WP_Automatic_Updater();
|
||||
if ( $check_vcs->is_vcs_checkout( WP_CONTENT_DIR ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $language_updates as $key => $language_update ) {
|
||||
$update = ! empty( $language_update->autoupdate );
|
||||
|
||||
/**
|
||||
* Filters whether to asynchronously update translation for core, a plugin, or a theme.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param bool $update Whether to update.
|
||||
* @param object $language_update The update offer.
|
||||
*/
|
||||
$update = apply_filters( 'async_update_translation', $update, $language_update );
|
||||
|
||||
if ( ! $update ) {
|
||||
unset( $language_updates[ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $language_updates ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Re-use the automatic upgrader skin if the parent upgrader is using it.
|
||||
if ( $upgrader && $upgrader->skin instanceof Automatic_Upgrader_Skin ) {
|
||||
$skin = $upgrader->skin;
|
||||
} else {
|
||||
$skin = new Language_Pack_Upgrader_Skin(
|
||||
array(
|
||||
'skip_header_footer' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$lp_upgrader = new Language_Pack_Upgrader( $skin );
|
||||
$lp_upgrader->bulk_upgrade( $language_updates );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the upgrade strings.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function upgrade_strings() {
|
||||
$this->strings['starting_upgrade'] = __( 'Some of your translations need updating. Sit tight for a few more seconds while they are updated as well.' );
|
||||
$this->strings['up_to_date'] = __( 'Your translations are all up to date.' );
|
||||
$this->strings['no_package'] = __( 'Update package not available.' );
|
||||
/* translators: %s: Package URL. */
|
||||
$this->strings['downloading_package'] = sprintf( __( 'Downloading translation from %s…' ), '<span class="code pre">%s</span>' );
|
||||
$this->strings['unpack_package'] = __( 'Unpacking the update…' );
|
||||
$this->strings['process_failed'] = __( 'Translation update failed.' );
|
||||
$this->strings['process_success'] = __( 'Translation updated successfully.' );
|
||||
$this->strings['remove_old'] = __( 'Removing the old version of the translation…' );
|
||||
$this->strings['remove_old_failed'] = __( 'Could not remove the old translation.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades a language pack.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string|false $update Optional. Whether an update offer is available. Default false.
|
||||
* @param array $args Optional. Other optional arguments, see
|
||||
* Language_Pack_Upgrader::bulk_upgrade(). Default empty array.
|
||||
* @return array|bool|WP_Error The result of the upgrade, or a WP_Error object instead.
|
||||
*/
|
||||
public function upgrade( $update = false, $args = array() ) {
|
||||
if ( $update ) {
|
||||
$update = array( $update );
|
||||
}
|
||||
|
||||
$results = $this->bulk_upgrade( $update, $args );
|
||||
|
||||
if ( ! is_array( $results ) ) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
return $results[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades several language packs at once.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
*
|
||||
* @param object[] $language_updates Optional. Array of language packs to update. See {@see wp_get_translation_updates()}.
|
||||
* Default empty array.
|
||||
* @param array $args {
|
||||
* Other arguments for upgrading multiple language packs. Default empty array.
|
||||
*
|
||||
* @type bool $clear_update_cache Whether to clear the update cache when done.
|
||||
* Default true.
|
||||
* }
|
||||
* @return array|bool|WP_Error Will return an array of results, or true if there are no updates,
|
||||
* false or WP_Error for initial errors.
|
||||
*/
|
||||
public function bulk_upgrade( $language_updates = array(), $args = array() ) {
|
||||
global $wp_filesystem;
|
||||
|
||||
$defaults = array(
|
||||
'clear_update_cache' => true,
|
||||
);
|
||||
$parsed_args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$this->init();
|
||||
$this->upgrade_strings();
|
||||
|
||||
if ( ! $language_updates ) {
|
||||
$language_updates = wp_get_translation_updates();
|
||||
}
|
||||
|
||||
if ( empty( $language_updates ) ) {
|
||||
$this->skin->header();
|
||||
$this->skin->set_result( true );
|
||||
$this->skin->feedback( 'up_to_date' );
|
||||
$this->skin->bulk_footer();
|
||||
$this->skin->footer();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( 'upgrader_process_complete' === current_filter() ) {
|
||||
$this->skin->feedback( 'starting_upgrade' );
|
||||
}
|
||||
|
||||
// Remove any existing upgrade filters from the plugin/theme upgraders #WP29425 & #WP29230.
|
||||
remove_all_filters( 'upgrader_pre_install' );
|
||||
remove_all_filters( 'upgrader_clear_destination' );
|
||||
remove_all_filters( 'upgrader_post_install' );
|
||||
remove_all_filters( 'upgrader_source_selection' );
|
||||
|
||||
add_filter( 'upgrader_source_selection', array( $this, 'check_package' ), 10, 2 );
|
||||
|
||||
$this->skin->header();
|
||||
|
||||
// Connect to the filesystem first.
|
||||
$res = $this->fs_connect( array( WP_CONTENT_DIR, WP_LANG_DIR ) );
|
||||
if ( ! $res ) {
|
||||
$this->skin->footer();
|
||||
return false;
|
||||
}
|
||||
|
||||
$results = array();
|
||||
|
||||
$this->update_count = count( $language_updates );
|
||||
$this->update_current = 0;
|
||||
|
||||
/*
|
||||
* The filesystem's mkdir() is not recursive. Make sure WP_LANG_DIR exists,
|
||||
* as we then may need to create a /plugins or /themes directory inside of it.
|
||||
*/
|
||||
$remote_destination = $wp_filesystem->find_folder( WP_LANG_DIR );
|
||||
if ( ! $wp_filesystem->exists( $remote_destination ) ) {
|
||||
if ( ! $wp_filesystem->mkdir( $remote_destination, FS_CHMOD_DIR ) ) {
|
||||
return new WP_Error( 'mkdir_failed_lang_dir', $this->strings['mkdir_failed'], $remote_destination );
|
||||
}
|
||||
}
|
||||
|
||||
$language_updates_results = array();
|
||||
|
||||
foreach ( $language_updates as $language_update ) {
|
||||
|
||||
$this->skin->language_update = $language_update;
|
||||
|
||||
$destination = WP_LANG_DIR;
|
||||
if ( 'plugin' === $language_update->type ) {
|
||||
$destination .= '/plugins';
|
||||
} elseif ( 'theme' === $language_update->type ) {
|
||||
$destination .= '/themes';
|
||||
}
|
||||
|
||||
++$this->update_current;
|
||||
|
||||
$options = array(
|
||||
'package' => $language_update->package,
|
||||
'destination' => $destination,
|
||||
'clear_destination' => true,
|
||||
'abort_if_destination_exists' => false, // We expect the destination to exist.
|
||||
'clear_working' => true,
|
||||
'is_multi' => true,
|
||||
'hook_extra' => array(
|
||||
'language_update_type' => $language_update->type,
|
||||
'language_update' => $language_update,
|
||||
),
|
||||
);
|
||||
|
||||
$result = $this->run( $options );
|
||||
|
||||
$results[] = $this->result;
|
||||
|
||||
// Prevent credentials auth screen from displaying multiple times.
|
||||
if ( false === $result ) {
|
||||
break;
|
||||
}
|
||||
|
||||
$language_updates_results[] = array(
|
||||
'language' => $language_update->language,
|
||||
'type' => $language_update->type,
|
||||
'slug' => isset( $language_update->slug ) ? $language_update->slug : 'default',
|
||||
'version' => $language_update->version,
|
||||
);
|
||||
}
|
||||
|
||||
// Remove upgrade hooks which are not required for translation updates.
|
||||
remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
|
||||
remove_action( 'upgrader_process_complete', 'wp_version_check' );
|
||||
remove_action( 'upgrader_process_complete', 'wp_update_plugins' );
|
||||
remove_action( 'upgrader_process_complete', 'wp_update_themes' );
|
||||
|
||||
/** This action is documented in wp-admin/includes/class-wp-upgrader.php */
|
||||
do_action(
|
||||
'upgrader_process_complete',
|
||||
$this,
|
||||
array(
|
||||
'action' => 'update',
|
||||
'type' => 'translation',
|
||||
'bulk' => true,
|
||||
'translations' => $language_updates_results,
|
||||
)
|
||||
);
|
||||
|
||||
// Re-add upgrade hooks.
|
||||
add_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
|
||||
add_action( 'upgrader_process_complete', 'wp_version_check', 10, 0 );
|
||||
add_action( 'upgrader_process_complete', 'wp_update_plugins', 10, 0 );
|
||||
add_action( 'upgrader_process_complete', 'wp_update_themes', 10, 0 );
|
||||
|
||||
$this->skin->bulk_footer();
|
||||
|
||||
$this->skin->footer();
|
||||
|
||||
// Clean up our hooks, in case something else does an upgrade on this connection.
|
||||
remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
|
||||
|
||||
if ( $parsed_args['clear_update_cache'] ) {
|
||||
wp_clean_update_cache();
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the package source contains .mo and .po files.
|
||||
*
|
||||
* Hooked to the {@see 'upgrader_source_selection'} filter by
|
||||
* Language_Pack_Upgrader::bulk_upgrade().
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
*
|
||||
* @param string|WP_Error $source The path to the downloaded package source.
|
||||
* @param string $remote_source Remote file source location.
|
||||
* @return string|WP_Error The source as passed, or a WP_Error object on failure.
|
||||
*/
|
||||
public function check_package( $source, $remote_source ) {
|
||||
global $wp_filesystem;
|
||||
|
||||
if ( is_wp_error( $source ) ) {
|
||||
return $source;
|
||||
}
|
||||
|
||||
// Check that the folder contains a valid language.
|
||||
$files = $wp_filesystem->dirlist( $remote_source );
|
||||
|
||||
// Check to see if a .po and .mo exist in the folder.
|
||||
$po = false;
|
||||
$mo = false;
|
||||
foreach ( (array) $files as $file => $filedata ) {
|
||||
if ( str_ends_with( $file, '.po' ) ) {
|
||||
$po = true;
|
||||
} elseif ( str_ends_with( $file, '.mo' ) ) {
|
||||
$mo = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $mo || ! $po ) {
|
||||
return new WP_Error(
|
||||
'incompatible_archive_pomo',
|
||||
$this->strings['incompatible_archive'],
|
||||
sprintf(
|
||||
/* translators: 1: .po, 2: .mo */
|
||||
__( 'The language pack is missing either the %1$s or %2$s files.' ),
|
||||
'<code>.po</code>',
|
||||
'<code>.mo</code>'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of an item being updated.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param object $update The data for an update.
|
||||
* @return string The name of the item being updated.
|
||||
*/
|
||||
public function get_name_for_update( $update ) {
|
||||
switch ( $update->type ) {
|
||||
case 'core':
|
||||
return 'WordPress'; // Not translated.
|
||||
|
||||
case 'theme':
|
||||
$theme = wp_get_theme( $update->slug );
|
||||
if ( $theme->exists() ) {
|
||||
return $theme->Get( 'Name' );
|
||||
}
|
||||
break;
|
||||
case 'plugin':
|
||||
$plugin_data = get_plugins( '/' . $update->slug );
|
||||
$plugin_data = reset( $plugin_data );
|
||||
if ( $plugin_data ) {
|
||||
return $plugin_data['Name'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears existing translations where this item is going to be installed into.
|
||||
*
|
||||
* @since 5.1.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
*
|
||||
* @param string $remote_destination The location on the remote filesystem to be cleared.
|
||||
* @return bool|WP_Error True upon success, WP_Error on failure.
|
||||
*/
|
||||
public function clear_destination( $remote_destination ) {
|
||||
global $wp_filesystem;
|
||||
|
||||
$language_update = $this->skin->language_update;
|
||||
$language_directory = WP_LANG_DIR . '/'; // Local path for use with glob().
|
||||
|
||||
if ( 'core' === $language_update->type ) {
|
||||
$files = array(
|
||||
$remote_destination . $language_update->language . '.po',
|
||||
$remote_destination . $language_update->language . '.mo',
|
||||
$remote_destination . $language_update->language . '.l10n.php',
|
||||
$remote_destination . 'admin-' . $language_update->language . '.po',
|
||||
$remote_destination . 'admin-' . $language_update->language . '.mo',
|
||||
$remote_destination . 'admin-' . $language_update->language . '.l10n.php',
|
||||
$remote_destination . 'admin-network-' . $language_update->language . '.po',
|
||||
$remote_destination . 'admin-network-' . $language_update->language . '.mo',
|
||||
$remote_destination . 'admin-network-' . $language_update->language . '.l10n.php',
|
||||
$remote_destination . 'continents-cities-' . $language_update->language . '.po',
|
||||
$remote_destination . 'continents-cities-' . $language_update->language . '.mo',
|
||||
$remote_destination . 'continents-cities-' . $language_update->language . '.l10n.php',
|
||||
);
|
||||
|
||||
$json_translation_files = glob( $language_directory . $language_update->language . '-*.json' );
|
||||
if ( $json_translation_files ) {
|
||||
foreach ( $json_translation_files as $json_translation_file ) {
|
||||
$files[] = str_replace( $language_directory, $remote_destination, $json_translation_file );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$files = array(
|
||||
$remote_destination . $language_update->slug . '-' . $language_update->language . '.po',
|
||||
$remote_destination . $language_update->slug . '-' . $language_update->language . '.mo',
|
||||
$remote_destination . $language_update->slug . '-' . $language_update->language . '.l10n.php',
|
||||
);
|
||||
|
||||
$language_directory = $language_directory . $language_update->type . 's/';
|
||||
$json_translation_files = glob( $language_directory . $language_update->slug . '-' . $language_update->language . '-*.json' );
|
||||
if ( $json_translation_files ) {
|
||||
foreach ( $json_translation_files as $json_translation_file ) {
|
||||
$files[] = str_replace( $language_directory, $remote_destination, $json_translation_file );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$files = array_filter( $files, array( $wp_filesystem, 'exists' ) );
|
||||
|
||||
// No files to delete.
|
||||
if ( ! $files ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check all files are writable before attempting to clear the destination.
|
||||
$unwritable_files = array();
|
||||
|
||||
// Check writability.
|
||||
foreach ( $files as $file ) {
|
||||
if ( ! $wp_filesystem->is_writable( $file ) ) {
|
||||
// Attempt to alter permissions to allow writes and try again.
|
||||
$wp_filesystem->chmod( $file, FS_CHMOD_FILE );
|
||||
if ( ! $wp_filesystem->is_writable( $file ) ) {
|
||||
$unwritable_files[] = $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $unwritable_files ) ) {
|
||||
return new WP_Error( 'files_not_writable', $this->strings['files_not_writable'], implode( ', ', $unwritable_files ) );
|
||||
}
|
||||
|
||||
foreach ( $files as $file ) {
|
||||
if ( ! $wp_filesystem->delete( $file ) ) {
|
||||
return new WP_Error( 'remove_old_failed', $this->strings['remove_old_failed'] );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrade API: Language_Pack_Upgrader class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used for updating/installing language packs (translations)
|
||||
* for plugins, themes, and core.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader.php.
|
||||
*
|
||||
* @see WP_Upgrader
|
||||
*/
|
||||
class Language_Pack_Upgrader extends WP_Upgrader {
|
||||
|
||||
/**
|
||||
* Result of the language pack upgrade.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @var array|WP_Error $result
|
||||
* @see WP_Upgrader::$result
|
||||
*/
|
||||
public $result;
|
||||
|
||||
/**
|
||||
* Whether a bulk upgrade/installation is being performed.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @var bool $bulk
|
||||
*/
|
||||
public $bulk = true;
|
||||
|
||||
/**
|
||||
* Asynchronously upgrades language packs after other upgrades have been made.
|
||||
*
|
||||
* Hooked to the {@see 'upgrader_process_complete'} action by default.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param false|WP_Upgrader $upgrader Optional. WP_Upgrader instance or false. If `$upgrader` is
|
||||
* a Language_Pack_Upgrader instance, the method will bail to
|
||||
* avoid recursion. Otherwise unused. Default false.
|
||||
*/
|
||||
public static function async_upgrade( $upgrader = false ) {
|
||||
// Avoid recursion.
|
||||
if ( $upgrader && $upgrader instanceof Language_Pack_Upgrader ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Nothing to do?
|
||||
$language_updates = wp_get_translation_updates();
|
||||
if ( ! $language_updates ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Avoid messing with VCS installations, at least for now.
|
||||
* Noted: this is not the ideal way to accomplish this.
|
||||
*/
|
||||
$check_vcs = new WP_Automatic_Updater();
|
||||
if ( $check_vcs->is_vcs_checkout( WP_CONTENT_DIR ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $language_updates as $key => $language_update ) {
|
||||
$update = ! empty( $language_update->autoupdate );
|
||||
|
||||
/**
|
||||
* Filters whether to asynchronously update translation for core, a plugin, or a theme.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param bool $update Whether to update.
|
||||
* @param object $language_update The update offer.
|
||||
*/
|
||||
$update = apply_filters( 'async_update_translation', $update, $language_update );
|
||||
|
||||
if ( ! $update ) {
|
||||
unset( $language_updates[ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $language_updates ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Re-use the automatic upgrader skin if the parent upgrader is using it.
|
||||
if ( $upgrader && $upgrader->skin instanceof Automatic_Upgrader_Skin ) {
|
||||
$skin = $upgrader->skin;
|
||||
} else {
|
||||
$skin = new Language_Pack_Upgrader_Skin(
|
||||
array(
|
||||
'skip_header_footer' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$lp_upgrader = new Language_Pack_Upgrader( $skin );
|
||||
$lp_upgrader->bulk_upgrade( $language_updates );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the upgrade strings.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public function upgrade_strings() {
|
||||
$this->strings['starting_upgrade'] = __( 'Some of your translations need updating. Sit tight for a few more seconds while they are updated as well.' );
|
||||
$this->strings['up_to_date'] = __( 'Your translations are all up to date.' );
|
||||
$this->strings['no_package'] = __( 'Update package not available.' );
|
||||
/* translators: %s: Package URL. */
|
||||
$this->strings['downloading_package'] = sprintf( __( 'Downloading translation from %s…' ), '<span class="code pre">%s</span>' );
|
||||
$this->strings['unpack_package'] = __( 'Unpacking the update…' );
|
||||
$this->strings['process_failed'] = __( 'Translation update failed.' );
|
||||
$this->strings['process_success'] = __( 'Translation updated successfully.' );
|
||||
$this->strings['remove_old'] = __( 'Removing the old version of the translation…' );
|
||||
$this->strings['remove_old_failed'] = __( 'Could not remove the old translation.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades a language pack.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string|false $update Optional. Whether an update offer is available. Default false.
|
||||
* @param array $args Optional. Other optional arguments, see
|
||||
* Language_Pack_Upgrader::bulk_upgrade(). Default empty array.
|
||||
* @return array|bool|WP_Error The result of the upgrade, or a WP_Error object instead.
|
||||
*/
|
||||
public function upgrade( $update = false, $args = array() ) {
|
||||
if ( $update ) {
|
||||
$update = array( $update );
|
||||
}
|
||||
|
||||
$results = $this->bulk_upgrade( $update, $args );
|
||||
|
||||
if ( ! is_array( $results ) ) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
return $results[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades several language packs at once.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
*
|
||||
* @param object[] $language_updates Optional. Array of language packs to update. See {@see wp_get_translation_updates()}.
|
||||
* Default empty array.
|
||||
* @param array $args {
|
||||
* Other arguments for upgrading multiple language packs. Default empty array.
|
||||
*
|
||||
* @type bool $clear_update_cache Whether to clear the update cache when done.
|
||||
* Default true.
|
||||
* }
|
||||
* @return array|bool|WP_Error Will return an array of results, or true if there are no updates,
|
||||
* false or WP_Error for initial errors.
|
||||
*/
|
||||
public function bulk_upgrade( $language_updates = array(), $args = array() ) {
|
||||
global $wp_filesystem;
|
||||
|
||||
$defaults = array(
|
||||
'clear_update_cache' => true,
|
||||
);
|
||||
$parsed_args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$this->init();
|
||||
$this->upgrade_strings();
|
||||
|
||||
if ( ! $language_updates ) {
|
||||
$language_updates = wp_get_translation_updates();
|
||||
}
|
||||
|
||||
if ( empty( $language_updates ) ) {
|
||||
$this->skin->header();
|
||||
$this->skin->set_result( true );
|
||||
$this->skin->feedback( 'up_to_date' );
|
||||
$this->skin->bulk_footer();
|
||||
$this->skin->footer();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( 'upgrader_process_complete' === current_filter() ) {
|
||||
$this->skin->feedback( 'starting_upgrade' );
|
||||
}
|
||||
|
||||
// Remove any existing upgrade filters from the plugin/theme upgraders #WP29425 & #WP29230.
|
||||
remove_all_filters( 'upgrader_pre_install' );
|
||||
remove_all_filters( 'upgrader_clear_destination' );
|
||||
remove_all_filters( 'upgrader_post_install' );
|
||||
remove_all_filters( 'upgrader_source_selection' );
|
||||
|
||||
add_filter( 'upgrader_source_selection', array( $this, 'check_package' ), 10, 2 );
|
||||
|
||||
$this->skin->header();
|
||||
|
||||
// Connect to the filesystem first.
|
||||
$res = $this->fs_connect( array( WP_CONTENT_DIR, WP_LANG_DIR ) );
|
||||
if ( ! $res ) {
|
||||
$this->skin->footer();
|
||||
return false;
|
||||
}
|
||||
|
||||
$results = array();
|
||||
|
||||
$this->update_count = count( $language_updates );
|
||||
$this->update_current = 0;
|
||||
|
||||
/*
|
||||
* The filesystem's mkdir() is not recursive. Make sure WP_LANG_DIR exists,
|
||||
* as we then may need to create a /plugins or /themes directory inside of it.
|
||||
*/
|
||||
$remote_destination = $wp_filesystem->find_folder( WP_LANG_DIR );
|
||||
if ( ! $wp_filesystem->exists( $remote_destination ) ) {
|
||||
if ( ! $wp_filesystem->mkdir( $remote_destination, FS_CHMOD_DIR ) ) {
|
||||
return new WP_Error( 'mkdir_failed_lang_dir', $this->strings['mkdir_failed'], $remote_destination );
|
||||
}
|
||||
}
|
||||
|
||||
$language_updates_results = array();
|
||||
|
||||
foreach ( $language_updates as $language_update ) {
|
||||
|
||||
$this->skin->language_update = $language_update;
|
||||
|
||||
$destination = WP_LANG_DIR;
|
||||
if ( 'plugin' === $language_update->type ) {
|
||||
$destination .= '/plugins';
|
||||
} elseif ( 'theme' === $language_update->type ) {
|
||||
$destination .= '/themes';
|
||||
}
|
||||
|
||||
++$this->update_current;
|
||||
|
||||
$options = array(
|
||||
'package' => $language_update->package,
|
||||
'destination' => $destination,
|
||||
'clear_destination' => true,
|
||||
'abort_if_destination_exists' => false, // We expect the destination to exist.
|
||||
'clear_working' => true,
|
||||
'is_multi' => true,
|
||||
'hook_extra' => array(
|
||||
'language_update_type' => $language_update->type,
|
||||
'language_update' => $language_update,
|
||||
),
|
||||
);
|
||||
|
||||
$result = $this->run( $options );
|
||||
|
||||
$results[] = $this->result;
|
||||
|
||||
// Prevent credentials auth screen from displaying multiple times.
|
||||
if ( false === $result ) {
|
||||
break;
|
||||
}
|
||||
|
||||
$language_updates_results[] = array(
|
||||
'language' => $language_update->language,
|
||||
'type' => $language_update->type,
|
||||
'slug' => isset( $language_update->slug ) ? $language_update->slug : 'default',
|
||||
'version' => $language_update->version,
|
||||
);
|
||||
}
|
||||
|
||||
// Remove upgrade hooks which are not required for translation updates.
|
||||
remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
|
||||
remove_action( 'upgrader_process_complete', 'wp_version_check' );
|
||||
remove_action( 'upgrader_process_complete', 'wp_update_plugins' );
|
||||
remove_action( 'upgrader_process_complete', 'wp_update_themes' );
|
||||
|
||||
/** This action is documented in wp-admin/includes/class-wp-upgrader.php */
|
||||
do_action(
|
||||
'upgrader_process_complete',
|
||||
$this,
|
||||
array(
|
||||
'action' => 'update',
|
||||
'type' => 'translation',
|
||||
'bulk' => true,
|
||||
'translations' => $language_updates_results,
|
||||
)
|
||||
);
|
||||
|
||||
// Re-add upgrade hooks.
|
||||
add_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
|
||||
add_action( 'upgrader_process_complete', 'wp_version_check', 10, 0 );
|
||||
add_action( 'upgrader_process_complete', 'wp_update_plugins', 10, 0 );
|
||||
add_action( 'upgrader_process_complete', 'wp_update_themes', 10, 0 );
|
||||
|
||||
$this->skin->bulk_footer();
|
||||
|
||||
$this->skin->footer();
|
||||
|
||||
// Clean up our hooks, in case something else does an upgrade on this connection.
|
||||
remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
|
||||
|
||||
if ( $parsed_args['clear_update_cache'] ) {
|
||||
wp_clean_update_cache();
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the package source contains .mo and .po files.
|
||||
*
|
||||
* Hooked to the {@see 'upgrader_source_selection'} filter by
|
||||
* Language_Pack_Upgrader::bulk_upgrade().
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
*
|
||||
* @param string|WP_Error $source The path to the downloaded package source.
|
||||
* @param string $remote_source Remote file source location.
|
||||
* @return string|WP_Error The source as passed, or a WP_Error object on failure.
|
||||
*/
|
||||
public function check_package( $source, $remote_source ) {
|
||||
global $wp_filesystem;
|
||||
|
||||
if ( is_wp_error( $source ) ) {
|
||||
return $source;
|
||||
}
|
||||
|
||||
// Check that the folder contains a valid language.
|
||||
$files = $wp_filesystem->dirlist( $remote_source );
|
||||
|
||||
// Check to see if a .po and .mo exist in the folder.
|
||||
$po = false;
|
||||
$mo = false;
|
||||
foreach ( (array) $files as $file => $filedata ) {
|
||||
if ( str_ends_with( $file, '.po' ) ) {
|
||||
$po = true;
|
||||
} elseif ( str_ends_with( $file, '.mo' ) ) {
|
||||
$mo = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $mo || ! $po ) {
|
||||
return new WP_Error(
|
||||
'incompatible_archive_pomo',
|
||||
$this->strings['incompatible_archive'],
|
||||
sprintf(
|
||||
/* translators: 1: .po, 2: .mo */
|
||||
__( 'The language pack is missing either the %1$s or %2$s files.' ),
|
||||
'<code>.po</code>',
|
||||
'<code>.mo</code>'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of an item being updated.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param object $update The data for an update.
|
||||
* @return string The name of the item being updated.
|
||||
*/
|
||||
public function get_name_for_update( $update ) {
|
||||
switch ( $update->type ) {
|
||||
case 'core':
|
||||
return 'WordPress'; // Not translated.
|
||||
|
||||
case 'theme':
|
||||
$theme = wp_get_theme( $update->slug );
|
||||
if ( $theme->exists() ) {
|
||||
return $theme->Get( 'Name' );
|
||||
}
|
||||
break;
|
||||
case 'plugin':
|
||||
$plugin_data = get_plugins( '/' . $update->slug );
|
||||
$plugin_data = reset( $plugin_data );
|
||||
if ( $plugin_data ) {
|
||||
return $plugin_data['Name'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears existing translations where this item is going to be installed into.
|
||||
*
|
||||
* @since 5.1.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
*
|
||||
* @param string $remote_destination The location on the remote filesystem to be cleared.
|
||||
* @return bool|WP_Error True upon success, WP_Error on failure.
|
||||
*/
|
||||
public function clear_destination( $remote_destination ) {
|
||||
global $wp_filesystem;
|
||||
|
||||
$language_update = $this->skin->language_update;
|
||||
$language_directory = WP_LANG_DIR . '/'; // Local path for use with glob().
|
||||
|
||||
if ( 'core' === $language_update->type ) {
|
||||
$files = array(
|
||||
$remote_destination . $language_update->language . '.po',
|
||||
$remote_destination . $language_update->language . '.mo',
|
||||
$remote_destination . $language_update->language . '.l10n.php',
|
||||
$remote_destination . 'admin-' . $language_update->language . '.po',
|
||||
$remote_destination . 'admin-' . $language_update->language . '.mo',
|
||||
$remote_destination . 'admin-' . $language_update->language . '.l10n.php',
|
||||
$remote_destination . 'admin-network-' . $language_update->language . '.po',
|
||||
$remote_destination . 'admin-network-' . $language_update->language . '.mo',
|
||||
$remote_destination . 'admin-network-' . $language_update->language . '.l10n.php',
|
||||
$remote_destination . 'continents-cities-' . $language_update->language . '.po',
|
||||
$remote_destination . 'continents-cities-' . $language_update->language . '.mo',
|
||||
$remote_destination . 'continents-cities-' . $language_update->language . '.l10n.php',
|
||||
);
|
||||
|
||||
$json_translation_files = glob( $language_directory . $language_update->language . '-*.json' );
|
||||
if ( $json_translation_files ) {
|
||||
foreach ( $json_translation_files as $json_translation_file ) {
|
||||
$files[] = str_replace( $language_directory, $remote_destination, $json_translation_file );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$files = array(
|
||||
$remote_destination . $language_update->slug . '-' . $language_update->language . '.po',
|
||||
$remote_destination . $language_update->slug . '-' . $language_update->language . '.mo',
|
||||
$remote_destination . $language_update->slug . '-' . $language_update->language . '.l10n.php',
|
||||
);
|
||||
|
||||
$language_directory = $language_directory . $language_update->type . 's/';
|
||||
$json_translation_files = glob( $language_directory . $language_update->slug . '-' . $language_update->language . '-*.json' );
|
||||
if ( $json_translation_files ) {
|
||||
foreach ( $json_translation_files as $json_translation_file ) {
|
||||
$files[] = str_replace( $language_directory, $remote_destination, $json_translation_file );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$files = array_filter( $files, array( $wp_filesystem, 'exists' ) );
|
||||
|
||||
// No files to delete.
|
||||
if ( ! $files ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check all files are writable before attempting to clear the destination.
|
||||
$unwritable_files = array();
|
||||
|
||||
// Check writability.
|
||||
foreach ( $files as $file ) {
|
||||
if ( ! $wp_filesystem->is_writable( $file ) ) {
|
||||
// Attempt to alter permissions to allow writes and try again.
|
||||
$wp_filesystem->chmod( $file, FS_CHMOD_FILE );
|
||||
if ( ! $wp_filesystem->is_writable( $file ) ) {
|
||||
$unwritable_files[] = $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $unwritable_files ) ) {
|
||||
return new WP_Error( 'files_not_writable', $this->strings['files_not_writable'], implode( ', ', $unwritable_files ) );
|
||||
}
|
||||
|
||||
foreach ( $files as $file ) {
|
||||
if ( ! $wp_filesystem->delete( $file ) ) {
|
||||
return new WP_Error( 'remove_old_failed', $this->strings['remove_old_failed'] );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,349 +1,349 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Plugin_Installer_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin Installer Skin for WordPress Plugin Installer.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see WP_Upgrader_Skin
|
||||
*/
|
||||
class Plugin_Installer_Skin extends WP_Upgrader_Skin {
|
||||
public $api;
|
||||
public $type;
|
||||
public $url;
|
||||
public $overwrite;
|
||||
|
||||
private $is_downgrading = false;
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'type' => 'web',
|
||||
'url' => '',
|
||||
'plugin' => '',
|
||||
'nonce' => '',
|
||||
'title' => '',
|
||||
'overwrite' => '',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$this->type = $args['type'];
|
||||
$this->url = $args['url'];
|
||||
$this->api = isset( $args['api'] ) ? $args['api'] : array();
|
||||
$this->overwrite = $args['overwrite'];
|
||||
|
||||
parent::__construct( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action before installing a plugin.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function before() {
|
||||
if ( ! empty( $this->api ) ) {
|
||||
$this->upgrader->strings['process_success'] = sprintf(
|
||||
$this->upgrader->strings['process_success_specific'],
|
||||
$this->api->name,
|
||||
$this->api->version
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the `process_failed` error when updating a plugin by uploading a zip file.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param WP_Error $wp_error WP_Error object.
|
||||
* @return bool True if the error should be hidden, false otherwise.
|
||||
*/
|
||||
public function hide_process_failed( $wp_error ) {
|
||||
if (
|
||||
'upload' === $this->type &&
|
||||
'' === $this->overwrite &&
|
||||
$wp_error->get_error_code() === 'folder_exists'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action following a plugin install.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function after() {
|
||||
// Check if the plugin can be overwritten and output the HTML.
|
||||
if ( $this->do_overwrite() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$plugin_file = $this->upgrader->plugin_info();
|
||||
|
||||
$install_actions = array();
|
||||
|
||||
$from = isset( $_GET['from'] ) ? wp_unslash( $_GET['from'] ) : 'plugins';
|
||||
|
||||
if ( 'import' === $from ) {
|
||||
$install_actions['activate_plugin'] = sprintf(
|
||||
'<a class="button button-primary" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( 'plugins.php?action=activate&from=import&plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ),
|
||||
__( 'Activate Plugin & Run Importer' )
|
||||
);
|
||||
} elseif ( 'press-this' === $from ) {
|
||||
$install_actions['activate_plugin'] = sprintf(
|
||||
'<a class="button button-primary" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( 'plugins.php?action=activate&from=press-this&plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ),
|
||||
__( 'Activate Plugin & Go to Press This' )
|
||||
);
|
||||
} else {
|
||||
$install_actions['activate_plugin'] = sprintf(
|
||||
'<a class="button button-primary" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ),
|
||||
__( 'Activate Plugin' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( is_multisite() && current_user_can( 'manage_network_plugins' ) ) {
|
||||
$install_actions['network_activate'] = sprintf(
|
||||
'<a class="button button-primary" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( 'plugins.php?action=activate&networkwide=1&plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ),
|
||||
_x( 'Network Activate', 'plugin' )
|
||||
);
|
||||
unset( $install_actions['activate_plugin'] );
|
||||
}
|
||||
|
||||
if ( 'import' === $from ) {
|
||||
$install_actions['importers_page'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
admin_url( 'import.php' ),
|
||||
__( 'Go to Importers' )
|
||||
);
|
||||
} elseif ( 'web' === $this->type ) {
|
||||
$install_actions['plugins_page'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'plugin-install.php' ),
|
||||
__( 'Go to Plugin Installer' )
|
||||
);
|
||||
} elseif ( 'upload' === $this->type && 'plugins' === $from ) {
|
||||
$install_actions['plugins_page'] = sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
self_admin_url( 'plugin-install.php' ),
|
||||
__( 'Go to Plugin Installer' )
|
||||
);
|
||||
} else {
|
||||
$install_actions['plugins_page'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'plugins.php' ),
|
||||
__( 'Go to Plugins page' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! $this->result || is_wp_error( $this->result ) ) {
|
||||
unset( $install_actions['activate_plugin'], $install_actions['network_activate'] );
|
||||
} elseif ( ! current_user_can( 'activate_plugin', $plugin_file ) || is_plugin_active( $plugin_file ) ) {
|
||||
unset( $install_actions['activate_plugin'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a single plugin installation.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string[] $install_actions Array of plugin action links.
|
||||
* @param object $api Object containing WordPress.org API plugin data. Empty
|
||||
* for non-API installs, such as when a plugin is installed
|
||||
* via upload.
|
||||
* @param string $plugin_file Path to the plugin file relative to the plugins directory.
|
||||
*/
|
||||
$install_actions = apply_filters( 'install_plugin_complete_actions', $install_actions, $this->api, $plugin_file );
|
||||
|
||||
if ( ! empty( $install_actions ) ) {
|
||||
$this->feedback( implode( ' ', (array) $install_actions ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the plugin can be overwritten and outputs the HTML for overwriting a plugin on upload.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @return bool Whether the plugin can be overwritten and HTML was outputted.
|
||||
*/
|
||||
private function do_overwrite() {
|
||||
if ( 'upload' !== $this->type || ! is_wp_error( $this->result ) || 'folder_exists' !== $this->result->get_error_code() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$folder = $this->result->get_error_data( 'folder_exists' );
|
||||
$folder = ltrim( substr( $folder, strlen( WP_PLUGIN_DIR ) ), '/' );
|
||||
|
||||
$current_plugin_data = false;
|
||||
$all_plugins = get_plugins();
|
||||
|
||||
foreach ( $all_plugins as $plugin => $plugin_data ) {
|
||||
if ( strrpos( $plugin, $folder ) !== 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$current_plugin_data = $plugin_data;
|
||||
}
|
||||
|
||||
$new_plugin_data = $this->upgrader->new_plugin_data;
|
||||
|
||||
if ( ! $current_plugin_data || ! $new_plugin_data ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
echo '<h2 class="update-from-upload-heading">' . esc_html__( 'This plugin is already installed.' ) . '</h2>';
|
||||
|
||||
$this->is_downgrading = version_compare( $current_plugin_data['Version'], $new_plugin_data['Version'], '>' );
|
||||
|
||||
$rows = array(
|
||||
'Name' => __( 'Plugin name' ),
|
||||
'Version' => __( 'Version' ),
|
||||
'Author' => __( 'Author' ),
|
||||
'RequiresWP' => __( 'Required WordPress version' ),
|
||||
'RequiresPHP' => __( 'Required PHP version' ),
|
||||
);
|
||||
|
||||
$table = '<table class="update-from-upload-comparison"><tbody>';
|
||||
$table .= '<tr><th></th><th>' . esc_html_x( 'Current', 'plugin' ) . '</th>';
|
||||
$table .= '<th>' . esc_html_x( 'Uploaded', 'plugin' ) . '</th></tr>';
|
||||
|
||||
$is_same_plugin = true; // Let's consider only these rows.
|
||||
|
||||
foreach ( $rows as $field => $label ) {
|
||||
$old_value = ! empty( $current_plugin_data[ $field ] ) ? (string) $current_plugin_data[ $field ] : '-';
|
||||
$new_value = ! empty( $new_plugin_data[ $field ] ) ? (string) $new_plugin_data[ $field ] : '-';
|
||||
|
||||
$is_same_plugin = $is_same_plugin && ( $old_value === $new_value );
|
||||
|
||||
$diff_field = ( 'Version' !== $field && $new_value !== $old_value );
|
||||
$diff_version = ( 'Version' === $field && $this->is_downgrading );
|
||||
|
||||
$table .= '<tr><td class="name-label">' . $label . '</td><td>' . wp_strip_all_tags( $old_value ) . '</td>';
|
||||
$table .= ( $diff_field || $diff_version ) ? '<td class="warning">' : '<td>';
|
||||
$table .= wp_strip_all_tags( $new_value ) . '</td></tr>';
|
||||
}
|
||||
|
||||
$table .= '</tbody></table>';
|
||||
|
||||
/**
|
||||
* Filters the compare table output for overwriting a plugin package on upload.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param string $table The output table with Name, Version, Author, RequiresWP, and RequiresPHP info.
|
||||
* @param array $current_plugin_data Array with current plugin data.
|
||||
* @param array $new_plugin_data Array with uploaded plugin data.
|
||||
*/
|
||||
echo apply_filters( 'install_plugin_overwrite_comparison', $table, $current_plugin_data, $new_plugin_data );
|
||||
|
||||
$install_actions = array();
|
||||
$can_update = true;
|
||||
|
||||
$blocked_message = '<p>' . esc_html__( 'The plugin cannot be updated due to the following:' ) . '</p>';
|
||||
$blocked_message .= '<ul class="ul-disc">';
|
||||
|
||||
$requires_php = isset( $new_plugin_data['RequiresPHP'] ) ? $new_plugin_data['RequiresPHP'] : null;
|
||||
$requires_wp = isset( $new_plugin_data['RequiresWP'] ) ? $new_plugin_data['RequiresWP'] : null;
|
||||
|
||||
if ( ! is_php_version_compatible( $requires_php ) ) {
|
||||
$error = sprintf(
|
||||
/* translators: 1: Current PHP version, 2: Version required by the uploaded plugin. */
|
||||
__( 'The PHP version on your server is %1$s, however the uploaded plugin requires %2$s.' ),
|
||||
PHP_VERSION,
|
||||
$requires_php
|
||||
);
|
||||
|
||||
$blocked_message .= '<li>' . esc_html( $error ) . '</li>';
|
||||
$can_update = false;
|
||||
}
|
||||
|
||||
if ( ! is_wp_version_compatible( $requires_wp ) ) {
|
||||
$error = sprintf(
|
||||
/* translators: 1: Current WordPress version, 2: Version required by the uploaded plugin. */
|
||||
__( 'Your WordPress version is %1$s, however the uploaded plugin requires %2$s.' ),
|
||||
get_bloginfo( 'version' ),
|
||||
$requires_wp
|
||||
);
|
||||
|
||||
$blocked_message .= '<li>' . esc_html( $error ) . '</li>';
|
||||
$can_update = false;
|
||||
}
|
||||
|
||||
$blocked_message .= '</ul>';
|
||||
|
||||
if ( $can_update ) {
|
||||
if ( $this->is_downgrading ) {
|
||||
$warning = sprintf(
|
||||
/* translators: %s: Documentation URL. */
|
||||
__( 'You are uploading an older version of a current plugin. You can continue to install the older version, but be sure to <a href="%s">back up your database and files</a> first.' ),
|
||||
__( 'https://wordpress.org/documentation/article/wordpress-backups/' )
|
||||
);
|
||||
} else {
|
||||
$warning = sprintf(
|
||||
/* translators: %s: Documentation URL. */
|
||||
__( 'You are updating a plugin. Be sure to <a href="%s">back up your database and files</a> first.' ),
|
||||
__( 'https://wordpress.org/documentation/article/wordpress-backups/' )
|
||||
);
|
||||
}
|
||||
|
||||
echo '<p class="update-from-upload-notice">' . $warning . '</p>';
|
||||
|
||||
$overwrite = $this->is_downgrading ? 'downgrade-plugin' : 'update-plugin';
|
||||
|
||||
$install_actions['overwrite_plugin'] = sprintf(
|
||||
'<a class="button button-primary update-from-upload-overwrite" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( add_query_arg( 'overwrite', $overwrite, $this->url ), 'plugin-upload' ),
|
||||
_x( 'Replace current with uploaded', 'plugin' )
|
||||
);
|
||||
} else {
|
||||
echo $blocked_message;
|
||||
}
|
||||
|
||||
$cancel_url = add_query_arg( 'action', 'upload-plugin-cancel-overwrite', $this->url );
|
||||
|
||||
$install_actions['plugins_page'] = sprintf(
|
||||
'<a class="button" href="%s">%s</a>',
|
||||
wp_nonce_url( $cancel_url, 'plugin-upload-cancel-overwrite' ),
|
||||
__( 'Cancel and go back' )
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a single plugin installation failure
|
||||
* when overwriting is allowed.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param string[] $install_actions Array of plugin action links.
|
||||
* @param object $api Object containing WordPress.org API plugin data.
|
||||
* @param array $new_plugin_data Array with uploaded plugin data.
|
||||
*/
|
||||
$install_actions = apply_filters( 'install_plugin_overwrite_actions', $install_actions, $this->api, $new_plugin_data );
|
||||
|
||||
if ( ! empty( $install_actions ) ) {
|
||||
printf(
|
||||
'<p class="update-from-upload-expired hidden">%s</p>',
|
||||
__( 'The uploaded file has expired. Please go back and upload it again.' )
|
||||
);
|
||||
echo '<p class="update-from-upload-actions">' . implode( ' ', (array) $install_actions ) . '</p>';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Plugin_Installer_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin Installer Skin for WordPress Plugin Installer.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see WP_Upgrader_Skin
|
||||
*/
|
||||
class Plugin_Installer_Skin extends WP_Upgrader_Skin {
|
||||
public $api;
|
||||
public $type;
|
||||
public $url;
|
||||
public $overwrite;
|
||||
|
||||
private $is_downgrading = false;
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'type' => 'web',
|
||||
'url' => '',
|
||||
'plugin' => '',
|
||||
'nonce' => '',
|
||||
'title' => '',
|
||||
'overwrite' => '',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$this->type = $args['type'];
|
||||
$this->url = $args['url'];
|
||||
$this->api = isset( $args['api'] ) ? $args['api'] : array();
|
||||
$this->overwrite = $args['overwrite'];
|
||||
|
||||
parent::__construct( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action before installing a plugin.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function before() {
|
||||
if ( ! empty( $this->api ) ) {
|
||||
$this->upgrader->strings['process_success'] = sprintf(
|
||||
$this->upgrader->strings['process_success_specific'],
|
||||
$this->api->name,
|
||||
$this->api->version
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the `process_failed` error when updating a plugin by uploading a zip file.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param WP_Error $wp_error WP_Error object.
|
||||
* @return bool True if the error should be hidden, false otherwise.
|
||||
*/
|
||||
public function hide_process_failed( $wp_error ) {
|
||||
if (
|
||||
'upload' === $this->type &&
|
||||
'' === $this->overwrite &&
|
||||
$wp_error->get_error_code() === 'folder_exists'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action following a plugin install.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function after() {
|
||||
// Check if the plugin can be overwritten and output the HTML.
|
||||
if ( $this->do_overwrite() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$plugin_file = $this->upgrader->plugin_info();
|
||||
|
||||
$install_actions = array();
|
||||
|
||||
$from = isset( $_GET['from'] ) ? wp_unslash( $_GET['from'] ) : 'plugins';
|
||||
|
||||
if ( 'import' === $from ) {
|
||||
$install_actions['activate_plugin'] = sprintf(
|
||||
'<a class="button button-primary" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( 'plugins.php?action=activate&from=import&plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ),
|
||||
__( 'Activate Plugin & Run Importer' )
|
||||
);
|
||||
} elseif ( 'press-this' === $from ) {
|
||||
$install_actions['activate_plugin'] = sprintf(
|
||||
'<a class="button button-primary" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( 'plugins.php?action=activate&from=press-this&plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ),
|
||||
__( 'Activate Plugin & Go to Press This' )
|
||||
);
|
||||
} else {
|
||||
$install_actions['activate_plugin'] = sprintf(
|
||||
'<a class="button button-primary" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ),
|
||||
__( 'Activate Plugin' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( is_multisite() && current_user_can( 'manage_network_plugins' ) ) {
|
||||
$install_actions['network_activate'] = sprintf(
|
||||
'<a class="button button-primary" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( 'plugins.php?action=activate&networkwide=1&plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ),
|
||||
_x( 'Network Activate', 'plugin' )
|
||||
);
|
||||
unset( $install_actions['activate_plugin'] );
|
||||
}
|
||||
|
||||
if ( 'import' === $from ) {
|
||||
$install_actions['importers_page'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
admin_url( 'import.php' ),
|
||||
__( 'Go to Importers' )
|
||||
);
|
||||
} elseif ( 'web' === $this->type ) {
|
||||
$install_actions['plugins_page'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'plugin-install.php' ),
|
||||
__( 'Go to Plugin Installer' )
|
||||
);
|
||||
} elseif ( 'upload' === $this->type && 'plugins' === $from ) {
|
||||
$install_actions['plugins_page'] = sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
self_admin_url( 'plugin-install.php' ),
|
||||
__( 'Go to Plugin Installer' )
|
||||
);
|
||||
} else {
|
||||
$install_actions['plugins_page'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'plugins.php' ),
|
||||
__( 'Go to Plugins page' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! $this->result || is_wp_error( $this->result ) ) {
|
||||
unset( $install_actions['activate_plugin'], $install_actions['network_activate'] );
|
||||
} elseif ( ! current_user_can( 'activate_plugin', $plugin_file ) || is_plugin_active( $plugin_file ) ) {
|
||||
unset( $install_actions['activate_plugin'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a single plugin installation.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string[] $install_actions Array of plugin action links.
|
||||
* @param object $api Object containing WordPress.org API plugin data. Empty
|
||||
* for non-API installs, such as when a plugin is installed
|
||||
* via upload.
|
||||
* @param string $plugin_file Path to the plugin file relative to the plugins directory.
|
||||
*/
|
||||
$install_actions = apply_filters( 'install_plugin_complete_actions', $install_actions, $this->api, $plugin_file );
|
||||
|
||||
if ( ! empty( $install_actions ) ) {
|
||||
$this->feedback( implode( ' ', (array) $install_actions ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the plugin can be overwritten and outputs the HTML for overwriting a plugin on upload.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @return bool Whether the plugin can be overwritten and HTML was outputted.
|
||||
*/
|
||||
private function do_overwrite() {
|
||||
if ( 'upload' !== $this->type || ! is_wp_error( $this->result ) || 'folder_exists' !== $this->result->get_error_code() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$folder = $this->result->get_error_data( 'folder_exists' );
|
||||
$folder = ltrim( substr( $folder, strlen( WP_PLUGIN_DIR ) ), '/' );
|
||||
|
||||
$current_plugin_data = false;
|
||||
$all_plugins = get_plugins();
|
||||
|
||||
foreach ( $all_plugins as $plugin => $plugin_data ) {
|
||||
if ( strrpos( $plugin, $folder ) !== 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$current_plugin_data = $plugin_data;
|
||||
}
|
||||
|
||||
$new_plugin_data = $this->upgrader->new_plugin_data;
|
||||
|
||||
if ( ! $current_plugin_data || ! $new_plugin_data ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
echo '<h2 class="update-from-upload-heading">' . esc_html__( 'This plugin is already installed.' ) . '</h2>';
|
||||
|
||||
$this->is_downgrading = version_compare( $current_plugin_data['Version'], $new_plugin_data['Version'], '>' );
|
||||
|
||||
$rows = array(
|
||||
'Name' => __( 'Plugin name' ),
|
||||
'Version' => __( 'Version' ),
|
||||
'Author' => __( 'Author' ),
|
||||
'RequiresWP' => __( 'Required WordPress version' ),
|
||||
'RequiresPHP' => __( 'Required PHP version' ),
|
||||
);
|
||||
|
||||
$table = '<table class="update-from-upload-comparison"><tbody>';
|
||||
$table .= '<tr><th></th><th>' . esc_html_x( 'Current', 'plugin' ) . '</th>';
|
||||
$table .= '<th>' . esc_html_x( 'Uploaded', 'plugin' ) . '</th></tr>';
|
||||
|
||||
$is_same_plugin = true; // Let's consider only these rows.
|
||||
|
||||
foreach ( $rows as $field => $label ) {
|
||||
$old_value = ! empty( $current_plugin_data[ $field ] ) ? (string) $current_plugin_data[ $field ] : '-';
|
||||
$new_value = ! empty( $new_plugin_data[ $field ] ) ? (string) $new_plugin_data[ $field ] : '-';
|
||||
|
||||
$is_same_plugin = $is_same_plugin && ( $old_value === $new_value );
|
||||
|
||||
$diff_field = ( 'Version' !== $field && $new_value !== $old_value );
|
||||
$diff_version = ( 'Version' === $field && $this->is_downgrading );
|
||||
|
||||
$table .= '<tr><td class="name-label">' . $label . '</td><td>' . wp_strip_all_tags( $old_value ) . '</td>';
|
||||
$table .= ( $diff_field || $diff_version ) ? '<td class="warning">' : '<td>';
|
||||
$table .= wp_strip_all_tags( $new_value ) . '</td></tr>';
|
||||
}
|
||||
|
||||
$table .= '</tbody></table>';
|
||||
|
||||
/**
|
||||
* Filters the compare table output for overwriting a plugin package on upload.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param string $table The output table with Name, Version, Author, RequiresWP, and RequiresPHP info.
|
||||
* @param array $current_plugin_data Array with current plugin data.
|
||||
* @param array $new_plugin_data Array with uploaded plugin data.
|
||||
*/
|
||||
echo apply_filters( 'install_plugin_overwrite_comparison', $table, $current_plugin_data, $new_plugin_data );
|
||||
|
||||
$install_actions = array();
|
||||
$can_update = true;
|
||||
|
||||
$blocked_message = '<p>' . esc_html__( 'The plugin cannot be updated due to the following:' ) . '</p>';
|
||||
$blocked_message .= '<ul class="ul-disc">';
|
||||
|
||||
$requires_php = isset( $new_plugin_data['RequiresPHP'] ) ? $new_plugin_data['RequiresPHP'] : null;
|
||||
$requires_wp = isset( $new_plugin_data['RequiresWP'] ) ? $new_plugin_data['RequiresWP'] : null;
|
||||
|
||||
if ( ! is_php_version_compatible( $requires_php ) ) {
|
||||
$error = sprintf(
|
||||
/* translators: 1: Current PHP version, 2: Version required by the uploaded plugin. */
|
||||
__( 'The PHP version on your server is %1$s, however the uploaded plugin requires %2$s.' ),
|
||||
PHP_VERSION,
|
||||
$requires_php
|
||||
);
|
||||
|
||||
$blocked_message .= '<li>' . esc_html( $error ) . '</li>';
|
||||
$can_update = false;
|
||||
}
|
||||
|
||||
if ( ! is_wp_version_compatible( $requires_wp ) ) {
|
||||
$error = sprintf(
|
||||
/* translators: 1: Current WordPress version, 2: Version required by the uploaded plugin. */
|
||||
__( 'Your WordPress version is %1$s, however the uploaded plugin requires %2$s.' ),
|
||||
get_bloginfo( 'version' ),
|
||||
$requires_wp
|
||||
);
|
||||
|
||||
$blocked_message .= '<li>' . esc_html( $error ) . '</li>';
|
||||
$can_update = false;
|
||||
}
|
||||
|
||||
$blocked_message .= '</ul>';
|
||||
|
||||
if ( $can_update ) {
|
||||
if ( $this->is_downgrading ) {
|
||||
$warning = sprintf(
|
||||
/* translators: %s: Documentation URL. */
|
||||
__( 'You are uploading an older version of a current plugin. You can continue to install the older version, but be sure to <a href="%s">back up your database and files</a> first.' ),
|
||||
__( 'https://wordpress.org/documentation/article/wordpress-backups/' )
|
||||
);
|
||||
} else {
|
||||
$warning = sprintf(
|
||||
/* translators: %s: Documentation URL. */
|
||||
__( 'You are updating a plugin. Be sure to <a href="%s">back up your database and files</a> first.' ),
|
||||
__( 'https://wordpress.org/documentation/article/wordpress-backups/' )
|
||||
);
|
||||
}
|
||||
|
||||
echo '<p class="update-from-upload-notice">' . $warning . '</p>';
|
||||
|
||||
$overwrite = $this->is_downgrading ? 'downgrade-plugin' : 'update-plugin';
|
||||
|
||||
$install_actions['overwrite_plugin'] = sprintf(
|
||||
'<a class="button button-primary update-from-upload-overwrite" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( add_query_arg( 'overwrite', $overwrite, $this->url ), 'plugin-upload' ),
|
||||
_x( 'Replace current with uploaded', 'plugin' )
|
||||
);
|
||||
} else {
|
||||
echo $blocked_message;
|
||||
}
|
||||
|
||||
$cancel_url = add_query_arg( 'action', 'upload-plugin-cancel-overwrite', $this->url );
|
||||
|
||||
$install_actions['plugins_page'] = sprintf(
|
||||
'<a class="button" href="%s">%s</a>',
|
||||
wp_nonce_url( $cancel_url, 'plugin-upload-cancel-overwrite' ),
|
||||
__( 'Cancel and go back' )
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a single plugin installation failure
|
||||
* when overwriting is allowed.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param string[] $install_actions Array of plugin action links.
|
||||
* @param object $api Object containing WordPress.org API plugin data.
|
||||
* @param array $new_plugin_data Array with uploaded plugin data.
|
||||
*/
|
||||
$install_actions = apply_filters( 'install_plugin_overwrite_actions', $install_actions, $this->api, $new_plugin_data );
|
||||
|
||||
if ( ! empty( $install_actions ) ) {
|
||||
printf(
|
||||
'<p class="update-from-upload-expired hidden">%s</p>',
|
||||
__( 'The uploaded file has expired. Please go back and upload it again.' )
|
||||
);
|
||||
echo '<p class="update-from-upload-actions">' . implode( ' ', (array) $install_actions ) . '</p>';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,123 +1,123 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Plugin_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin Upgrader Skin for WordPress Plugin Upgrades.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see WP_Upgrader_Skin
|
||||
*/
|
||||
class Plugin_Upgrader_Skin extends WP_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Holds the plugin slug in the Plugin Directory.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $plugin = '';
|
||||
|
||||
/**
|
||||
* Whether the plugin is active.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $plugin_active = false;
|
||||
|
||||
/**
|
||||
* Whether the plugin is active for the entire network.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $plugin_network_active = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Sets up the plugin upgrader skin.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param array $args Optional. The plugin upgrader skin arguments to
|
||||
* override default options. Default empty array.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'url' => '',
|
||||
'plugin' => '',
|
||||
'nonce' => '',
|
||||
'title' => __( 'Update Plugin' ),
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$this->plugin = $args['plugin'];
|
||||
|
||||
$this->plugin_active = is_plugin_active( $this->plugin );
|
||||
$this->plugin_network_active = is_plugin_active_for_network( $this->plugin );
|
||||
|
||||
parent::__construct( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action following a single plugin update.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function after() {
|
||||
$this->plugin = $this->upgrader->plugin_info();
|
||||
if ( ! empty( $this->plugin ) && ! is_wp_error( $this->result ) && $this->plugin_active ) {
|
||||
// Currently used only when JS is off for a single plugin update?
|
||||
printf(
|
||||
'<iframe title="%s" style="border:0;overflow:hidden" width="100%%" height="170" src="%s"></iframe>',
|
||||
esc_attr__( 'Update progress' ),
|
||||
wp_nonce_url( 'update.php?action=activate-plugin&networkwide=' . $this->plugin_network_active . '&plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin )
|
||||
);
|
||||
}
|
||||
|
||||
$this->decrement_update_count( 'plugin' );
|
||||
|
||||
$update_actions = array(
|
||||
'activate_plugin' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin ),
|
||||
__( 'Activate Plugin' )
|
||||
),
|
||||
'plugins_page' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'plugins.php' ),
|
||||
__( 'Go to Plugins page' )
|
||||
),
|
||||
);
|
||||
|
||||
if ( $this->plugin_active || ! $this->result || is_wp_error( $this->result ) || ! current_user_can( 'activate_plugin', $this->plugin ) ) {
|
||||
unset( $update_actions['activate_plugin'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a single plugin update.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string[] $update_actions Array of plugin action links.
|
||||
* @param string $plugin Path to the plugin file relative to the plugins directory.
|
||||
*/
|
||||
$update_actions = apply_filters( 'update_plugin_complete_actions', $update_actions, $this->plugin );
|
||||
|
||||
if ( ! empty( $update_actions ) ) {
|
||||
$this->feedback( implode( ' | ', (array) $update_actions ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Plugin_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin Upgrader Skin for WordPress Plugin Upgrades.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see WP_Upgrader_Skin
|
||||
*/
|
||||
class Plugin_Upgrader_Skin extends WP_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Holds the plugin slug in the Plugin Directory.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $plugin = '';
|
||||
|
||||
/**
|
||||
* Whether the plugin is active.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $plugin_active = false;
|
||||
|
||||
/**
|
||||
* Whether the plugin is active for the entire network.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $plugin_network_active = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Sets up the plugin upgrader skin.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param array $args Optional. The plugin upgrader skin arguments to
|
||||
* override default options. Default empty array.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'url' => '',
|
||||
'plugin' => '',
|
||||
'nonce' => '',
|
||||
'title' => __( 'Update Plugin' ),
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$this->plugin = $args['plugin'];
|
||||
|
||||
$this->plugin_active = is_plugin_active( $this->plugin );
|
||||
$this->plugin_network_active = is_plugin_active_for_network( $this->plugin );
|
||||
|
||||
parent::__construct( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action following a single plugin update.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function after() {
|
||||
$this->plugin = $this->upgrader->plugin_info();
|
||||
if ( ! empty( $this->plugin ) && ! is_wp_error( $this->result ) && $this->plugin_active ) {
|
||||
// Currently used only when JS is off for a single plugin update?
|
||||
printf(
|
||||
'<iframe title="%s" style="border:0;overflow:hidden" width="100%%" height="170" src="%s"></iframe>',
|
||||
esc_attr__( 'Update progress' ),
|
||||
wp_nonce_url( 'update.php?action=activate-plugin&networkwide=' . $this->plugin_network_active . '&plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin )
|
||||
);
|
||||
}
|
||||
|
||||
$this->decrement_update_count( 'plugin' );
|
||||
|
||||
$update_actions = array(
|
||||
'activate_plugin' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $this->plugin ), 'activate-plugin_' . $this->plugin ),
|
||||
__( 'Activate Plugin' )
|
||||
),
|
||||
'plugins_page' => sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'plugins.php' ),
|
||||
__( 'Go to Plugins page' )
|
||||
),
|
||||
);
|
||||
|
||||
if ( $this->plugin_active || ! $this->result || is_wp_error( $this->result ) || ! current_user_can( 'activate_plugin', $this->plugin ) ) {
|
||||
unset( $update_actions['activate_plugin'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a single plugin update.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string[] $update_actions Array of plugin action links.
|
||||
* @param string $plugin Path to the plugin file relative to the plugins directory.
|
||||
*/
|
||||
$update_actions = apply_filters( 'update_plugin_complete_actions', $update_actions, $this->plugin );
|
||||
|
||||
if ( ! empty( $update_actions ) ) {
|
||||
$this->feedback( implode( ' | ', (array) $update_actions ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,384 +1,384 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Theme_Installer_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Theme Installer Skin for the WordPress Theme Installer.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see WP_Upgrader_Skin
|
||||
*/
|
||||
class Theme_Installer_Skin extends WP_Upgrader_Skin {
|
||||
public $api;
|
||||
public $type;
|
||||
public $url;
|
||||
public $overwrite;
|
||||
|
||||
private $is_downgrading = false;
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'type' => 'web',
|
||||
'url' => '',
|
||||
'theme' => '',
|
||||
'nonce' => '',
|
||||
'title' => '',
|
||||
'overwrite' => '',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$this->type = $args['type'];
|
||||
$this->url = $args['url'];
|
||||
$this->api = isset( $args['api'] ) ? $args['api'] : array();
|
||||
$this->overwrite = $args['overwrite'];
|
||||
|
||||
parent::__construct( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action before installing a theme.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function before() {
|
||||
if ( ! empty( $this->api ) ) {
|
||||
$this->upgrader->strings['process_success'] = sprintf(
|
||||
$this->upgrader->strings['process_success_specific'],
|
||||
$this->api->name,
|
||||
$this->api->version
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the `process_failed` error when updating a theme by uploading a zip file.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param WP_Error $wp_error WP_Error object.
|
||||
* @return bool True if the error should be hidden, false otherwise.
|
||||
*/
|
||||
public function hide_process_failed( $wp_error ) {
|
||||
if (
|
||||
'upload' === $this->type &&
|
||||
'' === $this->overwrite &&
|
||||
$wp_error->get_error_code() === 'folder_exists'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action following a single theme install.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function after() {
|
||||
if ( $this->do_overwrite() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( empty( $this->upgrader->result['destination_name'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$theme_info = $this->upgrader->theme_info();
|
||||
if ( empty( $theme_info ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$name = $theme_info->display( 'Name' );
|
||||
$stylesheet = $this->upgrader->result['destination_name'];
|
||||
$template = $theme_info->get_template();
|
||||
|
||||
$activate_link = add_query_arg(
|
||||
array(
|
||||
'action' => 'activate',
|
||||
'template' => urlencode( $template ),
|
||||
'stylesheet' => urlencode( $stylesheet ),
|
||||
),
|
||||
admin_url( 'themes.php' )
|
||||
);
|
||||
$activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
|
||||
|
||||
$install_actions = array();
|
||||
|
||||
if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) && ! $theme_info->is_block_theme() ) {
|
||||
$customize_url = add_query_arg(
|
||||
array(
|
||||
'theme' => urlencode( $stylesheet ),
|
||||
'return' => urlencode( admin_url( 'web' === $this->type ? 'theme-install.php' : 'themes.php' ) ),
|
||||
),
|
||||
admin_url( 'customize.php' )
|
||||
);
|
||||
|
||||
$install_actions['preview'] = sprintf(
|
||||
'<a href="%s" class="hide-if-no-customize load-customize">' .
|
||||
'<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
|
||||
esc_url( $customize_url ),
|
||||
__( 'Live Preview' ),
|
||||
/* translators: Hidden accessibility text. %s: Theme name. */
|
||||
sprintf( __( 'Live Preview “%s”' ), $name )
|
||||
);
|
||||
}
|
||||
|
||||
$install_actions['activate'] = sprintf(
|
||||
'<a href="%s" class="activatelink">' .
|
||||
'<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
|
||||
esc_url( $activate_link ),
|
||||
_x( 'Activate', 'theme' ),
|
||||
/* translators: Hidden accessibility text. %s: Theme name. */
|
||||
sprintf( _x( 'Activate “%s”', 'theme' ), $name )
|
||||
);
|
||||
|
||||
if ( is_network_admin() && current_user_can( 'manage_network_themes' ) ) {
|
||||
$install_actions['network_enable'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
esc_url( wp_nonce_url( 'themes.php?action=enable&theme=' . urlencode( $stylesheet ), 'enable-theme_' . $stylesheet ) ),
|
||||
__( 'Network Enable' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( 'web' === $this->type ) {
|
||||
$install_actions['themes_page'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'theme-install.php' ),
|
||||
__( 'Go to Theme Installer' )
|
||||
);
|
||||
} elseif ( current_user_can( 'switch_themes' ) || current_user_can( 'edit_theme_options' ) ) {
|
||||
$install_actions['themes_page'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'themes.php' ),
|
||||
__( 'Go to Themes page' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() || ! current_user_can( 'switch_themes' ) ) {
|
||||
unset( $install_actions['activate'], $install_actions['preview'] );
|
||||
} elseif ( get_option( 'template' ) === $stylesheet ) {
|
||||
unset( $install_actions['activate'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a single theme installation.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string[] $install_actions Array of theme action links.
|
||||
* @param object $api Object containing WordPress.org API theme data.
|
||||
* @param string $stylesheet Theme directory name.
|
||||
* @param WP_Theme $theme_info Theme object.
|
||||
*/
|
||||
$install_actions = apply_filters( 'install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info );
|
||||
if ( ! empty( $install_actions ) ) {
|
||||
$this->feedback( implode( ' | ', (array) $install_actions ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the theme can be overwritten and outputs the HTML for overwriting a theme on upload.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @return bool Whether the theme can be overwritten and HTML was outputted.
|
||||
*/
|
||||
private function do_overwrite() {
|
||||
if ( 'upload' !== $this->type || ! is_wp_error( $this->result ) || 'folder_exists' !== $this->result->get_error_code() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$folder = $this->result->get_error_data( 'folder_exists' );
|
||||
$folder = rtrim( $folder, '/' );
|
||||
|
||||
$current_theme_data = false;
|
||||
$all_themes = wp_get_themes( array( 'errors' => null ) );
|
||||
|
||||
foreach ( $all_themes as $theme ) {
|
||||
$stylesheet_dir = wp_normalize_path( $theme->get_stylesheet_directory() );
|
||||
|
||||
if ( rtrim( $stylesheet_dir, '/' ) !== $folder ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$current_theme_data = $theme;
|
||||
}
|
||||
|
||||
$new_theme_data = $this->upgrader->new_theme_data;
|
||||
|
||||
if ( ! $current_theme_data || ! $new_theme_data ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
echo '<h2 class="update-from-upload-heading">' . esc_html__( 'This theme is already installed.' ) . '</h2>';
|
||||
|
||||
// Check errors for active theme.
|
||||
if ( is_wp_error( $current_theme_data->errors() ) ) {
|
||||
$this->feedback( 'current_theme_has_errors', $current_theme_data->errors()->get_error_message() );
|
||||
}
|
||||
|
||||
$this->is_downgrading = version_compare( $current_theme_data['Version'], $new_theme_data['Version'], '>' );
|
||||
|
||||
$is_invalid_parent = false;
|
||||
if ( ! empty( $new_theme_data['Template'] ) ) {
|
||||
$is_invalid_parent = ! in_array( $new_theme_data['Template'], array_keys( $all_themes ), true );
|
||||
}
|
||||
|
||||
$rows = array(
|
||||
'Name' => __( 'Theme name' ),
|
||||
'Version' => __( 'Version' ),
|
||||
'Author' => __( 'Author' ),
|
||||
'RequiresWP' => __( 'Required WordPress version' ),
|
||||
'RequiresPHP' => __( 'Required PHP version' ),
|
||||
'Template' => __( 'Parent theme' ),
|
||||
);
|
||||
|
||||
$table = '<table class="update-from-upload-comparison"><tbody>';
|
||||
$table .= '<tr><th></th><th>' . esc_html_x( 'Active', 'theme' ) . '</th><th>' . esc_html_x( 'Uploaded', 'theme' ) . '</th></tr>';
|
||||
|
||||
$is_same_theme = true; // Let's consider only these rows.
|
||||
|
||||
foreach ( $rows as $field => $label ) {
|
||||
$old_value = $current_theme_data->display( $field, false );
|
||||
$old_value = $old_value ? (string) $old_value : '-';
|
||||
|
||||
$new_value = ! empty( $new_theme_data[ $field ] ) ? (string) $new_theme_data[ $field ] : '-';
|
||||
|
||||
if ( $old_value === $new_value && '-' === $new_value && 'Template' === $field ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$is_same_theme = $is_same_theme && ( $old_value === $new_value );
|
||||
|
||||
$diff_field = ( 'Version' !== $field && $new_value !== $old_value );
|
||||
$diff_version = ( 'Version' === $field && $this->is_downgrading );
|
||||
$invalid_parent = false;
|
||||
|
||||
if ( 'Template' === $field && $is_invalid_parent ) {
|
||||
$invalid_parent = true;
|
||||
$new_value .= ' ' . __( '(not found)' );
|
||||
}
|
||||
|
||||
$table .= '<tr><td class="name-label">' . $label . '</td><td>' . wp_strip_all_tags( $old_value ) . '</td>';
|
||||
$table .= ( $diff_field || $diff_version || $invalid_parent ) ? '<td class="warning">' : '<td>';
|
||||
$table .= wp_strip_all_tags( $new_value ) . '</td></tr>';
|
||||
}
|
||||
|
||||
$table .= '</tbody></table>';
|
||||
|
||||
/**
|
||||
* Filters the compare table output for overwriting a theme package on upload.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param string $table The output table with Name, Version, Author, RequiresWP, and RequiresPHP info.
|
||||
* @param WP_Theme $current_theme_data Active theme data.
|
||||
* @param array $new_theme_data Array with uploaded theme data.
|
||||
*/
|
||||
echo apply_filters( 'install_theme_overwrite_comparison', $table, $current_theme_data, $new_theme_data );
|
||||
|
||||
$install_actions = array();
|
||||
$can_update = true;
|
||||
|
||||
$blocked_message = '<p>' . esc_html__( 'The theme cannot be updated due to the following:' ) . '</p>';
|
||||
$blocked_message .= '<ul class="ul-disc">';
|
||||
|
||||
$requires_php = isset( $new_theme_data['RequiresPHP'] ) ? $new_theme_data['RequiresPHP'] : null;
|
||||
$requires_wp = isset( $new_theme_data['RequiresWP'] ) ? $new_theme_data['RequiresWP'] : null;
|
||||
|
||||
if ( ! is_php_version_compatible( $requires_php ) ) {
|
||||
$error = sprintf(
|
||||
/* translators: 1: Current PHP version, 2: Version required by the uploaded theme. */
|
||||
__( 'The PHP version on your server is %1$s, however the uploaded theme requires %2$s.' ),
|
||||
PHP_VERSION,
|
||||
$requires_php
|
||||
);
|
||||
|
||||
$blocked_message .= '<li>' . esc_html( $error ) . '</li>';
|
||||
$can_update = false;
|
||||
}
|
||||
|
||||
if ( ! is_wp_version_compatible( $requires_wp ) ) {
|
||||
$error = sprintf(
|
||||
/* translators: 1: Current WordPress version, 2: Version required by the uploaded theme. */
|
||||
__( 'Your WordPress version is %1$s, however the uploaded theme requires %2$s.' ),
|
||||
get_bloginfo( 'version' ),
|
||||
$requires_wp
|
||||
);
|
||||
|
||||
$blocked_message .= '<li>' . esc_html( $error ) . '</li>';
|
||||
$can_update = false;
|
||||
}
|
||||
|
||||
$blocked_message .= '</ul>';
|
||||
|
||||
if ( $can_update ) {
|
||||
if ( $this->is_downgrading ) {
|
||||
$warning = sprintf(
|
||||
/* translators: %s: Documentation URL. */
|
||||
__( 'You are uploading an older version of the active theme. You can continue to install the older version, but be sure to <a href="%s">back up your database and files</a> first.' ),
|
||||
__( 'https://wordpress.org/documentation/article/wordpress-backups/' )
|
||||
);
|
||||
} else {
|
||||
$warning = sprintf(
|
||||
/* translators: %s: Documentation URL. */
|
||||
__( 'You are updating a theme. Be sure to <a href="%s">back up your database and files</a> first.' ),
|
||||
__( 'https://wordpress.org/documentation/article/wordpress-backups/' )
|
||||
);
|
||||
}
|
||||
|
||||
echo '<p class="update-from-upload-notice">' . $warning . '</p>';
|
||||
|
||||
$overwrite = $this->is_downgrading ? 'downgrade-theme' : 'update-theme';
|
||||
|
||||
$install_actions['overwrite_theme'] = sprintf(
|
||||
'<a class="button button-primary update-from-upload-overwrite" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( add_query_arg( 'overwrite', $overwrite, $this->url ), 'theme-upload' ),
|
||||
_x( 'Replace active with uploaded', 'theme' )
|
||||
);
|
||||
} else {
|
||||
echo $blocked_message;
|
||||
}
|
||||
|
||||
$cancel_url = add_query_arg( 'action', 'upload-theme-cancel-overwrite', $this->url );
|
||||
|
||||
$install_actions['themes_page'] = sprintf(
|
||||
'<a class="button" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( $cancel_url, 'theme-upload-cancel-overwrite' ),
|
||||
__( 'Cancel and go back' )
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a single theme installation failure
|
||||
* when overwriting is allowed.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param string[] $install_actions Array of theme action links.
|
||||
* @param object $api Object containing WordPress.org API theme data.
|
||||
* @param array $new_theme_data Array with uploaded theme data.
|
||||
*/
|
||||
$install_actions = apply_filters( 'install_theme_overwrite_actions', $install_actions, $this->api, $new_theme_data );
|
||||
|
||||
if ( ! empty( $install_actions ) ) {
|
||||
printf(
|
||||
'<p class="update-from-upload-expired hidden">%s</p>',
|
||||
__( 'The uploaded file has expired. Please go back and upload it again.' )
|
||||
);
|
||||
echo '<p class="update-from-upload-actions">' . implode( ' ', (array) $install_actions ) . '</p>';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Theme_Installer_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Theme Installer Skin for the WordPress Theme Installer.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see WP_Upgrader_Skin
|
||||
*/
|
||||
class Theme_Installer_Skin extends WP_Upgrader_Skin {
|
||||
public $api;
|
||||
public $type;
|
||||
public $url;
|
||||
public $overwrite;
|
||||
|
||||
private $is_downgrading = false;
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'type' => 'web',
|
||||
'url' => '',
|
||||
'theme' => '',
|
||||
'nonce' => '',
|
||||
'title' => '',
|
||||
'overwrite' => '',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$this->type = $args['type'];
|
||||
$this->url = $args['url'];
|
||||
$this->api = isset( $args['api'] ) ? $args['api'] : array();
|
||||
$this->overwrite = $args['overwrite'];
|
||||
|
||||
parent::__construct( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action before installing a theme.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function before() {
|
||||
if ( ! empty( $this->api ) ) {
|
||||
$this->upgrader->strings['process_success'] = sprintf(
|
||||
$this->upgrader->strings['process_success_specific'],
|
||||
$this->api->name,
|
||||
$this->api->version
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the `process_failed` error when updating a theme by uploading a zip file.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param WP_Error $wp_error WP_Error object.
|
||||
* @return bool True if the error should be hidden, false otherwise.
|
||||
*/
|
||||
public function hide_process_failed( $wp_error ) {
|
||||
if (
|
||||
'upload' === $this->type &&
|
||||
'' === $this->overwrite &&
|
||||
$wp_error->get_error_code() === 'folder_exists'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action following a single theme install.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function after() {
|
||||
if ( $this->do_overwrite() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( empty( $this->upgrader->result['destination_name'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$theme_info = $this->upgrader->theme_info();
|
||||
if ( empty( $theme_info ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$name = $theme_info->display( 'Name' );
|
||||
$stylesheet = $this->upgrader->result['destination_name'];
|
||||
$template = $theme_info->get_template();
|
||||
|
||||
$activate_link = add_query_arg(
|
||||
array(
|
||||
'action' => 'activate',
|
||||
'template' => urlencode( $template ),
|
||||
'stylesheet' => urlencode( $stylesheet ),
|
||||
),
|
||||
admin_url( 'themes.php' )
|
||||
);
|
||||
$activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
|
||||
|
||||
$install_actions = array();
|
||||
|
||||
if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) && ! $theme_info->is_block_theme() ) {
|
||||
$customize_url = add_query_arg(
|
||||
array(
|
||||
'theme' => urlencode( $stylesheet ),
|
||||
'return' => urlencode( admin_url( 'web' === $this->type ? 'theme-install.php' : 'themes.php' ) ),
|
||||
),
|
||||
admin_url( 'customize.php' )
|
||||
);
|
||||
|
||||
$install_actions['preview'] = sprintf(
|
||||
'<a href="%s" class="hide-if-no-customize load-customize">' .
|
||||
'<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
|
||||
esc_url( $customize_url ),
|
||||
__( 'Live Preview' ),
|
||||
/* translators: Hidden accessibility text. %s: Theme name. */
|
||||
sprintf( __( 'Live Preview “%s”' ), $name )
|
||||
);
|
||||
}
|
||||
|
||||
$install_actions['activate'] = sprintf(
|
||||
'<a href="%s" class="activatelink">' .
|
||||
'<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
|
||||
esc_url( $activate_link ),
|
||||
_x( 'Activate', 'theme' ),
|
||||
/* translators: Hidden accessibility text. %s: Theme name. */
|
||||
sprintf( _x( 'Activate “%s”', 'theme' ), $name )
|
||||
);
|
||||
|
||||
if ( is_network_admin() && current_user_can( 'manage_network_themes' ) ) {
|
||||
$install_actions['network_enable'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
esc_url( wp_nonce_url( 'themes.php?action=enable&theme=' . urlencode( $stylesheet ), 'enable-theme_' . $stylesheet ) ),
|
||||
__( 'Network Enable' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( 'web' === $this->type ) {
|
||||
$install_actions['themes_page'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'theme-install.php' ),
|
||||
__( 'Go to Theme Installer' )
|
||||
);
|
||||
} elseif ( current_user_can( 'switch_themes' ) || current_user_can( 'edit_theme_options' ) ) {
|
||||
$install_actions['themes_page'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'themes.php' ),
|
||||
__( 'Go to Themes page' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() || ! current_user_can( 'switch_themes' ) ) {
|
||||
unset( $install_actions['activate'], $install_actions['preview'] );
|
||||
} elseif ( get_option( 'template' ) === $stylesheet ) {
|
||||
unset( $install_actions['activate'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a single theme installation.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string[] $install_actions Array of theme action links.
|
||||
* @param object $api Object containing WordPress.org API theme data.
|
||||
* @param string $stylesheet Theme directory name.
|
||||
* @param WP_Theme $theme_info Theme object.
|
||||
*/
|
||||
$install_actions = apply_filters( 'install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info );
|
||||
if ( ! empty( $install_actions ) ) {
|
||||
$this->feedback( implode( ' | ', (array) $install_actions ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the theme can be overwritten and outputs the HTML for overwriting a theme on upload.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @return bool Whether the theme can be overwritten and HTML was outputted.
|
||||
*/
|
||||
private function do_overwrite() {
|
||||
if ( 'upload' !== $this->type || ! is_wp_error( $this->result ) || 'folder_exists' !== $this->result->get_error_code() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$folder = $this->result->get_error_data( 'folder_exists' );
|
||||
$folder = rtrim( $folder, '/' );
|
||||
|
||||
$current_theme_data = false;
|
||||
$all_themes = wp_get_themes( array( 'errors' => null ) );
|
||||
|
||||
foreach ( $all_themes as $theme ) {
|
||||
$stylesheet_dir = wp_normalize_path( $theme->get_stylesheet_directory() );
|
||||
|
||||
if ( rtrim( $stylesheet_dir, '/' ) !== $folder ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$current_theme_data = $theme;
|
||||
}
|
||||
|
||||
$new_theme_data = $this->upgrader->new_theme_data;
|
||||
|
||||
if ( ! $current_theme_data || ! $new_theme_data ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
echo '<h2 class="update-from-upload-heading">' . esc_html__( 'This theme is already installed.' ) . '</h2>';
|
||||
|
||||
// Check errors for active theme.
|
||||
if ( is_wp_error( $current_theme_data->errors() ) ) {
|
||||
$this->feedback( 'current_theme_has_errors', $current_theme_data->errors()->get_error_message() );
|
||||
}
|
||||
|
||||
$this->is_downgrading = version_compare( $current_theme_data['Version'], $new_theme_data['Version'], '>' );
|
||||
|
||||
$is_invalid_parent = false;
|
||||
if ( ! empty( $new_theme_data['Template'] ) ) {
|
||||
$is_invalid_parent = ! in_array( $new_theme_data['Template'], array_keys( $all_themes ), true );
|
||||
}
|
||||
|
||||
$rows = array(
|
||||
'Name' => __( 'Theme name' ),
|
||||
'Version' => __( 'Version' ),
|
||||
'Author' => __( 'Author' ),
|
||||
'RequiresWP' => __( 'Required WordPress version' ),
|
||||
'RequiresPHP' => __( 'Required PHP version' ),
|
||||
'Template' => __( 'Parent theme' ),
|
||||
);
|
||||
|
||||
$table = '<table class="update-from-upload-comparison"><tbody>';
|
||||
$table .= '<tr><th></th><th>' . esc_html_x( 'Active', 'theme' ) . '</th><th>' . esc_html_x( 'Uploaded', 'theme' ) . '</th></tr>';
|
||||
|
||||
$is_same_theme = true; // Let's consider only these rows.
|
||||
|
||||
foreach ( $rows as $field => $label ) {
|
||||
$old_value = $current_theme_data->display( $field, false );
|
||||
$old_value = $old_value ? (string) $old_value : '-';
|
||||
|
||||
$new_value = ! empty( $new_theme_data[ $field ] ) ? (string) $new_theme_data[ $field ] : '-';
|
||||
|
||||
if ( $old_value === $new_value && '-' === $new_value && 'Template' === $field ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$is_same_theme = $is_same_theme && ( $old_value === $new_value );
|
||||
|
||||
$diff_field = ( 'Version' !== $field && $new_value !== $old_value );
|
||||
$diff_version = ( 'Version' === $field && $this->is_downgrading );
|
||||
$invalid_parent = false;
|
||||
|
||||
if ( 'Template' === $field && $is_invalid_parent ) {
|
||||
$invalid_parent = true;
|
||||
$new_value .= ' ' . __( '(not found)' );
|
||||
}
|
||||
|
||||
$table .= '<tr><td class="name-label">' . $label . '</td><td>' . wp_strip_all_tags( $old_value ) . '</td>';
|
||||
$table .= ( $diff_field || $diff_version || $invalid_parent ) ? '<td class="warning">' : '<td>';
|
||||
$table .= wp_strip_all_tags( $new_value ) . '</td></tr>';
|
||||
}
|
||||
|
||||
$table .= '</tbody></table>';
|
||||
|
||||
/**
|
||||
* Filters the compare table output for overwriting a theme package on upload.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param string $table The output table with Name, Version, Author, RequiresWP, and RequiresPHP info.
|
||||
* @param WP_Theme $current_theme_data Active theme data.
|
||||
* @param array $new_theme_data Array with uploaded theme data.
|
||||
*/
|
||||
echo apply_filters( 'install_theme_overwrite_comparison', $table, $current_theme_data, $new_theme_data );
|
||||
|
||||
$install_actions = array();
|
||||
$can_update = true;
|
||||
|
||||
$blocked_message = '<p>' . esc_html__( 'The theme cannot be updated due to the following:' ) . '</p>';
|
||||
$blocked_message .= '<ul class="ul-disc">';
|
||||
|
||||
$requires_php = isset( $new_theme_data['RequiresPHP'] ) ? $new_theme_data['RequiresPHP'] : null;
|
||||
$requires_wp = isset( $new_theme_data['RequiresWP'] ) ? $new_theme_data['RequiresWP'] : null;
|
||||
|
||||
if ( ! is_php_version_compatible( $requires_php ) ) {
|
||||
$error = sprintf(
|
||||
/* translators: 1: Current PHP version, 2: Version required by the uploaded theme. */
|
||||
__( 'The PHP version on your server is %1$s, however the uploaded theme requires %2$s.' ),
|
||||
PHP_VERSION,
|
||||
$requires_php
|
||||
);
|
||||
|
||||
$blocked_message .= '<li>' . esc_html( $error ) . '</li>';
|
||||
$can_update = false;
|
||||
}
|
||||
|
||||
if ( ! is_wp_version_compatible( $requires_wp ) ) {
|
||||
$error = sprintf(
|
||||
/* translators: 1: Current WordPress version, 2: Version required by the uploaded theme. */
|
||||
__( 'Your WordPress version is %1$s, however the uploaded theme requires %2$s.' ),
|
||||
get_bloginfo( 'version' ),
|
||||
$requires_wp
|
||||
);
|
||||
|
||||
$blocked_message .= '<li>' . esc_html( $error ) . '</li>';
|
||||
$can_update = false;
|
||||
}
|
||||
|
||||
$blocked_message .= '</ul>';
|
||||
|
||||
if ( $can_update ) {
|
||||
if ( $this->is_downgrading ) {
|
||||
$warning = sprintf(
|
||||
/* translators: %s: Documentation URL. */
|
||||
__( 'You are uploading an older version of the active theme. You can continue to install the older version, but be sure to <a href="%s">back up your database and files</a> first.' ),
|
||||
__( 'https://wordpress.org/documentation/article/wordpress-backups/' )
|
||||
);
|
||||
} else {
|
||||
$warning = sprintf(
|
||||
/* translators: %s: Documentation URL. */
|
||||
__( 'You are updating a theme. Be sure to <a href="%s">back up your database and files</a> first.' ),
|
||||
__( 'https://wordpress.org/documentation/article/wordpress-backups/' )
|
||||
);
|
||||
}
|
||||
|
||||
echo '<p class="update-from-upload-notice">' . $warning . '</p>';
|
||||
|
||||
$overwrite = $this->is_downgrading ? 'downgrade-theme' : 'update-theme';
|
||||
|
||||
$install_actions['overwrite_theme'] = sprintf(
|
||||
'<a class="button button-primary update-from-upload-overwrite" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( add_query_arg( 'overwrite', $overwrite, $this->url ), 'theme-upload' ),
|
||||
_x( 'Replace active with uploaded', 'theme' )
|
||||
);
|
||||
} else {
|
||||
echo $blocked_message;
|
||||
}
|
||||
|
||||
$cancel_url = add_query_arg( 'action', 'upload-theme-cancel-overwrite', $this->url );
|
||||
|
||||
$install_actions['themes_page'] = sprintf(
|
||||
'<a class="button" href="%s" target="_parent">%s</a>',
|
||||
wp_nonce_url( $cancel_url, 'theme-upload-cancel-overwrite' ),
|
||||
__( 'Cancel and go back' )
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a single theme installation failure
|
||||
* when overwriting is allowed.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param string[] $install_actions Array of theme action links.
|
||||
* @param object $api Object containing WordPress.org API theme data.
|
||||
* @param array $new_theme_data Array with uploaded theme data.
|
||||
*/
|
||||
$install_actions = apply_filters( 'install_theme_overwrite_actions', $install_actions, $this->api, $new_theme_data );
|
||||
|
||||
if ( ! empty( $install_actions ) ) {
|
||||
printf(
|
||||
'<p class="update-from-upload-expired hidden">%s</p>',
|
||||
__( 'The uploaded file has expired. Please go back and upload it again.' )
|
||||
);
|
||||
echo '<p class="update-from-upload-actions">' . implode( ' ', (array) $install_actions ) . '</p>';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,144 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Theme_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Theme Upgrader Skin for WordPress Theme Upgrades.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see WP_Upgrader_Skin
|
||||
*/
|
||||
class Theme_Upgrader_Skin extends WP_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Holds the theme slug in the Theme Directory.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $theme = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Sets up the theme upgrader skin.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param array $args Optional. The theme upgrader skin arguments to
|
||||
* override default options. Default empty array.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'url' => '',
|
||||
'theme' => '',
|
||||
'nonce' => '',
|
||||
'title' => __( 'Update Theme' ),
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$this->theme = $args['theme'];
|
||||
|
||||
parent::__construct( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action following a single theme update.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function after() {
|
||||
$this->decrement_update_count( 'theme' );
|
||||
|
||||
$update_actions = array();
|
||||
$theme_info = $this->upgrader->theme_info();
|
||||
if ( $theme_info ) {
|
||||
$name = $theme_info->display( 'Name' );
|
||||
$stylesheet = $this->upgrader->result['destination_name'];
|
||||
$template = $theme_info->get_template();
|
||||
|
||||
$activate_link = add_query_arg(
|
||||
array(
|
||||
'action' => 'activate',
|
||||
'template' => urlencode( $template ),
|
||||
'stylesheet' => urlencode( $stylesheet ),
|
||||
),
|
||||
admin_url( 'themes.php' )
|
||||
);
|
||||
$activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
|
||||
|
||||
$customize_url = add_query_arg(
|
||||
array(
|
||||
'theme' => urlencode( $stylesheet ),
|
||||
'return' => urlencode( admin_url( 'themes.php' ) ),
|
||||
),
|
||||
admin_url( 'customize.php' )
|
||||
);
|
||||
|
||||
if ( get_stylesheet() === $stylesheet ) {
|
||||
if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
|
||||
$update_actions['preview'] = sprintf(
|
||||
'<a href="%s" class="hide-if-no-customize load-customize">' .
|
||||
'<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
|
||||
esc_url( $customize_url ),
|
||||
__( 'Customize' ),
|
||||
/* translators: Hidden accessibility text. %s: Theme name. */
|
||||
sprintf( __( 'Customize “%s”' ), $name )
|
||||
);
|
||||
}
|
||||
} elseif ( current_user_can( 'switch_themes' ) ) {
|
||||
if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
|
||||
$update_actions['preview'] = sprintf(
|
||||
'<a href="%s" class="hide-if-no-customize load-customize">' .
|
||||
'<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
|
||||
esc_url( $customize_url ),
|
||||
__( 'Live Preview' ),
|
||||
/* translators: Hidden accessibility text. %s: Theme name. */
|
||||
sprintf( __( 'Live Preview “%s”' ), $name )
|
||||
);
|
||||
}
|
||||
|
||||
$update_actions['activate'] = sprintf(
|
||||
'<a href="%s" class="activatelink">' .
|
||||
'<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
|
||||
esc_url( $activate_link ),
|
||||
_x( 'Activate', 'theme' ),
|
||||
/* translators: Hidden accessibility text. %s: Theme name. */
|
||||
sprintf( _x( 'Activate “%s”', 'theme' ), $name )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() ) {
|
||||
unset( $update_actions['preview'], $update_actions['activate'] );
|
||||
}
|
||||
}
|
||||
|
||||
$update_actions['themes_page'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'themes.php' ),
|
||||
__( 'Go to Themes page' )
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a single theme update.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string[] $update_actions Array of theme action links.
|
||||
* @param string $theme Theme directory name.
|
||||
*/
|
||||
$update_actions = apply_filters( 'update_theme_complete_actions', $update_actions, $this->theme );
|
||||
|
||||
if ( ! empty( $update_actions ) ) {
|
||||
$this->feedback( implode( ' | ', (array) $update_actions ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: Theme_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Theme Upgrader Skin for WordPress Theme Upgrades.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*
|
||||
* @see WP_Upgrader_Skin
|
||||
*/
|
||||
class Theme_Upgrader_Skin extends WP_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Holds the theme slug in the Theme Directory.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $theme = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Sets up the theme upgrader skin.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param array $args Optional. The theme upgrader skin arguments to
|
||||
* override default options. Default empty array.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'url' => '',
|
||||
'theme' => '',
|
||||
'nonce' => '',
|
||||
'title' => __( 'Update Theme' ),
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$this->theme = $args['theme'];
|
||||
|
||||
parent::__construct( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action following a single theme update.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function after() {
|
||||
$this->decrement_update_count( 'theme' );
|
||||
|
||||
$update_actions = array();
|
||||
$theme_info = $this->upgrader->theme_info();
|
||||
if ( $theme_info ) {
|
||||
$name = $theme_info->display( 'Name' );
|
||||
$stylesheet = $this->upgrader->result['destination_name'];
|
||||
$template = $theme_info->get_template();
|
||||
|
||||
$activate_link = add_query_arg(
|
||||
array(
|
||||
'action' => 'activate',
|
||||
'template' => urlencode( $template ),
|
||||
'stylesheet' => urlencode( $stylesheet ),
|
||||
),
|
||||
admin_url( 'themes.php' )
|
||||
);
|
||||
$activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
|
||||
|
||||
$customize_url = add_query_arg(
|
||||
array(
|
||||
'theme' => urlencode( $stylesheet ),
|
||||
'return' => urlencode( admin_url( 'themes.php' ) ),
|
||||
),
|
||||
admin_url( 'customize.php' )
|
||||
);
|
||||
|
||||
if ( get_stylesheet() === $stylesheet ) {
|
||||
if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
|
||||
$update_actions['preview'] = sprintf(
|
||||
'<a href="%s" class="hide-if-no-customize load-customize">' .
|
||||
'<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
|
||||
esc_url( $customize_url ),
|
||||
__( 'Customize' ),
|
||||
/* translators: Hidden accessibility text. %s: Theme name. */
|
||||
sprintf( __( 'Customize “%s”' ), $name )
|
||||
);
|
||||
}
|
||||
} elseif ( current_user_can( 'switch_themes' ) ) {
|
||||
if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
|
||||
$update_actions['preview'] = sprintf(
|
||||
'<a href="%s" class="hide-if-no-customize load-customize">' .
|
||||
'<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
|
||||
esc_url( $customize_url ),
|
||||
__( 'Live Preview' ),
|
||||
/* translators: Hidden accessibility text. %s: Theme name. */
|
||||
sprintf( __( 'Live Preview “%s”' ), $name )
|
||||
);
|
||||
}
|
||||
|
||||
$update_actions['activate'] = sprintf(
|
||||
'<a href="%s" class="activatelink">' .
|
||||
'<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
|
||||
esc_url( $activate_link ),
|
||||
_x( 'Activate', 'theme' ),
|
||||
/* translators: Hidden accessibility text. %s: Theme name. */
|
||||
sprintf( _x( 'Activate “%s”', 'theme' ), $name )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() ) {
|
||||
unset( $update_actions['preview'], $update_actions['activate'] );
|
||||
}
|
||||
}
|
||||
|
||||
$update_actions['themes_page'] = sprintf(
|
||||
'<a href="%s" target="_parent">%s</a>',
|
||||
self_admin_url( 'themes.php' ),
|
||||
__( 'Go to Themes page' )
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the list of action links available following a single theme update.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string[] $update_actions Array of theme action links.
|
||||
* @param string $theme Theme directory name.
|
||||
*/
|
||||
$update_actions = apply_filters( 'update_theme_complete_actions', $update_actions, $this->theme );
|
||||
|
||||
if ( ! empty( $update_actions ) ) {
|
||||
$this->feedback( implode( ' | ', (array) $update_actions ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,138 +1,138 @@
|
||||
<?php
|
||||
/**
|
||||
* Taxonomy API: Walker_Category_Checklist class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core walker class to output an unordered list of category checkbox input elements.
|
||||
*
|
||||
* @since 2.5.1
|
||||
*
|
||||
* @see Walker
|
||||
* @see wp_category_checklist()
|
||||
* @see wp_terms_checklist()
|
||||
*/
|
||||
class Walker_Category_Checklist extends Walker {
|
||||
public $tree_type = 'category';
|
||||
public $db_fields = array(
|
||||
'parent' => 'parent',
|
||||
'id' => 'term_id',
|
||||
); // TODO: Decouple this.
|
||||
|
||||
/**
|
||||
* Starts the list before the elements are added.
|
||||
*
|
||||
* @see Walker:start_lvl()
|
||||
*
|
||||
* @since 2.5.1
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param int $depth Depth of category. Used for tab indentation.
|
||||
* @param array $args An array of arguments. See {@see wp_terms_checklist()}.
|
||||
*/
|
||||
public function start_lvl( &$output, $depth = 0, $args = array() ) {
|
||||
$indent = str_repeat( "\t", $depth );
|
||||
$output .= "$indent<ul class='children'>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the list of after the elements are added.
|
||||
*
|
||||
* @see Walker::end_lvl()
|
||||
*
|
||||
* @since 2.5.1
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param int $depth Depth of category. Used for tab indentation.
|
||||
* @param array $args An array of arguments. See {@see wp_terms_checklist()}.
|
||||
*/
|
||||
public function end_lvl( &$output, $depth = 0, $args = array() ) {
|
||||
$indent = str_repeat( "\t", $depth );
|
||||
$output .= "$indent</ul>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the element output.
|
||||
*
|
||||
* @see Walker::start_el()
|
||||
*
|
||||
* @since 2.5.1
|
||||
* @since 5.9.0 Renamed `$category` to `$data_object` and `$id` to `$current_object_id`
|
||||
* to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param WP_Term $data_object The current term object.
|
||||
* @param int $depth Depth of the term in reference to parents. Default 0.
|
||||
* @param array $args An array of arguments. See {@see wp_terms_checklist()}.
|
||||
* @param int $current_object_id Optional. ID of the current term. Default 0.
|
||||
*/
|
||||
public function start_el( &$output, $data_object, $depth = 0, $args = array(), $current_object_id = 0 ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$category = $data_object;
|
||||
|
||||
if ( empty( $args['taxonomy'] ) ) {
|
||||
$taxonomy = 'category';
|
||||
} else {
|
||||
$taxonomy = $args['taxonomy'];
|
||||
}
|
||||
|
||||
if ( 'category' === $taxonomy ) {
|
||||
$name = 'post_category';
|
||||
} else {
|
||||
$name = 'tax_input[' . $taxonomy . ']';
|
||||
}
|
||||
|
||||
$args['popular_cats'] = ! empty( $args['popular_cats'] ) ? array_map( 'intval', $args['popular_cats'] ) : array();
|
||||
|
||||
$class = in_array( $category->term_id, $args['popular_cats'], true ) ? ' class="popular-category"' : '';
|
||||
|
||||
$args['selected_cats'] = ! empty( $args['selected_cats'] ) ? array_map( 'intval', $args['selected_cats'] ) : array();
|
||||
|
||||
if ( ! empty( $args['list_only'] ) ) {
|
||||
$aria_checked = 'false';
|
||||
$inner_class = 'category';
|
||||
|
||||
if ( in_array( $category->term_id, $args['selected_cats'], true ) ) {
|
||||
$inner_class .= ' selected';
|
||||
$aria_checked = 'true';
|
||||
}
|
||||
|
||||
$output .= "\n" . '<li' . $class . '>' .
|
||||
'<div class="' . $inner_class . '" data-term-id=' . $category->term_id .
|
||||
' tabindex="0" role="checkbox" aria-checked="' . $aria_checked . '">' .
|
||||
/** This filter is documented in wp-includes/category-template.php */
|
||||
esc_html( apply_filters( 'the_category', $category->name, '', '' ) ) . '</div>';
|
||||
} else {
|
||||
$is_selected = in_array( $category->term_id, $args['selected_cats'], true );
|
||||
$is_disabled = ! empty( $args['disabled'] );
|
||||
|
||||
$output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" .
|
||||
'<label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="' . $name . '[]" id="in-' . $taxonomy . '-' . $category->term_id . '"' .
|
||||
checked( $is_selected, true, false ) .
|
||||
disabled( $is_disabled, true, false ) . ' /> ' .
|
||||
/** This filter is documented in wp-includes/category-template.php */
|
||||
esc_html( apply_filters( 'the_category', $category->name, '', '' ) ) . '</label>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the element output, if needed.
|
||||
*
|
||||
* @see Walker::end_el()
|
||||
*
|
||||
* @since 2.5.1
|
||||
* @since 5.9.0 Renamed `$category` to `$data_object` to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param WP_Term $data_object The current term object.
|
||||
* @param int $depth Depth of the term in reference to parents. Default 0.
|
||||
* @param array $args An array of arguments. See {@see wp_terms_checklist()}.
|
||||
*/
|
||||
public function end_el( &$output, $data_object, $depth = 0, $args = array() ) {
|
||||
$output .= "</li>\n";
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Taxonomy API: Walker_Category_Checklist class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core walker class to output an unordered list of category checkbox input elements.
|
||||
*
|
||||
* @since 2.5.1
|
||||
*
|
||||
* @see Walker
|
||||
* @see wp_category_checklist()
|
||||
* @see wp_terms_checklist()
|
||||
*/
|
||||
class Walker_Category_Checklist extends Walker {
|
||||
public $tree_type = 'category';
|
||||
public $db_fields = array(
|
||||
'parent' => 'parent',
|
||||
'id' => 'term_id',
|
||||
); // TODO: Decouple this.
|
||||
|
||||
/**
|
||||
* Starts the list before the elements are added.
|
||||
*
|
||||
* @see Walker:start_lvl()
|
||||
*
|
||||
* @since 2.5.1
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param int $depth Depth of category. Used for tab indentation.
|
||||
* @param array $args An array of arguments. See {@see wp_terms_checklist()}.
|
||||
*/
|
||||
public function start_lvl( &$output, $depth = 0, $args = array() ) {
|
||||
$indent = str_repeat( "\t", $depth );
|
||||
$output .= "$indent<ul class='children'>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the list of after the elements are added.
|
||||
*
|
||||
* @see Walker::end_lvl()
|
||||
*
|
||||
* @since 2.5.1
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param int $depth Depth of category. Used for tab indentation.
|
||||
* @param array $args An array of arguments. See {@see wp_terms_checklist()}.
|
||||
*/
|
||||
public function end_lvl( &$output, $depth = 0, $args = array() ) {
|
||||
$indent = str_repeat( "\t", $depth );
|
||||
$output .= "$indent</ul>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the element output.
|
||||
*
|
||||
* @see Walker::start_el()
|
||||
*
|
||||
* @since 2.5.1
|
||||
* @since 5.9.0 Renamed `$category` to `$data_object` and `$id` to `$current_object_id`
|
||||
* to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param WP_Term $data_object The current term object.
|
||||
* @param int $depth Depth of the term in reference to parents. Default 0.
|
||||
* @param array $args An array of arguments. See {@see wp_terms_checklist()}.
|
||||
* @param int $current_object_id Optional. ID of the current term. Default 0.
|
||||
*/
|
||||
public function start_el( &$output, $data_object, $depth = 0, $args = array(), $current_object_id = 0 ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$category = $data_object;
|
||||
|
||||
if ( empty( $args['taxonomy'] ) ) {
|
||||
$taxonomy = 'category';
|
||||
} else {
|
||||
$taxonomy = $args['taxonomy'];
|
||||
}
|
||||
|
||||
if ( 'category' === $taxonomy ) {
|
||||
$name = 'post_category';
|
||||
} else {
|
||||
$name = 'tax_input[' . $taxonomy . ']';
|
||||
}
|
||||
|
||||
$args['popular_cats'] = ! empty( $args['popular_cats'] ) ? array_map( 'intval', $args['popular_cats'] ) : array();
|
||||
|
||||
$class = in_array( $category->term_id, $args['popular_cats'], true ) ? ' class="popular-category"' : '';
|
||||
|
||||
$args['selected_cats'] = ! empty( $args['selected_cats'] ) ? array_map( 'intval', $args['selected_cats'] ) : array();
|
||||
|
||||
if ( ! empty( $args['list_only'] ) ) {
|
||||
$aria_checked = 'false';
|
||||
$inner_class = 'category';
|
||||
|
||||
if ( in_array( $category->term_id, $args['selected_cats'], true ) ) {
|
||||
$inner_class .= ' selected';
|
||||
$aria_checked = 'true';
|
||||
}
|
||||
|
||||
$output .= "\n" . '<li' . $class . '>' .
|
||||
'<div class="' . $inner_class . '" data-term-id=' . $category->term_id .
|
||||
' tabindex="0" role="checkbox" aria-checked="' . $aria_checked . '">' .
|
||||
/** This filter is documented in wp-includes/category-template.php */
|
||||
esc_html( apply_filters( 'the_category', $category->name, '', '' ) ) . '</div>';
|
||||
} else {
|
||||
$is_selected = in_array( $category->term_id, $args['selected_cats'], true );
|
||||
$is_disabled = ! empty( $args['disabled'] );
|
||||
|
||||
$output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" .
|
||||
'<label class="selectit"><input value="' . $category->term_id . '" type="checkbox" name="' . $name . '[]" id="in-' . $taxonomy . '-' . $category->term_id . '"' .
|
||||
checked( $is_selected, true, false ) .
|
||||
disabled( $is_disabled, true, false ) . ' /> ' .
|
||||
/** This filter is documented in wp-includes/category-template.php */
|
||||
esc_html( apply_filters( 'the_category', $category->name, '', '' ) ) . '</label>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the element output, if needed.
|
||||
*
|
||||
* @see Walker::end_el()
|
||||
*
|
||||
* @since 2.5.1
|
||||
* @since 5.9.0 Renamed `$category` to `$data_object` to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param WP_Term $data_object The current term object.
|
||||
* @param int $depth Depth of the term in reference to parents. Default 0.
|
||||
* @param array $args An array of arguments. See {@see wp_terms_checklist()}.
|
||||
*/
|
||||
public function end_el( &$output, $data_object, $depth = 0, $args = array() ) {
|
||||
$output .= "</li>\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,126 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* Navigation Menu API: Walker_Nav_Menu_Checklist class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create HTML list of nav menu input items.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @uses Walker_Nav_Menu
|
||||
*/
|
||||
class Walker_Nav_Menu_Checklist extends Walker_Nav_Menu {
|
||||
/**
|
||||
* @param array|false $fields Database fields to use.
|
||||
*/
|
||||
public function __construct( $fields = false ) {
|
||||
if ( $fields ) {
|
||||
$this->db_fields = $fields;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the list before the elements are added.
|
||||
*
|
||||
* @see Walker_Nav_Menu::start_lvl()
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param int $depth Depth of page. Used for padding.
|
||||
* @param stdClass $args Not used.
|
||||
*/
|
||||
public function start_lvl( &$output, $depth = 0, $args = null ) {
|
||||
$indent = str_repeat( "\t", $depth );
|
||||
$output .= "\n$indent<ul class='children'>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the list of after the elements are added.
|
||||
*
|
||||
* @see Walker_Nav_Menu::end_lvl()
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param int $depth Depth of page. Used for padding.
|
||||
* @param stdClass $args Not used.
|
||||
*/
|
||||
public function end_lvl( &$output, $depth = 0, $args = null ) {
|
||||
$indent = str_repeat( "\t", $depth );
|
||||
$output .= "\n$indent</ul>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the element output.
|
||||
*
|
||||
* @see Walker_Nav_Menu::start_el()
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 5.9.0 Renamed `$item` to `$data_object` and `$id` to `$current_object_id`
|
||||
* to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @global int $_nav_menu_placeholder
|
||||
* @global int|string $nav_menu_selected_id
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param WP_Post $data_object Menu item data object.
|
||||
* @param int $depth Depth of menu item. Used for padding.
|
||||
* @param stdClass $args Not used.
|
||||
* @param int $current_object_id Optional. ID of the current menu item. Default 0.
|
||||
*/
|
||||
public function start_el( &$output, $data_object, $depth = 0, $args = null, $current_object_id = 0 ) {
|
||||
global $_nav_menu_placeholder, $nav_menu_selected_id;
|
||||
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$menu_item = $data_object;
|
||||
|
||||
$_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? (int) $_nav_menu_placeholder - 1 : -1;
|
||||
$possible_object_id = isset( $menu_item->post_type ) && 'nav_menu_item' === $menu_item->post_type ? $menu_item->object_id : $_nav_menu_placeholder;
|
||||
$possible_db_id = ( ! empty( $menu_item->ID ) ) && ( 0 < $possible_object_id ) ? (int) $menu_item->ID : 0;
|
||||
|
||||
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
|
||||
|
||||
$output .= $indent . '<li>';
|
||||
$output .= '<label class="menu-item-title">';
|
||||
$output .= '<input type="checkbox"' . wp_nav_menu_disabled_check( $nav_menu_selected_id, false ) . ' class="menu-item-checkbox';
|
||||
|
||||
if ( ! empty( $menu_item->front_or_home ) ) {
|
||||
$output .= ' add-to-top';
|
||||
}
|
||||
|
||||
$output .= '" name="menu-item[' . $possible_object_id . '][menu-item-object-id]" value="' . esc_attr( $menu_item->object_id ) . '" /> ';
|
||||
|
||||
if ( ! empty( $menu_item->label ) ) {
|
||||
$title = $menu_item->label;
|
||||
} elseif ( isset( $menu_item->post_type ) ) {
|
||||
/** This filter is documented in wp-includes/post-template.php */
|
||||
$title = apply_filters( 'the_title', $menu_item->post_title, $menu_item->ID );
|
||||
}
|
||||
|
||||
$output .= isset( $title ) ? esc_html( $title ) : esc_html( $menu_item->title );
|
||||
|
||||
if ( empty( $menu_item->label ) && isset( $menu_item->post_type ) && 'page' === $menu_item->post_type ) {
|
||||
// Append post states.
|
||||
$output .= _post_states( $menu_item, false );
|
||||
}
|
||||
|
||||
$output .= '</label>';
|
||||
|
||||
// Menu item hidden fields.
|
||||
$output .= '<input type="hidden" class="menu-item-db-id" name="menu-item[' . $possible_object_id . '][menu-item-db-id]" value="' . $possible_db_id . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-object" name="menu-item[' . $possible_object_id . '][menu-item-object]" value="' . esc_attr( $menu_item->object ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-parent-id" name="menu-item[' . $possible_object_id . '][menu-item-parent-id]" value="' . esc_attr( $menu_item->menu_item_parent ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-type" name="menu-item[' . $possible_object_id . '][menu-item-type]" value="' . esc_attr( $menu_item->type ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-title" name="menu-item[' . $possible_object_id . '][menu-item-title]" value="' . esc_attr( $menu_item->title ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-url" name="menu-item[' . $possible_object_id . '][menu-item-url]" value="' . esc_attr( $menu_item->url ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-target" name="menu-item[' . $possible_object_id . '][menu-item-target]" value="' . esc_attr( $menu_item->target ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-attr-title" name="menu-item[' . $possible_object_id . '][menu-item-attr-title]" value="' . esc_attr( $menu_item->attr_title ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-classes" name="menu-item[' . $possible_object_id . '][menu-item-classes]" value="' . esc_attr( implode( ' ', $menu_item->classes ) ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-xfn" name="menu-item[' . $possible_object_id . '][menu-item-xfn]" value="' . esc_attr( $menu_item->xfn ) . '" />';
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Navigation Menu API: Walker_Nav_Menu_Checklist class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create HTML list of nav menu input items.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @uses Walker_Nav_Menu
|
||||
*/
|
||||
class Walker_Nav_Menu_Checklist extends Walker_Nav_Menu {
|
||||
/**
|
||||
* @param array|false $fields Database fields to use.
|
||||
*/
|
||||
public function __construct( $fields = false ) {
|
||||
if ( $fields ) {
|
||||
$this->db_fields = $fields;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the list before the elements are added.
|
||||
*
|
||||
* @see Walker_Nav_Menu::start_lvl()
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param int $depth Depth of page. Used for padding.
|
||||
* @param stdClass $args Not used.
|
||||
*/
|
||||
public function start_lvl( &$output, $depth = 0, $args = null ) {
|
||||
$indent = str_repeat( "\t", $depth );
|
||||
$output .= "\n$indent<ul class='children'>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the list of after the elements are added.
|
||||
*
|
||||
* @see Walker_Nav_Menu::end_lvl()
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param int $depth Depth of page. Used for padding.
|
||||
* @param stdClass $args Not used.
|
||||
*/
|
||||
public function end_lvl( &$output, $depth = 0, $args = null ) {
|
||||
$indent = str_repeat( "\t", $depth );
|
||||
$output .= "\n$indent</ul>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the element output.
|
||||
*
|
||||
* @see Walker_Nav_Menu::start_el()
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 5.9.0 Renamed `$item` to `$data_object` and `$id` to `$current_object_id`
|
||||
* to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @global int $_nav_menu_placeholder
|
||||
* @global int|string $nav_menu_selected_id
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param WP_Post $data_object Menu item data object.
|
||||
* @param int $depth Depth of menu item. Used for padding.
|
||||
* @param stdClass $args Not used.
|
||||
* @param int $current_object_id Optional. ID of the current menu item. Default 0.
|
||||
*/
|
||||
public function start_el( &$output, $data_object, $depth = 0, $args = null, $current_object_id = 0 ) {
|
||||
global $_nav_menu_placeholder, $nav_menu_selected_id;
|
||||
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$menu_item = $data_object;
|
||||
|
||||
$_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? (int) $_nav_menu_placeholder - 1 : -1;
|
||||
$possible_object_id = isset( $menu_item->post_type ) && 'nav_menu_item' === $menu_item->post_type ? $menu_item->object_id : $_nav_menu_placeholder;
|
||||
$possible_db_id = ( ! empty( $menu_item->ID ) ) && ( 0 < $possible_object_id ) ? (int) $menu_item->ID : 0;
|
||||
|
||||
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
|
||||
|
||||
$output .= $indent . '<li>';
|
||||
$output .= '<label class="menu-item-title">';
|
||||
$output .= '<input type="checkbox"' . wp_nav_menu_disabled_check( $nav_menu_selected_id, false ) . ' class="menu-item-checkbox';
|
||||
|
||||
if ( ! empty( $menu_item->front_or_home ) ) {
|
||||
$output .= ' add-to-top';
|
||||
}
|
||||
|
||||
$output .= '" name="menu-item[' . $possible_object_id . '][menu-item-object-id]" value="' . esc_attr( $menu_item->object_id ) . '" /> ';
|
||||
|
||||
if ( ! empty( $menu_item->label ) ) {
|
||||
$title = $menu_item->label;
|
||||
} elseif ( isset( $menu_item->post_type ) ) {
|
||||
/** This filter is documented in wp-includes/post-template.php */
|
||||
$title = apply_filters( 'the_title', $menu_item->post_title, $menu_item->ID );
|
||||
}
|
||||
|
||||
$output .= isset( $title ) ? esc_html( $title ) : esc_html( $menu_item->title );
|
||||
|
||||
if ( empty( $menu_item->label ) && isset( $menu_item->post_type ) && 'page' === $menu_item->post_type ) {
|
||||
// Append post states.
|
||||
$output .= _post_states( $menu_item, false );
|
||||
}
|
||||
|
||||
$output .= '</label>';
|
||||
|
||||
// Menu item hidden fields.
|
||||
$output .= '<input type="hidden" class="menu-item-db-id" name="menu-item[' . $possible_object_id . '][menu-item-db-id]" value="' . $possible_db_id . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-object" name="menu-item[' . $possible_object_id . '][menu-item-object]" value="' . esc_attr( $menu_item->object ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-parent-id" name="menu-item[' . $possible_object_id . '][menu-item-parent-id]" value="' . esc_attr( $menu_item->menu_item_parent ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-type" name="menu-item[' . $possible_object_id . '][menu-item-type]" value="' . esc_attr( $menu_item->type ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-title" name="menu-item[' . $possible_object_id . '][menu-item-title]" value="' . esc_attr( $menu_item->title ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-url" name="menu-item[' . $possible_object_id . '][menu-item-url]" value="' . esc_attr( $menu_item->url ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-target" name="menu-item[' . $possible_object_id . '][menu-item-target]" value="' . esc_attr( $menu_item->target ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-attr-title" name="menu-item[' . $possible_object_id . '][menu-item-attr-title]" value="' . esc_attr( $menu_item->attr_title ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-classes" name="menu-item[' . $possible_object_id . '][menu-item-classes]" value="' . esc_attr( implode( ' ', $menu_item->classes ) ) . '" />';
|
||||
$output .= '<input type="hidden" class="menu-item-xfn" name="menu-item[' . $possible_object_id . '][menu-item-xfn]" value="' . esc_attr( $menu_item->xfn ) . '" />';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,323 +1,323 @@
|
||||
<?php
|
||||
/**
|
||||
* Navigation Menu API: Walker_Nav_Menu_Edit class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create HTML list of nav menu input items.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @see Walker_Nav_Menu
|
||||
*/
|
||||
class Walker_Nav_Menu_Edit extends Walker_Nav_Menu {
|
||||
/**
|
||||
* Starts the list before the elements are added.
|
||||
*
|
||||
* @see Walker_Nav_Menu::start_lvl()
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string $output Passed by reference.
|
||||
* @param int $depth Depth of menu item. Used for padding.
|
||||
* @param stdClass $args Not used.
|
||||
*/
|
||||
public function start_lvl( &$output, $depth = 0, $args = null ) {}
|
||||
|
||||
/**
|
||||
* Ends the list of after the elements are added.
|
||||
*
|
||||
* @see Walker_Nav_Menu::end_lvl()
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string $output Passed by reference.
|
||||
* @param int $depth Depth of menu item. Used for padding.
|
||||
* @param stdClass $args Not used.
|
||||
*/
|
||||
public function end_lvl( &$output, $depth = 0, $args = null ) {}
|
||||
|
||||
/**
|
||||
* Start the element output.
|
||||
*
|
||||
* @see Walker_Nav_Menu::start_el()
|
||||
* @since 3.0.0
|
||||
* @since 5.9.0 Renamed `$item` to `$data_object` and `$id` to `$current_object_id`
|
||||
* to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @global int $_wp_nav_menu_max_depth
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param WP_Post $data_object Menu item data object.
|
||||
* @param int $depth Depth of menu item. Used for padding.
|
||||
* @param stdClass $args Not used.
|
||||
* @param int $current_object_id Optional. ID of the current menu item. Default 0.
|
||||
*/
|
||||
public function start_el( &$output, $data_object, $depth = 0, $args = null, $current_object_id = 0 ) {
|
||||
global $_wp_nav_menu_max_depth;
|
||||
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$menu_item = $data_object;
|
||||
|
||||
$_wp_nav_menu_max_depth = $depth > $_wp_nav_menu_max_depth ? $depth : $_wp_nav_menu_max_depth;
|
||||
|
||||
ob_start();
|
||||
$item_id = esc_attr( $menu_item->ID );
|
||||
$removed_args = array(
|
||||
'action',
|
||||
'customlink-tab',
|
||||
'edit-menu-item',
|
||||
'menu-item',
|
||||
'page-tab',
|
||||
'_wpnonce',
|
||||
);
|
||||
|
||||
$original_title = false;
|
||||
|
||||
if ( 'taxonomy' === $menu_item->type ) {
|
||||
$original_object = get_term( (int) $menu_item->object_id, $menu_item->object );
|
||||
if ( $original_object && ! is_wp_error( $original_object ) ) {
|
||||
$original_title = $original_object->name;
|
||||
}
|
||||
} elseif ( 'post_type' === $menu_item->type ) {
|
||||
$original_object = get_post( $menu_item->object_id );
|
||||
if ( $original_object ) {
|
||||
$original_title = get_the_title( $original_object->ID );
|
||||
}
|
||||
} elseif ( 'post_type_archive' === $menu_item->type ) {
|
||||
$original_object = get_post_type_object( $menu_item->object );
|
||||
if ( $original_object ) {
|
||||
$original_title = $original_object->labels->archives;
|
||||
}
|
||||
}
|
||||
|
||||
$classes = array(
|
||||
'menu-item menu-item-depth-' . $depth,
|
||||
'menu-item-' . esc_attr( $menu_item->object ),
|
||||
'menu-item-edit-' . ( ( isset( $_GET['edit-menu-item'] ) && $item_id === $_GET['edit-menu-item'] ) ? 'active' : 'inactive' ),
|
||||
);
|
||||
|
||||
$title = $menu_item->title;
|
||||
|
||||
if ( ! empty( $menu_item->_invalid ) ) {
|
||||
$classes[] = 'menu-item-invalid';
|
||||
/* translators: %s: Title of an invalid menu item. */
|
||||
$title = sprintf( __( '%s (Invalid)' ), $menu_item->title );
|
||||
} elseif ( isset( $menu_item->post_status ) && 'draft' === $menu_item->post_status ) {
|
||||
$classes[] = 'pending';
|
||||
/* translators: %s: Title of a menu item in draft status. */
|
||||
$title = sprintf( __( '%s (Pending)' ), $menu_item->title );
|
||||
}
|
||||
|
||||
$title = ( ! isset( $menu_item->label ) || '' === $menu_item->label ) ? $title : $menu_item->label;
|
||||
|
||||
$submenu_text = '';
|
||||
if ( 0 === $depth ) {
|
||||
$submenu_text = 'style="display: none;"';
|
||||
}
|
||||
|
||||
?>
|
||||
<li id="menu-item-<?php echo $item_id; ?>" class="<?php echo implode( ' ', $classes ); ?>">
|
||||
<div class="menu-item-bar">
|
||||
<div class="menu-item-handle">
|
||||
<label class="item-title" for="menu-item-checkbox-<?php echo $item_id; ?>">
|
||||
<input id="menu-item-checkbox-<?php echo $item_id; ?>" type="checkbox" class="menu-item-checkbox" data-menu-item-id="<?php echo $item_id; ?>" disabled="disabled" />
|
||||
<span class="menu-item-title"><?php echo esc_html( $title ); ?></span>
|
||||
<span class="is-submenu" <?php echo $submenu_text; ?>><?php _e( 'sub item' ); ?></span>
|
||||
</label>
|
||||
<span class="item-controls">
|
||||
<span class="item-type"><?php echo esc_html( $menu_item->type_label ); ?></span>
|
||||
<span class="item-order hide-if-js">
|
||||
<?php
|
||||
printf(
|
||||
'<a href="%s" class="item-move-up" aria-label="%s">↑</a>',
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'move-up-menu-item',
|
||||
'menu-item' => $item_id,
|
||||
),
|
||||
remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) )
|
||||
),
|
||||
'move-menu_item'
|
||||
),
|
||||
esc_attr__( 'Move up' )
|
||||
);
|
||||
?>
|
||||
|
|
||||
<?php
|
||||
printf(
|
||||
'<a href="%s" class="item-move-down" aria-label="%s">↓</a>',
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'move-down-menu-item',
|
||||
'menu-item' => $item_id,
|
||||
),
|
||||
remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) )
|
||||
),
|
||||
'move-menu_item'
|
||||
),
|
||||
esc_attr__( 'Move down' )
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php
|
||||
if ( isset( $_GET['edit-menu-item'] ) && $item_id === $_GET['edit-menu-item'] ) {
|
||||
$edit_url = admin_url( 'nav-menus.php' );
|
||||
} else {
|
||||
$edit_url = add_query_arg(
|
||||
array(
|
||||
'edit-menu-item' => $item_id,
|
||||
),
|
||||
remove_query_arg( $removed_args, admin_url( 'nav-menus.php#menu-item-settings-' . $item_id ) )
|
||||
);
|
||||
}
|
||||
|
||||
printf(
|
||||
'<a class="item-edit" id="edit-%s" href="%s" aria-label="%s"><span class="screen-reader-text">%s</span></a>',
|
||||
$item_id,
|
||||
esc_url( $edit_url ),
|
||||
esc_attr__( 'Edit menu item' ),
|
||||
/* translators: Hidden accessibility text. */
|
||||
__( 'Edit' )
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="menu-item-settings wp-clearfix" id="menu-item-settings-<?php echo $item_id; ?>">
|
||||
<?php if ( 'custom' === $menu_item->type ) : ?>
|
||||
<p class="field-url description description-wide">
|
||||
<label for="edit-menu-item-url-<?php echo $item_id; ?>">
|
||||
<?php _e( 'URL' ); ?><br />
|
||||
<input type="text" id="edit-menu-item-url-<?php echo $item_id; ?>" class="widefat code edit-menu-item-url" name="menu-item-url[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->url ); ?>" />
|
||||
</label>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<p class="description description-wide">
|
||||
<label for="edit-menu-item-title-<?php echo $item_id; ?>">
|
||||
<?php _e( 'Navigation Label' ); ?><br />
|
||||
<input type="text" id="edit-menu-item-title-<?php echo $item_id; ?>" class="widefat edit-menu-item-title" name="menu-item-title[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->title ); ?>" />
|
||||
</label>
|
||||
</p>
|
||||
<p class="field-title-attribute field-attr-title description description-wide">
|
||||
<label for="edit-menu-item-attr-title-<?php echo $item_id; ?>">
|
||||
<?php _e( 'Title Attribute' ); ?><br />
|
||||
<input type="text" id="edit-menu-item-attr-title-<?php echo $item_id; ?>" class="widefat edit-menu-item-attr-title" name="menu-item-attr-title[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->post_excerpt ); ?>" />
|
||||
</label>
|
||||
</p>
|
||||
<p class="field-link-target description">
|
||||
<label for="edit-menu-item-target-<?php echo $item_id; ?>">
|
||||
<input type="checkbox" id="edit-menu-item-target-<?php echo $item_id; ?>" value="_blank" name="menu-item-target[<?php echo $item_id; ?>]"<?php checked( $menu_item->target, '_blank' ); ?> />
|
||||
<?php _e( 'Open link in a new tab' ); ?>
|
||||
</label>
|
||||
</p>
|
||||
<p class="field-css-classes description description-thin">
|
||||
<label for="edit-menu-item-classes-<?php echo $item_id; ?>">
|
||||
<?php _e( 'CSS Classes (optional)' ); ?><br />
|
||||
<input type="text" id="edit-menu-item-classes-<?php echo $item_id; ?>" class="widefat code edit-menu-item-classes" name="menu-item-classes[<?php echo $item_id; ?>]" value="<?php echo esc_attr( implode( ' ', $menu_item->classes ) ); ?>" />
|
||||
</label>
|
||||
</p>
|
||||
<p class="field-xfn description description-thin">
|
||||
<label for="edit-menu-item-xfn-<?php echo $item_id; ?>">
|
||||
<?php _e( 'Link Relationship (XFN)' ); ?><br />
|
||||
<input type="text" id="edit-menu-item-xfn-<?php echo $item_id; ?>" class="widefat code edit-menu-item-xfn" name="menu-item-xfn[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->xfn ); ?>" />
|
||||
</label>
|
||||
</p>
|
||||
<p class="field-description description description-wide">
|
||||
<label for="edit-menu-item-description-<?php echo $item_id; ?>">
|
||||
<?php _e( 'Description' ); ?><br />
|
||||
<textarea id="edit-menu-item-description-<?php echo $item_id; ?>" class="widefat edit-menu-item-description" rows="3" cols="20" name="menu-item-description[<?php echo $item_id; ?>]"><?php echo esc_html( $menu_item->description ); // textarea_escaped ?></textarea>
|
||||
<span class="description"><?php _e( 'The description will be displayed in the menu if the active theme supports it.' ); ?></span>
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Fires just before the move buttons of a nav menu item in the menu editor.
|
||||
*
|
||||
* @since 5.4.0
|
||||
*
|
||||
* @param string $item_id Menu item ID as a numeric string.
|
||||
* @param WP_Post $menu_item Menu item data object.
|
||||
* @param int $depth Depth of menu item. Used for padding.
|
||||
* @param stdClass|null $args An object of menu item arguments.
|
||||
* @param int $current_object_id Nav menu ID.
|
||||
*/
|
||||
do_action( 'wp_nav_menu_item_custom_fields', $item_id, $menu_item, $depth, $args, $current_object_id );
|
||||
?>
|
||||
|
||||
<fieldset class="field-move hide-if-no-js description description-wide">
|
||||
<span class="field-move-visual-label" aria-hidden="true"><?php _e( 'Move' ); ?></span>
|
||||
<button type="button" class="button-link menus-move menus-move-up" data-dir="up"><?php _e( 'Up one' ); ?></button>
|
||||
<button type="button" class="button-link menus-move menus-move-down" data-dir="down"><?php _e( 'Down one' ); ?></button>
|
||||
<button type="button" class="button-link menus-move menus-move-left" data-dir="left"></button>
|
||||
<button type="button" class="button-link menus-move menus-move-right" data-dir="right"></button>
|
||||
<button type="button" class="button-link menus-move menus-move-top" data-dir="top"><?php _e( 'To the top' ); ?></button>
|
||||
</fieldset>
|
||||
|
||||
<div class="menu-item-actions description-wide submitbox">
|
||||
<?php if ( 'custom' !== $menu_item->type && false !== $original_title ) : ?>
|
||||
<p class="link-to-original">
|
||||
<?php
|
||||
/* translators: %s: Link to menu item's original object. */
|
||||
printf( __( 'Original: %s' ), '<a href="' . esc_url( $menu_item->url ) . '">' . esc_html( $original_title ) . '</a>' );
|
||||
?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
printf(
|
||||
'<a class="item-delete submitdelete deletion" id="delete-%s" href="%s">%s</a>',
|
||||
$item_id,
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'delete-menu-item',
|
||||
'menu-item' => $item_id,
|
||||
),
|
||||
admin_url( 'nav-menus.php' )
|
||||
),
|
||||
'delete-menu_item_' . $item_id
|
||||
),
|
||||
__( 'Remove' )
|
||||
);
|
||||
?>
|
||||
<span class="meta-sep hide-if-no-js"> | </span>
|
||||
<?php
|
||||
printf(
|
||||
'<a class="item-cancel submitcancel hide-if-no-js" id="cancel-%s" href="%s#menu-item-settings-%s">%s</a>',
|
||||
$item_id,
|
||||
esc_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'edit-menu-item' => $item_id,
|
||||
'cancel' => time(),
|
||||
),
|
||||
admin_url( 'nav-menus.php' )
|
||||
)
|
||||
),
|
||||
$item_id,
|
||||
__( 'Cancel' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<input class="menu-item-data-db-id" type="hidden" name="menu-item-db-id[<?php echo $item_id; ?>]" value="<?php echo $item_id; ?>" />
|
||||
<input class="menu-item-data-object-id" type="hidden" name="menu-item-object-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->object_id ); ?>" />
|
||||
<input class="menu-item-data-object" type="hidden" name="menu-item-object[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->object ); ?>" />
|
||||
<input class="menu-item-data-parent-id" type="hidden" name="menu-item-parent-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->menu_item_parent ); ?>" />
|
||||
<input class="menu-item-data-position" type="hidden" name="menu-item-position[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->menu_order ); ?>" />
|
||||
<input class="menu-item-data-type" type="hidden" name="menu-item-type[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->type ); ?>" />
|
||||
</div><!-- .menu-item-settings-->
|
||||
<ul class="menu-item-transport"></ul>
|
||||
<?php
|
||||
$output .= ob_get_clean();
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Navigation Menu API: Walker_Nav_Menu_Edit class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create HTML list of nav menu input items.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @see Walker_Nav_Menu
|
||||
*/
|
||||
class Walker_Nav_Menu_Edit extends Walker_Nav_Menu {
|
||||
/**
|
||||
* Starts the list before the elements are added.
|
||||
*
|
||||
* @see Walker_Nav_Menu::start_lvl()
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string $output Passed by reference.
|
||||
* @param int $depth Depth of menu item. Used for padding.
|
||||
* @param stdClass $args Not used.
|
||||
*/
|
||||
public function start_lvl( &$output, $depth = 0, $args = null ) {}
|
||||
|
||||
/**
|
||||
* Ends the list of after the elements are added.
|
||||
*
|
||||
* @see Walker_Nav_Menu::end_lvl()
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string $output Passed by reference.
|
||||
* @param int $depth Depth of menu item. Used for padding.
|
||||
* @param stdClass $args Not used.
|
||||
*/
|
||||
public function end_lvl( &$output, $depth = 0, $args = null ) {}
|
||||
|
||||
/**
|
||||
* Start the element output.
|
||||
*
|
||||
* @see Walker_Nav_Menu::start_el()
|
||||
* @since 3.0.0
|
||||
* @since 5.9.0 Renamed `$item` to `$data_object` and `$id` to `$current_object_id`
|
||||
* to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @global int $_wp_nav_menu_max_depth
|
||||
*
|
||||
* @param string $output Used to append additional content (passed by reference).
|
||||
* @param WP_Post $data_object Menu item data object.
|
||||
* @param int $depth Depth of menu item. Used for padding.
|
||||
* @param stdClass $args Not used.
|
||||
* @param int $current_object_id Optional. ID of the current menu item. Default 0.
|
||||
*/
|
||||
public function start_el( &$output, $data_object, $depth = 0, $args = null, $current_object_id = 0 ) {
|
||||
global $_wp_nav_menu_max_depth;
|
||||
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$menu_item = $data_object;
|
||||
|
||||
$_wp_nav_menu_max_depth = $depth > $_wp_nav_menu_max_depth ? $depth : $_wp_nav_menu_max_depth;
|
||||
|
||||
ob_start();
|
||||
$item_id = esc_attr( $menu_item->ID );
|
||||
$removed_args = array(
|
||||
'action',
|
||||
'customlink-tab',
|
||||
'edit-menu-item',
|
||||
'menu-item',
|
||||
'page-tab',
|
||||
'_wpnonce',
|
||||
);
|
||||
|
||||
$original_title = false;
|
||||
|
||||
if ( 'taxonomy' === $menu_item->type ) {
|
||||
$original_object = get_term( (int) $menu_item->object_id, $menu_item->object );
|
||||
if ( $original_object && ! is_wp_error( $original_object ) ) {
|
||||
$original_title = $original_object->name;
|
||||
}
|
||||
} elseif ( 'post_type' === $menu_item->type ) {
|
||||
$original_object = get_post( $menu_item->object_id );
|
||||
if ( $original_object ) {
|
||||
$original_title = get_the_title( $original_object->ID );
|
||||
}
|
||||
} elseif ( 'post_type_archive' === $menu_item->type ) {
|
||||
$original_object = get_post_type_object( $menu_item->object );
|
||||
if ( $original_object ) {
|
||||
$original_title = $original_object->labels->archives;
|
||||
}
|
||||
}
|
||||
|
||||
$classes = array(
|
||||
'menu-item menu-item-depth-' . $depth,
|
||||
'menu-item-' . esc_attr( $menu_item->object ),
|
||||
'menu-item-edit-' . ( ( isset( $_GET['edit-menu-item'] ) && $item_id === $_GET['edit-menu-item'] ) ? 'active' : 'inactive' ),
|
||||
);
|
||||
|
||||
$title = $menu_item->title;
|
||||
|
||||
if ( ! empty( $menu_item->_invalid ) ) {
|
||||
$classes[] = 'menu-item-invalid';
|
||||
/* translators: %s: Title of an invalid menu item. */
|
||||
$title = sprintf( __( '%s (Invalid)' ), $menu_item->title );
|
||||
} elseif ( isset( $menu_item->post_status ) && 'draft' === $menu_item->post_status ) {
|
||||
$classes[] = 'pending';
|
||||
/* translators: %s: Title of a menu item in draft status. */
|
||||
$title = sprintf( __( '%s (Pending)' ), $menu_item->title );
|
||||
}
|
||||
|
||||
$title = ( ! isset( $menu_item->label ) || '' === $menu_item->label ) ? $title : $menu_item->label;
|
||||
|
||||
$submenu_text = '';
|
||||
if ( 0 === $depth ) {
|
||||
$submenu_text = 'style="display: none;"';
|
||||
}
|
||||
|
||||
?>
|
||||
<li id="menu-item-<?php echo $item_id; ?>" class="<?php echo implode( ' ', $classes ); ?>">
|
||||
<div class="menu-item-bar">
|
||||
<div class="menu-item-handle">
|
||||
<label class="item-title" for="menu-item-checkbox-<?php echo $item_id; ?>">
|
||||
<input id="menu-item-checkbox-<?php echo $item_id; ?>" type="checkbox" class="menu-item-checkbox" data-menu-item-id="<?php echo $item_id; ?>" disabled="disabled" />
|
||||
<span class="menu-item-title"><?php echo esc_html( $title ); ?></span>
|
||||
<span class="is-submenu" <?php echo $submenu_text; ?>><?php _e( 'sub item' ); ?></span>
|
||||
</label>
|
||||
<span class="item-controls">
|
||||
<span class="item-type"><?php echo esc_html( $menu_item->type_label ); ?></span>
|
||||
<span class="item-order hide-if-js">
|
||||
<?php
|
||||
printf(
|
||||
'<a href="%s" class="item-move-up" aria-label="%s">↑</a>',
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'move-up-menu-item',
|
||||
'menu-item' => $item_id,
|
||||
),
|
||||
remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) )
|
||||
),
|
||||
'move-menu_item'
|
||||
),
|
||||
esc_attr__( 'Move up' )
|
||||
);
|
||||
?>
|
||||
|
|
||||
<?php
|
||||
printf(
|
||||
'<a href="%s" class="item-move-down" aria-label="%s">↓</a>',
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'move-down-menu-item',
|
||||
'menu-item' => $item_id,
|
||||
),
|
||||
remove_query_arg( $removed_args, admin_url( 'nav-menus.php' ) )
|
||||
),
|
||||
'move-menu_item'
|
||||
),
|
||||
esc_attr__( 'Move down' )
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php
|
||||
if ( isset( $_GET['edit-menu-item'] ) && $item_id === $_GET['edit-menu-item'] ) {
|
||||
$edit_url = admin_url( 'nav-menus.php' );
|
||||
} else {
|
||||
$edit_url = add_query_arg(
|
||||
array(
|
||||
'edit-menu-item' => $item_id,
|
||||
),
|
||||
remove_query_arg( $removed_args, admin_url( 'nav-menus.php#menu-item-settings-' . $item_id ) )
|
||||
);
|
||||
}
|
||||
|
||||
printf(
|
||||
'<a class="item-edit" id="edit-%s" href="%s" aria-label="%s"><span class="screen-reader-text">%s</span></a>',
|
||||
$item_id,
|
||||
esc_url( $edit_url ),
|
||||
esc_attr__( 'Edit menu item' ),
|
||||
/* translators: Hidden accessibility text. */
|
||||
__( 'Edit' )
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="menu-item-settings wp-clearfix" id="menu-item-settings-<?php echo $item_id; ?>">
|
||||
<?php if ( 'custom' === $menu_item->type ) : ?>
|
||||
<p class="field-url description description-wide">
|
||||
<label for="edit-menu-item-url-<?php echo $item_id; ?>">
|
||||
<?php _e( 'URL' ); ?><br />
|
||||
<input type="text" id="edit-menu-item-url-<?php echo $item_id; ?>" class="widefat code edit-menu-item-url" name="menu-item-url[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->url ); ?>" />
|
||||
</label>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<p class="description description-wide">
|
||||
<label for="edit-menu-item-title-<?php echo $item_id; ?>">
|
||||
<?php _e( 'Navigation Label' ); ?><br />
|
||||
<input type="text" id="edit-menu-item-title-<?php echo $item_id; ?>" class="widefat edit-menu-item-title" name="menu-item-title[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->title ); ?>" />
|
||||
</label>
|
||||
</p>
|
||||
<p class="field-title-attribute field-attr-title description description-wide">
|
||||
<label for="edit-menu-item-attr-title-<?php echo $item_id; ?>">
|
||||
<?php _e( 'Title Attribute' ); ?><br />
|
||||
<input type="text" id="edit-menu-item-attr-title-<?php echo $item_id; ?>" class="widefat edit-menu-item-attr-title" name="menu-item-attr-title[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->post_excerpt ); ?>" />
|
||||
</label>
|
||||
</p>
|
||||
<p class="field-link-target description">
|
||||
<label for="edit-menu-item-target-<?php echo $item_id; ?>">
|
||||
<input type="checkbox" id="edit-menu-item-target-<?php echo $item_id; ?>" value="_blank" name="menu-item-target[<?php echo $item_id; ?>]"<?php checked( $menu_item->target, '_blank' ); ?> />
|
||||
<?php _e( 'Open link in a new tab' ); ?>
|
||||
</label>
|
||||
</p>
|
||||
<p class="field-css-classes description description-thin">
|
||||
<label for="edit-menu-item-classes-<?php echo $item_id; ?>">
|
||||
<?php _e( 'CSS Classes (optional)' ); ?><br />
|
||||
<input type="text" id="edit-menu-item-classes-<?php echo $item_id; ?>" class="widefat code edit-menu-item-classes" name="menu-item-classes[<?php echo $item_id; ?>]" value="<?php echo esc_attr( implode( ' ', $menu_item->classes ) ); ?>" />
|
||||
</label>
|
||||
</p>
|
||||
<p class="field-xfn description description-thin">
|
||||
<label for="edit-menu-item-xfn-<?php echo $item_id; ?>">
|
||||
<?php _e( 'Link Relationship (XFN)' ); ?><br />
|
||||
<input type="text" id="edit-menu-item-xfn-<?php echo $item_id; ?>" class="widefat code edit-menu-item-xfn" name="menu-item-xfn[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->xfn ); ?>" />
|
||||
</label>
|
||||
</p>
|
||||
<p class="field-description description description-wide">
|
||||
<label for="edit-menu-item-description-<?php echo $item_id; ?>">
|
||||
<?php _e( 'Description' ); ?><br />
|
||||
<textarea id="edit-menu-item-description-<?php echo $item_id; ?>" class="widefat edit-menu-item-description" rows="3" cols="20" name="menu-item-description[<?php echo $item_id; ?>]"><?php echo esc_html( $menu_item->description ); // textarea_escaped ?></textarea>
|
||||
<span class="description"><?php _e( 'The description will be displayed in the menu if the active theme supports it.' ); ?></span>
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<?php
|
||||
/**
|
||||
* Fires just before the move buttons of a nav menu item in the menu editor.
|
||||
*
|
||||
* @since 5.4.0
|
||||
*
|
||||
* @param string $item_id Menu item ID as a numeric string.
|
||||
* @param WP_Post $menu_item Menu item data object.
|
||||
* @param int $depth Depth of menu item. Used for padding.
|
||||
* @param stdClass|null $args An object of menu item arguments.
|
||||
* @param int $current_object_id Nav menu ID.
|
||||
*/
|
||||
do_action( 'wp_nav_menu_item_custom_fields', $item_id, $menu_item, $depth, $args, $current_object_id );
|
||||
?>
|
||||
|
||||
<fieldset class="field-move hide-if-no-js description description-wide">
|
||||
<span class="field-move-visual-label" aria-hidden="true"><?php _e( 'Move' ); ?></span>
|
||||
<button type="button" class="button-link menus-move menus-move-up" data-dir="up"><?php _e( 'Up one' ); ?></button>
|
||||
<button type="button" class="button-link menus-move menus-move-down" data-dir="down"><?php _e( 'Down one' ); ?></button>
|
||||
<button type="button" class="button-link menus-move menus-move-left" data-dir="left"></button>
|
||||
<button type="button" class="button-link menus-move menus-move-right" data-dir="right"></button>
|
||||
<button type="button" class="button-link menus-move menus-move-top" data-dir="top"><?php _e( 'To the top' ); ?></button>
|
||||
</fieldset>
|
||||
|
||||
<div class="menu-item-actions description-wide submitbox">
|
||||
<?php if ( 'custom' !== $menu_item->type && false !== $original_title ) : ?>
|
||||
<p class="link-to-original">
|
||||
<?php
|
||||
/* translators: %s: Link to menu item's original object. */
|
||||
printf( __( 'Original: %s' ), '<a href="' . esc_url( $menu_item->url ) . '">' . esc_html( $original_title ) . '</a>' );
|
||||
?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
printf(
|
||||
'<a class="item-delete submitdelete deletion" id="delete-%s" href="%s">%s</a>',
|
||||
$item_id,
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'delete-menu-item',
|
||||
'menu-item' => $item_id,
|
||||
),
|
||||
admin_url( 'nav-menus.php' )
|
||||
),
|
||||
'delete-menu_item_' . $item_id
|
||||
),
|
||||
__( 'Remove' )
|
||||
);
|
||||
?>
|
||||
<span class="meta-sep hide-if-no-js"> | </span>
|
||||
<?php
|
||||
printf(
|
||||
'<a class="item-cancel submitcancel hide-if-no-js" id="cancel-%s" href="%s#menu-item-settings-%s">%s</a>',
|
||||
$item_id,
|
||||
esc_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'edit-menu-item' => $item_id,
|
||||
'cancel' => time(),
|
||||
),
|
||||
admin_url( 'nav-menus.php' )
|
||||
)
|
||||
),
|
||||
$item_id,
|
||||
__( 'Cancel' )
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<input class="menu-item-data-db-id" type="hidden" name="menu-item-db-id[<?php echo $item_id; ?>]" value="<?php echo $item_id; ?>" />
|
||||
<input class="menu-item-data-object-id" type="hidden" name="menu-item-object-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->object_id ); ?>" />
|
||||
<input class="menu-item-data-object" type="hidden" name="menu-item-object[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->object ); ?>" />
|
||||
<input class="menu-item-data-parent-id" type="hidden" name="menu-item-parent-id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->menu_item_parent ); ?>" />
|
||||
<input class="menu-item-data-position" type="hidden" name="menu-item-position[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->menu_order ); ?>" />
|
||||
<input class="menu-item-data-type" type="hidden" name="menu-item-type[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item->type ); ?>" />
|
||||
</div><!-- .menu-item-settings-->
|
||||
<ul class="menu-item-transport"></ul>
|
||||
<?php
|
||||
$output .= ob_get_clean();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,159 +1,159 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: WP_Ajax_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Upgrader Skin for Ajax WordPress upgrades.
|
||||
*
|
||||
* This skin is designed to be used for Ajax updates.
|
||||
*
|
||||
* @since 4.6.0
|
||||
*
|
||||
* @see Automatic_Upgrader_Skin
|
||||
*/
|
||||
class WP_Ajax_Upgrader_Skin extends Automatic_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Plugin info.
|
||||
*
|
||||
* The Plugin_Upgrader::bulk_upgrade() method will fill this in
|
||||
* with info retrieved from the get_plugin_data() function.
|
||||
*
|
||||
* @var array Plugin data. Values will be empty if not supplied by the plugin.
|
||||
*/
|
||||
public $plugin_info = array();
|
||||
|
||||
/**
|
||||
* Theme info.
|
||||
*
|
||||
* The Theme_Upgrader::bulk_upgrade() method will fill this in
|
||||
* with info retrieved from the Theme_Upgrader::theme_info() method,
|
||||
* which in turn calls the wp_get_theme() function.
|
||||
*
|
||||
* @var WP_Theme|false The theme's info object, or false.
|
||||
*/
|
||||
public $theme_info = false;
|
||||
|
||||
/**
|
||||
* Holds the WP_Error object.
|
||||
*
|
||||
* @since 4.6.0
|
||||
*
|
||||
* @var null|WP_Error
|
||||
*/
|
||||
protected $errors = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Sets up the WordPress Ajax upgrader skin.
|
||||
*
|
||||
* @since 4.6.0
|
||||
*
|
||||
* @see WP_Upgrader_Skin::__construct()
|
||||
*
|
||||
* @param array $args Optional. The WordPress Ajax upgrader skin arguments to
|
||||
* override default options. See WP_Upgrader_Skin::__construct().
|
||||
* Default empty array.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
parent::__construct( $args );
|
||||
|
||||
$this->errors = new WP_Error();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of errors.
|
||||
*
|
||||
* @since 4.6.0
|
||||
*
|
||||
* @return WP_Error Errors during an upgrade.
|
||||
*/
|
||||
public function get_errors() {
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a string for error messages.
|
||||
*
|
||||
* @since 4.6.0
|
||||
*
|
||||
* @return string Error messages during an upgrade.
|
||||
*/
|
||||
public function get_error_messages() {
|
||||
$messages = array();
|
||||
|
||||
foreach ( $this->errors->get_error_codes() as $error_code ) {
|
||||
$error_data = $this->errors->get_error_data( $error_code );
|
||||
|
||||
if ( $error_data && is_string( $error_data ) ) {
|
||||
$messages[] = $this->errors->get_error_message( $error_code ) . ' ' . esc_html( strip_tags( $error_data ) );
|
||||
} else {
|
||||
$messages[] = $this->errors->get_error_message( $error_code );
|
||||
}
|
||||
}
|
||||
|
||||
return implode( ', ', $messages );
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores an error message about the upgrade.
|
||||
*
|
||||
* @since 4.6.0
|
||||
* @since 5.3.0 Formalized the existing `...$args` parameter by adding it
|
||||
* to the function signature.
|
||||
*
|
||||
* @param string|WP_Error $errors Errors.
|
||||
* @param mixed ...$args Optional text replacements.
|
||||
*/
|
||||
public function error( $errors, ...$args ) {
|
||||
if ( is_string( $errors ) ) {
|
||||
$string = $errors;
|
||||
if ( ! empty( $this->upgrader->strings[ $string ] ) ) {
|
||||
$string = $this->upgrader->strings[ $string ];
|
||||
}
|
||||
|
||||
if ( str_contains( $string, '%' ) ) {
|
||||
if ( ! empty( $args ) ) {
|
||||
$string = vsprintf( $string, $args );
|
||||
}
|
||||
}
|
||||
|
||||
// Count existing errors to generate a unique error code.
|
||||
$errors_count = count( $this->errors->get_error_codes() );
|
||||
$this->errors->add( 'unknown_upgrade_error_' . ( $errors_count + 1 ), $string );
|
||||
} elseif ( is_wp_error( $errors ) ) {
|
||||
foreach ( $errors->get_error_codes() as $error_code ) {
|
||||
$this->errors->add( $error_code, $errors->get_error_message( $error_code ), $errors->get_error_data( $error_code ) );
|
||||
}
|
||||
}
|
||||
|
||||
parent::error( $errors, ...$args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a message about the upgrade.
|
||||
*
|
||||
* @since 4.6.0
|
||||
* @since 5.3.0 Formalized the existing `...$args` parameter by adding it
|
||||
* to the function signature.
|
||||
* @since 5.9.0 Renamed `$data` to `$feedback` for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string|array|WP_Error $feedback Message data.
|
||||
* @param mixed ...$args Optional text replacements.
|
||||
*/
|
||||
public function feedback( $feedback, ...$args ) {
|
||||
if ( is_wp_error( $feedback ) ) {
|
||||
foreach ( $feedback->get_error_codes() as $error_code ) {
|
||||
$this->errors->add( $error_code, $feedback->get_error_message( $error_code ), $feedback->get_error_data( $error_code ) );
|
||||
}
|
||||
}
|
||||
|
||||
parent::feedback( $feedback, ...$args );
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: WP_Ajax_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Upgrader Skin for Ajax WordPress upgrades.
|
||||
*
|
||||
* This skin is designed to be used for Ajax updates.
|
||||
*
|
||||
* @since 4.6.0
|
||||
*
|
||||
* @see Automatic_Upgrader_Skin
|
||||
*/
|
||||
class WP_Ajax_Upgrader_Skin extends Automatic_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Plugin info.
|
||||
*
|
||||
* The Plugin_Upgrader::bulk_upgrade() method will fill this in
|
||||
* with info retrieved from the get_plugin_data() function.
|
||||
*
|
||||
* @var array Plugin data. Values will be empty if not supplied by the plugin.
|
||||
*/
|
||||
public $plugin_info = array();
|
||||
|
||||
/**
|
||||
* Theme info.
|
||||
*
|
||||
* The Theme_Upgrader::bulk_upgrade() method will fill this in
|
||||
* with info retrieved from the Theme_Upgrader::theme_info() method,
|
||||
* which in turn calls the wp_get_theme() function.
|
||||
*
|
||||
* @var WP_Theme|false The theme's info object, or false.
|
||||
*/
|
||||
public $theme_info = false;
|
||||
|
||||
/**
|
||||
* Holds the WP_Error object.
|
||||
*
|
||||
* @since 4.6.0
|
||||
*
|
||||
* @var null|WP_Error
|
||||
*/
|
||||
protected $errors = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Sets up the WordPress Ajax upgrader skin.
|
||||
*
|
||||
* @since 4.6.0
|
||||
*
|
||||
* @see WP_Upgrader_Skin::__construct()
|
||||
*
|
||||
* @param array $args Optional. The WordPress Ajax upgrader skin arguments to
|
||||
* override default options. See WP_Upgrader_Skin::__construct().
|
||||
* Default empty array.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
parent::__construct( $args );
|
||||
|
||||
$this->errors = new WP_Error();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of errors.
|
||||
*
|
||||
* @since 4.6.0
|
||||
*
|
||||
* @return WP_Error Errors during an upgrade.
|
||||
*/
|
||||
public function get_errors() {
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a string for error messages.
|
||||
*
|
||||
* @since 4.6.0
|
||||
*
|
||||
* @return string Error messages during an upgrade.
|
||||
*/
|
||||
public function get_error_messages() {
|
||||
$messages = array();
|
||||
|
||||
foreach ( $this->errors->get_error_codes() as $error_code ) {
|
||||
$error_data = $this->errors->get_error_data( $error_code );
|
||||
|
||||
if ( $error_data && is_string( $error_data ) ) {
|
||||
$messages[] = $this->errors->get_error_message( $error_code ) . ' ' . esc_html( strip_tags( $error_data ) );
|
||||
} else {
|
||||
$messages[] = $this->errors->get_error_message( $error_code );
|
||||
}
|
||||
}
|
||||
|
||||
return implode( ', ', $messages );
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores an error message about the upgrade.
|
||||
*
|
||||
* @since 4.6.0
|
||||
* @since 5.3.0 Formalized the existing `...$args` parameter by adding it
|
||||
* to the function signature.
|
||||
*
|
||||
* @param string|WP_Error $errors Errors.
|
||||
* @param mixed ...$args Optional text replacements.
|
||||
*/
|
||||
public function error( $errors, ...$args ) {
|
||||
if ( is_string( $errors ) ) {
|
||||
$string = $errors;
|
||||
if ( ! empty( $this->upgrader->strings[ $string ] ) ) {
|
||||
$string = $this->upgrader->strings[ $string ];
|
||||
}
|
||||
|
||||
if ( str_contains( $string, '%' ) ) {
|
||||
if ( ! empty( $args ) ) {
|
||||
$string = vsprintf( $string, $args );
|
||||
}
|
||||
}
|
||||
|
||||
// Count existing errors to generate a unique error code.
|
||||
$errors_count = count( $this->errors->get_error_codes() );
|
||||
$this->errors->add( 'unknown_upgrade_error_' . ( $errors_count + 1 ), $string );
|
||||
} elseif ( is_wp_error( $errors ) ) {
|
||||
foreach ( $errors->get_error_codes() as $error_code ) {
|
||||
$this->errors->add( $error_code, $errors->get_error_message( $error_code ), $errors->get_error_data( $error_code ) );
|
||||
}
|
||||
}
|
||||
|
||||
parent::error( $errors, ...$args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a message about the upgrade.
|
||||
*
|
||||
* @since 4.6.0
|
||||
* @since 5.3.0 Formalized the existing `...$args` parameter by adding it
|
||||
* to the function signature.
|
||||
* @since 5.9.0 Renamed `$data` to `$feedback` for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string|array|WP_Error $feedback Message data.
|
||||
* @param mixed ...$args Optional text replacements.
|
||||
*/
|
||||
public function feedback( $feedback, ...$args ) {
|
||||
if ( is_wp_error( $feedback ) ) {
|
||||
foreach ( $feedback->get_error_codes() as $error_code ) {
|
||||
$this->errors->add( $error_code, $feedback->get_error_message( $error_code ), $feedback->get_error_data( $error_code ) );
|
||||
}
|
||||
}
|
||||
|
||||
parent::feedback( $feedback, ...$args );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,267 +1,267 @@
|
||||
<?php
|
||||
/**
|
||||
* List Table API: WP_Application_Passwords_List_Table class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 5.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for displaying the list of application password items.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @see WP_List_Table
|
||||
*/
|
||||
class WP_Application_Passwords_List_Table extends WP_List_Table {
|
||||
|
||||
/**
|
||||
* Gets the list of columns.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @return string[] Array of column titles keyed by their column name.
|
||||
*/
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'name' => __( 'Name' ),
|
||||
'created' => __( 'Created' ),
|
||||
'last_used' => __( 'Last Used' ),
|
||||
'last_ip' => __( 'Last IP' ),
|
||||
'revoke' => __( 'Revoke' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the list of items for displaying.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @global int $user_id User ID.
|
||||
*/
|
||||
public function prepare_items() {
|
||||
global $user_id;
|
||||
$this->items = array_reverse( WP_Application_Passwords::get_user_application_passwords( $user_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the name column output.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current application password item.
|
||||
*/
|
||||
public function column_name( $item ) {
|
||||
echo esc_html( $item['name'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the created column output.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current application password item.
|
||||
*/
|
||||
public function column_created( $item ) {
|
||||
if ( empty( $item['created'] ) ) {
|
||||
echo '—';
|
||||
} else {
|
||||
echo date_i18n( __( 'F j, Y' ), $item['created'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the last used column output.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current application password item.
|
||||
*/
|
||||
public function column_last_used( $item ) {
|
||||
if ( empty( $item['last_used'] ) ) {
|
||||
echo '—';
|
||||
} else {
|
||||
echo date_i18n( __( 'F j, Y' ), $item['last_used'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the last ip column output.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current application password item.
|
||||
*/
|
||||
public function column_last_ip( $item ) {
|
||||
if ( empty( $item['last_ip'] ) ) {
|
||||
echo '—';
|
||||
} else {
|
||||
echo $item['last_ip'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the revoke column output.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current application password item.
|
||||
*/
|
||||
public function column_revoke( $item ) {
|
||||
$name = 'revoke-application-password-' . $item['uuid'];
|
||||
printf(
|
||||
'<button type="button" name="%1$s" id="%1$s" class="button delete" aria-label="%2$s">%3$s</button>',
|
||||
esc_attr( $name ),
|
||||
/* translators: %s: the application password's given name. */
|
||||
esc_attr( sprintf( __( 'Revoke "%s"' ), $item['name'] ) ),
|
||||
__( 'Revoke' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates content for a single row of the table
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current item.
|
||||
* @param string $column_name The current column name.
|
||||
*/
|
||||
protected function column_default( $item, $column_name ) {
|
||||
/**
|
||||
* Fires for each custom column in the Application Passwords list table.
|
||||
*
|
||||
* Custom columns are registered using the {@see 'manage_application-passwords-user_columns'} filter.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param string $column_name Name of the custom column.
|
||||
* @param array $item The application password item.
|
||||
*/
|
||||
do_action( "manage_{$this->screen->id}_custom_column", $column_name, $item );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates custom table navigation to prevent conflicting nonces.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param string $which The location of the bulk actions: Either 'top' or 'bottom'.
|
||||
*/
|
||||
protected function display_tablenav( $which ) {
|
||||
?>
|
||||
<div class="tablenav <?php echo esc_attr( $which ); ?>">
|
||||
<?php if ( 'bottom' === $which ) : ?>
|
||||
<div class="alignright">
|
||||
<button type="button" name="revoke-all-application-passwords" id="revoke-all-application-passwords" class="button delete"><?php _e( 'Revoke all application passwords' ); ?></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="alignleft actions bulkactions">
|
||||
<?php $this->bulk_actions( $which ); ?>
|
||||
</div>
|
||||
<?php
|
||||
$this->extra_tablenav( $which );
|
||||
$this->pagination( $which );
|
||||
?>
|
||||
<br class="clear" />
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates content for a single row of the table.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current item.
|
||||
*/
|
||||
public function single_row( $item ) {
|
||||
echo '<tr data-uuid="' . esc_attr( $item['uuid'] ) . '">';
|
||||
$this->single_row_columns( $item );
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the default primary column.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @return string Name of the default primary column, in this case, 'name'.
|
||||
*/
|
||||
protected function get_default_primary_column_name() {
|
||||
return 'name';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the JavaScript template for the new row item.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*/
|
||||
public function print_js_template_row() {
|
||||
list( $columns, $hidden, , $primary ) = $this->get_column_info();
|
||||
|
||||
echo '<tr data-uuid="{{ data.uuid }}">';
|
||||
|
||||
foreach ( $columns as $column_name => $display_name ) {
|
||||
$is_primary = $primary === $column_name;
|
||||
$classes = "{$column_name} column-{$column_name}";
|
||||
|
||||
if ( $is_primary ) {
|
||||
$classes .= ' has-row-actions column-primary';
|
||||
}
|
||||
|
||||
if ( in_array( $column_name, $hidden, true ) ) {
|
||||
$classes .= ' hidden';
|
||||
}
|
||||
|
||||
printf( '<td class="%s" data-colname="%s">', esc_attr( $classes ), esc_attr( wp_strip_all_tags( $display_name ) ) );
|
||||
|
||||
switch ( $column_name ) {
|
||||
case 'name':
|
||||
echo '{{ data.name }}';
|
||||
break;
|
||||
case 'created':
|
||||
// JSON encoding automatically doubles backslashes to ensure they don't get lost when printing the inline JS.
|
||||
echo '<# print( wp.date.dateI18n( ' . wp_json_encode( __( 'F j, Y' ) ) . ', data.created ) ) #>';
|
||||
break;
|
||||
case 'last_used':
|
||||
echo '<# print( data.last_used !== null ? wp.date.dateI18n( ' . wp_json_encode( __( 'F j, Y' ) ) . ", data.last_used ) : '—' ) #>";
|
||||
break;
|
||||
case 'last_ip':
|
||||
echo "{{ data.last_ip || '—' }}";
|
||||
break;
|
||||
case 'revoke':
|
||||
printf(
|
||||
'<button type="button" class="button delete" aria-label="%1$s">%2$s</button>',
|
||||
/* translators: %s: the application password's given name. */
|
||||
esc_attr( sprintf( __( 'Revoke "%s"' ), '{{ data.name }}' ) ),
|
||||
esc_html__( 'Revoke' )
|
||||
);
|
||||
break;
|
||||
default:
|
||||
/**
|
||||
* Fires in the JavaScript row template for each custom column in the Application Passwords list table.
|
||||
*
|
||||
* Custom columns are registered using the {@see 'manage_application-passwords-user_columns'} filter.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param string $column_name Name of the custom column.
|
||||
*/
|
||||
do_action( "manage_{$this->screen->id}_custom_column_js_template", $column_name );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $is_primary ) {
|
||||
echo '<button type="button" class="toggle-row"><span class="screen-reader-text">' .
|
||||
/* translators: Hidden accessibility text. */
|
||||
__( 'Show more details' ) .
|
||||
'</span></button>';
|
||||
}
|
||||
|
||||
echo '</td>';
|
||||
}
|
||||
|
||||
echo '</tr>';
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* List Table API: WP_Application_Passwords_List_Table class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 5.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for displaying the list of application password items.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @see WP_List_Table
|
||||
*/
|
||||
class WP_Application_Passwords_List_Table extends WP_List_Table {
|
||||
|
||||
/**
|
||||
* Gets the list of columns.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @return string[] Array of column titles keyed by their column name.
|
||||
*/
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'name' => __( 'Name' ),
|
||||
'created' => __( 'Created' ),
|
||||
'last_used' => __( 'Last Used' ),
|
||||
'last_ip' => __( 'Last IP' ),
|
||||
'revoke' => __( 'Revoke' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the list of items for displaying.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @global int $user_id User ID.
|
||||
*/
|
||||
public function prepare_items() {
|
||||
global $user_id;
|
||||
$this->items = array_reverse( WP_Application_Passwords::get_user_application_passwords( $user_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the name column output.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current application password item.
|
||||
*/
|
||||
public function column_name( $item ) {
|
||||
echo esc_html( $item['name'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the created column output.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current application password item.
|
||||
*/
|
||||
public function column_created( $item ) {
|
||||
if ( empty( $item['created'] ) ) {
|
||||
echo '—';
|
||||
} else {
|
||||
echo date_i18n( __( 'F j, Y' ), $item['created'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the last used column output.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current application password item.
|
||||
*/
|
||||
public function column_last_used( $item ) {
|
||||
if ( empty( $item['last_used'] ) ) {
|
||||
echo '—';
|
||||
} else {
|
||||
echo date_i18n( __( 'F j, Y' ), $item['last_used'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the last ip column output.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current application password item.
|
||||
*/
|
||||
public function column_last_ip( $item ) {
|
||||
if ( empty( $item['last_ip'] ) ) {
|
||||
echo '—';
|
||||
} else {
|
||||
echo $item['last_ip'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the revoke column output.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current application password item.
|
||||
*/
|
||||
public function column_revoke( $item ) {
|
||||
$name = 'revoke-application-password-' . $item['uuid'];
|
||||
printf(
|
||||
'<button type="button" name="%1$s" id="%1$s" class="button delete" aria-label="%2$s">%3$s</button>',
|
||||
esc_attr( $name ),
|
||||
/* translators: %s: the application password's given name. */
|
||||
esc_attr( sprintf( __( 'Revoke "%s"' ), $item['name'] ) ),
|
||||
__( 'Revoke' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates content for a single row of the table
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current item.
|
||||
* @param string $column_name The current column name.
|
||||
*/
|
||||
protected function column_default( $item, $column_name ) {
|
||||
/**
|
||||
* Fires for each custom column in the Application Passwords list table.
|
||||
*
|
||||
* Custom columns are registered using the {@see 'manage_application-passwords-user_columns'} filter.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param string $column_name Name of the custom column.
|
||||
* @param array $item The application password item.
|
||||
*/
|
||||
do_action( "manage_{$this->screen->id}_custom_column", $column_name, $item );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates custom table navigation to prevent conflicting nonces.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param string $which The location of the bulk actions: Either 'top' or 'bottom'.
|
||||
*/
|
||||
protected function display_tablenav( $which ) {
|
||||
?>
|
||||
<div class="tablenav <?php echo esc_attr( $which ); ?>">
|
||||
<?php if ( 'bottom' === $which ) : ?>
|
||||
<div class="alignright">
|
||||
<button type="button" name="revoke-all-application-passwords" id="revoke-all-application-passwords" class="button delete"><?php _e( 'Revoke all application passwords' ); ?></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="alignleft actions bulkactions">
|
||||
<?php $this->bulk_actions( $which ); ?>
|
||||
</div>
|
||||
<?php
|
||||
$this->extra_tablenav( $which );
|
||||
$this->pagination( $which );
|
||||
?>
|
||||
<br class="clear" />
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates content for a single row of the table.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param array $item The current item.
|
||||
*/
|
||||
public function single_row( $item ) {
|
||||
echo '<tr data-uuid="' . esc_attr( $item['uuid'] ) . '">';
|
||||
$this->single_row_columns( $item );
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the default primary column.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @return string Name of the default primary column, in this case, 'name'.
|
||||
*/
|
||||
protected function get_default_primary_column_name() {
|
||||
return 'name';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the JavaScript template for the new row item.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*/
|
||||
public function print_js_template_row() {
|
||||
list( $columns, $hidden, , $primary ) = $this->get_column_info();
|
||||
|
||||
echo '<tr data-uuid="{{ data.uuid }}">';
|
||||
|
||||
foreach ( $columns as $column_name => $display_name ) {
|
||||
$is_primary = $primary === $column_name;
|
||||
$classes = "{$column_name} column-{$column_name}";
|
||||
|
||||
if ( $is_primary ) {
|
||||
$classes .= ' has-row-actions column-primary';
|
||||
}
|
||||
|
||||
if ( in_array( $column_name, $hidden, true ) ) {
|
||||
$classes .= ' hidden';
|
||||
}
|
||||
|
||||
printf( '<td class="%s" data-colname="%s">', esc_attr( $classes ), esc_attr( wp_strip_all_tags( $display_name ) ) );
|
||||
|
||||
switch ( $column_name ) {
|
||||
case 'name':
|
||||
echo '{{ data.name }}';
|
||||
break;
|
||||
case 'created':
|
||||
// JSON encoding automatically doubles backslashes to ensure they don't get lost when printing the inline JS.
|
||||
echo '<# print( wp.date.dateI18n( ' . wp_json_encode( __( 'F j, Y' ) ) . ', data.created ) ) #>';
|
||||
break;
|
||||
case 'last_used':
|
||||
echo '<# print( data.last_used !== null ? wp.date.dateI18n( ' . wp_json_encode( __( 'F j, Y' ) ) . ", data.last_used ) : '—' ) #>";
|
||||
break;
|
||||
case 'last_ip':
|
||||
echo "{{ data.last_ip || '—' }}";
|
||||
break;
|
||||
case 'revoke':
|
||||
printf(
|
||||
'<button type="button" class="button delete" aria-label="%1$s">%2$s</button>',
|
||||
/* translators: %s: the application password's given name. */
|
||||
esc_attr( sprintf( __( 'Revoke "%s"' ), '{{ data.name }}' ) ),
|
||||
esc_html__( 'Revoke' )
|
||||
);
|
||||
break;
|
||||
default:
|
||||
/**
|
||||
* Fires in the JavaScript row template for each custom column in the Application Passwords list table.
|
||||
*
|
||||
* Custom columns are registered using the {@see 'manage_application-passwords-user_columns'} filter.
|
||||
*
|
||||
* @since 5.6.0
|
||||
*
|
||||
* @param string $column_name Name of the custom column.
|
||||
*/
|
||||
do_action( "manage_{$this->screen->id}_custom_column_js_template", $column_name );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $is_primary ) {
|
||||
echo '<button type="button" class="toggle-row"><span class="screen-reader-text">' .
|
||||
/* translators: Hidden accessibility text. */
|
||||
__( 'Show more details' ) .
|
||||
'</span></button>';
|
||||
}
|
||||
|
||||
echo '</td>';
|
||||
}
|
||||
|
||||
echo '</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,327 +1,327 @@
|
||||
<?php
|
||||
/**
|
||||
* WP_Importer base class
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
class WP_Importer {
|
||||
/**
|
||||
* Class Constructor
|
||||
*/
|
||||
public function __construct() {}
|
||||
|
||||
/**
|
||||
* Returns array with imported permalinks from WordPress database.
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param string $importer_name
|
||||
* @param string $blog_id
|
||||
* @return array
|
||||
*/
|
||||
public function get_imported_posts( $importer_name, $blog_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$hashtable = array();
|
||||
|
||||
$limit = 100;
|
||||
$offset = 0;
|
||||
|
||||
// Grab all posts in chunks.
|
||||
do {
|
||||
$meta_key = $importer_name . '_' . $blog_id . '_permalink';
|
||||
$sql = $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = %s LIMIT %d,%d", $meta_key, $offset, $limit );
|
||||
$results = $wpdb->get_results( $sql );
|
||||
|
||||
// Increment offset.
|
||||
$offset = ( $limit + $offset );
|
||||
|
||||
if ( ! empty( $results ) ) {
|
||||
foreach ( $results as $r ) {
|
||||
// Set permalinks into array.
|
||||
$hashtable[ $r->meta_value ] = (int) $r->post_id;
|
||||
}
|
||||
}
|
||||
} while ( count( $results ) === $limit );
|
||||
|
||||
return $hashtable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns count of imported permalinks from WordPress database.
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param string $importer_name
|
||||
* @param string $blog_id
|
||||
* @return int
|
||||
*/
|
||||
public function count_imported_posts( $importer_name, $blog_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$count = 0;
|
||||
|
||||
// Get count of permalinks.
|
||||
$meta_key = $importer_name . '_' . $blog_id . '_permalink';
|
||||
$sql = $wpdb->prepare( "SELECT COUNT( post_id ) AS cnt FROM $wpdb->postmeta WHERE meta_key = %s", $meta_key );
|
||||
|
||||
$result = $wpdb->get_results( $sql );
|
||||
|
||||
if ( ! empty( $result ) ) {
|
||||
$count = (int) $result[0]->cnt;
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets array with imported comments from WordPress database.
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param string $blog_id
|
||||
* @return array
|
||||
*/
|
||||
public function get_imported_comments( $blog_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$hashtable = array();
|
||||
|
||||
$limit = 100;
|
||||
$offset = 0;
|
||||
|
||||
// Grab all comments in chunks.
|
||||
do {
|
||||
$sql = $wpdb->prepare( "SELECT comment_ID, comment_agent FROM $wpdb->comments LIMIT %d,%d", $offset, $limit );
|
||||
$results = $wpdb->get_results( $sql );
|
||||
|
||||
// Increment offset.
|
||||
$offset = ( $limit + $offset );
|
||||
|
||||
if ( ! empty( $results ) ) {
|
||||
foreach ( $results as $r ) {
|
||||
// Explode comment_agent key.
|
||||
list ( $comment_agent_blog_id, $source_comment_id ) = explode( '-', $r->comment_agent );
|
||||
|
||||
$source_comment_id = (int) $source_comment_id;
|
||||
|
||||
// Check if this comment came from this blog.
|
||||
if ( (int) $blog_id === (int) $comment_agent_blog_id ) {
|
||||
$hashtable[ $source_comment_id ] = (int) $r->comment_ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ( count( $results ) === $limit );
|
||||
|
||||
return $hashtable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $blog_id
|
||||
* @return int|void
|
||||
*/
|
||||
public function set_blog( $blog_id ) {
|
||||
if ( is_numeric( $blog_id ) ) {
|
||||
$blog_id = (int) $blog_id;
|
||||
} else {
|
||||
$blog = 'http://' . preg_replace( '#^https?://#', '', $blog_id );
|
||||
$parsed = parse_url( $blog );
|
||||
if ( ! $parsed || empty( $parsed['host'] ) ) {
|
||||
fwrite( STDERR, "Error: can not determine blog_id from $blog_id\n" );
|
||||
exit;
|
||||
}
|
||||
if ( empty( $parsed['path'] ) ) {
|
||||
$parsed['path'] = '/';
|
||||
}
|
||||
$blogs = get_sites(
|
||||
array(
|
||||
'domain' => $parsed['host'],
|
||||
'number' => 1,
|
||||
'path' => $parsed['path'],
|
||||
)
|
||||
);
|
||||
if ( ! $blogs ) {
|
||||
fwrite( STDERR, "Error: Could not find blog\n" );
|
||||
exit;
|
||||
}
|
||||
$blog = array_shift( $blogs );
|
||||
$blog_id = (int) $blog->blog_id;
|
||||
}
|
||||
|
||||
if ( function_exists( 'is_multisite' ) ) {
|
||||
if ( is_multisite() ) {
|
||||
switch_to_blog( $blog_id );
|
||||
}
|
||||
}
|
||||
|
||||
return $blog_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
* @return int|void
|
||||
*/
|
||||
public function set_user( $user_id ) {
|
||||
if ( is_numeric( $user_id ) ) {
|
||||
$user_id = (int) $user_id;
|
||||
} else {
|
||||
$user_id = (int) username_exists( $user_id );
|
||||
}
|
||||
|
||||
if ( ! $user_id || ! wp_set_current_user( $user_id ) ) {
|
||||
fwrite( STDERR, "Error: can not find user\n" );
|
||||
exit;
|
||||
}
|
||||
|
||||
return $user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts by strlen, longest string first.
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
* @return int
|
||||
*/
|
||||
public function cmpr_strlen( $a, $b ) {
|
||||
return strlen( $b ) - strlen( $a );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets URL.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param bool $head
|
||||
* @return array
|
||||
*/
|
||||
public function get_page( $url, $username = '', $password = '', $head = false ) {
|
||||
// Increase the timeout.
|
||||
add_filter( 'http_request_timeout', array( $this, 'bump_request_timeout' ) );
|
||||
|
||||
$headers = array();
|
||||
$args = array();
|
||||
if ( true === $head ) {
|
||||
$args['method'] = 'HEAD';
|
||||
}
|
||||
if ( ! empty( $username ) && ! empty( $password ) ) {
|
||||
$headers['Authorization'] = 'Basic ' . base64_encode( "$username:$password" );
|
||||
}
|
||||
|
||||
$args['headers'] = $headers;
|
||||
|
||||
return wp_safe_remote_request( $url, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Bumps up the request timeout for http requests.
|
||||
*
|
||||
* @param int $val
|
||||
* @return int
|
||||
*/
|
||||
public function bump_request_timeout( $val ) {
|
||||
return 60;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if user has exceeded disk quota.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_user_over_quota() {
|
||||
if ( function_exists( 'upload_is_user_over_quota' ) ) {
|
||||
if ( upload_is_user_over_quota() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces newlines, tabs, and multiple spaces with a single space.
|
||||
*
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
public function min_whitespace( $text ) {
|
||||
return preg_replace( '|[\r\n\t ]+|', ' ', $text );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets global variables that grow out of control during imports.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
* @global int[] $wp_actions
|
||||
*/
|
||||
public function stop_the_insanity() {
|
||||
global $wpdb, $wp_actions;
|
||||
// Or define( 'WP_IMPORTING', true );
|
||||
$wpdb->queries = array();
|
||||
// Reset $wp_actions to keep it from growing out of control.
|
||||
$wp_actions = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value of command line params.
|
||||
* Exits when a required param is not set.
|
||||
*
|
||||
* @param string $param
|
||||
* @param bool $required
|
||||
* @return mixed
|
||||
*/
|
||||
function get_cli_args( $param, $required = false ) {
|
||||
$args = $_SERVER['argv'];
|
||||
if ( ! is_array( $args ) ) {
|
||||
$args = array();
|
||||
}
|
||||
|
||||
$out = array();
|
||||
|
||||
$last_arg = null;
|
||||
$return = null;
|
||||
|
||||
$il = count( $args );
|
||||
|
||||
for ( $i = 1, $il; $i < $il; $i++ ) {
|
||||
if ( (bool) preg_match( '/^--(.+)/', $args[ $i ], $match ) ) {
|
||||
$parts = explode( '=', $match[1] );
|
||||
$key = preg_replace( '/[^a-z0-9]+/', '', $parts[0] );
|
||||
|
||||
if ( isset( $parts[1] ) ) {
|
||||
$out[ $key ] = $parts[1];
|
||||
} else {
|
||||
$out[ $key ] = true;
|
||||
}
|
||||
|
||||
$last_arg = $key;
|
||||
} elseif ( (bool) preg_match( '/^-([a-zA-Z0-9]+)/', $args[ $i ], $match ) ) {
|
||||
for ( $j = 0, $jl = strlen( $match[1] ); $j < $jl; $j++ ) {
|
||||
$key = $match[1][ $j ];
|
||||
$out[ $key ] = true;
|
||||
}
|
||||
|
||||
$last_arg = $key;
|
||||
} elseif ( null !== $last_arg ) {
|
||||
$out[ $last_arg ] = $args[ $i ];
|
||||
}
|
||||
}
|
||||
|
||||
// Check array for specified param.
|
||||
if ( isset( $out[ $param ] ) ) {
|
||||
// Set return value.
|
||||
$return = $out[ $param ];
|
||||
}
|
||||
|
||||
// Check for missing required param.
|
||||
if ( ! isset( $out[ $param ] ) && $required ) {
|
||||
// Display message and exit.
|
||||
echo "\"$param\" parameter is required but was not specified\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* WP_Importer base class
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
class WP_Importer {
|
||||
/**
|
||||
* Class Constructor
|
||||
*/
|
||||
public function __construct() {}
|
||||
|
||||
/**
|
||||
* Returns array with imported permalinks from WordPress database.
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param string $importer_name
|
||||
* @param string $blog_id
|
||||
* @return array
|
||||
*/
|
||||
public function get_imported_posts( $importer_name, $blog_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$hashtable = array();
|
||||
|
||||
$limit = 100;
|
||||
$offset = 0;
|
||||
|
||||
// Grab all posts in chunks.
|
||||
do {
|
||||
$meta_key = $importer_name . '_' . $blog_id . '_permalink';
|
||||
$sql = $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = %s LIMIT %d,%d", $meta_key, $offset, $limit );
|
||||
$results = $wpdb->get_results( $sql );
|
||||
|
||||
// Increment offset.
|
||||
$offset = ( $limit + $offset );
|
||||
|
||||
if ( ! empty( $results ) ) {
|
||||
foreach ( $results as $r ) {
|
||||
// Set permalinks into array.
|
||||
$hashtable[ $r->meta_value ] = (int) $r->post_id;
|
||||
}
|
||||
}
|
||||
} while ( count( $results ) === $limit );
|
||||
|
||||
return $hashtable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns count of imported permalinks from WordPress database.
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param string $importer_name
|
||||
* @param string $blog_id
|
||||
* @return int
|
||||
*/
|
||||
public function count_imported_posts( $importer_name, $blog_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$count = 0;
|
||||
|
||||
// Get count of permalinks.
|
||||
$meta_key = $importer_name . '_' . $blog_id . '_permalink';
|
||||
$sql = $wpdb->prepare( "SELECT COUNT( post_id ) AS cnt FROM $wpdb->postmeta WHERE meta_key = %s", $meta_key );
|
||||
|
||||
$result = $wpdb->get_results( $sql );
|
||||
|
||||
if ( ! empty( $result ) ) {
|
||||
$count = (int) $result[0]->cnt;
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets array with imported comments from WordPress database.
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param string $blog_id
|
||||
* @return array
|
||||
*/
|
||||
public function get_imported_comments( $blog_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$hashtable = array();
|
||||
|
||||
$limit = 100;
|
||||
$offset = 0;
|
||||
|
||||
// Grab all comments in chunks.
|
||||
do {
|
||||
$sql = $wpdb->prepare( "SELECT comment_ID, comment_agent FROM $wpdb->comments LIMIT %d,%d", $offset, $limit );
|
||||
$results = $wpdb->get_results( $sql );
|
||||
|
||||
// Increment offset.
|
||||
$offset = ( $limit + $offset );
|
||||
|
||||
if ( ! empty( $results ) ) {
|
||||
foreach ( $results as $r ) {
|
||||
// Explode comment_agent key.
|
||||
list ( $comment_agent_blog_id, $source_comment_id ) = explode( '-', $r->comment_agent );
|
||||
|
||||
$source_comment_id = (int) $source_comment_id;
|
||||
|
||||
// Check if this comment came from this blog.
|
||||
if ( (int) $blog_id === (int) $comment_agent_blog_id ) {
|
||||
$hashtable[ $source_comment_id ] = (int) $r->comment_ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ( count( $results ) === $limit );
|
||||
|
||||
return $hashtable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $blog_id
|
||||
* @return int|void
|
||||
*/
|
||||
public function set_blog( $blog_id ) {
|
||||
if ( is_numeric( $blog_id ) ) {
|
||||
$blog_id = (int) $blog_id;
|
||||
} else {
|
||||
$blog = 'http://' . preg_replace( '#^https?://#', '', $blog_id );
|
||||
$parsed = parse_url( $blog );
|
||||
if ( ! $parsed || empty( $parsed['host'] ) ) {
|
||||
fwrite( STDERR, "Error: can not determine blog_id from $blog_id\n" );
|
||||
exit;
|
||||
}
|
||||
if ( empty( $parsed['path'] ) ) {
|
||||
$parsed['path'] = '/';
|
||||
}
|
||||
$blogs = get_sites(
|
||||
array(
|
||||
'domain' => $parsed['host'],
|
||||
'number' => 1,
|
||||
'path' => $parsed['path'],
|
||||
)
|
||||
);
|
||||
if ( ! $blogs ) {
|
||||
fwrite( STDERR, "Error: Could not find blog\n" );
|
||||
exit;
|
||||
}
|
||||
$blog = array_shift( $blogs );
|
||||
$blog_id = (int) $blog->blog_id;
|
||||
}
|
||||
|
||||
if ( function_exists( 'is_multisite' ) ) {
|
||||
if ( is_multisite() ) {
|
||||
switch_to_blog( $blog_id );
|
||||
}
|
||||
}
|
||||
|
||||
return $blog_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
* @return int|void
|
||||
*/
|
||||
public function set_user( $user_id ) {
|
||||
if ( is_numeric( $user_id ) ) {
|
||||
$user_id = (int) $user_id;
|
||||
} else {
|
||||
$user_id = (int) username_exists( $user_id );
|
||||
}
|
||||
|
||||
if ( ! $user_id || ! wp_set_current_user( $user_id ) ) {
|
||||
fwrite( STDERR, "Error: can not find user\n" );
|
||||
exit;
|
||||
}
|
||||
|
||||
return $user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts by strlen, longest string first.
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
* @return int
|
||||
*/
|
||||
public function cmpr_strlen( $a, $b ) {
|
||||
return strlen( $b ) - strlen( $a );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets URL.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param bool $head
|
||||
* @return array
|
||||
*/
|
||||
public function get_page( $url, $username = '', $password = '', $head = false ) {
|
||||
// Increase the timeout.
|
||||
add_filter( 'http_request_timeout', array( $this, 'bump_request_timeout' ) );
|
||||
|
||||
$headers = array();
|
||||
$args = array();
|
||||
if ( true === $head ) {
|
||||
$args['method'] = 'HEAD';
|
||||
}
|
||||
if ( ! empty( $username ) && ! empty( $password ) ) {
|
||||
$headers['Authorization'] = 'Basic ' . base64_encode( "$username:$password" );
|
||||
}
|
||||
|
||||
$args['headers'] = $headers;
|
||||
|
||||
return wp_safe_remote_request( $url, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Bumps up the request timeout for http requests.
|
||||
*
|
||||
* @param int $val
|
||||
* @return int
|
||||
*/
|
||||
public function bump_request_timeout( $val ) {
|
||||
return 60;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if user has exceeded disk quota.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_user_over_quota() {
|
||||
if ( function_exists( 'upload_is_user_over_quota' ) ) {
|
||||
if ( upload_is_user_over_quota() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces newlines, tabs, and multiple spaces with a single space.
|
||||
*
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
public function min_whitespace( $text ) {
|
||||
return preg_replace( '|[\r\n\t ]+|', ' ', $text );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets global variables that grow out of control during imports.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
* @global int[] $wp_actions
|
||||
*/
|
||||
public function stop_the_insanity() {
|
||||
global $wpdb, $wp_actions;
|
||||
// Or define( 'WP_IMPORTING', true );
|
||||
$wpdb->queries = array();
|
||||
// Reset $wp_actions to keep it from growing out of control.
|
||||
$wp_actions = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns value of command line params.
|
||||
* Exits when a required param is not set.
|
||||
*
|
||||
* @param string $param
|
||||
* @param bool $required
|
||||
* @return mixed
|
||||
*/
|
||||
function get_cli_args( $param, $required = false ) {
|
||||
$args = $_SERVER['argv'];
|
||||
if ( ! is_array( $args ) ) {
|
||||
$args = array();
|
||||
}
|
||||
|
||||
$out = array();
|
||||
|
||||
$last_arg = null;
|
||||
$return = null;
|
||||
|
||||
$il = count( $args );
|
||||
|
||||
for ( $i = 1, $il; $i < $il; $i++ ) {
|
||||
if ( (bool) preg_match( '/^--(.+)/', $args[ $i ], $match ) ) {
|
||||
$parts = explode( '=', $match[1] );
|
||||
$key = preg_replace( '/[^a-z0-9]+/', '', $parts[0] );
|
||||
|
||||
if ( isset( $parts[1] ) ) {
|
||||
$out[ $key ] = $parts[1];
|
||||
} else {
|
||||
$out[ $key ] = true;
|
||||
}
|
||||
|
||||
$last_arg = $key;
|
||||
} elseif ( (bool) preg_match( '/^-([a-zA-Z0-9]+)/', $args[ $i ], $match ) ) {
|
||||
for ( $j = 0, $jl = strlen( $match[1] ); $j < $jl; $j++ ) {
|
||||
$key = $match[1][ $j ];
|
||||
$out[ $key ] = true;
|
||||
}
|
||||
|
||||
$last_arg = $key;
|
||||
} elseif ( null !== $last_arg ) {
|
||||
$out[ $last_arg ] = $args[ $i ];
|
||||
}
|
||||
}
|
||||
|
||||
// Check array for specified param.
|
||||
if ( isset( $out[ $param ] ) ) {
|
||||
// Set return value.
|
||||
$return = $out[ $param ];
|
||||
}
|
||||
|
||||
// Check for missing required param.
|
||||
if ( ! isset( $out[ $param ] ) && $required ) {
|
||||
// Display message and exit.
|
||||
echo "\"$param\" parameter is required but was not specified\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
@@ -1,175 +1,175 @@
|
||||
<?php
|
||||
/**
|
||||
* Administration API: WP_Internal_Pointers class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement an internal admin pointers API.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
final class WP_Internal_Pointers {
|
||||
/**
|
||||
* Initializes the new feature pointers.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* All pointers can be disabled using the following:
|
||||
* remove_action( 'admin_enqueue_scripts', array( 'WP_Internal_Pointers', 'enqueue_scripts' ) );
|
||||
*
|
||||
* Individual pointers (e.g. wp390_widgets) can be disabled using the following:
|
||||
*
|
||||
* function yourprefix_remove_pointers() {
|
||||
* remove_action(
|
||||
* 'admin_print_footer_scripts',
|
||||
* array( 'WP_Internal_Pointers', 'pointer_wp390_widgets' )
|
||||
* );
|
||||
* }
|
||||
* add_action( 'admin_enqueue_scripts', 'yourprefix_remove_pointers', 11 );
|
||||
*
|
||||
* @param string $hook_suffix The current admin page.
|
||||
*/
|
||||
public static function enqueue_scripts( $hook_suffix ) {
|
||||
/*
|
||||
* Register feature pointers
|
||||
*
|
||||
* Format:
|
||||
* array(
|
||||
* hook_suffix => pointer callback
|
||||
* )
|
||||
*
|
||||
* Example:
|
||||
* array(
|
||||
* 'themes.php' => 'wp390_widgets'
|
||||
* )
|
||||
*/
|
||||
$registered_pointers = array(
|
||||
// None currently.
|
||||
);
|
||||
|
||||
// Check if screen related pointer is registered.
|
||||
if ( empty( $registered_pointers[ $hook_suffix ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$pointers = (array) $registered_pointers[ $hook_suffix ];
|
||||
|
||||
/*
|
||||
* Specify required capabilities for feature pointers
|
||||
*
|
||||
* Format:
|
||||
* array(
|
||||
* pointer callback => Array of required capabilities
|
||||
* )
|
||||
*
|
||||
* Example:
|
||||
* array(
|
||||
* 'wp390_widgets' => array( 'edit_theme_options' )
|
||||
* )
|
||||
*/
|
||||
$caps_required = array(
|
||||
// None currently.
|
||||
);
|
||||
|
||||
// Get dismissed pointers.
|
||||
$dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
|
||||
|
||||
$got_pointers = false;
|
||||
foreach ( array_diff( $pointers, $dismissed ) as $pointer ) {
|
||||
if ( isset( $caps_required[ $pointer ] ) ) {
|
||||
foreach ( $caps_required[ $pointer ] as $cap ) {
|
||||
if ( ! current_user_can( $cap ) ) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bind pointer print function.
|
||||
add_action( 'admin_print_footer_scripts', array( 'WP_Internal_Pointers', 'pointer_' . $pointer ) );
|
||||
$got_pointers = true;
|
||||
}
|
||||
|
||||
if ( ! $got_pointers ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add pointers script and style to queue.
|
||||
wp_enqueue_style( 'wp-pointer' );
|
||||
wp_enqueue_script( 'wp-pointer' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the pointer JavaScript data.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param string $pointer_id The pointer ID.
|
||||
* @param string $selector The HTML elements, on which the pointer should be attached.
|
||||
* @param array $args Arguments to be passed to the pointer JS (see wp-pointer.js).
|
||||
*/
|
||||
private static function print_js( $pointer_id, $selector, $args ) {
|
||||
if ( empty( $pointer_id ) || empty( $selector ) || empty( $args ) || empty( $args['content'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
(function($){
|
||||
var options = <?php echo wp_json_encode( $args ); ?>, setup;
|
||||
|
||||
if ( ! options )
|
||||
return;
|
||||
|
||||
options = $.extend( options, {
|
||||
close: function() {
|
||||
$.post( ajaxurl, {
|
||||
pointer: '<?php echo $pointer_id; ?>',
|
||||
action: 'dismiss-wp-pointer'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
setup = function() {
|
||||
$('<?php echo $selector; ?>').first().pointer( options ).pointer('open');
|
||||
};
|
||||
|
||||
if ( options.position && options.position.defer_loading )
|
||||
$(window).bind( 'load.wp-pointers', setup );
|
||||
else
|
||||
$( function() {
|
||||
setup();
|
||||
} );
|
||||
|
||||
})( jQuery );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
public static function pointer_wp330_toolbar() {}
|
||||
public static function pointer_wp330_media_uploader() {}
|
||||
public static function pointer_wp330_saving_widgets() {}
|
||||
public static function pointer_wp340_customize_current_theme_link() {}
|
||||
public static function pointer_wp340_choose_image_from_library() {}
|
||||
public static function pointer_wp350_media() {}
|
||||
public static function pointer_wp360_revisions() {}
|
||||
public static function pointer_wp360_locks() {}
|
||||
public static function pointer_wp390_widgets() {}
|
||||
public static function pointer_wp410_dfw() {}
|
||||
public static function pointer_wp496_privacy() {}
|
||||
|
||||
/**
|
||||
* Prevents new users from seeing existing 'new feature' pointers.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
*/
|
||||
public static function dismiss_pointers_for_new_users( $user_id ) {
|
||||
add_user_meta( $user_id, 'dismissed_wp_pointers', '' );
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Administration API: WP_Internal_Pointers class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement an internal admin pointers API.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
final class WP_Internal_Pointers {
|
||||
/**
|
||||
* Initializes the new feature pointers.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* All pointers can be disabled using the following:
|
||||
* remove_action( 'admin_enqueue_scripts', array( 'WP_Internal_Pointers', 'enqueue_scripts' ) );
|
||||
*
|
||||
* Individual pointers (e.g. wp390_widgets) can be disabled using the following:
|
||||
*
|
||||
* function yourprefix_remove_pointers() {
|
||||
* remove_action(
|
||||
* 'admin_print_footer_scripts',
|
||||
* array( 'WP_Internal_Pointers', 'pointer_wp390_widgets' )
|
||||
* );
|
||||
* }
|
||||
* add_action( 'admin_enqueue_scripts', 'yourprefix_remove_pointers', 11 );
|
||||
*
|
||||
* @param string $hook_suffix The current admin page.
|
||||
*/
|
||||
public static function enqueue_scripts( $hook_suffix ) {
|
||||
/*
|
||||
* Register feature pointers
|
||||
*
|
||||
* Format:
|
||||
* array(
|
||||
* hook_suffix => pointer callback
|
||||
* )
|
||||
*
|
||||
* Example:
|
||||
* array(
|
||||
* 'themes.php' => 'wp390_widgets'
|
||||
* )
|
||||
*/
|
||||
$registered_pointers = array(
|
||||
// None currently.
|
||||
);
|
||||
|
||||
// Check if screen related pointer is registered.
|
||||
if ( empty( $registered_pointers[ $hook_suffix ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$pointers = (array) $registered_pointers[ $hook_suffix ];
|
||||
|
||||
/*
|
||||
* Specify required capabilities for feature pointers
|
||||
*
|
||||
* Format:
|
||||
* array(
|
||||
* pointer callback => Array of required capabilities
|
||||
* )
|
||||
*
|
||||
* Example:
|
||||
* array(
|
||||
* 'wp390_widgets' => array( 'edit_theme_options' )
|
||||
* )
|
||||
*/
|
||||
$caps_required = array(
|
||||
// None currently.
|
||||
);
|
||||
|
||||
// Get dismissed pointers.
|
||||
$dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
|
||||
|
||||
$got_pointers = false;
|
||||
foreach ( array_diff( $pointers, $dismissed ) as $pointer ) {
|
||||
if ( isset( $caps_required[ $pointer ] ) ) {
|
||||
foreach ( $caps_required[ $pointer ] as $cap ) {
|
||||
if ( ! current_user_can( $cap ) ) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bind pointer print function.
|
||||
add_action( 'admin_print_footer_scripts', array( 'WP_Internal_Pointers', 'pointer_' . $pointer ) );
|
||||
$got_pointers = true;
|
||||
}
|
||||
|
||||
if ( ! $got_pointers ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add pointers script and style to queue.
|
||||
wp_enqueue_style( 'wp-pointer' );
|
||||
wp_enqueue_script( 'wp-pointer' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the pointer JavaScript data.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param string $pointer_id The pointer ID.
|
||||
* @param string $selector The HTML elements, on which the pointer should be attached.
|
||||
* @param array $args Arguments to be passed to the pointer JS (see wp-pointer.js).
|
||||
*/
|
||||
private static function print_js( $pointer_id, $selector, $args ) {
|
||||
if ( empty( $pointer_id ) || empty( $selector ) || empty( $args ) || empty( $args['content'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
(function($){
|
||||
var options = <?php echo wp_json_encode( $args ); ?>, setup;
|
||||
|
||||
if ( ! options )
|
||||
return;
|
||||
|
||||
options = $.extend( options, {
|
||||
close: function() {
|
||||
$.post( ajaxurl, {
|
||||
pointer: '<?php echo $pointer_id; ?>',
|
||||
action: 'dismiss-wp-pointer'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
setup = function() {
|
||||
$('<?php echo $selector; ?>').first().pointer( options ).pointer('open');
|
||||
};
|
||||
|
||||
if ( options.position && options.position.defer_loading )
|
||||
$(window).bind( 'load.wp-pointers', setup );
|
||||
else
|
||||
$( function() {
|
||||
setup();
|
||||
} );
|
||||
|
||||
})( jQuery );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
public static function pointer_wp330_toolbar() {}
|
||||
public static function pointer_wp330_media_uploader() {}
|
||||
public static function pointer_wp330_saving_widgets() {}
|
||||
public static function pointer_wp340_customize_current_theme_link() {}
|
||||
public static function pointer_wp340_choose_image_from_library() {}
|
||||
public static function pointer_wp350_media() {}
|
||||
public static function pointer_wp360_revisions() {}
|
||||
public static function pointer_wp360_locks() {}
|
||||
public static function pointer_wp390_widgets() {}
|
||||
public static function pointer_wp410_dfw() {}
|
||||
public static function pointer_wp496_privacy() {}
|
||||
|
||||
/**
|
||||
* Prevents new users from seeing existing 'new feature' pointers.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
*/
|
||||
public static function dismiss_pointers_for_new_users( $user_id ) {
|
||||
add_user_meta( $user_id, 'dismissed_wp_pointers', '' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,354 +1,354 @@
|
||||
<?php
|
||||
/**
|
||||
* List Table API: WP_Links_List_Table class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 3.1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement displaying links in a list table.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @see WP_List_Table
|
||||
*/
|
||||
class WP_Links_List_Table extends WP_List_Table {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @see WP_List_Table::__construct() for more information on default arguments.
|
||||
*
|
||||
* @param array $args An associative array of arguments.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'plural' => 'bookmarks',
|
||||
'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function ajax_user_can() {
|
||||
return current_user_can( 'manage_links' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @global int $cat_id
|
||||
* @global string $s
|
||||
* @global string $orderby
|
||||
* @global string $order
|
||||
*/
|
||||
public function prepare_items() {
|
||||
global $cat_id, $s, $orderby, $order;
|
||||
|
||||
wp_reset_vars( array( 'action', 'cat_id', 'link_id', 'orderby', 'order', 's' ) );
|
||||
|
||||
$args = array(
|
||||
'hide_invisible' => 0,
|
||||
'hide_empty' => 0,
|
||||
);
|
||||
|
||||
if ( 'all' !== $cat_id ) {
|
||||
$args['category'] = $cat_id;
|
||||
}
|
||||
if ( ! empty( $s ) ) {
|
||||
$args['search'] = $s;
|
||||
}
|
||||
if ( ! empty( $orderby ) ) {
|
||||
$args['orderby'] = $orderby;
|
||||
}
|
||||
if ( ! empty( $order ) ) {
|
||||
$args['order'] = $order;
|
||||
}
|
||||
|
||||
$this->items = get_bookmarks( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function no_items() {
|
||||
_e( 'No links found.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_bulk_actions() {
|
||||
$actions = array();
|
||||
$actions['delete'] = __( 'Delete' );
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @global int $cat_id
|
||||
* @param string $which
|
||||
*/
|
||||
protected function extra_tablenav( $which ) {
|
||||
global $cat_id;
|
||||
|
||||
if ( 'top' !== $which ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="alignleft actions">
|
||||
<?php
|
||||
$dropdown_options = array(
|
||||
'selected' => $cat_id,
|
||||
'name' => 'cat_id',
|
||||
'taxonomy' => 'link_category',
|
||||
'show_option_all' => get_taxonomy( 'link_category' )->labels->all_items,
|
||||
'hide_empty' => true,
|
||||
'hierarchical' => 1,
|
||||
'show_count' => 0,
|
||||
'orderby' => 'name',
|
||||
);
|
||||
|
||||
echo '<label class="screen-reader-text" for="cat_id">' . get_taxonomy( 'link_category' )->labels->filter_by_item . '</label>';
|
||||
|
||||
wp_dropdown_categories( $dropdown_options );
|
||||
|
||||
submit_button( __( 'Filter' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of column titles keyed by their column name.
|
||||
*/
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'cb' => '<input type="checkbox" />',
|
||||
'name' => _x( 'Name', 'link name' ),
|
||||
'url' => __( 'URL' ),
|
||||
'categories' => __( 'Categories' ),
|
||||
'rel' => __( 'Relationship' ),
|
||||
'visible' => __( 'Visible' ),
|
||||
'rating' => __( 'Rating' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_sortable_columns() {
|
||||
return array(
|
||||
'name' => array( 'name', false, _x( 'Name', 'link name' ), __( 'Table ordered by Name.' ), 'asc' ),
|
||||
'url' => array( 'url', false, __( 'URL' ), __( 'Table ordered by URL.' ) ),
|
||||
'visible' => array( 'visible', false, __( 'Visible' ), __( 'Table ordered by Visibility.' ) ),
|
||||
'rating' => array( 'rating', false, __( 'Rating' ), __( 'Table ordered by Rating.' ) ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the default primary column.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @return string Name of the default primary column, in this case, 'name'.
|
||||
*/
|
||||
protected function get_default_primary_column_name() {
|
||||
return 'name';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the checkbox column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @since 5.9.0 Renamed `$link` to `$item` to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @param object $item The current link object.
|
||||
*/
|
||||
public function column_cb( $item ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$link = $item;
|
||||
|
||||
?>
|
||||
<input type="checkbox" name="linkcheck[]" id="cb-select-<?php echo $link->link_id; ?>" value="<?php echo esc_attr( $link->link_id ); ?>" />
|
||||
<label for="cb-select-<?php echo $link->link_id; ?>">
|
||||
<span class="screen-reader-text">
|
||||
<?php
|
||||
/* translators: Hidden accessibility text. %s: Link name. */
|
||||
printf( __( 'Select %s' ), $link->link_name );
|
||||
?>
|
||||
</span>
|
||||
</label>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the link name column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param object $link The current link object.
|
||||
*/
|
||||
public function column_name( $link ) {
|
||||
$edit_link = get_edit_bookmark_link( $link );
|
||||
printf(
|
||||
'<strong><a class="row-title" href="%s" aria-label="%s">%s</a></strong>',
|
||||
$edit_link,
|
||||
/* translators: %s: Link name. */
|
||||
esc_attr( sprintf( __( 'Edit “%s”' ), $link->link_name ) ),
|
||||
$link->link_name
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the link URL column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param object $link The current link object.
|
||||
*/
|
||||
public function column_url( $link ) {
|
||||
$short_url = url_shorten( $link->link_url );
|
||||
echo "<a href='$link->link_url'>$short_url</a>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the link categories column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @global int $cat_id
|
||||
*
|
||||
* @param object $link The current link object.
|
||||
*/
|
||||
public function column_categories( $link ) {
|
||||
global $cat_id;
|
||||
|
||||
$cat_names = array();
|
||||
foreach ( $link->link_category as $category ) {
|
||||
$cat = get_term( $category, 'link_category', OBJECT, 'display' );
|
||||
if ( is_wp_error( $cat ) ) {
|
||||
echo $cat->get_error_message();
|
||||
}
|
||||
$cat_name = $cat->name;
|
||||
if ( (int) $cat_id !== $category ) {
|
||||
$cat_name = "<a href='link-manager.php?cat_id=$category'>$cat_name</a>";
|
||||
}
|
||||
$cat_names[] = $cat_name;
|
||||
}
|
||||
echo implode( ', ', $cat_names );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the link relation column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param object $link The current link object.
|
||||
*/
|
||||
public function column_rel( $link ) {
|
||||
echo empty( $link->link_rel ) ? '<br />' : $link->link_rel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the link visibility column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param object $link The current link object.
|
||||
*/
|
||||
public function column_visible( $link ) {
|
||||
if ( 'Y' === $link->link_visible ) {
|
||||
_e( 'Yes' );
|
||||
} else {
|
||||
_e( 'No' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the link rating column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param object $link The current link object.
|
||||
*/
|
||||
public function column_rating( $link ) {
|
||||
echo $link->link_rating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the default column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @since 5.9.0 Renamed `$link` to `$item` to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @param object $item Link object.
|
||||
* @param string $column_name Current column name.
|
||||
*/
|
||||
public function column_default( $item, $column_name ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$link = $item;
|
||||
|
||||
/**
|
||||
* Fires for each registered custom link column.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $column_name Name of the custom column.
|
||||
* @param int $link_id Link ID.
|
||||
*/
|
||||
do_action( 'manage_link_custom_column', $column_name, $link->link_id );
|
||||
}
|
||||
|
||||
public function display_rows() {
|
||||
foreach ( $this->items as $link ) {
|
||||
$link = sanitize_bookmark( $link );
|
||||
$link->link_name = esc_attr( $link->link_name );
|
||||
$link->link_category = wp_get_link_cats( $link->link_id );
|
||||
?>
|
||||
<tr id="link-<?php echo $link->link_id; ?>">
|
||||
<?php $this->single_row_columns( $link ); ?>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates and displays row action links.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @since 5.9.0 Renamed `$link` to `$item` to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @param object $item Link being acted upon.
|
||||
* @param string $column_name Current column name.
|
||||
* @param string $primary Primary column name.
|
||||
* @return string Row actions output for links, or an empty string
|
||||
* if the current column is not the primary column.
|
||||
*/
|
||||
protected function handle_row_actions( $item, $column_name, $primary ) {
|
||||
if ( $primary !== $column_name ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$link = $item;
|
||||
|
||||
$edit_link = get_edit_bookmark_link( $link );
|
||||
|
||||
$actions = array();
|
||||
$actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>';
|
||||
$actions['delete'] = sprintf(
|
||||
'<a class="submitdelete" href="%s" onclick="return confirm( \'%s\' );">%s</a>',
|
||||
wp_nonce_url( "link.php?action=delete&link_id=$link->link_id", 'delete-bookmark_' . $link->link_id ),
|
||||
/* translators: %s: Link name. */
|
||||
esc_js( sprintf( __( "You are about to delete this link '%s'\n 'Cancel' to stop, 'OK' to delete." ), $link->link_name ) ),
|
||||
__( 'Delete' )
|
||||
);
|
||||
|
||||
return $this->row_actions( $actions );
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* List Table API: WP_Links_List_Table class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 3.1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement displaying links in a list table.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @see WP_List_Table
|
||||
*/
|
||||
class WP_Links_List_Table extends WP_List_Table {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @see WP_List_Table::__construct() for more information on default arguments.
|
||||
*
|
||||
* @param array $args An associative array of arguments.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'plural' => 'bookmarks',
|
||||
'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function ajax_user_can() {
|
||||
return current_user_can( 'manage_links' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @global int $cat_id
|
||||
* @global string $s
|
||||
* @global string $orderby
|
||||
* @global string $order
|
||||
*/
|
||||
public function prepare_items() {
|
||||
global $cat_id, $s, $orderby, $order;
|
||||
|
||||
wp_reset_vars( array( 'action', 'cat_id', 'link_id', 'orderby', 'order', 's' ) );
|
||||
|
||||
$args = array(
|
||||
'hide_invisible' => 0,
|
||||
'hide_empty' => 0,
|
||||
);
|
||||
|
||||
if ( 'all' !== $cat_id ) {
|
||||
$args['category'] = $cat_id;
|
||||
}
|
||||
if ( ! empty( $s ) ) {
|
||||
$args['search'] = $s;
|
||||
}
|
||||
if ( ! empty( $orderby ) ) {
|
||||
$args['orderby'] = $orderby;
|
||||
}
|
||||
if ( ! empty( $order ) ) {
|
||||
$args['order'] = $order;
|
||||
}
|
||||
|
||||
$this->items = get_bookmarks( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function no_items() {
|
||||
_e( 'No links found.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_bulk_actions() {
|
||||
$actions = array();
|
||||
$actions['delete'] = __( 'Delete' );
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @global int $cat_id
|
||||
* @param string $which
|
||||
*/
|
||||
protected function extra_tablenav( $which ) {
|
||||
global $cat_id;
|
||||
|
||||
if ( 'top' !== $which ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="alignleft actions">
|
||||
<?php
|
||||
$dropdown_options = array(
|
||||
'selected' => $cat_id,
|
||||
'name' => 'cat_id',
|
||||
'taxonomy' => 'link_category',
|
||||
'show_option_all' => get_taxonomy( 'link_category' )->labels->all_items,
|
||||
'hide_empty' => true,
|
||||
'hierarchical' => 1,
|
||||
'show_count' => 0,
|
||||
'orderby' => 'name',
|
||||
);
|
||||
|
||||
echo '<label class="screen-reader-text" for="cat_id">' . get_taxonomy( 'link_category' )->labels->filter_by_item . '</label>';
|
||||
|
||||
wp_dropdown_categories( $dropdown_options );
|
||||
|
||||
submit_button( __( 'Filter' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of column titles keyed by their column name.
|
||||
*/
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'cb' => '<input type="checkbox" />',
|
||||
'name' => _x( 'Name', 'link name' ),
|
||||
'url' => __( 'URL' ),
|
||||
'categories' => __( 'Categories' ),
|
||||
'rel' => __( 'Relationship' ),
|
||||
'visible' => __( 'Visible' ),
|
||||
'rating' => __( 'Rating' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_sortable_columns() {
|
||||
return array(
|
||||
'name' => array( 'name', false, _x( 'Name', 'link name' ), __( 'Table ordered by Name.' ), 'asc' ),
|
||||
'url' => array( 'url', false, __( 'URL' ), __( 'Table ordered by URL.' ) ),
|
||||
'visible' => array( 'visible', false, __( 'Visible' ), __( 'Table ordered by Visibility.' ) ),
|
||||
'rating' => array( 'rating', false, __( 'Rating' ), __( 'Table ordered by Rating.' ) ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the default primary column.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @return string Name of the default primary column, in this case, 'name'.
|
||||
*/
|
||||
protected function get_default_primary_column_name() {
|
||||
return 'name';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the checkbox column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @since 5.9.0 Renamed `$link` to `$item` to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @param object $item The current link object.
|
||||
*/
|
||||
public function column_cb( $item ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$link = $item;
|
||||
|
||||
?>
|
||||
<input type="checkbox" name="linkcheck[]" id="cb-select-<?php echo $link->link_id; ?>" value="<?php echo esc_attr( $link->link_id ); ?>" />
|
||||
<label for="cb-select-<?php echo $link->link_id; ?>">
|
||||
<span class="screen-reader-text">
|
||||
<?php
|
||||
/* translators: Hidden accessibility text. %s: Link name. */
|
||||
printf( __( 'Select %s' ), $link->link_name );
|
||||
?>
|
||||
</span>
|
||||
</label>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the link name column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param object $link The current link object.
|
||||
*/
|
||||
public function column_name( $link ) {
|
||||
$edit_link = get_edit_bookmark_link( $link );
|
||||
printf(
|
||||
'<strong><a class="row-title" href="%s" aria-label="%s">%s</a></strong>',
|
||||
$edit_link,
|
||||
/* translators: %s: Link name. */
|
||||
esc_attr( sprintf( __( 'Edit “%s”' ), $link->link_name ) ),
|
||||
$link->link_name
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the link URL column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param object $link The current link object.
|
||||
*/
|
||||
public function column_url( $link ) {
|
||||
$short_url = url_shorten( $link->link_url );
|
||||
echo "<a href='$link->link_url'>$short_url</a>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the link categories column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @global int $cat_id
|
||||
*
|
||||
* @param object $link The current link object.
|
||||
*/
|
||||
public function column_categories( $link ) {
|
||||
global $cat_id;
|
||||
|
||||
$cat_names = array();
|
||||
foreach ( $link->link_category as $category ) {
|
||||
$cat = get_term( $category, 'link_category', OBJECT, 'display' );
|
||||
if ( is_wp_error( $cat ) ) {
|
||||
echo $cat->get_error_message();
|
||||
}
|
||||
$cat_name = $cat->name;
|
||||
if ( (int) $cat_id !== $category ) {
|
||||
$cat_name = "<a href='link-manager.php?cat_id=$category'>$cat_name</a>";
|
||||
}
|
||||
$cat_names[] = $cat_name;
|
||||
}
|
||||
echo implode( ', ', $cat_names );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the link relation column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param object $link The current link object.
|
||||
*/
|
||||
public function column_rel( $link ) {
|
||||
echo empty( $link->link_rel ) ? '<br />' : $link->link_rel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the link visibility column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param object $link The current link object.
|
||||
*/
|
||||
public function column_visible( $link ) {
|
||||
if ( 'Y' === $link->link_visible ) {
|
||||
_e( 'Yes' );
|
||||
} else {
|
||||
_e( 'No' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the link rating column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param object $link The current link object.
|
||||
*/
|
||||
public function column_rating( $link ) {
|
||||
echo $link->link_rating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the default column output.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @since 5.9.0 Renamed `$link` to `$item` to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @param object $item Link object.
|
||||
* @param string $column_name Current column name.
|
||||
*/
|
||||
public function column_default( $item, $column_name ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$link = $item;
|
||||
|
||||
/**
|
||||
* Fires for each registered custom link column.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $column_name Name of the custom column.
|
||||
* @param int $link_id Link ID.
|
||||
*/
|
||||
do_action( 'manage_link_custom_column', $column_name, $link->link_id );
|
||||
}
|
||||
|
||||
public function display_rows() {
|
||||
foreach ( $this->items as $link ) {
|
||||
$link = sanitize_bookmark( $link );
|
||||
$link->link_name = esc_attr( $link->link_name );
|
||||
$link->link_category = wp_get_link_cats( $link->link_id );
|
||||
?>
|
||||
<tr id="link-<?php echo $link->link_id; ?>">
|
||||
<?php $this->single_row_columns( $link ); ?>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates and displays row action links.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @since 5.9.0 Renamed `$link` to `$item` to match parent class for PHP 8 named parameter support.
|
||||
*
|
||||
* @param object $item Link being acted upon.
|
||||
* @param string $column_name Current column name.
|
||||
* @param string $primary Primary column name.
|
||||
* @return string Row actions output for links, or an empty string
|
||||
* if the current column is not the primary column.
|
||||
*/
|
||||
protected function handle_row_actions( $item, $column_name, $primary ) {
|
||||
if ( $primary !== $column_name ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$link = $item;
|
||||
|
||||
$edit_link = get_edit_bookmark_link( $link );
|
||||
|
||||
$actions = array();
|
||||
$actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>';
|
||||
$actions['delete'] = sprintf(
|
||||
'<a class="submitdelete" href="%s" onclick="return confirm( \'%s\' );">%s</a>',
|
||||
wp_nonce_url( "link.php?action=delete&link_id=$link->link_id", 'delete-bookmark_' . $link->link_id ),
|
||||
/* translators: %s: Link name. */
|
||||
esc_js( sprintf( __( "You are about to delete this link '%s'\n 'Cancel' to stop, 'OK' to delete." ), $link->link_name ) ),
|
||||
__( 'Delete' )
|
||||
);
|
||||
|
||||
return $this->row_actions( $actions );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Helper functions for displaying a list of items in an ajaxified HTML table.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage List_Table
|
||||
* @since 4.7.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Helper class to be used only by back compat functions.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
class _WP_List_Table_Compat extends WP_List_Table {
|
||||
public $_screen;
|
||||
public $_columns;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string|WP_Screen $screen The screen hook name or screen object.
|
||||
* @param string[] $columns An array of columns with column IDs as the keys
|
||||
* and translated column names as the values.
|
||||
*/
|
||||
public function __construct( $screen, $columns = array() ) {
|
||||
if ( is_string( $screen ) ) {
|
||||
$screen = convert_to_screen( $screen );
|
||||
}
|
||||
|
||||
$this->_screen = $screen;
|
||||
|
||||
if ( ! empty( $columns ) ) {
|
||||
$this->_columns = $columns;
|
||||
add_filter( 'manage_' . $screen->id . '_columns', array( $this, 'get_columns' ), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of all, hidden, and sortable columns.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_column_info() {
|
||||
$columns = get_column_headers( $this->_screen );
|
||||
$hidden = get_hidden_columns( $this->_screen );
|
||||
$sortable = array();
|
||||
$primary = $this->get_default_primary_column_name();
|
||||
|
||||
return array( $columns, $hidden, $sortable, $primary );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of columns.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
return $this->_columns;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Helper functions for displaying a list of items in an ajaxified HTML table.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage List_Table
|
||||
* @since 4.7.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Helper class to be used only by back compat functions.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
class _WP_List_Table_Compat extends WP_List_Table {
|
||||
public $_screen;
|
||||
public $_columns;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string|WP_Screen $screen The screen hook name or screen object.
|
||||
* @param string[] $columns An array of columns with column IDs as the keys
|
||||
* and translated column names as the values.
|
||||
*/
|
||||
public function __construct( $screen, $columns = array() ) {
|
||||
if ( is_string( $screen ) ) {
|
||||
$screen = convert_to_screen( $screen );
|
||||
}
|
||||
|
||||
$this->_screen = $screen;
|
||||
|
||||
if ( ! empty( $columns ) ) {
|
||||
$this->_columns = $columns;
|
||||
add_filter( 'manage_' . $screen->id . '_columns', array( $this, 'get_columns' ), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of all, hidden, and sortable columns.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_column_info() {
|
||||
$columns = get_column_headers( $this->_screen );
|
||||
$hidden = get_hidden_columns( $this->_screen );
|
||||
$sortable = array();
|
||||
$primary = $this->get_default_primary_column_name();
|
||||
|
||||
return array( $columns, $hidden, $sortable, $primary );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of columns.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
return $this->_columns;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,77 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* List Table API: WP_Post_Comments_List_Table class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement displaying post comments in a list table.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @see WP_Comments_List_Table
|
||||
*/
|
||||
class WP_Post_Comments_List_Table extends WP_Comments_List_Table {
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_column_info() {
|
||||
return array(
|
||||
array(
|
||||
'author' => __( 'Author' ),
|
||||
'comment' => _x( 'Comment', 'column name' ),
|
||||
),
|
||||
array(),
|
||||
array(),
|
||||
'comment',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_table_classes() {
|
||||
$classes = parent::get_table_classes();
|
||||
$classes[] = 'wp-list-table';
|
||||
$classes[] = 'comments-box';
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $output_empty
|
||||
*/
|
||||
public function display( $output_empty = false ) {
|
||||
$singular = $this->_args['singular'];
|
||||
|
||||
wp_nonce_field( 'fetch-list-' . get_class( $this ), '_ajax_fetch_list_nonce' );
|
||||
?>
|
||||
<table class="<?php echo implode( ' ', $this->get_table_classes() ); ?>" style="display:none;">
|
||||
<tbody id="the-comment-list"
|
||||
<?php
|
||||
if ( $singular ) {
|
||||
echo " data-wp-lists='list:$singular'";
|
||||
}
|
||||
?>
|
||||
>
|
||||
<?php
|
||||
if ( ! $output_empty ) {
|
||||
$this->display_rows_or_placeholder();
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $comment_status
|
||||
* @return int
|
||||
*/
|
||||
public function get_per_page( $comment_status = false ) {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* List Table API: WP_Post_Comments_List_Table class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement displaying post comments in a list table.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @see WP_Comments_List_Table
|
||||
*/
|
||||
class WP_Post_Comments_List_Table extends WP_Comments_List_Table {
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_column_info() {
|
||||
return array(
|
||||
array(
|
||||
'author' => __( 'Author' ),
|
||||
'comment' => _x( 'Comment', 'column name' ),
|
||||
),
|
||||
array(),
|
||||
array(),
|
||||
'comment',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_table_classes() {
|
||||
$classes = parent::get_table_classes();
|
||||
$classes[] = 'wp-list-table';
|
||||
$classes[] = 'comments-box';
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $output_empty
|
||||
*/
|
||||
public function display( $output_empty = false ) {
|
||||
$singular = $this->_args['singular'];
|
||||
|
||||
wp_nonce_field( 'fetch-list-' . get_class( $this ), '_ajax_fetch_list_nonce' );
|
||||
?>
|
||||
<table class="<?php echo implode( ' ', $this->get_table_classes() ); ?>" style="display:none;">
|
||||
<tbody id="the-comment-list"
|
||||
<?php
|
||||
if ( $singular ) {
|
||||
echo " data-wp-lists='list:$singular'";
|
||||
}
|
||||
?>
|
||||
>
|
||||
<?php
|
||||
if ( ! $output_empty ) {
|
||||
$this->display_rows_or_placeholder();
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $comment_status
|
||||
* @return int
|
||||
*/
|
||||
public function get_per_page( $comment_status = false ) {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+160
-160
@@ -1,160 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* List Table API: WP_Privacy_Data_Export_Requests_List_Table class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.9.6
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'WP_Privacy_Requests_Table' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-requests-table.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Privacy_Data_Export_Requests_Table class.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*/
|
||||
class WP_Privacy_Data_Export_Requests_List_Table extends WP_Privacy_Requests_Table {
|
||||
/**
|
||||
* Action name for the requests this table will work with.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @var string $request_type Name of action.
|
||||
*/
|
||||
protected $request_type = 'export_personal_data';
|
||||
|
||||
/**
|
||||
* Post type for the requests.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @var string $post_type The post type.
|
||||
*/
|
||||
protected $post_type = 'user_request';
|
||||
|
||||
/**
|
||||
* Actions column.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @param WP_User_Request $item Item being shown.
|
||||
* @return string Email column markup.
|
||||
*/
|
||||
public function column_email( $item ) {
|
||||
/** This filter is documented in wp-admin/includes/ajax-actions.php */
|
||||
$exporters = apply_filters( 'wp_privacy_personal_data_exporters', array() );
|
||||
$exporters_count = count( $exporters );
|
||||
$status = $item->status;
|
||||
$request_id = $item->ID;
|
||||
$nonce = wp_create_nonce( 'wp-privacy-export-personal-data-' . $request_id );
|
||||
|
||||
$download_data_markup = '<span class="export-personal-data" ' .
|
||||
'data-exporters-count="' . esc_attr( $exporters_count ) . '" ' .
|
||||
'data-request-id="' . esc_attr( $request_id ) . '" ' .
|
||||
'data-nonce="' . esc_attr( $nonce ) .
|
||||
'">';
|
||||
|
||||
$download_data_markup .= '<span class="export-personal-data-idle"><button type="button" class="button-link export-personal-data-handle">' . __( 'Download personal data' ) . '</button></span>' .
|
||||
'<span class="export-personal-data-processing hidden">' . __( 'Downloading data...' ) . ' <span class="export-progress"></span></span>' .
|
||||
'<span class="export-personal-data-success hidden"><button type="button" class="button-link export-personal-data-handle">' . __( 'Download personal data again' ) . '</button></span>' .
|
||||
'<span class="export-personal-data-failed hidden">' . __( 'Download failed.' ) . ' <button type="button" class="button-link export-personal-data-handle">' . __( 'Retry' ) . '</button></span>';
|
||||
|
||||
$download_data_markup .= '</span>';
|
||||
|
||||
$row_actions['download-data'] = $download_data_markup;
|
||||
|
||||
if ( 'request-completed' !== $status ) {
|
||||
$complete_request_markup = '<span>';
|
||||
$complete_request_markup .= sprintf(
|
||||
'<a href="%s" class="complete-request" aria-label="%s">%s</a>',
|
||||
esc_url(
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'complete',
|
||||
'request_id' => array( $request_id ),
|
||||
),
|
||||
admin_url( 'export-personal-data.php' )
|
||||
),
|
||||
'bulk-privacy_requests'
|
||||
)
|
||||
),
|
||||
esc_attr(
|
||||
sprintf(
|
||||
/* translators: %s: Request email. */
|
||||
__( 'Mark export request for “%s” as completed.' ),
|
||||
$item->email
|
||||
)
|
||||
),
|
||||
__( 'Complete request' )
|
||||
);
|
||||
$complete_request_markup .= '</span>';
|
||||
}
|
||||
|
||||
if ( ! empty( $complete_request_markup ) ) {
|
||||
$row_actions['complete-request'] = $complete_request_markup;
|
||||
}
|
||||
|
||||
return sprintf( '<a href="%1$s">%2$s</a> %3$s', esc_url( 'mailto:' . $item->email ), $item->email, $this->row_actions( $row_actions ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the next steps column.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @param WP_User_Request $item Item being shown.
|
||||
*/
|
||||
public function column_next_steps( $item ) {
|
||||
$status = $item->status;
|
||||
|
||||
switch ( $status ) {
|
||||
case 'request-pending':
|
||||
esc_html_e( 'Waiting for confirmation' );
|
||||
break;
|
||||
case 'request-confirmed':
|
||||
/** This filter is documented in wp-admin/includes/ajax-actions.php */
|
||||
$exporters = apply_filters( 'wp_privacy_personal_data_exporters', array() );
|
||||
$exporters_count = count( $exporters );
|
||||
$request_id = $item->ID;
|
||||
$nonce = wp_create_nonce( 'wp-privacy-export-personal-data-' . $request_id );
|
||||
|
||||
echo '<div class="export-personal-data" ' .
|
||||
'data-send-as-email="1" ' .
|
||||
'data-exporters-count="' . esc_attr( $exporters_count ) . '" ' .
|
||||
'data-request-id="' . esc_attr( $request_id ) . '" ' .
|
||||
'data-nonce="' . esc_attr( $nonce ) .
|
||||
'">';
|
||||
|
||||
?>
|
||||
<span class="export-personal-data-idle"><button type="button" class="button-link export-personal-data-handle"><?php _e( 'Send export link' ); ?></button></span>
|
||||
<span class="export-personal-data-processing hidden"><?php _e( 'Sending email...' ); ?> <span class="export-progress"></span></span>
|
||||
<span class="export-personal-data-success success-message hidden"><?php _e( 'Email sent.' ); ?></span>
|
||||
<span class="export-personal-data-failed hidden"><?php _e( 'Email could not be sent.' ); ?> <button type="button" class="button-link export-personal-data-handle"><?php _e( 'Retry' ); ?></button></span>
|
||||
<?php
|
||||
|
||||
echo '</div>';
|
||||
break;
|
||||
case 'request-failed':
|
||||
echo '<button type="submit" class="button-link" name="privacy_action_email_retry[' . $item->ID . ']" id="privacy_action_email_retry[' . $item->ID . ']">' . __( 'Retry' ) . '</button>';
|
||||
break;
|
||||
case 'request-completed':
|
||||
echo '<a href="' . esc_url(
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'delete',
|
||||
'request_id' => array( $item->ID ),
|
||||
),
|
||||
admin_url( 'export-personal-data.php' )
|
||||
),
|
||||
'bulk-privacy_requests'
|
||||
)
|
||||
) . '">' . esc_html__( 'Remove request' ) . '</a>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* List Table API: WP_Privacy_Data_Export_Requests_List_Table class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.9.6
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'WP_Privacy_Requests_Table' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-requests-table.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Privacy_Data_Export_Requests_Table class.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*/
|
||||
class WP_Privacy_Data_Export_Requests_List_Table extends WP_Privacy_Requests_Table {
|
||||
/**
|
||||
* Action name for the requests this table will work with.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @var string $request_type Name of action.
|
||||
*/
|
||||
protected $request_type = 'export_personal_data';
|
||||
|
||||
/**
|
||||
* Post type for the requests.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @var string $post_type The post type.
|
||||
*/
|
||||
protected $post_type = 'user_request';
|
||||
|
||||
/**
|
||||
* Actions column.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @param WP_User_Request $item Item being shown.
|
||||
* @return string Email column markup.
|
||||
*/
|
||||
public function column_email( $item ) {
|
||||
/** This filter is documented in wp-admin/includes/ajax-actions.php */
|
||||
$exporters = apply_filters( 'wp_privacy_personal_data_exporters', array() );
|
||||
$exporters_count = count( $exporters );
|
||||
$status = $item->status;
|
||||
$request_id = $item->ID;
|
||||
$nonce = wp_create_nonce( 'wp-privacy-export-personal-data-' . $request_id );
|
||||
|
||||
$download_data_markup = '<span class="export-personal-data" ' .
|
||||
'data-exporters-count="' . esc_attr( $exporters_count ) . '" ' .
|
||||
'data-request-id="' . esc_attr( $request_id ) . '" ' .
|
||||
'data-nonce="' . esc_attr( $nonce ) .
|
||||
'">';
|
||||
|
||||
$download_data_markup .= '<span class="export-personal-data-idle"><button type="button" class="button-link export-personal-data-handle">' . __( 'Download personal data' ) . '</button></span>' .
|
||||
'<span class="export-personal-data-processing hidden">' . __( 'Downloading data...' ) . ' <span class="export-progress"></span></span>' .
|
||||
'<span class="export-personal-data-success hidden"><button type="button" class="button-link export-personal-data-handle">' . __( 'Download personal data again' ) . '</button></span>' .
|
||||
'<span class="export-personal-data-failed hidden">' . __( 'Download failed.' ) . ' <button type="button" class="button-link export-personal-data-handle">' . __( 'Retry' ) . '</button></span>';
|
||||
|
||||
$download_data_markup .= '</span>';
|
||||
|
||||
$row_actions['download-data'] = $download_data_markup;
|
||||
|
||||
if ( 'request-completed' !== $status ) {
|
||||
$complete_request_markup = '<span>';
|
||||
$complete_request_markup .= sprintf(
|
||||
'<a href="%s" class="complete-request" aria-label="%s">%s</a>',
|
||||
esc_url(
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'complete',
|
||||
'request_id' => array( $request_id ),
|
||||
),
|
||||
admin_url( 'export-personal-data.php' )
|
||||
),
|
||||
'bulk-privacy_requests'
|
||||
)
|
||||
),
|
||||
esc_attr(
|
||||
sprintf(
|
||||
/* translators: %s: Request email. */
|
||||
__( 'Mark export request for “%s” as completed.' ),
|
||||
$item->email
|
||||
)
|
||||
),
|
||||
__( 'Complete request' )
|
||||
);
|
||||
$complete_request_markup .= '</span>';
|
||||
}
|
||||
|
||||
if ( ! empty( $complete_request_markup ) ) {
|
||||
$row_actions['complete-request'] = $complete_request_markup;
|
||||
}
|
||||
|
||||
return sprintf( '<a href="%1$s">%2$s</a> %3$s', esc_url( 'mailto:' . $item->email ), $item->email, $this->row_actions( $row_actions ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the next steps column.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @param WP_User_Request $item Item being shown.
|
||||
*/
|
||||
public function column_next_steps( $item ) {
|
||||
$status = $item->status;
|
||||
|
||||
switch ( $status ) {
|
||||
case 'request-pending':
|
||||
esc_html_e( 'Waiting for confirmation' );
|
||||
break;
|
||||
case 'request-confirmed':
|
||||
/** This filter is documented in wp-admin/includes/ajax-actions.php */
|
||||
$exporters = apply_filters( 'wp_privacy_personal_data_exporters', array() );
|
||||
$exporters_count = count( $exporters );
|
||||
$request_id = $item->ID;
|
||||
$nonce = wp_create_nonce( 'wp-privacy-export-personal-data-' . $request_id );
|
||||
|
||||
echo '<div class="export-personal-data" ' .
|
||||
'data-send-as-email="1" ' .
|
||||
'data-exporters-count="' . esc_attr( $exporters_count ) . '" ' .
|
||||
'data-request-id="' . esc_attr( $request_id ) . '" ' .
|
||||
'data-nonce="' . esc_attr( $nonce ) .
|
||||
'">';
|
||||
|
||||
?>
|
||||
<span class="export-personal-data-idle"><button type="button" class="button-link export-personal-data-handle"><?php _e( 'Send export link' ); ?></button></span>
|
||||
<span class="export-personal-data-processing hidden"><?php _e( 'Sending email...' ); ?> <span class="export-progress"></span></span>
|
||||
<span class="export-personal-data-success success-message hidden"><?php _e( 'Email sent.' ); ?></span>
|
||||
<span class="export-personal-data-failed hidden"><?php _e( 'Email could not be sent.' ); ?> <button type="button" class="button-link export-personal-data-handle"><?php _e( 'Retry' ); ?></button></span>
|
||||
<?php
|
||||
|
||||
echo '</div>';
|
||||
break;
|
||||
case 'request-failed':
|
||||
echo '<button type="submit" class="button-link" name="privacy_action_email_retry[' . $item->ID . ']" id="privacy_action_email_retry[' . $item->ID . ']">' . __( 'Retry' ) . '</button>';
|
||||
break;
|
||||
case 'request-completed':
|
||||
echo '<a href="' . esc_url(
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'delete',
|
||||
'request_id' => array( $item->ID ),
|
||||
),
|
||||
admin_url( 'export-personal-data.php' )
|
||||
),
|
||||
'bulk-privacy_requests'
|
||||
)
|
||||
) . '">' . esc_html__( 'Remove request' ) . '</a>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+167
-167
@@ -1,167 +1,167 @@
|
||||
<?php
|
||||
/**
|
||||
* List Table API: WP_Privacy_Data_Removal_Requests_List_Table class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.9.6
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'WP_Privacy_Requests_Table' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-requests-table.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Privacy_Data_Removal_Requests_List_Table class.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*/
|
||||
class WP_Privacy_Data_Removal_Requests_List_Table extends WP_Privacy_Requests_Table {
|
||||
/**
|
||||
* Action name for the requests this table will work with.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @var string $request_type Name of action.
|
||||
*/
|
||||
protected $request_type = 'remove_personal_data';
|
||||
|
||||
/**
|
||||
* Post type for the requests.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @var string $post_type The post type.
|
||||
*/
|
||||
protected $post_type = 'user_request';
|
||||
|
||||
/**
|
||||
* Outputs the Actions column.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @param WP_User_Request $item Item being shown.
|
||||
* @return string Email column markup.
|
||||
*/
|
||||
public function column_email( $item ) {
|
||||
$row_actions = array();
|
||||
|
||||
// Allow the administrator to "force remove" the personal data even if confirmation has not yet been received.
|
||||
$status = $item->status;
|
||||
$request_id = $item->ID;
|
||||
$row_actions = array();
|
||||
if ( 'request-confirmed' !== $status ) {
|
||||
/** This filter is documented in wp-admin/includes/ajax-actions.php */
|
||||
$erasers = apply_filters( 'wp_privacy_personal_data_erasers', array() );
|
||||
$erasers_count = count( $erasers );
|
||||
$nonce = wp_create_nonce( 'wp-privacy-erase-personal-data-' . $request_id );
|
||||
|
||||
$remove_data_markup = '<span class="remove-personal-data force-remove-personal-data" ' .
|
||||
'data-erasers-count="' . esc_attr( $erasers_count ) . '" ' .
|
||||
'data-request-id="' . esc_attr( $request_id ) . '" ' .
|
||||
'data-nonce="' . esc_attr( $nonce ) .
|
||||
'">';
|
||||
|
||||
$remove_data_markup .= '<span class="remove-personal-data-idle"><button type="button" class="button-link remove-personal-data-handle">' . __( 'Force erase personal data' ) . '</button></span>' .
|
||||
'<span class="remove-personal-data-processing hidden">' . __( 'Erasing data...' ) . ' <span class="erasure-progress"></span></span>' .
|
||||
'<span class="remove-personal-data-success hidden">' . __( 'Erasure completed.' ) . '</span>' .
|
||||
'<span class="remove-personal-data-failed hidden">' . __( 'Force erasure has failed.' ) . ' <button type="button" class="button-link remove-personal-data-handle">' . __( 'Retry' ) . '</button></span>';
|
||||
|
||||
$remove_data_markup .= '</span>';
|
||||
|
||||
$row_actions['remove-data'] = $remove_data_markup;
|
||||
}
|
||||
|
||||
if ( 'request-completed' !== $status ) {
|
||||
$complete_request_markup = '<span>';
|
||||
$complete_request_markup .= sprintf(
|
||||
'<a href="%s" class="complete-request" aria-label="%s">%s</a>',
|
||||
esc_url(
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'complete',
|
||||
'request_id' => array( $request_id ),
|
||||
),
|
||||
admin_url( 'erase-personal-data.php' )
|
||||
),
|
||||
'bulk-privacy_requests'
|
||||
)
|
||||
),
|
||||
esc_attr(
|
||||
sprintf(
|
||||
/* translators: %s: Request email. */
|
||||
__( 'Mark export request for “%s” as completed.' ),
|
||||
$item->email
|
||||
)
|
||||
),
|
||||
__( 'Complete request' )
|
||||
);
|
||||
$complete_request_markup .= '</span>';
|
||||
}
|
||||
|
||||
if ( ! empty( $complete_request_markup ) ) {
|
||||
$row_actions['complete-request'] = $complete_request_markup;
|
||||
}
|
||||
|
||||
return sprintf( '<a href="%1$s">%2$s</a> %3$s', esc_url( 'mailto:' . $item->email ), $item->email, $this->row_actions( $row_actions ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the Next steps column.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @param WP_User_Request $item Item being shown.
|
||||
*/
|
||||
public function column_next_steps( $item ) {
|
||||
$status = $item->status;
|
||||
|
||||
switch ( $status ) {
|
||||
case 'request-pending':
|
||||
esc_html_e( 'Waiting for confirmation' );
|
||||
break;
|
||||
case 'request-confirmed':
|
||||
/** This filter is documented in wp-admin/includes/ajax-actions.php */
|
||||
$erasers = apply_filters( 'wp_privacy_personal_data_erasers', array() );
|
||||
$erasers_count = count( $erasers );
|
||||
$request_id = $item->ID;
|
||||
$nonce = wp_create_nonce( 'wp-privacy-erase-personal-data-' . $request_id );
|
||||
|
||||
echo '<div class="remove-personal-data" ' .
|
||||
'data-force-erase="1" ' .
|
||||
'data-erasers-count="' . esc_attr( $erasers_count ) . '" ' .
|
||||
'data-request-id="' . esc_attr( $request_id ) . '" ' .
|
||||
'data-nonce="' . esc_attr( $nonce ) .
|
||||
'">';
|
||||
|
||||
?>
|
||||
<span class="remove-personal-data-idle"><button type="button" class="button-link remove-personal-data-handle"><?php _e( 'Erase personal data' ); ?></button></span>
|
||||
<span class="remove-personal-data-processing hidden"><?php _e( 'Erasing data...' ); ?> <span class="erasure-progress"></span></span>
|
||||
<span class="remove-personal-data-success success-message hidden" ><?php _e( 'Erasure completed.' ); ?></span>
|
||||
<span class="remove-personal-data-failed hidden"><?php _e( 'Data erasure has failed.' ); ?> <button type="button" class="button-link remove-personal-data-handle"><?php _e( 'Retry' ); ?></button></span>
|
||||
<?php
|
||||
|
||||
echo '</div>';
|
||||
|
||||
break;
|
||||
case 'request-failed':
|
||||
echo '<button type="submit" class="button-link" name="privacy_action_email_retry[' . $item->ID . ']" id="privacy_action_email_retry[' . $item->ID . ']">' . __( 'Retry' ) . '</button>';
|
||||
break;
|
||||
case 'request-completed':
|
||||
echo '<a href="' . esc_url(
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'delete',
|
||||
'request_id' => array( $item->ID ),
|
||||
),
|
||||
admin_url( 'erase-personal-data.php' )
|
||||
),
|
||||
'bulk-privacy_requests'
|
||||
)
|
||||
) . '">' . esc_html__( 'Remove request' ) . '</a>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* List Table API: WP_Privacy_Data_Removal_Requests_List_Table class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.9.6
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'WP_Privacy_Requests_Table' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-privacy-requests-table.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* WP_Privacy_Data_Removal_Requests_List_Table class.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*/
|
||||
class WP_Privacy_Data_Removal_Requests_List_Table extends WP_Privacy_Requests_Table {
|
||||
/**
|
||||
* Action name for the requests this table will work with.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @var string $request_type Name of action.
|
||||
*/
|
||||
protected $request_type = 'remove_personal_data';
|
||||
|
||||
/**
|
||||
* Post type for the requests.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @var string $post_type The post type.
|
||||
*/
|
||||
protected $post_type = 'user_request';
|
||||
|
||||
/**
|
||||
* Outputs the Actions column.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @param WP_User_Request $item Item being shown.
|
||||
* @return string Email column markup.
|
||||
*/
|
||||
public function column_email( $item ) {
|
||||
$row_actions = array();
|
||||
|
||||
// Allow the administrator to "force remove" the personal data even if confirmation has not yet been received.
|
||||
$status = $item->status;
|
||||
$request_id = $item->ID;
|
||||
$row_actions = array();
|
||||
if ( 'request-confirmed' !== $status ) {
|
||||
/** This filter is documented in wp-admin/includes/ajax-actions.php */
|
||||
$erasers = apply_filters( 'wp_privacy_personal_data_erasers', array() );
|
||||
$erasers_count = count( $erasers );
|
||||
$nonce = wp_create_nonce( 'wp-privacy-erase-personal-data-' . $request_id );
|
||||
|
||||
$remove_data_markup = '<span class="remove-personal-data force-remove-personal-data" ' .
|
||||
'data-erasers-count="' . esc_attr( $erasers_count ) . '" ' .
|
||||
'data-request-id="' . esc_attr( $request_id ) . '" ' .
|
||||
'data-nonce="' . esc_attr( $nonce ) .
|
||||
'">';
|
||||
|
||||
$remove_data_markup .= '<span class="remove-personal-data-idle"><button type="button" class="button-link remove-personal-data-handle">' . __( 'Force erase personal data' ) . '</button></span>' .
|
||||
'<span class="remove-personal-data-processing hidden">' . __( 'Erasing data...' ) . ' <span class="erasure-progress"></span></span>' .
|
||||
'<span class="remove-personal-data-success hidden">' . __( 'Erasure completed.' ) . '</span>' .
|
||||
'<span class="remove-personal-data-failed hidden">' . __( 'Force erasure has failed.' ) . ' <button type="button" class="button-link remove-personal-data-handle">' . __( 'Retry' ) . '</button></span>';
|
||||
|
||||
$remove_data_markup .= '</span>';
|
||||
|
||||
$row_actions['remove-data'] = $remove_data_markup;
|
||||
}
|
||||
|
||||
if ( 'request-completed' !== $status ) {
|
||||
$complete_request_markup = '<span>';
|
||||
$complete_request_markup .= sprintf(
|
||||
'<a href="%s" class="complete-request" aria-label="%s">%s</a>',
|
||||
esc_url(
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'complete',
|
||||
'request_id' => array( $request_id ),
|
||||
),
|
||||
admin_url( 'erase-personal-data.php' )
|
||||
),
|
||||
'bulk-privacy_requests'
|
||||
)
|
||||
),
|
||||
esc_attr(
|
||||
sprintf(
|
||||
/* translators: %s: Request email. */
|
||||
__( 'Mark export request for “%s” as completed.' ),
|
||||
$item->email
|
||||
)
|
||||
),
|
||||
__( 'Complete request' )
|
||||
);
|
||||
$complete_request_markup .= '</span>';
|
||||
}
|
||||
|
||||
if ( ! empty( $complete_request_markup ) ) {
|
||||
$row_actions['complete-request'] = $complete_request_markup;
|
||||
}
|
||||
|
||||
return sprintf( '<a href="%1$s">%2$s</a> %3$s', esc_url( 'mailto:' . $item->email ), $item->email, $this->row_actions( $row_actions ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the Next steps column.
|
||||
*
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @param WP_User_Request $item Item being shown.
|
||||
*/
|
||||
public function column_next_steps( $item ) {
|
||||
$status = $item->status;
|
||||
|
||||
switch ( $status ) {
|
||||
case 'request-pending':
|
||||
esc_html_e( 'Waiting for confirmation' );
|
||||
break;
|
||||
case 'request-confirmed':
|
||||
/** This filter is documented in wp-admin/includes/ajax-actions.php */
|
||||
$erasers = apply_filters( 'wp_privacy_personal_data_erasers', array() );
|
||||
$erasers_count = count( $erasers );
|
||||
$request_id = $item->ID;
|
||||
$nonce = wp_create_nonce( 'wp-privacy-erase-personal-data-' . $request_id );
|
||||
|
||||
echo '<div class="remove-personal-data" ' .
|
||||
'data-force-erase="1" ' .
|
||||
'data-erasers-count="' . esc_attr( $erasers_count ) . '" ' .
|
||||
'data-request-id="' . esc_attr( $request_id ) . '" ' .
|
||||
'data-nonce="' . esc_attr( $nonce ) .
|
||||
'">';
|
||||
|
||||
?>
|
||||
<span class="remove-personal-data-idle"><button type="button" class="button-link remove-personal-data-handle"><?php _e( 'Erase personal data' ); ?></button></span>
|
||||
<span class="remove-personal-data-processing hidden"><?php _e( 'Erasing data...' ); ?> <span class="erasure-progress"></span></span>
|
||||
<span class="remove-personal-data-success success-message hidden" ><?php _e( 'Erasure completed.' ); ?></span>
|
||||
<span class="remove-personal-data-failed hidden"><?php _e( 'Data erasure has failed.' ); ?> <button type="button" class="button-link remove-personal-data-handle"><?php _e( 'Retry' ); ?></button></span>
|
||||
<?php
|
||||
|
||||
echo '</div>';
|
||||
|
||||
break;
|
||||
case 'request-failed':
|
||||
echo '<button type="submit" class="button-link" name="privacy_action_email_retry[' . $item->ID . ']" id="privacy_action_email_retry[' . $item->ID . ']">' . __( 'Retry' ) . '</button>';
|
||||
break;
|
||||
case 'request-completed':
|
||||
echo '<a href="' . esc_url(
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'action' => 'delete',
|
||||
'request_id' => array( $item->ID ),
|
||||
),
|
||||
admin_url( 'erase-personal-data.php' )
|
||||
),
|
||||
'bulk-privacy_requests'
|
||||
)
|
||||
) . '">' . esc_html__( 'Remove request' ) . '</a>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,458 +1,458 @@
|
||||
<?php
|
||||
/**
|
||||
* Class for testing automatic updates in the WordPress code.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Site_Health
|
||||
* @since 5.2.0
|
||||
*/
|
||||
|
||||
#[AllowDynamicProperties]
|
||||
class WP_Site_Health_Auto_Updates {
|
||||
/**
|
||||
* WP_Site_Health_Auto_Updates constructor.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
public function __construct() {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs tests to determine if auto-updates can run.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function run_tests() {
|
||||
$tests = array(
|
||||
$this->test_constants( 'WP_AUTO_UPDATE_CORE', array( true, 'beta', 'rc', 'development', 'branch-development', 'minor' ) ),
|
||||
$this->test_wp_version_check_attached(),
|
||||
$this->test_filters_automatic_updater_disabled(),
|
||||
$this->test_wp_automatic_updates_disabled(),
|
||||
$this->test_if_failed_update(),
|
||||
$this->test_vcs_abspath(),
|
||||
$this->test_check_wp_filesystem_method(),
|
||||
$this->test_all_files_writable(),
|
||||
$this->test_accepts_dev_updates(),
|
||||
$this->test_accepts_minor_updates(),
|
||||
);
|
||||
|
||||
$tests = array_filter( $tests );
|
||||
$tests = array_map(
|
||||
static function ( $test ) {
|
||||
$test = (object) $test;
|
||||
|
||||
if ( empty( $test->severity ) ) {
|
||||
$test->severity = 'warning';
|
||||
}
|
||||
|
||||
return $test;
|
||||
},
|
||||
$tests
|
||||
);
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if auto-updates related constants are set correctly.
|
||||
*
|
||||
* @since 5.2.0
|
||||
* @since 5.5.1 The `$value` parameter can accept an array.
|
||||
*
|
||||
* @param string $constant The name of the constant to check.
|
||||
* @param bool|string|array $value The value that the constant should be, if set,
|
||||
* or an array of acceptable values.
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function test_constants( $constant, $value ) {
|
||||
$acceptable_values = (array) $value;
|
||||
|
||||
if ( defined( $constant ) && ! in_array( constant( $constant ), $acceptable_values, true ) ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: 1: Name of the constant used. 2: Value of the constant used. */
|
||||
__( 'The %1$s constant is defined as %2$s' ),
|
||||
"<code>$constant</code>",
|
||||
'<code>' . esc_html( var_export( constant( $constant ), true ) ) . '</code>'
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if updates are intercepted by a filter.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function test_wp_version_check_attached() {
|
||||
if ( ( ! is_multisite() || is_main_site() && is_network_admin() )
|
||||
&& ! has_filter( 'wp_version_check', 'wp_version_check' )
|
||||
) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: %s: Name of the filter used. */
|
||||
__( 'A plugin has prevented updates by disabling %s.' ),
|
||||
'<code>wp_version_check()</code>'
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if automatic updates are disabled by a filter.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function test_filters_automatic_updater_disabled() {
|
||||
/** This filter is documented in wp-admin/includes/class-wp-automatic-updater.php */
|
||||
if ( apply_filters( 'automatic_updater_disabled', false ) ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: %s: Name of the filter used. */
|
||||
__( 'The %s filter is enabled.' ),
|
||||
'<code>automatic_updater_disabled</code>'
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if automatic updates are disabled.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*
|
||||
* @return array|false The test results. False if auto-updates are enabled.
|
||||
*/
|
||||
public function test_wp_automatic_updates_disabled() {
|
||||
if ( ! class_exists( 'WP_Automatic_Updater' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-automatic-updater.php';
|
||||
}
|
||||
|
||||
$auto_updates = new WP_Automatic_Updater();
|
||||
|
||||
if ( ! $auto_updates->is_disabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array(
|
||||
'description' => __( 'All automatic updates are disabled.' ),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if automatic updates have tried to run, but failed, previously.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array|false The test results. False if the auto-updates failed.
|
||||
*/
|
||||
public function test_if_failed_update() {
|
||||
$failed = get_site_option( 'auto_core_update_failed' );
|
||||
|
||||
if ( ! $failed ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! empty( $failed['critical'] ) ) {
|
||||
$description = __( 'A previous automatic background update ended with a critical failure, so updates are now disabled.' );
|
||||
$description .= ' ' . __( 'You would have received an email because of this.' );
|
||||
$description .= ' ' . __( "When you've been able to update using the \"Update now\" button on Dashboard > Updates, this error will be cleared for future update attempts." );
|
||||
$description .= ' ' . sprintf(
|
||||
/* translators: %s: Code of error shown. */
|
||||
__( 'The error code was %s.' ),
|
||||
'<code>' . $failed['error_code'] . '</code>'
|
||||
);
|
||||
return array(
|
||||
'description' => $description,
|
||||
'severity' => 'warning',
|
||||
);
|
||||
}
|
||||
|
||||
$description = __( 'A previous automatic background update could not occur.' );
|
||||
if ( empty( $failed['retry'] ) ) {
|
||||
$description .= ' ' . __( 'You would have received an email because of this.' );
|
||||
}
|
||||
|
||||
$description .= ' ' . __( 'Another attempt will be made with the next release.' );
|
||||
$description .= ' ' . sprintf(
|
||||
/* translators: %s: Code of error shown. */
|
||||
__( 'The error code was %s.' ),
|
||||
'<code>' . $failed['error_code'] . '</code>'
|
||||
);
|
||||
return array(
|
||||
'description' => $description,
|
||||
'severity' => 'warning',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if WordPress is controlled by a VCS (Git, Subversion etc).
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function test_vcs_abspath() {
|
||||
$context_dirs = array( ABSPATH );
|
||||
$vcs_dirs = array( '.svn', '.git', '.hg', '.bzr' );
|
||||
$check_dirs = array();
|
||||
|
||||
foreach ( $context_dirs as $context_dir ) {
|
||||
// Walk up from $context_dir to the root.
|
||||
do {
|
||||
$check_dirs[] = $context_dir;
|
||||
|
||||
// Once we've hit '/' or 'C:\', we need to stop. dirname will keep returning the input here.
|
||||
if ( dirname( $context_dir ) === $context_dir ) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Continue one level at a time.
|
||||
} while ( $context_dir = dirname( $context_dir ) );
|
||||
}
|
||||
|
||||
$check_dirs = array_unique( $check_dirs );
|
||||
|
||||
// Search all directories we've found for evidence of version control.
|
||||
foreach ( $vcs_dirs as $vcs_dir ) {
|
||||
foreach ( $check_dirs as $check_dir ) {
|
||||
// phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition,Squiz.PHP.DisallowMultipleAssignments
|
||||
if ( $checkout = @is_dir( rtrim( $check_dir, '\\/' ) . "/$vcs_dir" ) ) {
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** This filter is documented in wp-admin/includes/class-wp-automatic-updater.php */
|
||||
if ( $checkout && ! apply_filters( 'automatic_updates_is_vcs_checkout', true, ABSPATH ) ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: 1: Folder name. 2: Version control directory. 3: Filter name. */
|
||||
__( 'The folder %1$s was detected as being under version control (%2$s), but the %3$s filter is allowing updates.' ),
|
||||
'<code>' . $check_dir . '</code>',
|
||||
"<code>$vcs_dir</code>",
|
||||
'<code>automatic_updates_is_vcs_checkout</code>'
|
||||
),
|
||||
'severity' => 'info',
|
||||
);
|
||||
}
|
||||
|
||||
if ( $checkout ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: 1: Folder name. 2: Version control directory. */
|
||||
__( 'The folder %1$s was detected as being under version control (%2$s).' ),
|
||||
'<code>' . $check_dir . '</code>',
|
||||
"<code>$vcs_dir</code>"
|
||||
),
|
||||
'severity' => 'warning',
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'description' => __( 'No version control systems were detected.' ),
|
||||
'severity' => 'pass',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if we can access files without providing credentials.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function test_check_wp_filesystem_method() {
|
||||
// Make sure the `request_filesystem_credentials()` function is available during our REST API call.
|
||||
if ( ! function_exists( 'request_filesystem_credentials' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
}
|
||||
|
||||
$skin = new Automatic_Upgrader_Skin();
|
||||
$success = $skin->request_filesystem_credentials( false, ABSPATH );
|
||||
|
||||
if ( ! $success ) {
|
||||
$description = __( 'Your installation of WordPress prompts for FTP credentials to perform updates.' );
|
||||
$description .= ' ' . __( '(Your site is performing updates over FTP due to file ownership. Talk to your hosting company.)' );
|
||||
|
||||
return array(
|
||||
'description' => $description,
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'description' => __( 'Your installation of WordPress does not require FTP credentials to perform updates.' ),
|
||||
'severity' => 'pass',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if core files are writable by the web user/group.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
*
|
||||
* @return array|false The test results. False if they're not writeable.
|
||||
*/
|
||||
public function test_all_files_writable() {
|
||||
global $wp_filesystem;
|
||||
|
||||
require ABSPATH . WPINC . '/version.php'; // $wp_version; // x.y.z
|
||||
|
||||
$skin = new Automatic_Upgrader_Skin();
|
||||
$success = $skin->request_filesystem_credentials( false, ABSPATH );
|
||||
|
||||
if ( ! $success ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WP_Filesystem();
|
||||
|
||||
if ( 'direct' !== $wp_filesystem->method ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the `get_core_checksums()` function is available during our REST API call.
|
||||
if ( ! function_exists( 'get_core_checksums' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/update.php';
|
||||
}
|
||||
|
||||
$checksums = get_core_checksums( $wp_version, 'en_US' );
|
||||
$dev = ( str_contains( $wp_version, '-' ) );
|
||||
// Get the last stable version's files and test against that.
|
||||
if ( ! $checksums && $dev ) {
|
||||
$checksums = get_core_checksums( (float) $wp_version - 0.1, 'en_US' );
|
||||
}
|
||||
|
||||
// There aren't always checksums for development releases, so just skip the test if we still can't find any.
|
||||
if ( ! $checksums && $dev ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $checksums ) {
|
||||
$description = sprintf(
|
||||
/* translators: %s: WordPress version. */
|
||||
__( "Couldn't retrieve a list of the checksums for WordPress %s." ),
|
||||
$wp_version
|
||||
);
|
||||
$description .= ' ' . __( 'This could mean that connections are failing to WordPress.org.' );
|
||||
return array(
|
||||
'description' => $description,
|
||||
'severity' => 'warning',
|
||||
);
|
||||
}
|
||||
|
||||
$unwritable_files = array();
|
||||
foreach ( array_keys( $checksums ) as $file ) {
|
||||
if ( str_starts_with( $file, 'wp-content' ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! file_exists( ABSPATH . $file ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! is_writable( ABSPATH . $file ) ) {
|
||||
$unwritable_files[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $unwritable_files ) {
|
||||
if ( count( $unwritable_files ) > 20 ) {
|
||||
$unwritable_files = array_slice( $unwritable_files, 0, 20 );
|
||||
$unwritable_files[] = '...';
|
||||
}
|
||||
return array(
|
||||
'description' => __( 'Some files are not writable by WordPress:' ) . ' <ul><li>' . implode( '</li><li>', $unwritable_files ) . '</li></ul>',
|
||||
'severity' => 'fail',
|
||||
);
|
||||
} else {
|
||||
return array(
|
||||
'description' => __( 'All of your WordPress files are writable.' ),
|
||||
'severity' => 'pass',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the install is using a development branch and can use nightly packages.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array|false The test results. False if it isn't a development version.
|
||||
*/
|
||||
public function test_accepts_dev_updates() {
|
||||
require ABSPATH . WPINC . '/version.php'; // $wp_version; // x.y.z
|
||||
// Only for dev versions.
|
||||
if ( ! str_contains( $wp_version, '-' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( defined( 'WP_AUTO_UPDATE_CORE' ) && ( 'minor' === WP_AUTO_UPDATE_CORE || false === WP_AUTO_UPDATE_CORE ) ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: %s: Name of the constant used. */
|
||||
__( 'WordPress development updates are blocked by the %s constant.' ),
|
||||
'<code>WP_AUTO_UPDATE_CORE</code>'
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
|
||||
/** This filter is documented in wp-admin/includes/class-core-upgrader.php */
|
||||
if ( ! apply_filters( 'allow_dev_auto_core_updates', $wp_version ) ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: %s: Name of the filter used. */
|
||||
__( 'WordPress development updates are blocked by the %s filter.' ),
|
||||
'<code>allow_dev_auto_core_updates</code>'
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the site supports automatic minor updates.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function test_accepts_minor_updates() {
|
||||
if ( defined( 'WP_AUTO_UPDATE_CORE' ) && false === WP_AUTO_UPDATE_CORE ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: %s: Name of the constant used. */
|
||||
__( 'WordPress security and maintenance releases are blocked by %s.' ),
|
||||
"<code>define( 'WP_AUTO_UPDATE_CORE', false );</code>"
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
|
||||
/** This filter is documented in wp-admin/includes/class-core-upgrader.php */
|
||||
if ( ! apply_filters( 'allow_minor_auto_core_updates', true ) ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: %s: Name of the filter used. */
|
||||
__( 'WordPress security and maintenance releases are blocked by the %s filter.' ),
|
||||
'<code>allow_minor_auto_core_updates</code>'
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Class for testing automatic updates in the WordPress code.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Site_Health
|
||||
* @since 5.2.0
|
||||
*/
|
||||
|
||||
#[AllowDynamicProperties]
|
||||
class WP_Site_Health_Auto_Updates {
|
||||
/**
|
||||
* WP_Site_Health_Auto_Updates constructor.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*/
|
||||
public function __construct() {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Runs tests to determine if auto-updates can run.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function run_tests() {
|
||||
$tests = array(
|
||||
$this->test_constants( 'WP_AUTO_UPDATE_CORE', array( true, 'beta', 'rc', 'development', 'branch-development', 'minor' ) ),
|
||||
$this->test_wp_version_check_attached(),
|
||||
$this->test_filters_automatic_updater_disabled(),
|
||||
$this->test_wp_automatic_updates_disabled(),
|
||||
$this->test_if_failed_update(),
|
||||
$this->test_vcs_abspath(),
|
||||
$this->test_check_wp_filesystem_method(),
|
||||
$this->test_all_files_writable(),
|
||||
$this->test_accepts_dev_updates(),
|
||||
$this->test_accepts_minor_updates(),
|
||||
);
|
||||
|
||||
$tests = array_filter( $tests );
|
||||
$tests = array_map(
|
||||
static function ( $test ) {
|
||||
$test = (object) $test;
|
||||
|
||||
if ( empty( $test->severity ) ) {
|
||||
$test->severity = 'warning';
|
||||
}
|
||||
|
||||
return $test;
|
||||
},
|
||||
$tests
|
||||
);
|
||||
|
||||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if auto-updates related constants are set correctly.
|
||||
*
|
||||
* @since 5.2.0
|
||||
* @since 5.5.1 The `$value` parameter can accept an array.
|
||||
*
|
||||
* @param string $constant The name of the constant to check.
|
||||
* @param bool|string|array $value The value that the constant should be, if set,
|
||||
* or an array of acceptable values.
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function test_constants( $constant, $value ) {
|
||||
$acceptable_values = (array) $value;
|
||||
|
||||
if ( defined( $constant ) && ! in_array( constant( $constant ), $acceptable_values, true ) ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: 1: Name of the constant used. 2: Value of the constant used. */
|
||||
__( 'The %1$s constant is defined as %2$s' ),
|
||||
"<code>$constant</code>",
|
||||
'<code>' . esc_html( var_export( constant( $constant ), true ) ) . '</code>'
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if updates are intercepted by a filter.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function test_wp_version_check_attached() {
|
||||
if ( ( ! is_multisite() || is_main_site() && is_network_admin() )
|
||||
&& ! has_filter( 'wp_version_check', 'wp_version_check' )
|
||||
) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: %s: Name of the filter used. */
|
||||
__( 'A plugin has prevented updates by disabling %s.' ),
|
||||
'<code>wp_version_check()</code>'
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if automatic updates are disabled by a filter.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function test_filters_automatic_updater_disabled() {
|
||||
/** This filter is documented in wp-admin/includes/class-wp-automatic-updater.php */
|
||||
if ( apply_filters( 'automatic_updater_disabled', false ) ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: %s: Name of the filter used. */
|
||||
__( 'The %s filter is enabled.' ),
|
||||
'<code>automatic_updater_disabled</code>'
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if automatic updates are disabled.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*
|
||||
* @return array|false The test results. False if auto-updates are enabled.
|
||||
*/
|
||||
public function test_wp_automatic_updates_disabled() {
|
||||
if ( ! class_exists( 'WP_Automatic_Updater' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-automatic-updater.php';
|
||||
}
|
||||
|
||||
$auto_updates = new WP_Automatic_Updater();
|
||||
|
||||
if ( ! $auto_updates->is_disabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array(
|
||||
'description' => __( 'All automatic updates are disabled.' ),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if automatic updates have tried to run, but failed, previously.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array|false The test results. False if the auto-updates failed.
|
||||
*/
|
||||
public function test_if_failed_update() {
|
||||
$failed = get_site_option( 'auto_core_update_failed' );
|
||||
|
||||
if ( ! $failed ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! empty( $failed['critical'] ) ) {
|
||||
$description = __( 'A previous automatic background update ended with a critical failure, so updates are now disabled.' );
|
||||
$description .= ' ' . __( 'You would have received an email because of this.' );
|
||||
$description .= ' ' . __( "When you've been able to update using the \"Update now\" button on Dashboard > Updates, this error will be cleared for future update attempts." );
|
||||
$description .= ' ' . sprintf(
|
||||
/* translators: %s: Code of error shown. */
|
||||
__( 'The error code was %s.' ),
|
||||
'<code>' . $failed['error_code'] . '</code>'
|
||||
);
|
||||
return array(
|
||||
'description' => $description,
|
||||
'severity' => 'warning',
|
||||
);
|
||||
}
|
||||
|
||||
$description = __( 'A previous automatic background update could not occur.' );
|
||||
if ( empty( $failed['retry'] ) ) {
|
||||
$description .= ' ' . __( 'You would have received an email because of this.' );
|
||||
}
|
||||
|
||||
$description .= ' ' . __( 'Another attempt will be made with the next release.' );
|
||||
$description .= ' ' . sprintf(
|
||||
/* translators: %s: Code of error shown. */
|
||||
__( 'The error code was %s.' ),
|
||||
'<code>' . $failed['error_code'] . '</code>'
|
||||
);
|
||||
return array(
|
||||
'description' => $description,
|
||||
'severity' => 'warning',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if WordPress is controlled by a VCS (Git, Subversion etc).
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function test_vcs_abspath() {
|
||||
$context_dirs = array( ABSPATH );
|
||||
$vcs_dirs = array( '.svn', '.git', '.hg', '.bzr' );
|
||||
$check_dirs = array();
|
||||
|
||||
foreach ( $context_dirs as $context_dir ) {
|
||||
// Walk up from $context_dir to the root.
|
||||
do {
|
||||
$check_dirs[] = $context_dir;
|
||||
|
||||
// Once we've hit '/' or 'C:\', we need to stop. dirname will keep returning the input here.
|
||||
if ( dirname( $context_dir ) === $context_dir ) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Continue one level at a time.
|
||||
} while ( $context_dir = dirname( $context_dir ) );
|
||||
}
|
||||
|
||||
$check_dirs = array_unique( $check_dirs );
|
||||
|
||||
// Search all directories we've found for evidence of version control.
|
||||
foreach ( $vcs_dirs as $vcs_dir ) {
|
||||
foreach ( $check_dirs as $check_dir ) {
|
||||
// phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition,Squiz.PHP.DisallowMultipleAssignments
|
||||
if ( $checkout = @is_dir( rtrim( $check_dir, '\\/' ) . "/$vcs_dir" ) ) {
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** This filter is documented in wp-admin/includes/class-wp-automatic-updater.php */
|
||||
if ( $checkout && ! apply_filters( 'automatic_updates_is_vcs_checkout', true, ABSPATH ) ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: 1: Folder name. 2: Version control directory. 3: Filter name. */
|
||||
__( 'The folder %1$s was detected as being under version control (%2$s), but the %3$s filter is allowing updates.' ),
|
||||
'<code>' . $check_dir . '</code>',
|
||||
"<code>$vcs_dir</code>",
|
||||
'<code>automatic_updates_is_vcs_checkout</code>'
|
||||
),
|
||||
'severity' => 'info',
|
||||
);
|
||||
}
|
||||
|
||||
if ( $checkout ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: 1: Folder name. 2: Version control directory. */
|
||||
__( 'The folder %1$s was detected as being under version control (%2$s).' ),
|
||||
'<code>' . $check_dir . '</code>',
|
||||
"<code>$vcs_dir</code>"
|
||||
),
|
||||
'severity' => 'warning',
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'description' => __( 'No version control systems were detected.' ),
|
||||
'severity' => 'pass',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if we can access files without providing credentials.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function test_check_wp_filesystem_method() {
|
||||
// Make sure the `request_filesystem_credentials()` function is available during our REST API call.
|
||||
if ( ! function_exists( 'request_filesystem_credentials' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
}
|
||||
|
||||
$skin = new Automatic_Upgrader_Skin();
|
||||
$success = $skin->request_filesystem_credentials( false, ABSPATH );
|
||||
|
||||
if ( ! $success ) {
|
||||
$description = __( 'Your installation of WordPress prompts for FTP credentials to perform updates.' );
|
||||
$description .= ' ' . __( '(Your site is performing updates over FTP due to file ownership. Talk to your hosting company.)' );
|
||||
|
||||
return array(
|
||||
'description' => $description,
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'description' => __( 'Your installation of WordPress does not require FTP credentials to perform updates.' ),
|
||||
'severity' => 'pass',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if core files are writable by the web user/group.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
*
|
||||
* @return array|false The test results. False if they're not writeable.
|
||||
*/
|
||||
public function test_all_files_writable() {
|
||||
global $wp_filesystem;
|
||||
|
||||
require ABSPATH . WPINC . '/version.php'; // $wp_version; // x.y.z
|
||||
|
||||
$skin = new Automatic_Upgrader_Skin();
|
||||
$success = $skin->request_filesystem_credentials( false, ABSPATH );
|
||||
|
||||
if ( ! $success ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WP_Filesystem();
|
||||
|
||||
if ( 'direct' !== $wp_filesystem->method ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the `get_core_checksums()` function is available during our REST API call.
|
||||
if ( ! function_exists( 'get_core_checksums' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/update.php';
|
||||
}
|
||||
|
||||
$checksums = get_core_checksums( $wp_version, 'en_US' );
|
||||
$dev = ( str_contains( $wp_version, '-' ) );
|
||||
// Get the last stable version's files and test against that.
|
||||
if ( ! $checksums && $dev ) {
|
||||
$checksums = get_core_checksums( (float) $wp_version - 0.1, 'en_US' );
|
||||
}
|
||||
|
||||
// There aren't always checksums for development releases, so just skip the test if we still can't find any.
|
||||
if ( ! $checksums && $dev ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $checksums ) {
|
||||
$description = sprintf(
|
||||
/* translators: %s: WordPress version. */
|
||||
__( "Couldn't retrieve a list of the checksums for WordPress %s." ),
|
||||
$wp_version
|
||||
);
|
||||
$description .= ' ' . __( 'This could mean that connections are failing to WordPress.org.' );
|
||||
return array(
|
||||
'description' => $description,
|
||||
'severity' => 'warning',
|
||||
);
|
||||
}
|
||||
|
||||
$unwritable_files = array();
|
||||
foreach ( array_keys( $checksums ) as $file ) {
|
||||
if ( str_starts_with( $file, 'wp-content' ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! file_exists( ABSPATH . $file ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( ! is_writable( ABSPATH . $file ) ) {
|
||||
$unwritable_files[] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $unwritable_files ) {
|
||||
if ( count( $unwritable_files ) > 20 ) {
|
||||
$unwritable_files = array_slice( $unwritable_files, 0, 20 );
|
||||
$unwritable_files[] = '...';
|
||||
}
|
||||
return array(
|
||||
'description' => __( 'Some files are not writable by WordPress:' ) . ' <ul><li>' . implode( '</li><li>', $unwritable_files ) . '</li></ul>',
|
||||
'severity' => 'fail',
|
||||
);
|
||||
} else {
|
||||
return array(
|
||||
'description' => __( 'All of your WordPress files are writable.' ),
|
||||
'severity' => 'pass',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the install is using a development branch and can use nightly packages.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array|false The test results. False if it isn't a development version.
|
||||
*/
|
||||
public function test_accepts_dev_updates() {
|
||||
require ABSPATH . WPINC . '/version.php'; // $wp_version; // x.y.z
|
||||
// Only for dev versions.
|
||||
if ( ! str_contains( $wp_version, '-' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( defined( 'WP_AUTO_UPDATE_CORE' ) && ( 'minor' === WP_AUTO_UPDATE_CORE || false === WP_AUTO_UPDATE_CORE ) ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: %s: Name of the constant used. */
|
||||
__( 'WordPress development updates are blocked by the %s constant.' ),
|
||||
'<code>WP_AUTO_UPDATE_CORE</code>'
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
|
||||
/** This filter is documented in wp-admin/includes/class-core-upgrader.php */
|
||||
if ( ! apply_filters( 'allow_dev_auto_core_updates', $wp_version ) ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: %s: Name of the filter used. */
|
||||
__( 'WordPress development updates are blocked by the %s filter.' ),
|
||||
'<code>allow_dev_auto_core_updates</code>'
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the site supports automatic minor updates.
|
||||
*
|
||||
* @since 5.2.0
|
||||
*
|
||||
* @return array The test results.
|
||||
*/
|
||||
public function test_accepts_minor_updates() {
|
||||
if ( defined( 'WP_AUTO_UPDATE_CORE' ) && false === WP_AUTO_UPDATE_CORE ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: %s: Name of the constant used. */
|
||||
__( 'WordPress security and maintenance releases are blocked by %s.' ),
|
||||
"<code>define( 'WP_AUTO_UPDATE_CORE', false );</code>"
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
|
||||
/** This filter is documented in wp-admin/includes/class-core-upgrader.php */
|
||||
if ( ! apply_filters( 'allow_minor_auto_core_updates', true ) ) {
|
||||
return array(
|
||||
'description' => sprintf(
|
||||
/* translators: %s: Name of the filter used. */
|
||||
__( 'WordPress security and maintenance releases are blocked by the %s filter.' ),
|
||||
'<code>allow_minor_auto_core_updates</code>'
|
||||
),
|
||||
'severity' => 'fail',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,237 +1,237 @@
|
||||
<?php
|
||||
/**
|
||||
* Administration API: WP_Site_Icon class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement site icon functionality.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
class WP_Site_Icon {
|
||||
|
||||
/**
|
||||
* The minimum size of the site icon.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @var int
|
||||
*/
|
||||
public $min_size = 512;
|
||||
|
||||
/**
|
||||
* The size to which to crop the image so that we can display it in the UI nicely.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @var int
|
||||
*/
|
||||
public $page_crop = 512;
|
||||
|
||||
/**
|
||||
* List of site icon sizes.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @var int[]
|
||||
*/
|
||||
public $site_icon_sizes = array(
|
||||
/*
|
||||
* Square, medium sized tiles for IE11+.
|
||||
*
|
||||
* See https://msdn.microsoft.com/library/dn455106(v=vs.85).aspx
|
||||
*/
|
||||
270,
|
||||
|
||||
/*
|
||||
* App icon for Android/Chrome.
|
||||
*
|
||||
* @link https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android
|
||||
* @link https://developer.chrome.com/multidevice/android/installtohomescreen
|
||||
*/
|
||||
192,
|
||||
|
||||
/*
|
||||
* App icons up to iPhone 6 Plus.
|
||||
*
|
||||
* See https://developer.apple.com/library/prerelease/ios/documentation/UserExperience/Conceptual/MobileHIG/IconMatrix.html
|
||||
*/
|
||||
180,
|
||||
|
||||
// Our regular Favicon.
|
||||
32,
|
||||
);
|
||||
|
||||
/**
|
||||
* Registers actions and filters.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'delete_attachment', array( $this, 'delete_attachment_data' ) );
|
||||
add_filter( 'get_post_metadata', array( $this, 'get_post_metadata' ), 10, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an attachment 'object'.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @deprecated 6.5.0
|
||||
*
|
||||
* @param string $cropped Cropped image URL.
|
||||
* @param int $parent_attachment_id Attachment ID of parent image.
|
||||
* @return array An array with attachment object data.
|
||||
*/
|
||||
public function create_attachment_object( $cropped, $parent_attachment_id ) {
|
||||
_deprecated_function( __METHOD__, '6.5.0', 'wp_copy_parent_attachment_properties()' );
|
||||
|
||||
$parent = get_post( $parent_attachment_id );
|
||||
$parent_url = wp_get_attachment_url( $parent->ID );
|
||||
$url = str_replace( wp_basename( $parent_url ), wp_basename( $cropped ), $parent_url );
|
||||
|
||||
$size = wp_getimagesize( $cropped );
|
||||
$image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
|
||||
|
||||
$attachment = array(
|
||||
'ID' => $parent_attachment_id,
|
||||
'post_title' => wp_basename( $cropped ),
|
||||
'post_content' => $url,
|
||||
'post_mime_type' => $image_type,
|
||||
'guid' => $url,
|
||||
'context' => 'site-icon',
|
||||
);
|
||||
|
||||
return $attachment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an attachment.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param array $attachment An array with attachment object data.
|
||||
* @param string $file File path of the attached image.
|
||||
* @return int Attachment ID.
|
||||
*/
|
||||
public function insert_attachment( $attachment, $file ) {
|
||||
$attachment_id = wp_insert_attachment( $attachment, $file );
|
||||
$metadata = wp_generate_attachment_metadata( $attachment_id, $file );
|
||||
|
||||
/**
|
||||
* Filters the site icon attachment metadata.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @see wp_generate_attachment_metadata()
|
||||
*
|
||||
* @param array $metadata Attachment metadata.
|
||||
*/
|
||||
$metadata = apply_filters( 'site_icon_attachment_metadata', $metadata );
|
||||
wp_update_attachment_metadata( $attachment_id, $metadata );
|
||||
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds additional sizes to be made when creating the site icon images.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param array[] $sizes Array of arrays containing information for additional sizes.
|
||||
* @return array[] Array of arrays containing additional image sizes.
|
||||
*/
|
||||
public function additional_sizes( $sizes = array() ) {
|
||||
$only_crop_sizes = array();
|
||||
|
||||
/**
|
||||
* Filters the different dimensions that a site icon is saved in.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param int[] $site_icon_sizes Array of sizes available for the Site Icon.
|
||||
*/
|
||||
$this->site_icon_sizes = apply_filters( 'site_icon_image_sizes', $this->site_icon_sizes );
|
||||
|
||||
// Use a natural sort of numbers.
|
||||
natsort( $this->site_icon_sizes );
|
||||
$this->site_icon_sizes = array_reverse( $this->site_icon_sizes );
|
||||
|
||||
// Ensure that we only resize the image into sizes that allow cropping.
|
||||
foreach ( $sizes as $name => $size_array ) {
|
||||
if ( isset( $size_array['crop'] ) ) {
|
||||
$only_crop_sizes[ $name ] = $size_array;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $this->site_icon_sizes as $size ) {
|
||||
if ( $size < $this->min_size ) {
|
||||
$only_crop_sizes[ 'site_icon-' . $size ] = array(
|
||||
'width ' => $size,
|
||||
'height' => $size,
|
||||
'crop' => true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $only_crop_sizes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Site Icon sizes to the array of image sizes on demand.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param string[] $sizes Array of image size names.
|
||||
* @return string[] Array of image size names.
|
||||
*/
|
||||
public function intermediate_image_sizes( $sizes = array() ) {
|
||||
/** This filter is documented in wp-admin/includes/class-wp-site-icon.php */
|
||||
$this->site_icon_sizes = apply_filters( 'site_icon_image_sizes', $this->site_icon_sizes );
|
||||
foreach ( $this->site_icon_sizes as $size ) {
|
||||
$sizes[] = 'site_icon-' . $size;
|
||||
}
|
||||
|
||||
return $sizes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the Site Icon when the image file is deleted.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param int $post_id Attachment ID.
|
||||
*/
|
||||
public function delete_attachment_data( $post_id ) {
|
||||
$site_icon_id = (int) get_option( 'site_icon' );
|
||||
|
||||
if ( $site_icon_id && $post_id === $site_icon_id ) {
|
||||
delete_option( 'site_icon' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds custom image sizes when meta data for an image is requested, that happens to be used as Site Icon.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param null|array|string $value The value get_metadata() should return a single metadata value, or an
|
||||
* array of values.
|
||||
* @param int $post_id Post ID.
|
||||
* @param string $meta_key Meta key.
|
||||
* @param bool $single Whether to return only the first value of the specified `$meta_key`.
|
||||
* @return array|null|string The attachment metadata value, array of values, or null.
|
||||
*/
|
||||
public function get_post_metadata( $value, $post_id, $meta_key, $single ) {
|
||||
if ( $single && '_wp_attachment_backup_sizes' === $meta_key ) {
|
||||
$site_icon_id = (int) get_option( 'site_icon' );
|
||||
|
||||
if ( $post_id === $site_icon_id ) {
|
||||
add_filter( 'intermediate_image_sizes', array( $this, 'intermediate_image_sizes' ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Administration API: WP_Site_Icon class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement site icon functionality.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
class WP_Site_Icon {
|
||||
|
||||
/**
|
||||
* The minimum size of the site icon.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @var int
|
||||
*/
|
||||
public $min_size = 512;
|
||||
|
||||
/**
|
||||
* The size to which to crop the image so that we can display it in the UI nicely.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @var int
|
||||
*/
|
||||
public $page_crop = 512;
|
||||
|
||||
/**
|
||||
* List of site icon sizes.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @var int[]
|
||||
*/
|
||||
public $site_icon_sizes = array(
|
||||
/*
|
||||
* Square, medium sized tiles for IE11+.
|
||||
*
|
||||
* See https://msdn.microsoft.com/library/dn455106(v=vs.85).aspx
|
||||
*/
|
||||
270,
|
||||
|
||||
/*
|
||||
* App icon for Android/Chrome.
|
||||
*
|
||||
* @link https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android
|
||||
* @link https://developer.chrome.com/multidevice/android/installtohomescreen
|
||||
*/
|
||||
192,
|
||||
|
||||
/*
|
||||
* App icons up to iPhone 6 Plus.
|
||||
*
|
||||
* See https://developer.apple.com/library/prerelease/ios/documentation/UserExperience/Conceptual/MobileHIG/IconMatrix.html
|
||||
*/
|
||||
180,
|
||||
|
||||
// Our regular Favicon.
|
||||
32,
|
||||
);
|
||||
|
||||
/**
|
||||
* Registers actions and filters.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'delete_attachment', array( $this, 'delete_attachment_data' ) );
|
||||
add_filter( 'get_post_metadata', array( $this, 'get_post_metadata' ), 10, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an attachment 'object'.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @deprecated 6.5.0
|
||||
*
|
||||
* @param string $cropped Cropped image URL.
|
||||
* @param int $parent_attachment_id Attachment ID of parent image.
|
||||
* @return array An array with attachment object data.
|
||||
*/
|
||||
public function create_attachment_object( $cropped, $parent_attachment_id ) {
|
||||
_deprecated_function( __METHOD__, '6.5.0', 'wp_copy_parent_attachment_properties()' );
|
||||
|
||||
$parent = get_post( $parent_attachment_id );
|
||||
$parent_url = wp_get_attachment_url( $parent->ID );
|
||||
$url = str_replace( wp_basename( $parent_url ), wp_basename( $cropped ), $parent_url );
|
||||
|
||||
$size = wp_getimagesize( $cropped );
|
||||
$image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
|
||||
|
||||
$attachment = array(
|
||||
'ID' => $parent_attachment_id,
|
||||
'post_title' => wp_basename( $cropped ),
|
||||
'post_content' => $url,
|
||||
'post_mime_type' => $image_type,
|
||||
'guid' => $url,
|
||||
'context' => 'site-icon',
|
||||
);
|
||||
|
||||
return $attachment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an attachment.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param array $attachment An array with attachment object data.
|
||||
* @param string $file File path of the attached image.
|
||||
* @return int Attachment ID.
|
||||
*/
|
||||
public function insert_attachment( $attachment, $file ) {
|
||||
$attachment_id = wp_insert_attachment( $attachment, $file );
|
||||
$metadata = wp_generate_attachment_metadata( $attachment_id, $file );
|
||||
|
||||
/**
|
||||
* Filters the site icon attachment metadata.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @see wp_generate_attachment_metadata()
|
||||
*
|
||||
* @param array $metadata Attachment metadata.
|
||||
*/
|
||||
$metadata = apply_filters( 'site_icon_attachment_metadata', $metadata );
|
||||
wp_update_attachment_metadata( $attachment_id, $metadata );
|
||||
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds additional sizes to be made when creating the site icon images.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param array[] $sizes Array of arrays containing information for additional sizes.
|
||||
* @return array[] Array of arrays containing additional image sizes.
|
||||
*/
|
||||
public function additional_sizes( $sizes = array() ) {
|
||||
$only_crop_sizes = array();
|
||||
|
||||
/**
|
||||
* Filters the different dimensions that a site icon is saved in.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param int[] $site_icon_sizes Array of sizes available for the Site Icon.
|
||||
*/
|
||||
$this->site_icon_sizes = apply_filters( 'site_icon_image_sizes', $this->site_icon_sizes );
|
||||
|
||||
// Use a natural sort of numbers.
|
||||
natsort( $this->site_icon_sizes );
|
||||
$this->site_icon_sizes = array_reverse( $this->site_icon_sizes );
|
||||
|
||||
// Ensure that we only resize the image into sizes that allow cropping.
|
||||
foreach ( $sizes as $name => $size_array ) {
|
||||
if ( isset( $size_array['crop'] ) ) {
|
||||
$only_crop_sizes[ $name ] = $size_array;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $this->site_icon_sizes as $size ) {
|
||||
if ( $size < $this->min_size ) {
|
||||
$only_crop_sizes[ 'site_icon-' . $size ] = array(
|
||||
'width ' => $size,
|
||||
'height' => $size,
|
||||
'crop' => true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $only_crop_sizes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Site Icon sizes to the array of image sizes on demand.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param string[] $sizes Array of image size names.
|
||||
* @return string[] Array of image size names.
|
||||
*/
|
||||
public function intermediate_image_sizes( $sizes = array() ) {
|
||||
/** This filter is documented in wp-admin/includes/class-wp-site-icon.php */
|
||||
$this->site_icon_sizes = apply_filters( 'site_icon_image_sizes', $this->site_icon_sizes );
|
||||
foreach ( $this->site_icon_sizes as $size ) {
|
||||
$sizes[] = 'site_icon-' . $size;
|
||||
}
|
||||
|
||||
return $sizes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the Site Icon when the image file is deleted.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param int $post_id Attachment ID.
|
||||
*/
|
||||
public function delete_attachment_data( $post_id ) {
|
||||
$site_icon_id = (int) get_option( 'site_icon' );
|
||||
|
||||
if ( $site_icon_id && $post_id === $site_icon_id ) {
|
||||
delete_option( 'site_icon' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds custom image sizes when meta data for an image is requested, that happens to be used as Site Icon.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param null|array|string $value The value get_metadata() should return a single metadata value, or an
|
||||
* array of values.
|
||||
* @param int $post_id Post ID.
|
||||
* @param string $meta_key Meta key.
|
||||
* @param bool $single Whether to return only the first value of the specified `$meta_key`.
|
||||
* @return array|null|string The attachment metadata value, array of values, or null.
|
||||
*/
|
||||
public function get_post_metadata( $value, $post_id, $meta_key, $single ) {
|
||||
if ( $single && '_wp_attachment_backup_sizes' === $meta_key ) {
|
||||
$site_icon_id = (int) get_option( 'site_icon' );
|
||||
|
||||
if ( $post_id === $site_icon_id ) {
|
||||
add_filter( 'intermediate_image_sizes', array( $this, 'intermediate_image_sizes' ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,360 +1,360 @@
|
||||
<?php
|
||||
/**
|
||||
* List Table API: WP_Themes_List_Table class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 3.1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement displaying installed themes in a list table.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @see WP_List_Table
|
||||
*/
|
||||
class WP_Themes_List_Table extends WP_List_Table {
|
||||
|
||||
protected $search_terms = array();
|
||||
public $features = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @see WP_List_Table::__construct() for more information on default arguments.
|
||||
*
|
||||
* @param array $args An associative array of arguments.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'ajax' => true,
|
||||
'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function ajax_user_can() {
|
||||
// Do not check edit_theme_options here. Ajax calls for available themes require switch_themes.
|
||||
return current_user_can( 'switch_themes' );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function prepare_items() {
|
||||
$themes = wp_get_themes( array( 'allowed' => true ) );
|
||||
|
||||
if ( ! empty( $_REQUEST['s'] ) ) {
|
||||
$this->search_terms = array_unique( array_filter( array_map( 'trim', explode( ',', strtolower( wp_unslash( $_REQUEST['s'] ) ) ) ) ) );
|
||||
}
|
||||
|
||||
if ( ! empty( $_REQUEST['features'] ) ) {
|
||||
$this->features = $_REQUEST['features'];
|
||||
}
|
||||
|
||||
if ( $this->search_terms || $this->features ) {
|
||||
foreach ( $themes as $key => $theme ) {
|
||||
if ( ! $this->search_theme( $theme ) ) {
|
||||
unset( $themes[ $key ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset( $themes[ get_option( 'stylesheet' ) ] );
|
||||
WP_Theme::sort_by_name( $themes );
|
||||
|
||||
$per_page = 36;
|
||||
$page = $this->get_pagenum();
|
||||
|
||||
$start = ( $page - 1 ) * $per_page;
|
||||
|
||||
$this->items = array_slice( $themes, $start, $per_page, true );
|
||||
|
||||
$this->set_pagination_args(
|
||||
array(
|
||||
'total_items' => count( $themes ),
|
||||
'per_page' => $per_page,
|
||||
'infinite_scroll' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function no_items() {
|
||||
if ( $this->search_terms || $this->features ) {
|
||||
_e( 'No items found.' );
|
||||
return;
|
||||
}
|
||||
|
||||
$blog_id = get_current_blog_id();
|
||||
if ( is_multisite() ) {
|
||||
if ( current_user_can( 'install_themes' ) && current_user_can( 'manage_network_themes' ) ) {
|
||||
printf(
|
||||
/* translators: 1: URL to Themes tab on Edit Site screen, 2: URL to Add Themes screen. */
|
||||
__( 'You only have one theme enabled for this site right now. Visit the Network Admin to <a href="%1$s">enable</a> or <a href="%2$s">install</a> more themes.' ),
|
||||
network_admin_url( 'site-themes.php?id=' . $blog_id ),
|
||||
network_admin_url( 'theme-install.php' )
|
||||
);
|
||||
|
||||
return;
|
||||
} elseif ( current_user_can( 'manage_network_themes' ) ) {
|
||||
printf(
|
||||
/* translators: %s: URL to Themes tab on Edit Site screen. */
|
||||
__( 'You only have one theme enabled for this site right now. Visit the Network Admin to <a href="%s">enable</a> more themes.' ),
|
||||
network_admin_url( 'site-themes.php?id=' . $blog_id )
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
// Else, fallthrough. install_themes doesn't help if you can't enable it.
|
||||
} else {
|
||||
if ( current_user_can( 'install_themes' ) ) {
|
||||
printf(
|
||||
/* translators: %s: URL to Add Themes screen. */
|
||||
__( 'You only have one theme installed right now. Live a little! You can choose from over 1,000 free themes in the WordPress Theme Directory at any time: just click on the <a href="%s">Install Themes</a> tab above.' ),
|
||||
admin_url( 'theme-install.php' )
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Fallthrough.
|
||||
printf(
|
||||
/* translators: %s: Network title. */
|
||||
__( 'Only the active theme is available to you. Contact the %s administrator for information about accessing additional themes.' ),
|
||||
get_site_option( 'site_name' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $which
|
||||
*/
|
||||
public function tablenav( $which = 'top' ) {
|
||||
if ( $this->get_pagination_arg( 'total_pages' ) <= 1 ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="tablenav themes <?php echo $which; ?>">
|
||||
<?php $this->pagination( $which ); ?>
|
||||
<span class="spinner"></span>
|
||||
<br class="clear" />
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the themes table.
|
||||
*
|
||||
* Overrides the parent display() method to provide a different container.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public function display() {
|
||||
wp_nonce_field( 'fetch-list-' . get_class( $this ), '_ajax_fetch_list_nonce' );
|
||||
?>
|
||||
<?php $this->tablenav( 'top' ); ?>
|
||||
|
||||
<div id="availablethemes">
|
||||
<?php $this->display_rows_or_placeholder(); ?>
|
||||
</div>
|
||||
|
||||
<?php $this->tablenav( 'bottom' ); ?>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of column titles keyed by their column name.
|
||||
*/
|
||||
public function get_columns() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function display_rows_or_placeholder() {
|
||||
if ( $this->has_items() ) {
|
||||
$this->display_rows();
|
||||
} else {
|
||||
echo '<div class="no-items">';
|
||||
$this->no_items();
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function display_rows() {
|
||||
$themes = $this->items;
|
||||
|
||||
foreach ( $themes as $theme ) :
|
||||
?>
|
||||
<div class="available-theme">
|
||||
<?php
|
||||
|
||||
$template = $theme->get_template();
|
||||
$stylesheet = $theme->get_stylesheet();
|
||||
$title = $theme->display( 'Name' );
|
||||
$version = $theme->display( 'Version' );
|
||||
$author = $theme->display( 'Author' );
|
||||
|
||||
$activate_link = wp_nonce_url( 'themes.php?action=activate&template=' . urlencode( $template ) . '&stylesheet=' . urlencode( $stylesheet ), 'switch-theme_' . $stylesheet );
|
||||
|
||||
$actions = array();
|
||||
$actions['activate'] = sprintf(
|
||||
'<a href="%s" class="activatelink" title="%s">%s</a>',
|
||||
$activate_link,
|
||||
/* translators: %s: Theme name. */
|
||||
esc_attr( sprintf( _x( 'Activate “%s”', 'theme' ), $title ) ),
|
||||
_x( 'Activate', 'theme' )
|
||||
);
|
||||
|
||||
if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
|
||||
$actions['preview'] .= sprintf(
|
||||
'<a href="%s" class="load-customize hide-if-no-customize">%s</a>',
|
||||
wp_customize_url( $stylesheet ),
|
||||
__( 'Live Preview' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! is_multisite() && current_user_can( 'delete_themes' ) ) {
|
||||
$actions['delete'] = sprintf(
|
||||
'<a class="submitdelete deletion" href="%s" onclick="return confirm( \'%s\' );">%s</a>',
|
||||
wp_nonce_url( 'themes.php?action=delete&stylesheet=' . urlencode( $stylesheet ), 'delete-theme_' . $stylesheet ),
|
||||
/* translators: %s: Theme name. */
|
||||
esc_js( sprintf( __( "You are about to delete this theme '%s'\n 'Cancel' to stop, 'OK' to delete." ), $title ) ),
|
||||
__( 'Delete' )
|
||||
);
|
||||
}
|
||||
|
||||
/** This filter is documented in wp-admin/includes/class-wp-ms-themes-list-table.php */
|
||||
$actions = apply_filters( 'theme_action_links', $actions, $theme, 'all' );
|
||||
|
||||
/** This filter is documented in wp-admin/includes/class-wp-ms-themes-list-table.php */
|
||||
$actions = apply_filters( "theme_action_links_{$stylesheet}", $actions, $theme, 'all' );
|
||||
$delete_action = isset( $actions['delete'] ) ? '<div class="delete-theme">' . $actions['delete'] . '</div>' : '';
|
||||
unset( $actions['delete'] );
|
||||
|
||||
$screenshot = $theme->get_screenshot();
|
||||
?>
|
||||
|
||||
<span class="screenshot hide-if-customize">
|
||||
<?php if ( $screenshot ) : ?>
|
||||
<img src="<?php echo esc_url( $screenshot . '?ver=' . $theme->version ); ?>" alt="" />
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
<a href="<?php echo wp_customize_url( $stylesheet ); ?>" class="screenshot load-customize hide-if-no-customize">
|
||||
<?php if ( $screenshot ) : ?>
|
||||
<img src="<?php echo esc_url( $screenshot . '?ver=' . $theme->version ); ?>" alt="" />
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
|
||||
<h3><?php echo $title; ?></h3>
|
||||
<div class="theme-author">
|
||||
<?php
|
||||
/* translators: %s: Theme author. */
|
||||
printf( __( 'By %s' ), $author );
|
||||
?>
|
||||
</div>
|
||||
<div class="action-links">
|
||||
<ul>
|
||||
<?php foreach ( $actions as $action ) : ?>
|
||||
<li><?php echo $action; ?></li>
|
||||
<?php endforeach; ?>
|
||||
<li class="hide-if-no-js"><a href="#" class="theme-detail"><?php _e( 'Details' ); ?></a></li>
|
||||
</ul>
|
||||
<?php echo $delete_action; ?>
|
||||
|
||||
<?php theme_update_available( $theme ); ?>
|
||||
</div>
|
||||
|
||||
<div class="themedetaildiv hide-if-js">
|
||||
<p><strong><?php _e( 'Version:' ); ?></strong> <?php echo $version; ?></p>
|
||||
<p><?php echo $theme->display( 'Description' ); ?></p>
|
||||
<?php
|
||||
if ( $theme->parent() ) {
|
||||
printf(
|
||||
/* translators: 1: Link to documentation on child themes, 2: Name of parent theme. */
|
||||
' <p class="howto">' . __( 'This <a href="%1$s">child theme</a> requires its parent theme, %2$s.' ) . '</p>',
|
||||
__( 'https://developer.wordpress.org/themes/advanced-topics/child-themes/' ),
|
||||
$theme->parent()->display( 'Name' )
|
||||
);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
endforeach;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WP_Theme $theme
|
||||
* @return bool
|
||||
*/
|
||||
public function search_theme( $theme ) {
|
||||
// Search the features.
|
||||
foreach ( $this->features as $word ) {
|
||||
if ( ! in_array( $word, $theme->get( 'Tags' ), true ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Match all phrases.
|
||||
foreach ( $this->search_terms as $word ) {
|
||||
if ( in_array( $word, $theme->get( 'Tags' ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( array( 'Name', 'Description', 'Author', 'AuthorURI' ) as $header ) {
|
||||
// Don't mark up; Do translate.
|
||||
if ( false !== stripos( strip_tags( $theme->display( $header, false, true ) ), $word ) ) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ( false !== stripos( $theme->get_stylesheet(), $word ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( false !== stripos( $theme->get_template(), $word ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send required variables to JavaScript land
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param array $extra_args
|
||||
*/
|
||||
public function _js_vars( $extra_args = array() ) {
|
||||
$search_string = isset( $_REQUEST['s'] ) ? esc_attr( wp_unslash( $_REQUEST['s'] ) ) : '';
|
||||
|
||||
$args = array(
|
||||
'search' => $search_string,
|
||||
'features' => $this->features,
|
||||
'paged' => $this->get_pagenum(),
|
||||
'total_pages' => ! empty( $this->_pagination_args['total_pages'] ) ? $this->_pagination_args['total_pages'] : 1,
|
||||
);
|
||||
|
||||
if ( is_array( $extra_args ) ) {
|
||||
$args = array_merge( $args, $extra_args );
|
||||
}
|
||||
|
||||
printf( "<script type='text/javascript'>var theme_list_args = %s;</script>\n", wp_json_encode( $args ) );
|
||||
parent::_js_vars();
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* List Table API: WP_Themes_List_Table class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 3.1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement displaying installed themes in a list table.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @see WP_List_Table
|
||||
*/
|
||||
class WP_Themes_List_Table extends WP_List_Table {
|
||||
|
||||
protected $search_terms = array();
|
||||
public $features = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @see WP_List_Table::__construct() for more information on default arguments.
|
||||
*
|
||||
* @param array $args An associative array of arguments.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'ajax' => true,
|
||||
'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function ajax_user_can() {
|
||||
// Do not check edit_theme_options here. Ajax calls for available themes require switch_themes.
|
||||
return current_user_can( 'switch_themes' );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function prepare_items() {
|
||||
$themes = wp_get_themes( array( 'allowed' => true ) );
|
||||
|
||||
if ( ! empty( $_REQUEST['s'] ) ) {
|
||||
$this->search_terms = array_unique( array_filter( array_map( 'trim', explode( ',', strtolower( wp_unslash( $_REQUEST['s'] ) ) ) ) ) );
|
||||
}
|
||||
|
||||
if ( ! empty( $_REQUEST['features'] ) ) {
|
||||
$this->features = $_REQUEST['features'];
|
||||
}
|
||||
|
||||
if ( $this->search_terms || $this->features ) {
|
||||
foreach ( $themes as $key => $theme ) {
|
||||
if ( ! $this->search_theme( $theme ) ) {
|
||||
unset( $themes[ $key ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset( $themes[ get_option( 'stylesheet' ) ] );
|
||||
WP_Theme::sort_by_name( $themes );
|
||||
|
||||
$per_page = 36;
|
||||
$page = $this->get_pagenum();
|
||||
|
||||
$start = ( $page - 1 ) * $per_page;
|
||||
|
||||
$this->items = array_slice( $themes, $start, $per_page, true );
|
||||
|
||||
$this->set_pagination_args(
|
||||
array(
|
||||
'total_items' => count( $themes ),
|
||||
'per_page' => $per_page,
|
||||
'infinite_scroll' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function no_items() {
|
||||
if ( $this->search_terms || $this->features ) {
|
||||
_e( 'No items found.' );
|
||||
return;
|
||||
}
|
||||
|
||||
$blog_id = get_current_blog_id();
|
||||
if ( is_multisite() ) {
|
||||
if ( current_user_can( 'install_themes' ) && current_user_can( 'manage_network_themes' ) ) {
|
||||
printf(
|
||||
/* translators: 1: URL to Themes tab on Edit Site screen, 2: URL to Add Themes screen. */
|
||||
__( 'You only have one theme enabled for this site right now. Visit the Network Admin to <a href="%1$s">enable</a> or <a href="%2$s">install</a> more themes.' ),
|
||||
network_admin_url( 'site-themes.php?id=' . $blog_id ),
|
||||
network_admin_url( 'theme-install.php' )
|
||||
);
|
||||
|
||||
return;
|
||||
} elseif ( current_user_can( 'manage_network_themes' ) ) {
|
||||
printf(
|
||||
/* translators: %s: URL to Themes tab on Edit Site screen. */
|
||||
__( 'You only have one theme enabled for this site right now. Visit the Network Admin to <a href="%s">enable</a> more themes.' ),
|
||||
network_admin_url( 'site-themes.php?id=' . $blog_id )
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
// Else, fallthrough. install_themes doesn't help if you can't enable it.
|
||||
} else {
|
||||
if ( current_user_can( 'install_themes' ) ) {
|
||||
printf(
|
||||
/* translators: %s: URL to Add Themes screen. */
|
||||
__( 'You only have one theme installed right now. Live a little! You can choose from over 1,000 free themes in the WordPress Theme Directory at any time: just click on the <a href="%s">Install Themes</a> tab above.' ),
|
||||
admin_url( 'theme-install.php' )
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Fallthrough.
|
||||
printf(
|
||||
/* translators: %s: Network title. */
|
||||
__( 'Only the active theme is available to you. Contact the %s administrator for information about accessing additional themes.' ),
|
||||
get_site_option( 'site_name' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $which
|
||||
*/
|
||||
public function tablenav( $which = 'top' ) {
|
||||
if ( $this->get_pagination_arg( 'total_pages' ) <= 1 ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="tablenav themes <?php echo $which; ?>">
|
||||
<?php $this->pagination( $which ); ?>
|
||||
<span class="spinner"></span>
|
||||
<br class="clear" />
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the themes table.
|
||||
*
|
||||
* Overrides the parent display() method to provide a different container.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public function display() {
|
||||
wp_nonce_field( 'fetch-list-' . get_class( $this ), '_ajax_fetch_list_nonce' );
|
||||
?>
|
||||
<?php $this->tablenav( 'top' ); ?>
|
||||
|
||||
<div id="availablethemes">
|
||||
<?php $this->display_rows_or_placeholder(); ?>
|
||||
</div>
|
||||
|
||||
<?php $this->tablenav( 'bottom' ); ?>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of column titles keyed by their column name.
|
||||
*/
|
||||
public function get_columns() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function display_rows_or_placeholder() {
|
||||
if ( $this->has_items() ) {
|
||||
$this->display_rows();
|
||||
} else {
|
||||
echo '<div class="no-items">';
|
||||
$this->no_items();
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function display_rows() {
|
||||
$themes = $this->items;
|
||||
|
||||
foreach ( $themes as $theme ) :
|
||||
?>
|
||||
<div class="available-theme">
|
||||
<?php
|
||||
|
||||
$template = $theme->get_template();
|
||||
$stylesheet = $theme->get_stylesheet();
|
||||
$title = $theme->display( 'Name' );
|
||||
$version = $theme->display( 'Version' );
|
||||
$author = $theme->display( 'Author' );
|
||||
|
||||
$activate_link = wp_nonce_url( 'themes.php?action=activate&template=' . urlencode( $template ) . '&stylesheet=' . urlencode( $stylesheet ), 'switch-theme_' . $stylesheet );
|
||||
|
||||
$actions = array();
|
||||
$actions['activate'] = sprintf(
|
||||
'<a href="%s" class="activatelink" title="%s">%s</a>',
|
||||
$activate_link,
|
||||
/* translators: %s: Theme name. */
|
||||
esc_attr( sprintf( _x( 'Activate “%s”', 'theme' ), $title ) ),
|
||||
_x( 'Activate', 'theme' )
|
||||
);
|
||||
|
||||
if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
|
||||
$actions['preview'] .= sprintf(
|
||||
'<a href="%s" class="load-customize hide-if-no-customize">%s</a>',
|
||||
wp_customize_url( $stylesheet ),
|
||||
__( 'Live Preview' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! is_multisite() && current_user_can( 'delete_themes' ) ) {
|
||||
$actions['delete'] = sprintf(
|
||||
'<a class="submitdelete deletion" href="%s" onclick="return confirm( \'%s\' );">%s</a>',
|
||||
wp_nonce_url( 'themes.php?action=delete&stylesheet=' . urlencode( $stylesheet ), 'delete-theme_' . $stylesheet ),
|
||||
/* translators: %s: Theme name. */
|
||||
esc_js( sprintf( __( "You are about to delete this theme '%s'\n 'Cancel' to stop, 'OK' to delete." ), $title ) ),
|
||||
__( 'Delete' )
|
||||
);
|
||||
}
|
||||
|
||||
/** This filter is documented in wp-admin/includes/class-wp-ms-themes-list-table.php */
|
||||
$actions = apply_filters( 'theme_action_links', $actions, $theme, 'all' );
|
||||
|
||||
/** This filter is documented in wp-admin/includes/class-wp-ms-themes-list-table.php */
|
||||
$actions = apply_filters( "theme_action_links_{$stylesheet}", $actions, $theme, 'all' );
|
||||
$delete_action = isset( $actions['delete'] ) ? '<div class="delete-theme">' . $actions['delete'] . '</div>' : '';
|
||||
unset( $actions['delete'] );
|
||||
|
||||
$screenshot = $theme->get_screenshot();
|
||||
?>
|
||||
|
||||
<span class="screenshot hide-if-customize">
|
||||
<?php if ( $screenshot ) : ?>
|
||||
<img src="<?php echo esc_url( $screenshot . '?ver=' . $theme->version ); ?>" alt="" />
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
<a href="<?php echo wp_customize_url( $stylesheet ); ?>" class="screenshot load-customize hide-if-no-customize">
|
||||
<?php if ( $screenshot ) : ?>
|
||||
<img src="<?php echo esc_url( $screenshot . '?ver=' . $theme->version ); ?>" alt="" />
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
|
||||
<h3><?php echo $title; ?></h3>
|
||||
<div class="theme-author">
|
||||
<?php
|
||||
/* translators: %s: Theme author. */
|
||||
printf( __( 'By %s' ), $author );
|
||||
?>
|
||||
</div>
|
||||
<div class="action-links">
|
||||
<ul>
|
||||
<?php foreach ( $actions as $action ) : ?>
|
||||
<li><?php echo $action; ?></li>
|
||||
<?php endforeach; ?>
|
||||
<li class="hide-if-no-js"><a href="#" class="theme-detail"><?php _e( 'Details' ); ?></a></li>
|
||||
</ul>
|
||||
<?php echo $delete_action; ?>
|
||||
|
||||
<?php theme_update_available( $theme ); ?>
|
||||
</div>
|
||||
|
||||
<div class="themedetaildiv hide-if-js">
|
||||
<p><strong><?php _e( 'Version:' ); ?></strong> <?php echo $version; ?></p>
|
||||
<p><?php echo $theme->display( 'Description' ); ?></p>
|
||||
<?php
|
||||
if ( $theme->parent() ) {
|
||||
printf(
|
||||
/* translators: 1: Link to documentation on child themes, 2: Name of parent theme. */
|
||||
' <p class="howto">' . __( 'This <a href="%1$s">child theme</a> requires its parent theme, %2$s.' ) . '</p>',
|
||||
__( 'https://developer.wordpress.org/themes/advanced-topics/child-themes/' ),
|
||||
$theme->parent()->display( 'Name' )
|
||||
);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
endforeach;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WP_Theme $theme
|
||||
* @return bool
|
||||
*/
|
||||
public function search_theme( $theme ) {
|
||||
// Search the features.
|
||||
foreach ( $this->features as $word ) {
|
||||
if ( ! in_array( $word, $theme->get( 'Tags' ), true ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Match all phrases.
|
||||
foreach ( $this->search_terms as $word ) {
|
||||
if ( in_array( $word, $theme->get( 'Tags' ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( array( 'Name', 'Description', 'Author', 'AuthorURI' ) as $header ) {
|
||||
// Don't mark up; Do translate.
|
||||
if ( false !== stripos( strip_tags( $theme->display( $header, false, true ) ), $word ) ) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
if ( false !== stripos( $theme->get_stylesheet(), $word ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( false !== stripos( $theme->get_template(), $word ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send required variables to JavaScript land
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param array $extra_args
|
||||
*/
|
||||
public function _js_vars( $extra_args = array() ) {
|
||||
$search_string = isset( $_REQUEST['s'] ) ? esc_attr( wp_unslash( $_REQUEST['s'] ) ) : '';
|
||||
|
||||
$args = array(
|
||||
'search' => $search_string,
|
||||
'features' => $this->features,
|
||||
'paged' => $this->get_pagenum(),
|
||||
'total_pages' => ! empty( $this->_pagination_args['total_pages'] ) ? $this->_pagination_args['total_pages'] : 1,
|
||||
);
|
||||
|
||||
if ( is_array( $extra_args ) ) {
|
||||
$args = array_merge( $args, $extra_args );
|
||||
}
|
||||
|
||||
printf( "<script type='text/javascript'>var theme_list_args = %s;</script>\n", wp_json_encode( $args ) );
|
||||
parent::_js_vars();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,285 +1,285 @@
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: WP_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generic Skin for the WordPress Upgrader classes. This skin is designed to be extended for specific purposes.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
class WP_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Holds the upgrader data.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var WP_Upgrader
|
||||
*/
|
||||
public $upgrader;
|
||||
|
||||
/**
|
||||
* Whether header is done.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $done_header = false;
|
||||
|
||||
/**
|
||||
* Whether footer is done.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $done_footer = false;
|
||||
|
||||
/**
|
||||
* Holds the result of an upgrade.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var string|bool|WP_Error
|
||||
*/
|
||||
public $result = false;
|
||||
|
||||
/**
|
||||
* Holds the options of an upgrade.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $options = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Sets up the generic skin for the WordPress Upgrader classes.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param array $args Optional. The WordPress upgrader skin arguments to
|
||||
* override default options. Default empty array.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'url' => '',
|
||||
'nonce' => '',
|
||||
'title' => '',
|
||||
'context' => false,
|
||||
);
|
||||
$this->options = wp_parse_args( $args, $defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param WP_Upgrader $upgrader
|
||||
*/
|
||||
public function set_upgrader( &$upgrader ) {
|
||||
if ( is_object( $upgrader ) ) {
|
||||
$this->upgrader =& $upgrader;
|
||||
}
|
||||
$this->add_strings();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function add_strings() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the result of an upgrade.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string|bool|WP_Error $result The result of an upgrade.
|
||||
*/
|
||||
public function set_result( $result ) {
|
||||
$this->result = $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a form to the user to request for their FTP/SSH details in order
|
||||
* to connect to the filesystem.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 The `$context` parameter default changed from `false` to an empty string.
|
||||
*
|
||||
* @see request_filesystem_credentials()
|
||||
*
|
||||
* @param bool|WP_Error $error Optional. Whether the current request has failed to connect,
|
||||
* or an error object. Default false.
|
||||
* @param string $context Optional. Full path to the directory that is tested
|
||||
* for being writable. Default empty.
|
||||
* @param bool $allow_relaxed_file_ownership Optional. Whether to allow Group/World writable. Default false.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
|
||||
$url = $this->options['url'];
|
||||
if ( ! $context ) {
|
||||
$context = $this->options['context'];
|
||||
}
|
||||
if ( ! empty( $this->options['nonce'] ) ) {
|
||||
$url = wp_nonce_url( $url, $this->options['nonce'] );
|
||||
}
|
||||
|
||||
$extra_fields = array();
|
||||
|
||||
return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function header() {
|
||||
if ( $this->done_header ) {
|
||||
return;
|
||||
}
|
||||
$this->done_header = true;
|
||||
echo '<div class="wrap">';
|
||||
echo '<h1>' . $this->options['title'] . '</h1>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function footer() {
|
||||
if ( $this->done_footer ) {
|
||||
return;
|
||||
}
|
||||
$this->done_footer = true;
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string|WP_Error $errors Errors.
|
||||
*/
|
||||
public function error( $errors ) {
|
||||
if ( ! $this->done_header ) {
|
||||
$this->header();
|
||||
}
|
||||
if ( is_string( $errors ) ) {
|
||||
$this->feedback( $errors );
|
||||
} elseif ( is_wp_error( $errors ) && $errors->has_errors() ) {
|
||||
foreach ( $errors->get_error_messages() as $message ) {
|
||||
if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) ) {
|
||||
$this->feedback( $message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
|
||||
} else {
|
||||
$this->feedback( $message );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0
|
||||
* @since 5.9.0 Renamed `$string` (a PHP reserved keyword) to `$feedback` for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string $feedback Message data.
|
||||
* @param mixed ...$args Optional text replacements.
|
||||
*/
|
||||
public function feedback( $feedback, ...$args ) {
|
||||
if ( isset( $this->upgrader->strings[ $feedback ] ) ) {
|
||||
$feedback = $this->upgrader->strings[ $feedback ];
|
||||
}
|
||||
|
||||
if ( str_contains( $feedback, '%' ) ) {
|
||||
if ( $args ) {
|
||||
$args = array_map( 'strip_tags', $args );
|
||||
$args = array_map( 'esc_html', $args );
|
||||
$feedback = vsprintf( $feedback, $args );
|
||||
}
|
||||
}
|
||||
if ( empty( $feedback ) ) {
|
||||
return;
|
||||
}
|
||||
show_message( $feedback );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action before an update.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function before() {}
|
||||
|
||||
/**
|
||||
* Performs and action following an update.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function after() {}
|
||||
|
||||
/**
|
||||
* Outputs JavaScript that calls function to decrement the update counts.
|
||||
*
|
||||
* @since 3.9.0
|
||||
*
|
||||
* @param string $type Type of update count to decrement. Likely values include 'plugin',
|
||||
* 'theme', 'translation', etc.
|
||||
*/
|
||||
protected function decrement_update_count( $type ) {
|
||||
if ( ! $this->result || is_wp_error( $this->result ) || 'up_to_date' === $this->result ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( defined( 'IFRAME_REQUEST' ) ) {
|
||||
echo '<script type="text/javascript">
|
||||
if ( window.postMessage && JSON ) {
|
||||
window.parent.postMessage(
|
||||
JSON.stringify( {
|
||||
action: "decrementUpdateCount",
|
||||
upgradeType: "' . $type . '"
|
||||
} ),
|
||||
window.location.protocol + "//" + window.location.hostname
|
||||
+ ( "" !== window.location.port ? ":" + window.location.port : "" )
|
||||
);
|
||||
}
|
||||
</script>';
|
||||
} else {
|
||||
echo '<script type="text/javascript">
|
||||
(function( wp ) {
|
||||
if ( wp && wp.updates && wp.updates.decrementCount ) {
|
||||
wp.updates.decrementCount( "' . $type . '" );
|
||||
}
|
||||
})( window.wp );
|
||||
</script>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function bulk_header() {}
|
||||
|
||||
/**
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function bulk_footer() {}
|
||||
|
||||
/**
|
||||
* Hides the `process_failed` error message when updating by uploading a zip file.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param WP_Error $wp_error WP_Error object.
|
||||
* @return bool True if the error should be hidden, false otherwise.
|
||||
*/
|
||||
public function hide_process_failed( $wp_error ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Upgrader API: WP_Upgrader_Skin class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 4.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generic Skin for the WordPress Upgrader classes. This skin is designed to be extended for specific purposes.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
|
||||
*/
|
||||
#[AllowDynamicProperties]
|
||||
class WP_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Holds the upgrader data.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var WP_Upgrader
|
||||
*/
|
||||
public $upgrader;
|
||||
|
||||
/**
|
||||
* Whether header is done.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $done_header = false;
|
||||
|
||||
/**
|
||||
* Whether footer is done.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $done_footer = false;
|
||||
|
||||
/**
|
||||
* Holds the result of an upgrade.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var string|bool|WP_Error
|
||||
*/
|
||||
public $result = false;
|
||||
|
||||
/**
|
||||
* Holds the options of an upgrade.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $options = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Sets up the generic skin for the WordPress Upgrader classes.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param array $args Optional. The WordPress upgrader skin arguments to
|
||||
* override default options. Default empty array.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
$defaults = array(
|
||||
'url' => '',
|
||||
'nonce' => '',
|
||||
'title' => '',
|
||||
'context' => false,
|
||||
);
|
||||
$this->options = wp_parse_args( $args, $defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param WP_Upgrader $upgrader
|
||||
*/
|
||||
public function set_upgrader( &$upgrader ) {
|
||||
if ( is_object( $upgrader ) ) {
|
||||
$this->upgrader =& $upgrader;
|
||||
}
|
||||
$this->add_strings();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function add_strings() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the result of an upgrade.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string|bool|WP_Error $result The result of an upgrade.
|
||||
*/
|
||||
public function set_result( $result ) {
|
||||
$this->result = $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a form to the user to request for their FTP/SSH details in order
|
||||
* to connect to the filesystem.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.6.0 The `$context` parameter default changed from `false` to an empty string.
|
||||
*
|
||||
* @see request_filesystem_credentials()
|
||||
*
|
||||
* @param bool|WP_Error $error Optional. Whether the current request has failed to connect,
|
||||
* or an error object. Default false.
|
||||
* @param string $context Optional. Full path to the directory that is tested
|
||||
* for being writable. Default empty.
|
||||
* @param bool $allow_relaxed_file_ownership Optional. Whether to allow Group/World writable. Default false.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
|
||||
$url = $this->options['url'];
|
||||
if ( ! $context ) {
|
||||
$context = $this->options['context'];
|
||||
}
|
||||
if ( ! empty( $this->options['nonce'] ) ) {
|
||||
$url = wp_nonce_url( $url, $this->options['nonce'] );
|
||||
}
|
||||
|
||||
$extra_fields = array();
|
||||
|
||||
return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function header() {
|
||||
if ( $this->done_header ) {
|
||||
return;
|
||||
}
|
||||
$this->done_header = true;
|
||||
echo '<div class="wrap">';
|
||||
echo '<h1>' . $this->options['title'] . '</h1>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function footer() {
|
||||
if ( $this->done_footer ) {
|
||||
return;
|
||||
}
|
||||
$this->done_footer = true;
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string|WP_Error $errors Errors.
|
||||
*/
|
||||
public function error( $errors ) {
|
||||
if ( ! $this->done_header ) {
|
||||
$this->header();
|
||||
}
|
||||
if ( is_string( $errors ) ) {
|
||||
$this->feedback( $errors );
|
||||
} elseif ( is_wp_error( $errors ) && $errors->has_errors() ) {
|
||||
foreach ( $errors->get_error_messages() as $message ) {
|
||||
if ( $errors->get_error_data() && is_string( $errors->get_error_data() ) ) {
|
||||
$this->feedback( $message . ' ' . esc_html( strip_tags( $errors->get_error_data() ) ) );
|
||||
} else {
|
||||
$this->feedback( $message );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.8.0
|
||||
* @since 5.9.0 Renamed `$string` (a PHP reserved keyword) to `$feedback` for PHP 8 named parameter support.
|
||||
*
|
||||
* @param string $feedback Message data.
|
||||
* @param mixed ...$args Optional text replacements.
|
||||
*/
|
||||
public function feedback( $feedback, ...$args ) {
|
||||
if ( isset( $this->upgrader->strings[ $feedback ] ) ) {
|
||||
$feedback = $this->upgrader->strings[ $feedback ];
|
||||
}
|
||||
|
||||
if ( str_contains( $feedback, '%' ) ) {
|
||||
if ( $args ) {
|
||||
$args = array_map( 'strip_tags', $args );
|
||||
$args = array_map( 'esc_html', $args );
|
||||
$feedback = vsprintf( $feedback, $args );
|
||||
}
|
||||
}
|
||||
if ( empty( $feedback ) ) {
|
||||
return;
|
||||
}
|
||||
show_message( $feedback );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action before an update.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function before() {}
|
||||
|
||||
/**
|
||||
* Performs and action following an update.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
public function after() {}
|
||||
|
||||
/**
|
||||
* Outputs JavaScript that calls function to decrement the update counts.
|
||||
*
|
||||
* @since 3.9.0
|
||||
*
|
||||
* @param string $type Type of update count to decrement. Likely values include 'plugin',
|
||||
* 'theme', 'translation', etc.
|
||||
*/
|
||||
protected function decrement_update_count( $type ) {
|
||||
if ( ! $this->result || is_wp_error( $this->result ) || 'up_to_date' === $this->result ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( defined( 'IFRAME_REQUEST' ) ) {
|
||||
echo '<script type="text/javascript">
|
||||
if ( window.postMessage && JSON ) {
|
||||
window.parent.postMessage(
|
||||
JSON.stringify( {
|
||||
action: "decrementUpdateCount",
|
||||
upgradeType: "' . $type . '"
|
||||
} ),
|
||||
window.location.protocol + "//" + window.location.hostname
|
||||
+ ( "" !== window.location.port ? ":" + window.location.port : "" )
|
||||
);
|
||||
}
|
||||
</script>';
|
||||
} else {
|
||||
echo '<script type="text/javascript">
|
||||
(function( wp ) {
|
||||
if ( wp && wp.updates && wp.updates.decrementCount ) {
|
||||
wp.updates.decrementCount( "' . $type . '" );
|
||||
}
|
||||
})( window.wp );
|
||||
</script>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function bulk_header() {}
|
||||
|
||||
/**
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public function bulk_footer() {}
|
||||
|
||||
/**
|
||||
* Hides the `process_failed` error message when updating by uploading a zip file.
|
||||
*
|
||||
* @since 5.5.0
|
||||
*
|
||||
* @param WP_Error $wp_error WP_Error object.
|
||||
* @return bool True if the error should be hidden, false otherwise.
|
||||
*/
|
||||
public function hide_process_failed( $wp_error ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* The User Interface "Skins" for the WordPress File Upgrader
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 2.8.0
|
||||
* @deprecated 4.7.0
|
||||
*/
|
||||
|
||||
_deprecated_file( basename( __FILE__ ), '4.7.0', 'class-wp-upgrader.php' );
|
||||
|
||||
/** WP_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skin.php';
|
||||
|
||||
/** Plugin_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader-skin.php';
|
||||
|
||||
/** Theme_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-theme-upgrader-skin.php';
|
||||
|
||||
/** Bulk_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-bulk-upgrader-skin.php';
|
||||
|
||||
/** Bulk_Plugin_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-bulk-plugin-upgrader-skin.php';
|
||||
|
||||
/** Bulk_Theme_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-bulk-theme-upgrader-skin.php';
|
||||
|
||||
/** Plugin_Installer_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-plugin-installer-skin.php';
|
||||
|
||||
/** Theme_Installer_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-theme-installer-skin.php';
|
||||
|
||||
/** Language_Pack_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-language-pack-upgrader-skin.php';
|
||||
|
||||
/** Automatic_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-automatic-upgrader-skin.php';
|
||||
|
||||
/** WP_Ajax_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-ajax-upgrader-skin.php';
|
||||
<?php
|
||||
/**
|
||||
* The User Interface "Skins" for the WordPress File Upgrader
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Upgrader
|
||||
* @since 2.8.0
|
||||
* @deprecated 4.7.0
|
||||
*/
|
||||
|
||||
_deprecated_file( basename( __FILE__ ), '4.7.0', 'class-wp-upgrader.php' );
|
||||
|
||||
/** WP_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skin.php';
|
||||
|
||||
/** Plugin_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader-skin.php';
|
||||
|
||||
/** Theme_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-theme-upgrader-skin.php';
|
||||
|
||||
/** Bulk_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-bulk-upgrader-skin.php';
|
||||
|
||||
/** Bulk_Plugin_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-bulk-plugin-upgrader-skin.php';
|
||||
|
||||
/** Bulk_Theme_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-bulk-theme-upgrader-skin.php';
|
||||
|
||||
/** Plugin_Installer_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-plugin-installer-skin.php';
|
||||
|
||||
/** Theme_Installer_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-theme-installer-skin.php';
|
||||
|
||||
/** Language_Pack_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-language-pack-upgrader-skin.php';
|
||||
|
||||
/** Automatic_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-automatic-upgrader-skin.php';
|
||||
|
||||
/** WP_Ajax_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-ajax-upgrader-skin.php';
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,219 +1,219 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Comment Administration API.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 2.3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Determines if a comment exists based on author and date.
|
||||
*
|
||||
* For best performance, use `$timezone = 'gmt'`, which queries a field that is properly indexed. The default value
|
||||
* for `$timezone` is 'blog' for legacy reasons.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @since 4.4.0 Added the `$timezone` parameter.
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param string $comment_author Author of the comment.
|
||||
* @param string $comment_date Date of the comment.
|
||||
* @param string $timezone Timezone. Accepts 'blog' or 'gmt'. Default 'blog'.
|
||||
* @return string|null Comment post ID on success.
|
||||
*/
|
||||
function comment_exists( $comment_author, $comment_date, $timezone = 'blog' ) {
|
||||
global $wpdb;
|
||||
|
||||
$date_field = 'comment_date';
|
||||
if ( 'gmt' === $timezone ) {
|
||||
$date_field = 'comment_date_gmt';
|
||||
}
|
||||
|
||||
return $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT comment_post_ID FROM $wpdb->comments
|
||||
WHERE comment_author = %s AND $date_field = %s",
|
||||
stripslashes( $comment_author ),
|
||||
stripslashes( $comment_date )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a comment with values provided in $_POST.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @since 5.5.0 A return value was added.
|
||||
*
|
||||
* @return int|WP_Error The value 1 if the comment was updated, 0 if not updated.
|
||||
* A WP_Error object on failure.
|
||||
*/
|
||||
function edit_comment() {
|
||||
if ( ! current_user_can( 'edit_comment', (int) $_POST['comment_ID'] ) ) {
|
||||
wp_die( __( 'Sorry, you are not allowed to edit comments on this post.' ) );
|
||||
}
|
||||
|
||||
if ( isset( $_POST['newcomment_author'] ) ) {
|
||||
$_POST['comment_author'] = $_POST['newcomment_author'];
|
||||
}
|
||||
if ( isset( $_POST['newcomment_author_email'] ) ) {
|
||||
$_POST['comment_author_email'] = $_POST['newcomment_author_email'];
|
||||
}
|
||||
if ( isset( $_POST['newcomment_author_url'] ) ) {
|
||||
$_POST['comment_author_url'] = $_POST['newcomment_author_url'];
|
||||
}
|
||||
if ( isset( $_POST['comment_status'] ) ) {
|
||||
$_POST['comment_approved'] = $_POST['comment_status'];
|
||||
}
|
||||
if ( isset( $_POST['content'] ) ) {
|
||||
$_POST['comment_content'] = $_POST['content'];
|
||||
}
|
||||
if ( isset( $_POST['comment_ID'] ) ) {
|
||||
$_POST['comment_ID'] = (int) $_POST['comment_ID'];
|
||||
}
|
||||
|
||||
foreach ( array( 'aa', 'mm', 'jj', 'hh', 'mn' ) as $timeunit ) {
|
||||
if ( ! empty( $_POST[ 'hidden_' . $timeunit ] ) && $_POST[ 'hidden_' . $timeunit ] !== $_POST[ $timeunit ] ) {
|
||||
$_POST['edit_date'] = '1';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['edit_date'] ) ) {
|
||||
$aa = $_POST['aa'];
|
||||
$mm = $_POST['mm'];
|
||||
$jj = $_POST['jj'];
|
||||
$hh = $_POST['hh'];
|
||||
$mn = $_POST['mn'];
|
||||
$ss = $_POST['ss'];
|
||||
$jj = ( $jj > 31 ) ? 31 : $jj;
|
||||
$hh = ( $hh > 23 ) ? $hh - 24 : $hh;
|
||||
$mn = ( $mn > 59 ) ? $mn - 60 : $mn;
|
||||
$ss = ( $ss > 59 ) ? $ss - 60 : $ss;
|
||||
|
||||
$_POST['comment_date'] = "$aa-$mm-$jj $hh:$mn:$ss";
|
||||
}
|
||||
|
||||
return wp_update_comment( $_POST, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a WP_Comment object based on comment ID.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $id ID of comment to retrieve.
|
||||
* @return WP_Comment|false Comment if found. False on failure.
|
||||
*/
|
||||
function get_comment_to_edit( $id ) {
|
||||
$comment = get_comment( $id );
|
||||
if ( ! $comment ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$comment->comment_ID = (int) $comment->comment_ID;
|
||||
$comment->comment_post_ID = (int) $comment->comment_post_ID;
|
||||
|
||||
$comment->comment_content = format_to_edit( $comment->comment_content );
|
||||
/**
|
||||
* Filters the comment content before editing.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $comment_content Comment content.
|
||||
*/
|
||||
$comment->comment_content = apply_filters( 'comment_edit_pre', $comment->comment_content );
|
||||
|
||||
$comment->comment_author = format_to_edit( $comment->comment_author );
|
||||
$comment->comment_author_email = format_to_edit( $comment->comment_author_email );
|
||||
$comment->comment_author_url = format_to_edit( $comment->comment_author_url );
|
||||
$comment->comment_author_url = esc_url( $comment->comment_author_url );
|
||||
|
||||
return $comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of pending comments on a post or posts.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param int|int[] $post_id Either a single Post ID or an array of Post IDs
|
||||
* @return int|int[] Either a single Posts pending comments as an int or an array of ints keyed on the Post IDs
|
||||
*/
|
||||
function get_pending_comments_num( $post_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$single = false;
|
||||
if ( ! is_array( $post_id ) ) {
|
||||
$post_id_array = (array) $post_id;
|
||||
$single = true;
|
||||
} else {
|
||||
$post_id_array = $post_id;
|
||||
}
|
||||
$post_id_array = array_map( 'intval', $post_id_array );
|
||||
$post_id_in = "'" . implode( "', '", $post_id_array ) . "'";
|
||||
|
||||
$pending = $wpdb->get_results( "SELECT comment_post_ID, COUNT(comment_ID) as num_comments FROM $wpdb->comments WHERE comment_post_ID IN ( $post_id_in ) AND comment_approved = '0' GROUP BY comment_post_ID", ARRAY_A );
|
||||
|
||||
if ( $single ) {
|
||||
if ( empty( $pending ) ) {
|
||||
return 0;
|
||||
} else {
|
||||
return absint( $pending[0]['num_comments'] );
|
||||
}
|
||||
}
|
||||
|
||||
$pending_keyed = array();
|
||||
|
||||
// Default to zero pending for all posts in request.
|
||||
foreach ( $post_id_array as $id ) {
|
||||
$pending_keyed[ $id ] = 0;
|
||||
}
|
||||
|
||||
if ( ! empty( $pending ) ) {
|
||||
foreach ( $pending as $pend ) {
|
||||
$pending_keyed[ $pend['comment_post_ID'] ] = absint( $pend['num_comments'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $pending_keyed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds avatars to relevant places in admin.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param string $name User name.
|
||||
* @return string Avatar with the user name.
|
||||
*/
|
||||
function floated_admin_avatar( $name ) {
|
||||
$avatar = get_avatar( get_comment(), 32, 'mystery' );
|
||||
return "$avatar $name";
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues comment shortcuts jQuery script.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function enqueue_comment_hotkeys_js() {
|
||||
if ( 'true' === get_user_option( 'comment_shortcuts' ) ) {
|
||||
wp_enqueue_script( 'jquery-table-hotkeys' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays error message at bottom of comments.
|
||||
*
|
||||
* @param string $msg Error Message. Assumed to contain HTML and be sanitized.
|
||||
*/
|
||||
function comment_footer_die( $msg ) {
|
||||
echo "<div class='wrap'><p>$msg</p></div>";
|
||||
require_once ABSPATH . 'wp-admin/admin-footer.php';
|
||||
die;
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* WordPress Comment Administration API.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 2.3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Determines if a comment exists based on author and date.
|
||||
*
|
||||
* For best performance, use `$timezone = 'gmt'`, which queries a field that is properly indexed. The default value
|
||||
* for `$timezone` is 'blog' for legacy reasons.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @since 4.4.0 Added the `$timezone` parameter.
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param string $comment_author Author of the comment.
|
||||
* @param string $comment_date Date of the comment.
|
||||
* @param string $timezone Timezone. Accepts 'blog' or 'gmt'. Default 'blog'.
|
||||
* @return string|null Comment post ID on success.
|
||||
*/
|
||||
function comment_exists( $comment_author, $comment_date, $timezone = 'blog' ) {
|
||||
global $wpdb;
|
||||
|
||||
$date_field = 'comment_date';
|
||||
if ( 'gmt' === $timezone ) {
|
||||
$date_field = 'comment_date_gmt';
|
||||
}
|
||||
|
||||
return $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT comment_post_ID FROM $wpdb->comments
|
||||
WHERE comment_author = %s AND $date_field = %s",
|
||||
stripslashes( $comment_author ),
|
||||
stripslashes( $comment_date )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a comment with values provided in $_POST.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @since 5.5.0 A return value was added.
|
||||
*
|
||||
* @return int|WP_Error The value 1 if the comment was updated, 0 if not updated.
|
||||
* A WP_Error object on failure.
|
||||
*/
|
||||
function edit_comment() {
|
||||
if ( ! current_user_can( 'edit_comment', (int) $_POST['comment_ID'] ) ) {
|
||||
wp_die( __( 'Sorry, you are not allowed to edit comments on this post.' ) );
|
||||
}
|
||||
|
||||
if ( isset( $_POST['newcomment_author'] ) ) {
|
||||
$_POST['comment_author'] = $_POST['newcomment_author'];
|
||||
}
|
||||
if ( isset( $_POST['newcomment_author_email'] ) ) {
|
||||
$_POST['comment_author_email'] = $_POST['newcomment_author_email'];
|
||||
}
|
||||
if ( isset( $_POST['newcomment_author_url'] ) ) {
|
||||
$_POST['comment_author_url'] = $_POST['newcomment_author_url'];
|
||||
}
|
||||
if ( isset( $_POST['comment_status'] ) ) {
|
||||
$_POST['comment_approved'] = $_POST['comment_status'];
|
||||
}
|
||||
if ( isset( $_POST['content'] ) ) {
|
||||
$_POST['comment_content'] = $_POST['content'];
|
||||
}
|
||||
if ( isset( $_POST['comment_ID'] ) ) {
|
||||
$_POST['comment_ID'] = (int) $_POST['comment_ID'];
|
||||
}
|
||||
|
||||
foreach ( array( 'aa', 'mm', 'jj', 'hh', 'mn' ) as $timeunit ) {
|
||||
if ( ! empty( $_POST[ 'hidden_' . $timeunit ] ) && $_POST[ 'hidden_' . $timeunit ] !== $_POST[ $timeunit ] ) {
|
||||
$_POST['edit_date'] = '1';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['edit_date'] ) ) {
|
||||
$aa = $_POST['aa'];
|
||||
$mm = $_POST['mm'];
|
||||
$jj = $_POST['jj'];
|
||||
$hh = $_POST['hh'];
|
||||
$mn = $_POST['mn'];
|
||||
$ss = $_POST['ss'];
|
||||
$jj = ( $jj > 31 ) ? 31 : $jj;
|
||||
$hh = ( $hh > 23 ) ? $hh - 24 : $hh;
|
||||
$mn = ( $mn > 59 ) ? $mn - 60 : $mn;
|
||||
$ss = ( $ss > 59 ) ? $ss - 60 : $ss;
|
||||
|
||||
$_POST['comment_date'] = "$aa-$mm-$jj $hh:$mn:$ss";
|
||||
}
|
||||
|
||||
return wp_update_comment( $_POST, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a WP_Comment object based on comment ID.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $id ID of comment to retrieve.
|
||||
* @return WP_Comment|false Comment if found. False on failure.
|
||||
*/
|
||||
function get_comment_to_edit( $id ) {
|
||||
$comment = get_comment( $id );
|
||||
if ( ! $comment ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$comment->comment_ID = (int) $comment->comment_ID;
|
||||
$comment->comment_post_ID = (int) $comment->comment_post_ID;
|
||||
|
||||
$comment->comment_content = format_to_edit( $comment->comment_content );
|
||||
/**
|
||||
* Filters the comment content before editing.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $comment_content Comment content.
|
||||
*/
|
||||
$comment->comment_content = apply_filters( 'comment_edit_pre', $comment->comment_content );
|
||||
|
||||
$comment->comment_author = format_to_edit( $comment->comment_author );
|
||||
$comment->comment_author_email = format_to_edit( $comment->comment_author_email );
|
||||
$comment->comment_author_url = format_to_edit( $comment->comment_author_url );
|
||||
$comment->comment_author_url = esc_url( $comment->comment_author_url );
|
||||
|
||||
return $comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of pending comments on a post or posts.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param int|int[] $post_id Either a single Post ID or an array of Post IDs
|
||||
* @return int|int[] Either a single Posts pending comments as an int or an array of ints keyed on the Post IDs
|
||||
*/
|
||||
function get_pending_comments_num( $post_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$single = false;
|
||||
if ( ! is_array( $post_id ) ) {
|
||||
$post_id_array = (array) $post_id;
|
||||
$single = true;
|
||||
} else {
|
||||
$post_id_array = $post_id;
|
||||
}
|
||||
$post_id_array = array_map( 'intval', $post_id_array );
|
||||
$post_id_in = "'" . implode( "', '", $post_id_array ) . "'";
|
||||
|
||||
$pending = $wpdb->get_results( "SELECT comment_post_ID, COUNT(comment_ID) as num_comments FROM $wpdb->comments WHERE comment_post_ID IN ( $post_id_in ) AND comment_approved = '0' GROUP BY comment_post_ID", ARRAY_A );
|
||||
|
||||
if ( $single ) {
|
||||
if ( empty( $pending ) ) {
|
||||
return 0;
|
||||
} else {
|
||||
return absint( $pending[0]['num_comments'] );
|
||||
}
|
||||
}
|
||||
|
||||
$pending_keyed = array();
|
||||
|
||||
// Default to zero pending for all posts in request.
|
||||
foreach ( $post_id_array as $id ) {
|
||||
$pending_keyed[ $id ] = 0;
|
||||
}
|
||||
|
||||
if ( ! empty( $pending ) ) {
|
||||
foreach ( $pending as $pend ) {
|
||||
$pending_keyed[ $pend['comment_post_ID'] ] = absint( $pend['num_comments'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $pending_keyed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds avatars to relevant places in admin.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param string $name User name.
|
||||
* @return string Avatar with the user name.
|
||||
*/
|
||||
function floated_admin_avatar( $name ) {
|
||||
$avatar = get_avatar( get_comment(), 32, 'mystery' );
|
||||
return "$avatar $name";
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues comment shortcuts jQuery script.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
function enqueue_comment_hotkeys_js() {
|
||||
if ( 'true' === get_user_option( 'comment_shortcuts' ) ) {
|
||||
wp_enqueue_script( 'jquery-table-hotkeys' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays error message at bottom of comments.
|
||||
*
|
||||
* @param string $msg Error Message. Assumed to contain HTML and be sanitized.
|
||||
*/
|
||||
function comment_footer_die( $msg ) {
|
||||
echo "<div class='wrap'><p>$msg</p></div>";
|
||||
require_once ABSPATH . 'wp-admin/admin-footer.php';
|
||||
die;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,166 +1,166 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Credits Administration API.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves the contributor credits.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @since 5.6.0 Added the `$version` and `$locale` parameters.
|
||||
*
|
||||
* @param string $version WordPress version. Defaults to the current version.
|
||||
* @param string $locale WordPress locale. Defaults to the current user's locale.
|
||||
* @return array|false A list of all of the contributors, or false on error.
|
||||
*/
|
||||
function wp_credits( $version = '', $locale = '' ) {
|
||||
if ( ! $version ) {
|
||||
// Include an unmodified $wp_version.
|
||||
require ABSPATH . WPINC . '/version.php';
|
||||
|
||||
$version = $wp_version;
|
||||
}
|
||||
|
||||
if ( ! $locale ) {
|
||||
$locale = get_user_locale();
|
||||
}
|
||||
|
||||
$results = get_site_transient( 'wordpress_credits_' . $locale );
|
||||
|
||||
if ( ! is_array( $results )
|
||||
|| str_contains( $version, '-' )
|
||||
|| ( isset( $results['data']['version'] ) && ! str_starts_with( $version, $results['data']['version'] ) )
|
||||
) {
|
||||
$url = "http://api.wordpress.org/core/credits/1.1/?version={$version}&locale={$locale}";
|
||||
$options = array( 'user-agent' => 'WordPress/' . $version . '; ' . home_url( '/' ) );
|
||||
|
||||
if ( wp_http_supports( array( 'ssl' ) ) ) {
|
||||
$url = set_url_scheme( $url, 'https' );
|
||||
}
|
||||
|
||||
$response = wp_remote_get( $url, $options );
|
||||
|
||||
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$results = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( ! is_array( $results ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
set_site_transient( 'wordpress_credits_' . $locale, $results, DAY_IN_SECONDS );
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the link to a contributor's WordPress.org profile page.
|
||||
*
|
||||
* @access private
|
||||
* @since 3.2.0
|
||||
*
|
||||
* @param string $display_name The contributor's display name (passed by reference).
|
||||
* @param string $username The contributor's username.
|
||||
* @param string $profiles URL to the contributor's WordPress.org profile page.
|
||||
*/
|
||||
function _wp_credits_add_profile_link( &$display_name, $username, $profiles ) {
|
||||
$display_name = '<a href="' . esc_url( sprintf( $profiles, $username ) ) . '">' . esc_html( $display_name ) . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the link to an external library used in WordPress.
|
||||
*
|
||||
* @access private
|
||||
* @since 3.2.0
|
||||
*
|
||||
* @param string $data External library data (passed by reference).
|
||||
*/
|
||||
function _wp_credits_build_object_link( &$data ) {
|
||||
$data = '<a href="' . esc_url( $data[1] ) . '">' . esc_html( $data[0] ) . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the title for a given group of contributors.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*
|
||||
* @param array $group_data The current contributor group.
|
||||
*/
|
||||
function wp_credits_section_title( $group_data = array() ) {
|
||||
if ( ! count( $group_data ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $group_data['name'] ) {
|
||||
if ( 'Translators' === $group_data['name'] ) {
|
||||
// Considered a special slug in the API response. (Also, will never be returned for en_US.)
|
||||
$title = _x( 'Translators', 'Translate this to be the equivalent of English Translators in your language for the credits page Translators section' );
|
||||
} elseif ( isset( $group_data['placeholders'] ) ) {
|
||||
// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
|
||||
$title = vsprintf( translate( $group_data['name'] ), $group_data['placeholders'] );
|
||||
} else {
|
||||
// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
|
||||
$title = translate( $group_data['name'] );
|
||||
}
|
||||
|
||||
echo '<h2 class="wp-people-group-title">' . esc_html( $title ) . "</h2>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a list of contributors for a given group.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*
|
||||
* @param array $credits The credits groups returned from the API.
|
||||
* @param string $slug The current group to display.
|
||||
*/
|
||||
function wp_credits_section_list( $credits = array(), $slug = '' ) {
|
||||
$group_data = isset( $credits['groups'][ $slug ] ) ? $credits['groups'][ $slug ] : array();
|
||||
$credits_data = $credits['data'];
|
||||
if ( ! count( $group_data ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $group_data['shuffle'] ) ) {
|
||||
shuffle( $group_data['data'] ); // We were going to sort by ability to pronounce "hierarchical," but that wouldn't be fair to Matt.
|
||||
}
|
||||
|
||||
switch ( $group_data['type'] ) {
|
||||
case 'list':
|
||||
array_walk( $group_data['data'], '_wp_credits_add_profile_link', $credits_data['profiles'] );
|
||||
echo '<p class="wp-credits-list">' . wp_sprintf( '%l.', $group_data['data'] ) . "</p>\n\n";
|
||||
break;
|
||||
case 'libraries':
|
||||
array_walk( $group_data['data'], '_wp_credits_build_object_link' );
|
||||
echo '<p class="wp-credits-list">' . wp_sprintf( '%l.', $group_data['data'] ) . "</p>\n\n";
|
||||
break;
|
||||
default:
|
||||
$compact = 'compact' === $group_data['type'];
|
||||
$classes = 'wp-people-group ' . ( $compact ? 'compact' : '' );
|
||||
echo '<ul class="' . $classes . '" id="wp-people-group-' . $slug . '">' . "\n";
|
||||
foreach ( $group_data['data'] as $person_data ) {
|
||||
echo '<li class="wp-person" id="wp-person-' . esc_attr( $person_data[2] ) . '">' . "\n\t";
|
||||
echo '<a href="' . esc_url( sprintf( $credits_data['profiles'], $person_data[2] ) ) . '" class="web">';
|
||||
$size = $compact ? 80 : 160;
|
||||
$data = get_avatar_data( $person_data[1] . '@md5.gravatar.com', array( 'size' => $size ) );
|
||||
$data2x = get_avatar_data( $person_data[1] . '@md5.gravatar.com', array( 'size' => $size * 2 ) );
|
||||
echo '<span class="wp-person-avatar"><img src="' . esc_url( $data['url'] ) . '" srcset="' . esc_url( $data2x['url'] ) . ' 2x" class="gravatar" alt="" /></span>' . "\n";
|
||||
echo esc_html( $person_data[0] ) . "</a>\n\t";
|
||||
if ( ! $compact && ! empty( $person_data[3] ) ) {
|
||||
// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
|
||||
echo '<span class="title">' . translate( $person_data[3] ) . "</span>\n";
|
||||
}
|
||||
echo "</li>\n";
|
||||
}
|
||||
echo "</ul>\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* WordPress Credits Administration API.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves the contributor credits.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @since 5.6.0 Added the `$version` and `$locale` parameters.
|
||||
*
|
||||
* @param string $version WordPress version. Defaults to the current version.
|
||||
* @param string $locale WordPress locale. Defaults to the current user's locale.
|
||||
* @return array|false A list of all of the contributors, or false on error.
|
||||
*/
|
||||
function wp_credits( $version = '', $locale = '' ) {
|
||||
if ( ! $version ) {
|
||||
// Include an unmodified $wp_version.
|
||||
require ABSPATH . WPINC . '/version.php';
|
||||
|
||||
$version = $wp_version;
|
||||
}
|
||||
|
||||
if ( ! $locale ) {
|
||||
$locale = get_user_locale();
|
||||
}
|
||||
|
||||
$results = get_site_transient( 'wordpress_credits_' . $locale );
|
||||
|
||||
if ( ! is_array( $results )
|
||||
|| str_contains( $version, '-' )
|
||||
|| ( isset( $results['data']['version'] ) && ! str_starts_with( $version, $results['data']['version'] ) )
|
||||
) {
|
||||
$url = "http://api.wordpress.org/core/credits/1.1/?version={$version}&locale={$locale}";
|
||||
$options = array( 'user-agent' => 'WordPress/' . $version . '; ' . home_url( '/' ) );
|
||||
|
||||
if ( wp_http_supports( array( 'ssl' ) ) ) {
|
||||
$url = set_url_scheme( $url, 'https' );
|
||||
}
|
||||
|
||||
$response = wp_remote_get( $url, $options );
|
||||
|
||||
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$results = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( ! is_array( $results ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
set_site_transient( 'wordpress_credits_' . $locale, $results, DAY_IN_SECONDS );
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the link to a contributor's WordPress.org profile page.
|
||||
*
|
||||
* @access private
|
||||
* @since 3.2.0
|
||||
*
|
||||
* @param string $display_name The contributor's display name (passed by reference).
|
||||
* @param string $username The contributor's username.
|
||||
* @param string $profiles URL to the contributor's WordPress.org profile page.
|
||||
*/
|
||||
function _wp_credits_add_profile_link( &$display_name, $username, $profiles ) {
|
||||
$display_name = '<a href="' . esc_url( sprintf( $profiles, $username ) ) . '">' . esc_html( $display_name ) . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the link to an external library used in WordPress.
|
||||
*
|
||||
* @access private
|
||||
* @since 3.2.0
|
||||
*
|
||||
* @param string $data External library data (passed by reference).
|
||||
*/
|
||||
function _wp_credits_build_object_link( &$data ) {
|
||||
$data = '<a href="' . esc_url( $data[1] ) . '">' . esc_html( $data[0] ) . '</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the title for a given group of contributors.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*
|
||||
* @param array $group_data The current contributor group.
|
||||
*/
|
||||
function wp_credits_section_title( $group_data = array() ) {
|
||||
if ( ! count( $group_data ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $group_data['name'] ) {
|
||||
if ( 'Translators' === $group_data['name'] ) {
|
||||
// Considered a special slug in the API response. (Also, will never be returned for en_US.)
|
||||
$title = _x( 'Translators', 'Translate this to be the equivalent of English Translators in your language for the credits page Translators section' );
|
||||
} elseif ( isset( $group_data['placeholders'] ) ) {
|
||||
// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
|
||||
$title = vsprintf( translate( $group_data['name'] ), $group_data['placeholders'] );
|
||||
} else {
|
||||
// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
|
||||
$title = translate( $group_data['name'] );
|
||||
}
|
||||
|
||||
echo '<h2 class="wp-people-group-title">' . esc_html( $title ) . "</h2>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a list of contributors for a given group.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*
|
||||
* @param array $credits The credits groups returned from the API.
|
||||
* @param string $slug The current group to display.
|
||||
*/
|
||||
function wp_credits_section_list( $credits = array(), $slug = '' ) {
|
||||
$group_data = isset( $credits['groups'][ $slug ] ) ? $credits['groups'][ $slug ] : array();
|
||||
$credits_data = $credits['data'];
|
||||
if ( ! count( $group_data ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $group_data['shuffle'] ) ) {
|
||||
shuffle( $group_data['data'] ); // We were going to sort by ability to pronounce "hierarchical," but that wouldn't be fair to Matt.
|
||||
}
|
||||
|
||||
switch ( $group_data['type'] ) {
|
||||
case 'list':
|
||||
array_walk( $group_data['data'], '_wp_credits_add_profile_link', $credits_data['profiles'] );
|
||||
echo '<p class="wp-credits-list">' . wp_sprintf( '%l.', $group_data['data'] ) . "</p>\n\n";
|
||||
break;
|
||||
case 'libraries':
|
||||
array_walk( $group_data['data'], '_wp_credits_build_object_link' );
|
||||
echo '<p class="wp-credits-list">' . wp_sprintf( '%l.', $group_data['data'] ) . "</p>\n\n";
|
||||
break;
|
||||
default:
|
||||
$compact = 'compact' === $group_data['type'];
|
||||
$classes = 'wp-people-group ' . ( $compact ? 'compact' : '' );
|
||||
echo '<ul class="' . $classes . '" id="wp-people-group-' . $slug . '">' . "\n";
|
||||
foreach ( $group_data['data'] as $person_data ) {
|
||||
echo '<li class="wp-person" id="wp-person-' . esc_attr( $person_data[2] ) . '">' . "\n\t";
|
||||
echo '<a href="' . esc_url( sprintf( $credits_data['profiles'], $person_data[2] ) ) . '" class="web">';
|
||||
$size = $compact ? 80 : 160;
|
||||
$data = get_avatar_data( $person_data[1] . '@md5.gravatar.com', array( 'size' => $size ) );
|
||||
$data2x = get_avatar_data( $person_data[1] . '@md5.gravatar.com', array( 'size' => $size * 2 ) );
|
||||
echo '<span class="wp-person-avatar"><img src="' . esc_url( $data['url'] ) . '" srcset="' . esc_url( $data2x['url'] ) . ' 2x" class="gravatar" alt="" /></span>' . "\n";
|
||||
echo esc_html( $person_data[0] ) . "</a>\n\t";
|
||||
if ( ! $compact && ! empty( $person_data[3] ) ) {
|
||||
// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
|
||||
echo '<span class="title">' . translate( $person_data[3] ) . "</span>\n";
|
||||
}
|
||||
echo "</li>\n";
|
||||
}
|
||||
echo "</ul>\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+2140
-2140
File diff suppressed because it is too large
Load Diff
+1591
-1591
File diff suppressed because it is too large
Load Diff
@@ -1,59 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Edit Tags Administration: Messages
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
$messages = array();
|
||||
// 0 = unused. Messages start at index 1.
|
||||
$messages['_item'] = array(
|
||||
0 => '',
|
||||
1 => __( 'Item added.' ),
|
||||
2 => __( 'Item deleted.' ),
|
||||
3 => __( 'Item updated.' ),
|
||||
4 => __( 'Item not added.' ),
|
||||
5 => __( 'Item not updated.' ),
|
||||
6 => __( 'Items deleted.' ),
|
||||
);
|
||||
|
||||
$messages['category'] = array(
|
||||
0 => '',
|
||||
1 => __( 'Category added.' ),
|
||||
2 => __( 'Category deleted.' ),
|
||||
3 => __( 'Category updated.' ),
|
||||
4 => __( 'Category not added.' ),
|
||||
5 => __( 'Category not updated.' ),
|
||||
6 => __( 'Categories deleted.' ),
|
||||
);
|
||||
|
||||
$messages['post_tag'] = array(
|
||||
0 => '',
|
||||
1 => __( 'Tag added.' ),
|
||||
2 => __( 'Tag deleted.' ),
|
||||
3 => __( 'Tag updated.' ),
|
||||
4 => __( 'Tag not added.' ),
|
||||
5 => __( 'Tag not updated.' ),
|
||||
6 => __( 'Tags deleted.' ),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the messages displayed when a tag is updated.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param array[] $messages Array of arrays of messages to be displayed, keyed by taxonomy name.
|
||||
*/
|
||||
$messages = apply_filters( 'term_updated_messages', $messages );
|
||||
|
||||
$message = false;
|
||||
if ( isset( $_REQUEST['message'] ) && (int) $_REQUEST['message'] ) {
|
||||
$msg = (int) $_REQUEST['message'];
|
||||
if ( isset( $messages[ $taxonomy ][ $msg ] ) ) {
|
||||
$message = $messages[ $taxonomy ][ $msg ];
|
||||
} elseif ( ! isset( $messages[ $taxonomy ] ) && isset( $messages['_item'][ $msg ] ) ) {
|
||||
$message = $messages['_item'][ $msg ];
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Edit Tags Administration: Messages
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
$messages = array();
|
||||
// 0 = unused. Messages start at index 1.
|
||||
$messages['_item'] = array(
|
||||
0 => '',
|
||||
1 => __( 'Item added.' ),
|
||||
2 => __( 'Item deleted.' ),
|
||||
3 => __( 'Item updated.' ),
|
||||
4 => __( 'Item not added.' ),
|
||||
5 => __( 'Item not updated.' ),
|
||||
6 => __( 'Items deleted.' ),
|
||||
);
|
||||
|
||||
$messages['category'] = array(
|
||||
0 => '',
|
||||
1 => __( 'Category added.' ),
|
||||
2 => __( 'Category deleted.' ),
|
||||
3 => __( 'Category updated.' ),
|
||||
4 => __( 'Category not added.' ),
|
||||
5 => __( 'Category not updated.' ),
|
||||
6 => __( 'Categories deleted.' ),
|
||||
);
|
||||
|
||||
$messages['post_tag'] = array(
|
||||
0 => '',
|
||||
1 => __( 'Tag added.' ),
|
||||
2 => __( 'Tag deleted.' ),
|
||||
3 => __( 'Tag updated.' ),
|
||||
4 => __( 'Tag not added.' ),
|
||||
5 => __( 'Tag not updated.' ),
|
||||
6 => __( 'Tags deleted.' ),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the messages displayed when a tag is updated.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param array[] $messages Array of arrays of messages to be displayed, keyed by taxonomy name.
|
||||
*/
|
||||
$messages = apply_filters( 'term_updated_messages', $messages );
|
||||
|
||||
$message = false;
|
||||
if ( isset( $_REQUEST['message'] ) && (int) $_REQUEST['message'] ) {
|
||||
$msg = (int) $_REQUEST['message'];
|
||||
if ( isset( $messages[ $taxonomy ][ $msg ] ) ) {
|
||||
$message = $messages[ $taxonomy ][ $msg ];
|
||||
} elseif ( ! isset( $messages[ $taxonomy ] ) && isset( $messages['_item'][ $msg ] ) ) {
|
||||
$message = $messages['_item'][ $msg ];
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+2835
-2835
File diff suppressed because it is too large
Load Diff
+1143
-1143
File diff suppressed because it is too large
Load Diff
+1251
-1251
File diff suppressed because it is too large
Load Diff
@@ -1,232 +1,232 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Administration Importer API.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves the list of importers.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @global array $wp_importers
|
||||
* @return array
|
||||
*/
|
||||
function get_importers() {
|
||||
global $wp_importers;
|
||||
if ( is_array( $wp_importers ) ) {
|
||||
uasort( $wp_importers, '_usort_by_first_member' );
|
||||
}
|
||||
return $wp_importers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts a multidimensional array by first member of each top level member.
|
||||
*
|
||||
* Used by uasort() as a callback, should not be used directly.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access private
|
||||
*
|
||||
* @param array $a
|
||||
* @param array $b
|
||||
* @return int
|
||||
*/
|
||||
function _usort_by_first_member( $a, $b ) {
|
||||
return strnatcasecmp( $a[0], $b[0] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers importer for WordPress.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @global array $wp_importers
|
||||
*
|
||||
* @param string $id Importer tag. Used to uniquely identify importer.
|
||||
* @param string $name Importer name and title.
|
||||
* @param string $description Importer description.
|
||||
* @param callable $callback Callback to run.
|
||||
* @return void|WP_Error Void on success. WP_Error when $callback is WP_Error.
|
||||
*/
|
||||
function register_importer( $id, $name, $description, $callback ) {
|
||||
global $wp_importers;
|
||||
if ( is_wp_error( $callback ) ) {
|
||||
return $callback;
|
||||
}
|
||||
$wp_importers[ $id ] = array( $name, $description, $callback );
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup importer.
|
||||
*
|
||||
* Removes attachment based on ID.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $id Importer ID.
|
||||
*/
|
||||
function wp_import_cleanup( $id ) {
|
||||
wp_delete_attachment( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles importer uploading and adds attachment.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return array Uploaded file's details on success, error message on failure.
|
||||
*/
|
||||
function wp_import_handle_upload() {
|
||||
if ( ! isset( $_FILES['import'] ) ) {
|
||||
return array(
|
||||
'error' => sprintf(
|
||||
/* translators: 1: php.ini, 2: post_max_size, 3: upload_max_filesize */
|
||||
__( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your %1$s file or by %2$s being defined as smaller than %3$s in %1$s.' ),
|
||||
'php.ini',
|
||||
'post_max_size',
|
||||
'upload_max_filesize'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$overrides = array(
|
||||
'test_form' => false,
|
||||
'test_type' => false,
|
||||
);
|
||||
$_FILES['import']['name'] .= '.txt';
|
||||
$upload = wp_handle_upload( $_FILES['import'], $overrides );
|
||||
|
||||
if ( isset( $upload['error'] ) ) {
|
||||
return $upload;
|
||||
}
|
||||
|
||||
// Construct the attachment array.
|
||||
$attachment = array(
|
||||
'post_title' => wp_basename( $upload['file'] ),
|
||||
'post_content' => $upload['url'],
|
||||
'post_mime_type' => $upload['type'],
|
||||
'guid' => $upload['url'],
|
||||
'context' => 'import',
|
||||
'post_status' => 'private',
|
||||
);
|
||||
|
||||
// Save the data.
|
||||
$id = wp_insert_attachment( $attachment, $upload['file'] );
|
||||
|
||||
/*
|
||||
* Schedule a cleanup for one day from now in case of failed
|
||||
* import or missing wp_import_cleanup() call.
|
||||
*/
|
||||
wp_schedule_single_event( time() + DAY_IN_SECONDS, 'importer_scheduled_cleanup', array( $id ) );
|
||||
|
||||
return array(
|
||||
'file' => $upload['file'],
|
||||
'id' => $id,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list from WordPress.org of popular importer plugins.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @return array Importers with metadata for each.
|
||||
*/
|
||||
function wp_get_popular_importers() {
|
||||
// Include an unmodified $wp_version.
|
||||
require ABSPATH . WPINC . '/version.php';
|
||||
|
||||
$locale = get_user_locale();
|
||||
$cache_key = 'popular_importers_' . md5( $locale . $wp_version );
|
||||
$popular_importers = get_site_transient( $cache_key );
|
||||
|
||||
if ( ! $popular_importers ) {
|
||||
$url = add_query_arg(
|
||||
array(
|
||||
'locale' => $locale,
|
||||
'version' => $wp_version,
|
||||
),
|
||||
'http://api.wordpress.org/core/importers/1.1/'
|
||||
);
|
||||
$options = array( 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ) );
|
||||
|
||||
if ( wp_http_supports( array( 'ssl' ) ) ) {
|
||||
$url = set_url_scheme( $url, 'https' );
|
||||
}
|
||||
|
||||
$response = wp_remote_get( $url, $options );
|
||||
$popular_importers = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( is_array( $popular_importers ) ) {
|
||||
set_site_transient( $cache_key, $popular_importers, 2 * DAY_IN_SECONDS );
|
||||
} else {
|
||||
$popular_importers = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_array( $popular_importers ) ) {
|
||||
// If the data was received as translated, return it as-is.
|
||||
if ( $popular_importers['translated'] ) {
|
||||
return $popular_importers['importers'];
|
||||
}
|
||||
|
||||
foreach ( $popular_importers['importers'] as &$importer ) {
|
||||
// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
|
||||
$importer['description'] = translate( $importer['description'] );
|
||||
if ( 'WordPress' !== $importer['name'] ) {
|
||||
// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
|
||||
$importer['name'] = translate( $importer['name'] );
|
||||
}
|
||||
}
|
||||
return $popular_importers['importers'];
|
||||
}
|
||||
|
||||
return array(
|
||||
// slug => name, description, plugin slug, and register_importer() slug.
|
||||
'blogger' => array(
|
||||
'name' => __( 'Blogger' ),
|
||||
'description' => __( 'Import posts, comments, and users from a Blogger blog.' ),
|
||||
'plugin-slug' => 'blogger-importer',
|
||||
'importer-id' => 'blogger',
|
||||
),
|
||||
'wpcat2tag' => array(
|
||||
'name' => __( 'Categories and Tags Converter' ),
|
||||
'description' => __( 'Convert existing categories to tags or tags to categories, selectively.' ),
|
||||
'plugin-slug' => 'wpcat2tag-importer',
|
||||
'importer-id' => 'wp-cat2tag',
|
||||
),
|
||||
'livejournal' => array(
|
||||
'name' => __( 'LiveJournal' ),
|
||||
'description' => __( 'Import posts from LiveJournal using their API.' ),
|
||||
'plugin-slug' => 'livejournal-importer',
|
||||
'importer-id' => 'livejournal',
|
||||
),
|
||||
'movabletype' => array(
|
||||
'name' => __( 'Movable Type and TypePad' ),
|
||||
'description' => __( 'Import posts and comments from a Movable Type or TypePad blog.' ),
|
||||
'plugin-slug' => 'movabletype-importer',
|
||||
'importer-id' => 'mt',
|
||||
),
|
||||
'rss' => array(
|
||||
'name' => __( 'RSS' ),
|
||||
'description' => __( 'Import posts from an RSS feed.' ),
|
||||
'plugin-slug' => 'rss-importer',
|
||||
'importer-id' => 'rss',
|
||||
),
|
||||
'tumblr' => array(
|
||||
'name' => __( 'Tumblr' ),
|
||||
'description' => __( 'Import posts & media from Tumblr using their API.' ),
|
||||
'plugin-slug' => 'tumblr-importer',
|
||||
'importer-id' => 'tumblr',
|
||||
),
|
||||
'wordpress' => array(
|
||||
'name' => 'WordPress',
|
||||
'description' => __( 'Import posts, pages, comments, custom fields, categories, and tags from a WordPress export file.' ),
|
||||
'plugin-slug' => 'wordpress-importer',
|
||||
'importer-id' => 'wordpress',
|
||||
),
|
||||
);
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* WordPress Administration Importer API.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves the list of importers.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @global array $wp_importers
|
||||
* @return array
|
||||
*/
|
||||
function get_importers() {
|
||||
global $wp_importers;
|
||||
if ( is_array( $wp_importers ) ) {
|
||||
uasort( $wp_importers, '_usort_by_first_member' );
|
||||
}
|
||||
return $wp_importers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts a multidimensional array by first member of each top level member.
|
||||
*
|
||||
* Used by uasort() as a callback, should not be used directly.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access private
|
||||
*
|
||||
* @param array $a
|
||||
* @param array $b
|
||||
* @return int
|
||||
*/
|
||||
function _usort_by_first_member( $a, $b ) {
|
||||
return strnatcasecmp( $a[0], $b[0] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers importer for WordPress.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @global array $wp_importers
|
||||
*
|
||||
* @param string $id Importer tag. Used to uniquely identify importer.
|
||||
* @param string $name Importer name and title.
|
||||
* @param string $description Importer description.
|
||||
* @param callable $callback Callback to run.
|
||||
* @return void|WP_Error Void on success. WP_Error when $callback is WP_Error.
|
||||
*/
|
||||
function register_importer( $id, $name, $description, $callback ) {
|
||||
global $wp_importers;
|
||||
if ( is_wp_error( $callback ) ) {
|
||||
return $callback;
|
||||
}
|
||||
$wp_importers[ $id ] = array( $name, $description, $callback );
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup importer.
|
||||
*
|
||||
* Removes attachment based on ID.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $id Importer ID.
|
||||
*/
|
||||
function wp_import_cleanup( $id ) {
|
||||
wp_delete_attachment( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles importer uploading and adds attachment.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return array Uploaded file's details on success, error message on failure.
|
||||
*/
|
||||
function wp_import_handle_upload() {
|
||||
if ( ! isset( $_FILES['import'] ) ) {
|
||||
return array(
|
||||
'error' => sprintf(
|
||||
/* translators: 1: php.ini, 2: post_max_size, 3: upload_max_filesize */
|
||||
__( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your %1$s file or by %2$s being defined as smaller than %3$s in %1$s.' ),
|
||||
'php.ini',
|
||||
'post_max_size',
|
||||
'upload_max_filesize'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$overrides = array(
|
||||
'test_form' => false,
|
||||
'test_type' => false,
|
||||
);
|
||||
$_FILES['import']['name'] .= '.txt';
|
||||
$upload = wp_handle_upload( $_FILES['import'], $overrides );
|
||||
|
||||
if ( isset( $upload['error'] ) ) {
|
||||
return $upload;
|
||||
}
|
||||
|
||||
// Construct the attachment array.
|
||||
$attachment = array(
|
||||
'post_title' => wp_basename( $upload['file'] ),
|
||||
'post_content' => $upload['url'],
|
||||
'post_mime_type' => $upload['type'],
|
||||
'guid' => $upload['url'],
|
||||
'context' => 'import',
|
||||
'post_status' => 'private',
|
||||
);
|
||||
|
||||
// Save the data.
|
||||
$id = wp_insert_attachment( $attachment, $upload['file'] );
|
||||
|
||||
/*
|
||||
* Schedule a cleanup for one day from now in case of failed
|
||||
* import or missing wp_import_cleanup() call.
|
||||
*/
|
||||
wp_schedule_single_event( time() + DAY_IN_SECONDS, 'importer_scheduled_cleanup', array( $id ) );
|
||||
|
||||
return array(
|
||||
'file' => $upload['file'],
|
||||
'id' => $id,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list from WordPress.org of popular importer plugins.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @return array Importers with metadata for each.
|
||||
*/
|
||||
function wp_get_popular_importers() {
|
||||
// Include an unmodified $wp_version.
|
||||
require ABSPATH . WPINC . '/version.php';
|
||||
|
||||
$locale = get_user_locale();
|
||||
$cache_key = 'popular_importers_' . md5( $locale . $wp_version );
|
||||
$popular_importers = get_site_transient( $cache_key );
|
||||
|
||||
if ( ! $popular_importers ) {
|
||||
$url = add_query_arg(
|
||||
array(
|
||||
'locale' => $locale,
|
||||
'version' => $wp_version,
|
||||
),
|
||||
'http://api.wordpress.org/core/importers/1.1/'
|
||||
);
|
||||
$options = array( 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ) );
|
||||
|
||||
if ( wp_http_supports( array( 'ssl' ) ) ) {
|
||||
$url = set_url_scheme( $url, 'https' );
|
||||
}
|
||||
|
||||
$response = wp_remote_get( $url, $options );
|
||||
$popular_importers = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( is_array( $popular_importers ) ) {
|
||||
set_site_transient( $cache_key, $popular_importers, 2 * DAY_IN_SECONDS );
|
||||
} else {
|
||||
$popular_importers = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_array( $popular_importers ) ) {
|
||||
// If the data was received as translated, return it as-is.
|
||||
if ( $popular_importers['translated'] ) {
|
||||
return $popular_importers['importers'];
|
||||
}
|
||||
|
||||
foreach ( $popular_importers['importers'] as &$importer ) {
|
||||
// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
|
||||
$importer['description'] = translate( $importer['description'] );
|
||||
if ( 'WordPress' !== $importer['name'] ) {
|
||||
// phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText
|
||||
$importer['name'] = translate( $importer['name'] );
|
||||
}
|
||||
}
|
||||
return $popular_importers['importers'];
|
||||
}
|
||||
|
||||
return array(
|
||||
// slug => name, description, plugin slug, and register_importer() slug.
|
||||
'blogger' => array(
|
||||
'name' => __( 'Blogger' ),
|
||||
'description' => __( 'Import posts, comments, and users from a Blogger blog.' ),
|
||||
'plugin-slug' => 'blogger-importer',
|
||||
'importer-id' => 'blogger',
|
||||
),
|
||||
'wpcat2tag' => array(
|
||||
'name' => __( 'Categories and Tags Converter' ),
|
||||
'description' => __( 'Convert existing categories to tags or tags to categories, selectively.' ),
|
||||
'plugin-slug' => 'wpcat2tag-importer',
|
||||
'importer-id' => 'wp-cat2tag',
|
||||
),
|
||||
'livejournal' => array(
|
||||
'name' => __( 'LiveJournal' ),
|
||||
'description' => __( 'Import posts from LiveJournal using their API.' ),
|
||||
'plugin-slug' => 'livejournal-importer',
|
||||
'importer-id' => 'livejournal',
|
||||
),
|
||||
'movabletype' => array(
|
||||
'name' => __( 'Movable Type and TypePad' ),
|
||||
'description' => __( 'Import posts and comments from a Movable Type or TypePad blog.' ),
|
||||
'plugin-slug' => 'movabletype-importer',
|
||||
'importer-id' => 'mt',
|
||||
),
|
||||
'rss' => array(
|
||||
'name' => __( 'RSS' ),
|
||||
'description' => __( 'Import posts from an RSS feed.' ),
|
||||
'plugin-slug' => 'rss-importer',
|
||||
'importer-id' => 'rss',
|
||||
),
|
||||
'tumblr' => array(
|
||||
'name' => __( 'Tumblr' ),
|
||||
'description' => __( 'Import posts & media from Tumblr using their API.' ),
|
||||
'plugin-slug' => 'tumblr-importer',
|
||||
'importer-id' => 'tumblr',
|
||||
),
|
||||
'wordpress' => array(
|
||||
'name' => 'WordPress',
|
||||
'description' => __( 'Import posts, pages, comments, custom fields, categories, and tags from a WordPress export file.' ),
|
||||
'plugin-slug' => 'wordpress-importer',
|
||||
'importer-id' => 'wordpress',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,108 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* Helper functions for displaying a list of items in an ajaxified HTML table.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage List_Table
|
||||
* @since 3.1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fetches an instance of a WP_List_Table class.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @global string $hook_suffix
|
||||
*
|
||||
* @param string $class_name The type of the list table, which is the class name.
|
||||
* @param array $args Optional. Arguments to pass to the class. Accepts 'screen'.
|
||||
* @return WP_List_Table|false List table object on success, false if the class does not exist.
|
||||
*/
|
||||
function _get_list_table( $class_name, $args = array() ) {
|
||||
$core_classes = array(
|
||||
// Site Admin.
|
||||
'WP_Posts_List_Table' => 'posts',
|
||||
'WP_Media_List_Table' => 'media',
|
||||
'WP_Terms_List_Table' => 'terms',
|
||||
'WP_Users_List_Table' => 'users',
|
||||
'WP_Comments_List_Table' => 'comments',
|
||||
'WP_Post_Comments_List_Table' => array( 'comments', 'post-comments' ),
|
||||
'WP_Links_List_Table' => 'links',
|
||||
'WP_Plugin_Install_List_Table' => 'plugin-install',
|
||||
'WP_Themes_List_Table' => 'themes',
|
||||
'WP_Theme_Install_List_Table' => array( 'themes', 'theme-install' ),
|
||||
'WP_Plugins_List_Table' => 'plugins',
|
||||
'WP_Application_Passwords_List_Table' => 'application-passwords',
|
||||
|
||||
// Network Admin.
|
||||
'WP_MS_Sites_List_Table' => 'ms-sites',
|
||||
'WP_MS_Users_List_Table' => 'ms-users',
|
||||
'WP_MS_Themes_List_Table' => 'ms-themes',
|
||||
|
||||
// Privacy requests tables.
|
||||
'WP_Privacy_Data_Export_Requests_List_Table' => 'privacy-data-export-requests',
|
||||
'WP_Privacy_Data_Removal_Requests_List_Table' => 'privacy-data-removal-requests',
|
||||
);
|
||||
|
||||
if ( isset( $core_classes[ $class_name ] ) ) {
|
||||
foreach ( (array) $core_classes[ $class_name ] as $required ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-' . $required . '-list-table.php';
|
||||
}
|
||||
|
||||
if ( isset( $args['screen'] ) ) {
|
||||
$args['screen'] = convert_to_screen( $args['screen'] );
|
||||
} elseif ( isset( $GLOBALS['hook_suffix'] ) ) {
|
||||
$args['screen'] = get_current_screen();
|
||||
} else {
|
||||
$args['screen'] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list table class to instantiate.
|
||||
*
|
||||
* @since 6.1.0
|
||||
*
|
||||
* @param string $class_name The list table class to use.
|
||||
* @param array $args An array containing _get_list_table() arguments.
|
||||
*/
|
||||
$custom_class_name = apply_filters( 'wp_list_table_class_name', $class_name, $args );
|
||||
|
||||
if ( is_string( $custom_class_name ) && class_exists( $custom_class_name ) ) {
|
||||
$class_name = $custom_class_name;
|
||||
}
|
||||
|
||||
return new $class_name( $args );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register column headers for a particular screen.
|
||||
*
|
||||
* @see get_column_headers(), print_column_headers(), get_hidden_columns()
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $screen The handle for the screen to register column headers for. This is
|
||||
* usually the hook name returned by the `add_*_page()` functions.
|
||||
* @param string[] $columns An array of columns with column IDs as the keys and translated
|
||||
* column names as the values.
|
||||
*/
|
||||
function register_column_headers( $screen, $columns ) {
|
||||
new _WP_List_Table_Compat( $screen, $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints column headers for a particular screen.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string|WP_Screen $screen The screen hook name or screen object.
|
||||
* @param bool $with_id Whether to set the ID attribute or not.
|
||||
*/
|
||||
function print_column_headers( $screen, $with_id = true ) {
|
||||
$wp_list_table = new _WP_List_Table_Compat( $screen );
|
||||
|
||||
$wp_list_table->print_column_headers( $with_id );
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Helper functions for displaying a list of items in an ajaxified HTML table.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage List_Table
|
||||
* @since 3.1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fetches an instance of a WP_List_Table class.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @global string $hook_suffix
|
||||
*
|
||||
* @param string $class_name The type of the list table, which is the class name.
|
||||
* @param array $args Optional. Arguments to pass to the class. Accepts 'screen'.
|
||||
* @return WP_List_Table|false List table object on success, false if the class does not exist.
|
||||
*/
|
||||
function _get_list_table( $class_name, $args = array() ) {
|
||||
$core_classes = array(
|
||||
// Site Admin.
|
||||
'WP_Posts_List_Table' => 'posts',
|
||||
'WP_Media_List_Table' => 'media',
|
||||
'WP_Terms_List_Table' => 'terms',
|
||||
'WP_Users_List_Table' => 'users',
|
||||
'WP_Comments_List_Table' => 'comments',
|
||||
'WP_Post_Comments_List_Table' => array( 'comments', 'post-comments' ),
|
||||
'WP_Links_List_Table' => 'links',
|
||||
'WP_Plugin_Install_List_Table' => 'plugin-install',
|
||||
'WP_Themes_List_Table' => 'themes',
|
||||
'WP_Theme_Install_List_Table' => array( 'themes', 'theme-install' ),
|
||||
'WP_Plugins_List_Table' => 'plugins',
|
||||
'WP_Application_Passwords_List_Table' => 'application-passwords',
|
||||
|
||||
// Network Admin.
|
||||
'WP_MS_Sites_List_Table' => 'ms-sites',
|
||||
'WP_MS_Users_List_Table' => 'ms-users',
|
||||
'WP_MS_Themes_List_Table' => 'ms-themes',
|
||||
|
||||
// Privacy requests tables.
|
||||
'WP_Privacy_Data_Export_Requests_List_Table' => 'privacy-data-export-requests',
|
||||
'WP_Privacy_Data_Removal_Requests_List_Table' => 'privacy-data-removal-requests',
|
||||
);
|
||||
|
||||
if ( isset( $core_classes[ $class_name ] ) ) {
|
||||
foreach ( (array) $core_classes[ $class_name ] as $required ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-' . $required . '-list-table.php';
|
||||
}
|
||||
|
||||
if ( isset( $args['screen'] ) ) {
|
||||
$args['screen'] = convert_to_screen( $args['screen'] );
|
||||
} elseif ( isset( $GLOBALS['hook_suffix'] ) ) {
|
||||
$args['screen'] = get_current_screen();
|
||||
} else {
|
||||
$args['screen'] = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list table class to instantiate.
|
||||
*
|
||||
* @since 6.1.0
|
||||
*
|
||||
* @param string $class_name The list table class to use.
|
||||
* @param array $args An array containing _get_list_table() arguments.
|
||||
*/
|
||||
$custom_class_name = apply_filters( 'wp_list_table_class_name', $class_name, $args );
|
||||
|
||||
if ( is_string( $custom_class_name ) && class_exists( $custom_class_name ) ) {
|
||||
$class_name = $custom_class_name;
|
||||
}
|
||||
|
||||
return new $class_name( $args );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register column headers for a particular screen.
|
||||
*
|
||||
* @see get_column_headers(), print_column_headers(), get_hidden_columns()
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $screen The handle for the screen to register column headers for. This is
|
||||
* usually the hook name returned by the `add_*_page()` functions.
|
||||
* @param string[] $columns An array of columns with column IDs as the keys and translated
|
||||
* column names as the values.
|
||||
*/
|
||||
function register_column_headers( $screen, $columns ) {
|
||||
new _WP_List_Table_Compat( $screen, $columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints column headers for a particular screen.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string|WP_Screen $screen The screen hook name or screen object.
|
||||
* @param bool $with_id Whether to set the ID attribute or not.
|
||||
*/
|
||||
function print_column_headers( $screen, $with_id = true ) {
|
||||
$wp_list_table = new _WP_List_Table_Compat( $screen );
|
||||
|
||||
$wp_list_table->print_column_headers( $with_id );
|
||||
}
|
||||
|
||||
+3873
-3873
File diff suppressed because it is too large
Load Diff
@@ -1,383 +1,383 @@
|
||||
<?php
|
||||
/**
|
||||
* Build Administration Menu.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
*/
|
||||
|
||||
if ( is_network_admin() ) {
|
||||
|
||||
/**
|
||||
* Fires before the administration menu loads in the Network Admin.
|
||||
*
|
||||
* The hook fires before menus and sub-menus are removed based on user privileges.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @access private
|
||||
*/
|
||||
do_action( '_network_admin_menu' );
|
||||
} elseif ( is_user_admin() ) {
|
||||
|
||||
/**
|
||||
* Fires before the administration menu loads in the User Admin.
|
||||
*
|
||||
* The hook fires before menus and sub-menus are removed based on user privileges.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @access private
|
||||
*/
|
||||
do_action( '_user_admin_menu' );
|
||||
} else {
|
||||
|
||||
/**
|
||||
* Fires before the administration menu loads in the admin.
|
||||
*
|
||||
* The hook fires before menus and sub-menus are removed based on user privileges.
|
||||
*
|
||||
* @since 2.2.0
|
||||
* @access private
|
||||
*/
|
||||
do_action( '_admin_menu' );
|
||||
}
|
||||
|
||||
// Create list of page plugin hook names.
|
||||
foreach ( $menu as $menu_page ) {
|
||||
$pos = strpos( $menu_page[2], '?' );
|
||||
|
||||
if ( false !== $pos ) {
|
||||
// Handle post_type=post|page|foo pages.
|
||||
$hook_name = substr( $menu_page[2], 0, $pos );
|
||||
$hook_args = substr( $menu_page[2], $pos + 1 );
|
||||
wp_parse_str( $hook_args, $hook_args );
|
||||
|
||||
// Set the hook name to be the post type.
|
||||
if ( isset( $hook_args['post_type'] ) ) {
|
||||
$hook_name = $hook_args['post_type'];
|
||||
} else {
|
||||
$hook_name = basename( $hook_name, '.php' );
|
||||
}
|
||||
unset( $hook_args );
|
||||
} else {
|
||||
$hook_name = basename( $menu_page[2], '.php' );
|
||||
}
|
||||
|
||||
$hook_name = sanitize_title( $hook_name );
|
||||
|
||||
if ( isset( $compat[ $hook_name ] ) ) {
|
||||
$hook_name = $compat[ $hook_name ];
|
||||
} elseif ( ! $hook_name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$admin_page_hooks[ $menu_page[2] ] = $hook_name;
|
||||
}
|
||||
unset( $menu_page, $compat );
|
||||
|
||||
$_wp_submenu_nopriv = array();
|
||||
$_wp_menu_nopriv = array();
|
||||
// Loop over submenus and remove pages for which the user does not have privs.
|
||||
foreach ( $submenu as $parent => $sub ) {
|
||||
foreach ( $sub as $index => $data ) {
|
||||
if ( ! current_user_can( $data[1] ) ) {
|
||||
unset( $submenu[ $parent ][ $index ] );
|
||||
$_wp_submenu_nopriv[ $parent ][ $data[2] ] = true;
|
||||
}
|
||||
}
|
||||
unset( $index, $data );
|
||||
|
||||
if ( empty( $submenu[ $parent ] ) ) {
|
||||
unset( $submenu[ $parent ] );
|
||||
}
|
||||
}
|
||||
unset( $sub, $parent );
|
||||
|
||||
/*
|
||||
* Loop over the top-level menu.
|
||||
* Menus for which the original parent is not accessible due to lack of privileges
|
||||
* will have the next submenu in line be assigned as the new menu parent.
|
||||
*/
|
||||
foreach ( $menu as $id => $data ) {
|
||||
if ( empty( $submenu[ $data[2] ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$subs = $submenu[ $data[2] ];
|
||||
$first_sub = reset( $subs );
|
||||
$old_parent = $data[2];
|
||||
$new_parent = $first_sub[2];
|
||||
|
||||
/*
|
||||
* If the first submenu is not the same as the assigned parent,
|
||||
* make the first submenu the new parent.
|
||||
*/
|
||||
if ( $new_parent !== $old_parent ) {
|
||||
$_wp_real_parent_file[ $old_parent ] = $new_parent;
|
||||
|
||||
$menu[ $id ][2] = $new_parent;
|
||||
|
||||
foreach ( $submenu[ $old_parent ] as $index => $data ) {
|
||||
$submenu[ $new_parent ][ $index ] = $submenu[ $old_parent ][ $index ];
|
||||
unset( $submenu[ $old_parent ][ $index ] );
|
||||
}
|
||||
unset( $submenu[ $old_parent ], $index );
|
||||
|
||||
if ( isset( $_wp_submenu_nopriv[ $old_parent ] ) ) {
|
||||
$_wp_submenu_nopriv[ $new_parent ] = $_wp_submenu_nopriv[ $old_parent ];
|
||||
}
|
||||
}
|
||||
}
|
||||
unset( $id, $data, $subs, $first_sub, $old_parent, $new_parent );
|
||||
|
||||
if ( is_network_admin() ) {
|
||||
|
||||
/**
|
||||
* Fires before the administration menu loads in the Network Admin.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $context Empty context.
|
||||
*/
|
||||
do_action( 'network_admin_menu', '' );
|
||||
} elseif ( is_user_admin() ) {
|
||||
|
||||
/**
|
||||
* Fires before the administration menu loads in the User Admin.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $context Empty context.
|
||||
*/
|
||||
do_action( 'user_admin_menu', '' );
|
||||
} else {
|
||||
|
||||
/**
|
||||
* Fires before the administration menu loads in the admin.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @param string $context Empty context.
|
||||
*/
|
||||
do_action( 'admin_menu', '' );
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove menus that have no accessible submenus and require privileges
|
||||
* that the user does not have. Run re-parent loop again.
|
||||
*/
|
||||
foreach ( $menu as $id => $data ) {
|
||||
if ( ! current_user_can( $data[1] ) ) {
|
||||
$_wp_menu_nopriv[ $data[2] ] = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is only one submenu and it is has same destination as the parent,
|
||||
* remove the submenu.
|
||||
*/
|
||||
if ( ! empty( $submenu[ $data[2] ] ) && 1 === count( $submenu[ $data[2] ] ) ) {
|
||||
$subs = $submenu[ $data[2] ];
|
||||
$first_sub = reset( $subs );
|
||||
|
||||
if ( $data[2] === $first_sub[2] ) {
|
||||
unset( $submenu[ $data[2] ] );
|
||||
}
|
||||
}
|
||||
|
||||
// If submenu is empty...
|
||||
if ( empty( $submenu[ $data[2] ] ) ) {
|
||||
// And user doesn't have privs, remove menu.
|
||||
if ( isset( $_wp_menu_nopriv[ $data[2] ] ) ) {
|
||||
unset( $menu[ $id ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
unset( $id, $data, $subs, $first_sub );
|
||||
|
||||
/**
|
||||
* Adds a CSS class to a string.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $class_to_add The CSS class to add.
|
||||
* @param string $classes The string to add the CSS class to.
|
||||
* @return string The string with the CSS class added.
|
||||
*/
|
||||
function add_cssclass( $class_to_add, $classes ) {
|
||||
if ( empty( $classes ) ) {
|
||||
return $class_to_add;
|
||||
}
|
||||
|
||||
return $classes . ' ' . $class_to_add;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds CSS classes for top-level administration menu items.
|
||||
*
|
||||
* The list of added classes includes `.menu-top-first` and `.menu-top-last`.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param array $menu The array of administration menu items.
|
||||
* @return array The array of administration menu items with the CSS classes added.
|
||||
*/
|
||||
function add_menu_classes( $menu ) {
|
||||
$first_item = false;
|
||||
$last_order = false;
|
||||
$items_count = count( $menu );
|
||||
|
||||
$i = 0;
|
||||
|
||||
foreach ( $menu as $order => $top ) {
|
||||
++$i;
|
||||
|
||||
if ( 0 === $order ) { // Dashboard is always shown/single.
|
||||
$menu[0][4] = add_cssclass( 'menu-top-first', $top[4] );
|
||||
$last_order = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( str_starts_with( $top[2], 'separator' ) && false !== $last_order ) { // If separator.
|
||||
$first_item = true;
|
||||
$classes = $menu[ $last_order ][4];
|
||||
|
||||
$menu[ $last_order ][4] = add_cssclass( 'menu-top-last', $classes );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $first_item ) {
|
||||
$first_item = false;
|
||||
$classes = $menu[ $order ][4];
|
||||
|
||||
$menu[ $order ][4] = add_cssclass( 'menu-top-first', $classes );
|
||||
}
|
||||
|
||||
if ( $i === $items_count ) { // Last item.
|
||||
$classes = $menu[ $order ][4];
|
||||
|
||||
$menu[ $order ][4] = add_cssclass( 'menu-top-last', $classes );
|
||||
}
|
||||
|
||||
$last_order = $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters administration menu array with classes added for top-level items.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param array $menu Associative array of administration menu items.
|
||||
*/
|
||||
return apply_filters( 'add_menu_classes', $menu );
|
||||
}
|
||||
|
||||
uksort( $menu, 'strnatcasecmp' ); // Make it all pretty.
|
||||
|
||||
/**
|
||||
* Filters whether to enable custom ordering of the administration menu.
|
||||
*
|
||||
* See the {@see 'menu_order'} filter for reordering menu items.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param bool $custom Whether custom ordering is enabled. Default false.
|
||||
*/
|
||||
if ( apply_filters( 'custom_menu_order', false ) ) {
|
||||
$menu_order = array();
|
||||
|
||||
foreach ( $menu as $menu_item ) {
|
||||
$menu_order[] = $menu_item[2];
|
||||
}
|
||||
unset( $menu_item );
|
||||
|
||||
$default_menu_order = $menu_order;
|
||||
|
||||
/**
|
||||
* Filters the order of administration menu items.
|
||||
*
|
||||
* A truthy value must first be passed to the {@see 'custom_menu_order'} filter
|
||||
* for this filter to work. Use the following to enable custom menu ordering:
|
||||
*
|
||||
* add_filter( 'custom_menu_order', '__return_true' );
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param array $menu_order An ordered array of menu items.
|
||||
*/
|
||||
$menu_order = apply_filters( 'menu_order', $menu_order );
|
||||
$menu_order = array_flip( $menu_order );
|
||||
|
||||
$default_menu_order = array_flip( $default_menu_order );
|
||||
|
||||
/**
|
||||
* @global array $menu_order
|
||||
* @global array $default_menu_order
|
||||
*
|
||||
* @param array $a
|
||||
* @param array $b
|
||||
* @return int
|
||||
*/
|
||||
function sort_menu( $a, $b ) {
|
||||
global $menu_order, $default_menu_order;
|
||||
|
||||
$a = $a[2];
|
||||
$b = $b[2];
|
||||
|
||||
if ( isset( $menu_order[ $a ] ) && ! isset( $menu_order[ $b ] ) ) {
|
||||
return -1;
|
||||
} elseif ( ! isset( $menu_order[ $a ] ) && isset( $menu_order[ $b ] ) ) {
|
||||
return 1;
|
||||
} elseif ( isset( $menu_order[ $a ] ) && isset( $menu_order[ $b ] ) ) {
|
||||
if ( $menu_order[ $a ] === $menu_order[ $b ] ) {
|
||||
return 0;
|
||||
}
|
||||
return ( $menu_order[ $a ] < $menu_order[ $b ] ) ? -1 : 1;
|
||||
} else {
|
||||
return ( $default_menu_order[ $a ] <= $default_menu_order[ $b ] ) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
usort( $menu, 'sort_menu' );
|
||||
unset( $menu_order, $default_menu_order );
|
||||
}
|
||||
|
||||
// Prevent adjacent separators.
|
||||
$prev_menu_was_separator = false;
|
||||
foreach ( $menu as $id => $data ) {
|
||||
if ( false === stristr( $data[4], 'wp-menu-separator' ) ) {
|
||||
|
||||
// This item is not a separator, so falsey the toggler and do nothing.
|
||||
$prev_menu_was_separator = false;
|
||||
} else {
|
||||
|
||||
// The previous item was a separator, so unset this one.
|
||||
if ( true === $prev_menu_was_separator ) {
|
||||
unset( $menu[ $id ] );
|
||||
}
|
||||
|
||||
// This item is a separator, so truthy the toggler and move on.
|
||||
$prev_menu_was_separator = true;
|
||||
}
|
||||
}
|
||||
unset( $id, $data, $prev_menu_was_separator );
|
||||
|
||||
// Remove the last menu item if it is a separator.
|
||||
$last_menu_key = array_keys( $menu );
|
||||
$last_menu_key = array_pop( $last_menu_key );
|
||||
if ( ! empty( $menu ) && 'wp-menu-separator' === $menu[ $last_menu_key ][4] ) {
|
||||
unset( $menu[ $last_menu_key ] );
|
||||
}
|
||||
unset( $last_menu_key );
|
||||
|
||||
if ( ! user_can_access_admin_page() ) {
|
||||
|
||||
/**
|
||||
* Fires when access to an admin page is denied.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
do_action( 'admin_page_access_denied' );
|
||||
|
||||
wp_die( __( 'Sorry, you are not allowed to access this page.' ), 403 );
|
||||
}
|
||||
|
||||
$menu = add_menu_classes( $menu );
|
||||
<?php
|
||||
/**
|
||||
* Build Administration Menu.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
*/
|
||||
|
||||
if ( is_network_admin() ) {
|
||||
|
||||
/**
|
||||
* Fires before the administration menu loads in the Network Admin.
|
||||
*
|
||||
* The hook fires before menus and sub-menus are removed based on user privileges.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @access private
|
||||
*/
|
||||
do_action( '_network_admin_menu' );
|
||||
} elseif ( is_user_admin() ) {
|
||||
|
||||
/**
|
||||
* Fires before the administration menu loads in the User Admin.
|
||||
*
|
||||
* The hook fires before menus and sub-menus are removed based on user privileges.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @access private
|
||||
*/
|
||||
do_action( '_user_admin_menu' );
|
||||
} else {
|
||||
|
||||
/**
|
||||
* Fires before the administration menu loads in the admin.
|
||||
*
|
||||
* The hook fires before menus and sub-menus are removed based on user privileges.
|
||||
*
|
||||
* @since 2.2.0
|
||||
* @access private
|
||||
*/
|
||||
do_action( '_admin_menu' );
|
||||
}
|
||||
|
||||
// Create list of page plugin hook names.
|
||||
foreach ( $menu as $menu_page ) {
|
||||
$pos = strpos( $menu_page[2], '?' );
|
||||
|
||||
if ( false !== $pos ) {
|
||||
// Handle post_type=post|page|foo pages.
|
||||
$hook_name = substr( $menu_page[2], 0, $pos );
|
||||
$hook_args = substr( $menu_page[2], $pos + 1 );
|
||||
wp_parse_str( $hook_args, $hook_args );
|
||||
|
||||
// Set the hook name to be the post type.
|
||||
if ( isset( $hook_args['post_type'] ) ) {
|
||||
$hook_name = $hook_args['post_type'];
|
||||
} else {
|
||||
$hook_name = basename( $hook_name, '.php' );
|
||||
}
|
||||
unset( $hook_args );
|
||||
} else {
|
||||
$hook_name = basename( $menu_page[2], '.php' );
|
||||
}
|
||||
|
||||
$hook_name = sanitize_title( $hook_name );
|
||||
|
||||
if ( isset( $compat[ $hook_name ] ) ) {
|
||||
$hook_name = $compat[ $hook_name ];
|
||||
} elseif ( ! $hook_name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$admin_page_hooks[ $menu_page[2] ] = $hook_name;
|
||||
}
|
||||
unset( $menu_page, $compat );
|
||||
|
||||
$_wp_submenu_nopriv = array();
|
||||
$_wp_menu_nopriv = array();
|
||||
// Loop over submenus and remove pages for which the user does not have privs.
|
||||
foreach ( $submenu as $parent => $sub ) {
|
||||
foreach ( $sub as $index => $data ) {
|
||||
if ( ! current_user_can( $data[1] ) ) {
|
||||
unset( $submenu[ $parent ][ $index ] );
|
||||
$_wp_submenu_nopriv[ $parent ][ $data[2] ] = true;
|
||||
}
|
||||
}
|
||||
unset( $index, $data );
|
||||
|
||||
if ( empty( $submenu[ $parent ] ) ) {
|
||||
unset( $submenu[ $parent ] );
|
||||
}
|
||||
}
|
||||
unset( $sub, $parent );
|
||||
|
||||
/*
|
||||
* Loop over the top-level menu.
|
||||
* Menus for which the original parent is not accessible due to lack of privileges
|
||||
* will have the next submenu in line be assigned as the new menu parent.
|
||||
*/
|
||||
foreach ( $menu as $id => $data ) {
|
||||
if ( empty( $submenu[ $data[2] ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$subs = $submenu[ $data[2] ];
|
||||
$first_sub = reset( $subs );
|
||||
$old_parent = $data[2];
|
||||
$new_parent = $first_sub[2];
|
||||
|
||||
/*
|
||||
* If the first submenu is not the same as the assigned parent,
|
||||
* make the first submenu the new parent.
|
||||
*/
|
||||
if ( $new_parent !== $old_parent ) {
|
||||
$_wp_real_parent_file[ $old_parent ] = $new_parent;
|
||||
|
||||
$menu[ $id ][2] = $new_parent;
|
||||
|
||||
foreach ( $submenu[ $old_parent ] as $index => $data ) {
|
||||
$submenu[ $new_parent ][ $index ] = $submenu[ $old_parent ][ $index ];
|
||||
unset( $submenu[ $old_parent ][ $index ] );
|
||||
}
|
||||
unset( $submenu[ $old_parent ], $index );
|
||||
|
||||
if ( isset( $_wp_submenu_nopriv[ $old_parent ] ) ) {
|
||||
$_wp_submenu_nopriv[ $new_parent ] = $_wp_submenu_nopriv[ $old_parent ];
|
||||
}
|
||||
}
|
||||
}
|
||||
unset( $id, $data, $subs, $first_sub, $old_parent, $new_parent );
|
||||
|
||||
if ( is_network_admin() ) {
|
||||
|
||||
/**
|
||||
* Fires before the administration menu loads in the Network Admin.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $context Empty context.
|
||||
*/
|
||||
do_action( 'network_admin_menu', '' );
|
||||
} elseif ( is_user_admin() ) {
|
||||
|
||||
/**
|
||||
* Fires before the administration menu loads in the User Admin.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $context Empty context.
|
||||
*/
|
||||
do_action( 'user_admin_menu', '' );
|
||||
} else {
|
||||
|
||||
/**
|
||||
* Fires before the administration menu loads in the admin.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @param string $context Empty context.
|
||||
*/
|
||||
do_action( 'admin_menu', '' );
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove menus that have no accessible submenus and require privileges
|
||||
* that the user does not have. Run re-parent loop again.
|
||||
*/
|
||||
foreach ( $menu as $id => $data ) {
|
||||
if ( ! current_user_can( $data[1] ) ) {
|
||||
$_wp_menu_nopriv[ $data[2] ] = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is only one submenu and it is has same destination as the parent,
|
||||
* remove the submenu.
|
||||
*/
|
||||
if ( ! empty( $submenu[ $data[2] ] ) && 1 === count( $submenu[ $data[2] ] ) ) {
|
||||
$subs = $submenu[ $data[2] ];
|
||||
$first_sub = reset( $subs );
|
||||
|
||||
if ( $data[2] === $first_sub[2] ) {
|
||||
unset( $submenu[ $data[2] ] );
|
||||
}
|
||||
}
|
||||
|
||||
// If submenu is empty...
|
||||
if ( empty( $submenu[ $data[2] ] ) ) {
|
||||
// And user doesn't have privs, remove menu.
|
||||
if ( isset( $_wp_menu_nopriv[ $data[2] ] ) ) {
|
||||
unset( $menu[ $id ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
unset( $id, $data, $subs, $first_sub );
|
||||
|
||||
/**
|
||||
* Adds a CSS class to a string.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $class_to_add The CSS class to add.
|
||||
* @param string $classes The string to add the CSS class to.
|
||||
* @return string The string with the CSS class added.
|
||||
*/
|
||||
function add_cssclass( $class_to_add, $classes ) {
|
||||
if ( empty( $classes ) ) {
|
||||
return $class_to_add;
|
||||
}
|
||||
|
||||
return $classes . ' ' . $class_to_add;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds CSS classes for top-level administration menu items.
|
||||
*
|
||||
* The list of added classes includes `.menu-top-first` and `.menu-top-last`.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param array $menu The array of administration menu items.
|
||||
* @return array The array of administration menu items with the CSS classes added.
|
||||
*/
|
||||
function add_menu_classes( $menu ) {
|
||||
$first_item = false;
|
||||
$last_order = false;
|
||||
$items_count = count( $menu );
|
||||
|
||||
$i = 0;
|
||||
|
||||
foreach ( $menu as $order => $top ) {
|
||||
++$i;
|
||||
|
||||
if ( 0 === $order ) { // Dashboard is always shown/single.
|
||||
$menu[0][4] = add_cssclass( 'menu-top-first', $top[4] );
|
||||
$last_order = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( str_starts_with( $top[2], 'separator' ) && false !== $last_order ) { // If separator.
|
||||
$first_item = true;
|
||||
$classes = $menu[ $last_order ][4];
|
||||
|
||||
$menu[ $last_order ][4] = add_cssclass( 'menu-top-last', $classes );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $first_item ) {
|
||||
$first_item = false;
|
||||
$classes = $menu[ $order ][4];
|
||||
|
||||
$menu[ $order ][4] = add_cssclass( 'menu-top-first', $classes );
|
||||
}
|
||||
|
||||
if ( $i === $items_count ) { // Last item.
|
||||
$classes = $menu[ $order ][4];
|
||||
|
||||
$menu[ $order ][4] = add_cssclass( 'menu-top-last', $classes );
|
||||
}
|
||||
|
||||
$last_order = $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters administration menu array with classes added for top-level items.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param array $menu Associative array of administration menu items.
|
||||
*/
|
||||
return apply_filters( 'add_menu_classes', $menu );
|
||||
}
|
||||
|
||||
uksort( $menu, 'strnatcasecmp' ); // Make it all pretty.
|
||||
|
||||
/**
|
||||
* Filters whether to enable custom ordering of the administration menu.
|
||||
*
|
||||
* See the {@see 'menu_order'} filter for reordering menu items.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param bool $custom Whether custom ordering is enabled. Default false.
|
||||
*/
|
||||
if ( apply_filters( 'custom_menu_order', false ) ) {
|
||||
$menu_order = array();
|
||||
|
||||
foreach ( $menu as $menu_item ) {
|
||||
$menu_order[] = $menu_item[2];
|
||||
}
|
||||
unset( $menu_item );
|
||||
|
||||
$default_menu_order = $menu_order;
|
||||
|
||||
/**
|
||||
* Filters the order of administration menu items.
|
||||
*
|
||||
* A truthy value must first be passed to the {@see 'custom_menu_order'} filter
|
||||
* for this filter to work. Use the following to enable custom menu ordering:
|
||||
*
|
||||
* add_filter( 'custom_menu_order', '__return_true' );
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param array $menu_order An ordered array of menu items.
|
||||
*/
|
||||
$menu_order = apply_filters( 'menu_order', $menu_order );
|
||||
$menu_order = array_flip( $menu_order );
|
||||
|
||||
$default_menu_order = array_flip( $default_menu_order );
|
||||
|
||||
/**
|
||||
* @global array $menu_order
|
||||
* @global array $default_menu_order
|
||||
*
|
||||
* @param array $a
|
||||
* @param array $b
|
||||
* @return int
|
||||
*/
|
||||
function sort_menu( $a, $b ) {
|
||||
global $menu_order, $default_menu_order;
|
||||
|
||||
$a = $a[2];
|
||||
$b = $b[2];
|
||||
|
||||
if ( isset( $menu_order[ $a ] ) && ! isset( $menu_order[ $b ] ) ) {
|
||||
return -1;
|
||||
} elseif ( ! isset( $menu_order[ $a ] ) && isset( $menu_order[ $b ] ) ) {
|
||||
return 1;
|
||||
} elseif ( isset( $menu_order[ $a ] ) && isset( $menu_order[ $b ] ) ) {
|
||||
if ( $menu_order[ $a ] === $menu_order[ $b ] ) {
|
||||
return 0;
|
||||
}
|
||||
return ( $menu_order[ $a ] < $menu_order[ $b ] ) ? -1 : 1;
|
||||
} else {
|
||||
return ( $default_menu_order[ $a ] <= $default_menu_order[ $b ] ) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
usort( $menu, 'sort_menu' );
|
||||
unset( $menu_order, $default_menu_order );
|
||||
}
|
||||
|
||||
// Prevent adjacent separators.
|
||||
$prev_menu_was_separator = false;
|
||||
foreach ( $menu as $id => $data ) {
|
||||
if ( false === stristr( $data[4], 'wp-menu-separator' ) ) {
|
||||
|
||||
// This item is not a separator, so falsey the toggler and do nothing.
|
||||
$prev_menu_was_separator = false;
|
||||
} else {
|
||||
|
||||
// The previous item was a separator, so unset this one.
|
||||
if ( true === $prev_menu_was_separator ) {
|
||||
unset( $menu[ $id ] );
|
||||
}
|
||||
|
||||
// This item is a separator, so truthy the toggler and move on.
|
||||
$prev_menu_was_separator = true;
|
||||
}
|
||||
}
|
||||
unset( $id, $data, $prev_menu_was_separator );
|
||||
|
||||
// Remove the last menu item if it is a separator.
|
||||
$last_menu_key = array_keys( $menu );
|
||||
$last_menu_key = array_pop( $last_menu_key );
|
||||
if ( ! empty( $menu ) && 'wp-menu-separator' === $menu[ $last_menu_key ][4] ) {
|
||||
unset( $menu[ $last_menu_key ] );
|
||||
}
|
||||
unset( $last_menu_key );
|
||||
|
||||
if ( ! user_can_access_admin_page() ) {
|
||||
|
||||
/**
|
||||
* Fires when access to an admin page is denied.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
do_action( 'admin_page_access_denied' );
|
||||
|
||||
wp_die( __( 'Sorry, you are not allowed to access this page.' ), 403 );
|
||||
}
|
||||
|
||||
$menu = add_menu_classes( $menu );
|
||||
|
||||
+1751
-1751
File diff suppressed because it is too large
Load Diff
+1659
-1659
File diff suppressed because it is too large
Load Diff
@@ -1,41 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Multisite Administration hooks
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.3.0
|
||||
*/
|
||||
|
||||
// Media hooks.
|
||||
add_filter( 'wp_handle_upload_prefilter', 'check_upload_size' );
|
||||
|
||||
// User hooks.
|
||||
add_action( 'user_admin_notices', 'new_user_email_admin_notice' );
|
||||
add_action( 'network_admin_notices', 'new_user_email_admin_notice' );
|
||||
|
||||
add_action( 'admin_page_access_denied', '_access_denied_splash', 99 );
|
||||
|
||||
// Site hooks.
|
||||
add_action( 'wpmueditblogaction', 'upload_space_setting' );
|
||||
|
||||
// Network hooks.
|
||||
add_action( 'update_site_option_admin_email', 'wp_network_admin_email_change_notification', 10, 4 );
|
||||
|
||||
// Post hooks.
|
||||
add_filter( 'wp_insert_post_data', 'avoid_blog_page_permalink_collision', 10, 2 );
|
||||
|
||||
// Tools hooks.
|
||||
add_filter( 'import_allow_create_users', 'check_import_new_users' );
|
||||
|
||||
// Notices hooks.
|
||||
add_action( 'admin_notices', 'site_admin_notice' );
|
||||
add_action( 'network_admin_notices', 'site_admin_notice' );
|
||||
|
||||
// Update hooks.
|
||||
add_action( 'network_admin_notices', 'update_nag', 3 );
|
||||
add_action( 'network_admin_notices', 'maintenance_nag', 10 );
|
||||
|
||||
// Network Admin hooks.
|
||||
add_action( 'add_site_option_new_admin_email', 'update_network_option_new_admin_email', 10, 2 );
|
||||
add_action( 'update_site_option_new_admin_email', 'update_network_option_new_admin_email', 10, 2 );
|
||||
<?php
|
||||
/**
|
||||
* Multisite Administration hooks
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.3.0
|
||||
*/
|
||||
|
||||
// Media hooks.
|
||||
add_filter( 'wp_handle_upload_prefilter', 'check_upload_size' );
|
||||
|
||||
// User hooks.
|
||||
add_action( 'user_admin_notices', 'new_user_email_admin_notice' );
|
||||
add_action( 'network_admin_notices', 'new_user_email_admin_notice' );
|
||||
|
||||
add_action( 'admin_page_access_denied', '_access_denied_splash', 99 );
|
||||
|
||||
// Site hooks.
|
||||
add_action( 'wpmueditblogaction', 'upload_space_setting' );
|
||||
|
||||
// Network hooks.
|
||||
add_action( 'update_site_option_admin_email', 'wp_network_admin_email_change_notification', 10, 4 );
|
||||
|
||||
// Post hooks.
|
||||
add_filter( 'wp_insert_post_data', 'avoid_blog_page_permalink_collision', 10, 2 );
|
||||
|
||||
// Tools hooks.
|
||||
add_filter( 'import_allow_create_users', 'check_import_new_users' );
|
||||
|
||||
// Notices hooks.
|
||||
add_action( 'admin_notices', 'site_admin_notice' );
|
||||
add_action( 'network_admin_notices', 'site_admin_notice' );
|
||||
|
||||
// Update hooks.
|
||||
add_action( 'network_admin_notices', 'update_nag', 3 );
|
||||
add_action( 'network_admin_notices', 'maintenance_nag', 10 );
|
||||
|
||||
// Network Admin hooks.
|
||||
add_action( 'add_site_option_new_admin_email', 'update_network_option_new_admin_email', 10, 2 );
|
||||
add_action( 'update_site_option_new_admin_email', 'update_network_option_new_admin_email', 10, 2 );
|
||||
|
||||
@@ -1,140 +1,140 @@
|
||||
<?php
|
||||
/**
|
||||
* Multisite: Deprecated admin functions from past versions and WordPress MU
|
||||
*
|
||||
* These functions should not be used and will be removed in a later version.
|
||||
* It is suggested to use for the alternatives instead when available.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Deprecated
|
||||
* @since 3.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Outputs the WPMU menu.
|
||||
*
|
||||
* @deprecated 3.0.0
|
||||
*/
|
||||
function wpmu_menu() {
|
||||
_deprecated_function( __FUNCTION__, '3.0.0' );
|
||||
// Deprecated. See #11763.
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the available space defined by the admin has been exceeded by the user.
|
||||
*
|
||||
* @deprecated 3.0.0 Use is_upload_space_available()
|
||||
* @see is_upload_space_available()
|
||||
*/
|
||||
function wpmu_checkAvailableSpace() {
|
||||
_deprecated_function( __FUNCTION__, '3.0.0', 'is_upload_space_available()' );
|
||||
|
||||
if ( ! is_upload_space_available() ) {
|
||||
wp_die( sprintf(
|
||||
/* translators: %s: Allowed space allocation. */
|
||||
__( 'Sorry, you have used your space allocation of %s. Please delete some files to upload more files.' ),
|
||||
size_format( get_space_allowed() * MB_IN_BYTES )
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WPMU options.
|
||||
*
|
||||
* @deprecated 3.0.0
|
||||
*/
|
||||
function mu_options( $options ) {
|
||||
_deprecated_function( __FUNCTION__, '3.0.0' );
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated functionality for activating a network-only plugin.
|
||||
*
|
||||
* @deprecated 3.0.0 Use activate_plugin()
|
||||
* @see activate_plugin()
|
||||
*/
|
||||
function activate_sitewide_plugin() {
|
||||
_deprecated_function( __FUNCTION__, '3.0.0', 'activate_plugin()' );
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated functionality for deactivating a network-only plugin.
|
||||
*
|
||||
* @deprecated 3.0.0 Use deactivate_plugin()
|
||||
* @see deactivate_plugin()
|
||||
*/
|
||||
function deactivate_sitewide_plugin( $plugin = false ) {
|
||||
_deprecated_function( __FUNCTION__, '3.0.0', 'deactivate_plugin()' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated functionality for determining if the current plugin is network-only.
|
||||
*
|
||||
* @deprecated 3.0.0 Use is_network_only_plugin()
|
||||
* @see is_network_only_plugin()
|
||||
*/
|
||||
function is_wpmu_sitewide_plugin( $file ) {
|
||||
_deprecated_function( __FUNCTION__, '3.0.0', 'is_network_only_plugin()' );
|
||||
return is_network_only_plugin( $file );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated functionality for getting themes network-enabled themes.
|
||||
*
|
||||
* @deprecated 3.4.0 Use WP_Theme::get_allowed_on_network()
|
||||
* @see WP_Theme::get_allowed_on_network()
|
||||
*/
|
||||
function get_site_allowed_themes() {
|
||||
_deprecated_function( __FUNCTION__, '3.4.0', 'WP_Theme::get_allowed_on_network()' );
|
||||
return array_map( 'intval', WP_Theme::get_allowed_on_network() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated functionality for getting themes allowed on a specific site.
|
||||
*
|
||||
* @deprecated 3.4.0 Use WP_Theme::get_allowed_on_site()
|
||||
* @see WP_Theme::get_allowed_on_site()
|
||||
*/
|
||||
function wpmu_get_blog_allowedthemes( $blog_id = 0 ) {
|
||||
_deprecated_function( __FUNCTION__, '3.4.0', 'WP_Theme::get_allowed_on_site()' );
|
||||
return array_map( 'intval', WP_Theme::get_allowed_on_site( $blog_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated functionality for determining whether a file is deprecated.
|
||||
*
|
||||
* @deprecated 3.5.0
|
||||
*/
|
||||
function ms_deprecated_blogs_file() {}
|
||||
|
||||
if ( ! function_exists( 'install_global_terms' ) ) :
|
||||
/**
|
||||
* Install global terms.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 6.1.0 This function no longer does anything.
|
||||
* @deprecated 6.1.0
|
||||
*/
|
||||
function install_global_terms() {
|
||||
_deprecated_function( __FUNCTION__, '6.1.0' );
|
||||
}
|
||||
endif;
|
||||
|
||||
/**
|
||||
* Synchronizes category and post tag slugs when global terms are enabled.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 6.1.0 This function no longer does anything.
|
||||
* @deprecated 6.1.0
|
||||
*
|
||||
* @param WP_Term|array $term The term.
|
||||
* @param string $taxonomy The taxonomy for `$term`.
|
||||
* @return WP_Term|array Always returns `$term`.
|
||||
*/
|
||||
function sync_category_tag_slugs( $term, $taxonomy ) {
|
||||
_deprecated_function( __FUNCTION__, '6.1.0' );
|
||||
|
||||
return $term;
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Multisite: Deprecated admin functions from past versions and WordPress MU
|
||||
*
|
||||
* These functions should not be used and will be removed in a later version.
|
||||
* It is suggested to use for the alternatives instead when available.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Deprecated
|
||||
* @since 3.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Outputs the WPMU menu.
|
||||
*
|
||||
* @deprecated 3.0.0
|
||||
*/
|
||||
function wpmu_menu() {
|
||||
_deprecated_function( __FUNCTION__, '3.0.0' );
|
||||
// Deprecated. See #11763.
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the available space defined by the admin has been exceeded by the user.
|
||||
*
|
||||
* @deprecated 3.0.0 Use is_upload_space_available()
|
||||
* @see is_upload_space_available()
|
||||
*/
|
||||
function wpmu_checkAvailableSpace() {
|
||||
_deprecated_function( __FUNCTION__, '3.0.0', 'is_upload_space_available()' );
|
||||
|
||||
if ( ! is_upload_space_available() ) {
|
||||
wp_die( sprintf(
|
||||
/* translators: %s: Allowed space allocation. */
|
||||
__( 'Sorry, you have used your space allocation of %s. Please delete some files to upload more files.' ),
|
||||
size_format( get_space_allowed() * MB_IN_BYTES )
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WPMU options.
|
||||
*
|
||||
* @deprecated 3.0.0
|
||||
*/
|
||||
function mu_options( $options ) {
|
||||
_deprecated_function( __FUNCTION__, '3.0.0' );
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated functionality for activating a network-only plugin.
|
||||
*
|
||||
* @deprecated 3.0.0 Use activate_plugin()
|
||||
* @see activate_plugin()
|
||||
*/
|
||||
function activate_sitewide_plugin() {
|
||||
_deprecated_function( __FUNCTION__, '3.0.0', 'activate_plugin()' );
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated functionality for deactivating a network-only plugin.
|
||||
*
|
||||
* @deprecated 3.0.0 Use deactivate_plugin()
|
||||
* @see deactivate_plugin()
|
||||
*/
|
||||
function deactivate_sitewide_plugin( $plugin = false ) {
|
||||
_deprecated_function( __FUNCTION__, '3.0.0', 'deactivate_plugin()' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated functionality for determining if the current plugin is network-only.
|
||||
*
|
||||
* @deprecated 3.0.0 Use is_network_only_plugin()
|
||||
* @see is_network_only_plugin()
|
||||
*/
|
||||
function is_wpmu_sitewide_plugin( $file ) {
|
||||
_deprecated_function( __FUNCTION__, '3.0.0', 'is_network_only_plugin()' );
|
||||
return is_network_only_plugin( $file );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated functionality for getting themes network-enabled themes.
|
||||
*
|
||||
* @deprecated 3.4.0 Use WP_Theme::get_allowed_on_network()
|
||||
* @see WP_Theme::get_allowed_on_network()
|
||||
*/
|
||||
function get_site_allowed_themes() {
|
||||
_deprecated_function( __FUNCTION__, '3.4.0', 'WP_Theme::get_allowed_on_network()' );
|
||||
return array_map( 'intval', WP_Theme::get_allowed_on_network() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated functionality for getting themes allowed on a specific site.
|
||||
*
|
||||
* @deprecated 3.4.0 Use WP_Theme::get_allowed_on_site()
|
||||
* @see WP_Theme::get_allowed_on_site()
|
||||
*/
|
||||
function wpmu_get_blog_allowedthemes( $blog_id = 0 ) {
|
||||
_deprecated_function( __FUNCTION__, '3.4.0', 'WP_Theme::get_allowed_on_site()' );
|
||||
return array_map( 'intval', WP_Theme::get_allowed_on_site( $blog_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated functionality for determining whether a file is deprecated.
|
||||
*
|
||||
* @deprecated 3.5.0
|
||||
*/
|
||||
function ms_deprecated_blogs_file() {}
|
||||
|
||||
if ( ! function_exists( 'install_global_terms' ) ) :
|
||||
/**
|
||||
* Install global terms.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 6.1.0 This function no longer does anything.
|
||||
* @deprecated 6.1.0
|
||||
*/
|
||||
function install_global_terms() {
|
||||
_deprecated_function( __FUNCTION__, '6.1.0' );
|
||||
}
|
||||
endif;
|
||||
|
||||
/**
|
||||
* Synchronizes category and post tag slugs when global terms are enabled.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @since 6.1.0 This function no longer does anything.
|
||||
* @deprecated 6.1.0
|
||||
*
|
||||
* @param WP_Term|array $term The term.
|
||||
* @param string $taxonomy The taxonomy for `$term`.
|
||||
* @return WP_Term|array Always returns `$term`.
|
||||
*/
|
||||
function sync_category_tag_slugs( $term, $taxonomy ) {
|
||||
_deprecated_function( __FUNCTION__, '6.1.0' );
|
||||
|
||||
return $term;
|
||||
}
|
||||
|
||||
+1174
-1174
File diff suppressed because it is too large
Load Diff
+1552
-1552
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,113 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* Noop functions for load-scripts.php and load-styles.php.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function __() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function _x() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function add_filter() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function has_filter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function esc_attr() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function apply_filters() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function get_option() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function is_lighttpd_before_150() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function add_action() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function did_action() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function do_action_ref_array() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function get_bloginfo() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function is_admin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function site_url() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function admin_url() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function home_url() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function includes_url() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function wp_guess_url() {}
|
||||
|
||||
function get_file( $path ) {
|
||||
|
||||
$path = realpath( $path );
|
||||
|
||||
if ( ! $path || ! @is_file( $path ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return @file_get_contents( $path );
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Noop functions for load-scripts.php and load-styles.php.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function __() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function _x() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function add_filter() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function has_filter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function esc_attr() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function apply_filters() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function get_option() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function is_lighttpd_before_150() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function add_action() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function did_action() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function do_action_ref_array() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function get_bloginfo() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function is_admin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function site_url() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function admin_url() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function home_url() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function includes_url() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function wp_guess_url() {}
|
||||
|
||||
function get_file( $path ) {
|
||||
|
||||
$path = realpath( $path );
|
||||
|
||||
if ( ! $path || ! @is_file( $path ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return @file_get_contents( $path );
|
||||
}
|
||||
|
||||
@@ -1,138 +1,138 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Options Administration API.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Output JavaScript to toggle display of additional settings if avatars are disabled.
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
function options_discussion_add_js() {
|
||||
?>
|
||||
<script>
|
||||
(function($){
|
||||
var parent = $( '#show_avatars' ),
|
||||
children = $( '.avatar-settings' );
|
||||
parent.on( 'change', function(){
|
||||
children.toggleClass( 'hide-if-js', ! this.checked );
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Display JavaScript on the page.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function options_general_add_js() {
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
jQuery( function($) {
|
||||
var $siteName = $( '#wp-admin-bar-site-name' ).children( 'a' ).first(),
|
||||
$siteIconPreview = $('#site-icon-preview-site-title'),
|
||||
homeURL = ( <?php echo wp_json_encode( get_home_url() ); ?> || '' ).replace( /^(https?:\/\/)?(www\.)?/, '' );
|
||||
|
||||
$( '#blogname' ).on( 'input', function() {
|
||||
var title = $.trim( $( this ).val() ) || homeURL;
|
||||
|
||||
// Truncate to 40 characters.
|
||||
if ( 40 < title.length ) {
|
||||
title = title.substring( 0, 40 ) + '\u2026';
|
||||
}
|
||||
|
||||
$siteName.text( title );
|
||||
$siteIconPreview.text( title );
|
||||
});
|
||||
|
||||
$( 'input[name="date_format"]' ).on( 'click', function() {
|
||||
if ( 'date_format_custom_radio' !== $(this).attr( 'id' ) )
|
||||
$( 'input[name="date_format_custom"]' ).val( $( this ).val() ).closest( 'fieldset' ).find( '.example' ).text( $( this ).parent( 'label' ).children( '.format-i18n' ).text() );
|
||||
});
|
||||
|
||||
$( 'input[name="date_format_custom"]' ).on( 'click input', function() {
|
||||
$( '#date_format_custom_radio' ).prop( 'checked', true );
|
||||
});
|
||||
|
||||
$( 'input[name="time_format"]' ).on( 'click', function() {
|
||||
if ( 'time_format_custom_radio' !== $(this).attr( 'id' ) )
|
||||
$( 'input[name="time_format_custom"]' ).val( $( this ).val() ).closest( 'fieldset' ).find( '.example' ).text( $( this ).parent( 'label' ).children( '.format-i18n' ).text() );
|
||||
});
|
||||
|
||||
$( 'input[name="time_format_custom"]' ).on( 'click input', function() {
|
||||
$( '#time_format_custom_radio' ).prop( 'checked', true );
|
||||
});
|
||||
|
||||
$( 'input[name="date_format_custom"], input[name="time_format_custom"]' ).on( 'input', function() {
|
||||
var format = $( this ),
|
||||
fieldset = format.closest( 'fieldset' ),
|
||||
example = fieldset.find( '.example' ),
|
||||
spinner = fieldset.find( '.spinner' );
|
||||
|
||||
// Debounce the event callback while users are typing.
|
||||
clearTimeout( $.data( this, 'timer' ) );
|
||||
$( this ).data( 'timer', setTimeout( function() {
|
||||
// If custom date is not empty.
|
||||
if ( format.val() ) {
|
||||
spinner.addClass( 'is-active' );
|
||||
|
||||
$.post( ajaxurl, {
|
||||
action: 'date_format_custom' === format.attr( 'name' ) ? 'date_format' : 'time_format',
|
||||
date : format.val()
|
||||
}, function( d ) { spinner.removeClass( 'is-active' ); example.text( d ); } );
|
||||
}
|
||||
}, 500 ) );
|
||||
} );
|
||||
|
||||
var languageSelect = $( '#WPLANG' );
|
||||
$( 'form' ).on( 'submit', function() {
|
||||
/*
|
||||
* Don't show a spinner for English and installed languages,
|
||||
* as there is nothing to download.
|
||||
*/
|
||||
if ( ! languageSelect.find( 'option:selected' ).data( 'installed' ) ) {
|
||||
$( '#submit', this ).after( '<span class="spinner language-install-spinner is-active" />' );
|
||||
}
|
||||
});
|
||||
} );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Display JavaScript on the page.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function options_reading_add_js() {
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
jQuery( function($) {
|
||||
var section = $('#front-static-pages'),
|
||||
staticPage = section.find('input:radio[value="page"]'),
|
||||
selects = section.find('select'),
|
||||
check_disabled = function(){
|
||||
selects.prop( 'disabled', ! staticPage.prop('checked') );
|
||||
};
|
||||
check_disabled();
|
||||
section.find( 'input:radio' ).on( 'change', check_disabled );
|
||||
} );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the site charset setting.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function options_reading_blog_charset() {
|
||||
echo '<input name="blog_charset" type="text" id="blog_charset" value="' . esc_attr( get_option( 'blog_charset' ) ) . '" class="regular-text" />';
|
||||
echo '<p class="description">' . __( 'The <a href="https://wordpress.org/documentation/article/wordpress-glossary/#character-set">character encoding</a> of your site (UTF-8 is recommended)' ) . '</p>';
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* WordPress Options Administration API.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Output JavaScript to toggle display of additional settings if avatars are disabled.
|
||||
*
|
||||
* @since 4.2.0
|
||||
*/
|
||||
function options_discussion_add_js() {
|
||||
?>
|
||||
<script>
|
||||
(function($){
|
||||
var parent = $( '#show_avatars' ),
|
||||
children = $( '.avatar-settings' );
|
||||
parent.on( 'change', function(){
|
||||
children.toggleClass( 'hide-if-js', ! this.checked );
|
||||
});
|
||||
})(jQuery);
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Display JavaScript on the page.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function options_general_add_js() {
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
jQuery( function($) {
|
||||
var $siteName = $( '#wp-admin-bar-site-name' ).children( 'a' ).first(),
|
||||
$siteIconPreview = $('#site-icon-preview-site-title'),
|
||||
homeURL = ( <?php echo wp_json_encode( get_home_url() ); ?> || '' ).replace( /^(https?:\/\/)?(www\.)?/, '' );
|
||||
|
||||
$( '#blogname' ).on( 'input', function() {
|
||||
var title = $.trim( $( this ).val() ) || homeURL;
|
||||
|
||||
// Truncate to 40 characters.
|
||||
if ( 40 < title.length ) {
|
||||
title = title.substring( 0, 40 ) + '\u2026';
|
||||
}
|
||||
|
||||
$siteName.text( title );
|
||||
$siteIconPreview.text( title );
|
||||
});
|
||||
|
||||
$( 'input[name="date_format"]' ).on( 'click', function() {
|
||||
if ( 'date_format_custom_radio' !== $(this).attr( 'id' ) )
|
||||
$( 'input[name="date_format_custom"]' ).val( $( this ).val() ).closest( 'fieldset' ).find( '.example' ).text( $( this ).parent( 'label' ).children( '.format-i18n' ).text() );
|
||||
});
|
||||
|
||||
$( 'input[name="date_format_custom"]' ).on( 'click input', function() {
|
||||
$( '#date_format_custom_radio' ).prop( 'checked', true );
|
||||
});
|
||||
|
||||
$( 'input[name="time_format"]' ).on( 'click', function() {
|
||||
if ( 'time_format_custom_radio' !== $(this).attr( 'id' ) )
|
||||
$( 'input[name="time_format_custom"]' ).val( $( this ).val() ).closest( 'fieldset' ).find( '.example' ).text( $( this ).parent( 'label' ).children( '.format-i18n' ).text() );
|
||||
});
|
||||
|
||||
$( 'input[name="time_format_custom"]' ).on( 'click input', function() {
|
||||
$( '#time_format_custom_radio' ).prop( 'checked', true );
|
||||
});
|
||||
|
||||
$( 'input[name="date_format_custom"], input[name="time_format_custom"]' ).on( 'input', function() {
|
||||
var format = $( this ),
|
||||
fieldset = format.closest( 'fieldset' ),
|
||||
example = fieldset.find( '.example' ),
|
||||
spinner = fieldset.find( '.spinner' );
|
||||
|
||||
// Debounce the event callback while users are typing.
|
||||
clearTimeout( $.data( this, 'timer' ) );
|
||||
$( this ).data( 'timer', setTimeout( function() {
|
||||
// If custom date is not empty.
|
||||
if ( format.val() ) {
|
||||
spinner.addClass( 'is-active' );
|
||||
|
||||
$.post( ajaxurl, {
|
||||
action: 'date_format_custom' === format.attr( 'name' ) ? 'date_format' : 'time_format',
|
||||
date : format.val()
|
||||
}, function( d ) { spinner.removeClass( 'is-active' ); example.text( d ); } );
|
||||
}
|
||||
}, 500 ) );
|
||||
} );
|
||||
|
||||
var languageSelect = $( '#WPLANG' );
|
||||
$( 'form' ).on( 'submit', function() {
|
||||
/*
|
||||
* Don't show a spinner for English and installed languages,
|
||||
* as there is nothing to download.
|
||||
*/
|
||||
if ( ! languageSelect.find( 'option:selected' ).data( 'installed' ) ) {
|
||||
$( '#submit', this ).after( '<span class="spinner language-install-spinner is-active" />' );
|
||||
}
|
||||
});
|
||||
} );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Display JavaScript on the page.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function options_reading_add_js() {
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
jQuery( function($) {
|
||||
var section = $('#front-static-pages'),
|
||||
staticPage = section.find('input:radio[value="page"]'),
|
||||
selects = section.find('select'),
|
||||
check_disabled = function(){
|
||||
selects.prop( 'disabled', ! staticPage.prop('checked') );
|
||||
};
|
||||
check_disabled();
|
||||
section.find( 'input:radio' ).on( 'change', check_disabled );
|
||||
} );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the site charset setting.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*/
|
||||
function options_reading_blog_charset() {
|
||||
echo '<input name="blog_charset" type="text" id="blog_charset" value="' . esc_attr( get_option( 'blog_charset' ) ) . '" class="regular-text" />';
|
||||
echo '<p class="description">' . __( 'The <a href="https://wordpress.org/documentation/article/wordpress-glossary/#character-set">character encoding</a> of your site (UTF-8 is recommended)' ) . '</p>';
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+2673
-2673
File diff suppressed because it is too large
Load Diff
+2651
-2651
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,473 +1,473 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Administration Revisions API
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 3.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the revision UI diff.
|
||||
*
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @param WP_Post|int $post The post object or post ID.
|
||||
* @param int $compare_from The revision ID to compare from.
|
||||
* @param int $compare_to The revision ID to come to.
|
||||
* @return array|false Associative array of a post's revisioned fields and their diffs.
|
||||
* Or, false on failure.
|
||||
*/
|
||||
function wp_get_revision_ui_diff( $post, $compare_from, $compare_to ) {
|
||||
$post = get_post( $post );
|
||||
if ( ! $post ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $compare_from ) {
|
||||
$compare_from = get_post( $compare_from );
|
||||
if ( ! $compare_from ) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// If we're dealing with the first revision...
|
||||
$compare_from = false;
|
||||
}
|
||||
|
||||
$compare_to = get_post( $compare_to );
|
||||
if ( ! $compare_to ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If comparing revisions, make sure we are dealing with the right post parent.
|
||||
* The parent post may be a 'revision' when revisions are disabled and we're looking at autosaves.
|
||||
*/
|
||||
if ( $compare_from && $compare_from->post_parent !== $post->ID && $compare_from->ID !== $post->ID ) {
|
||||
return false;
|
||||
}
|
||||
if ( $compare_to->post_parent !== $post->ID && $compare_to->ID !== $post->ID ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $compare_from && strtotime( $compare_from->post_date_gmt ) > strtotime( $compare_to->post_date_gmt ) ) {
|
||||
$temp = $compare_from;
|
||||
$compare_from = $compare_to;
|
||||
$compare_to = $temp;
|
||||
}
|
||||
|
||||
// Add default title if title field is empty.
|
||||
if ( $compare_from && empty( $compare_from->post_title ) ) {
|
||||
$compare_from->post_title = __( '(no title)' );
|
||||
}
|
||||
if ( empty( $compare_to->post_title ) ) {
|
||||
$compare_to->post_title = __( '(no title)' );
|
||||
}
|
||||
|
||||
$return = array();
|
||||
|
||||
foreach ( _wp_post_revision_fields( $post ) as $field => $name ) {
|
||||
/**
|
||||
* Contextually filter a post revision field.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$field`, corresponds to a name of a
|
||||
* field of the revision object.
|
||||
*
|
||||
* Possible hook names include:
|
||||
*
|
||||
* - `_wp_post_revision_field_post_title`
|
||||
* - `_wp_post_revision_field_post_content`
|
||||
* - `_wp_post_revision_field_post_excerpt`
|
||||
*
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @param string $revision_field The current revision field to compare to or from.
|
||||
* @param string $field The current revision field.
|
||||
* @param WP_Post $compare_from The revision post object to compare to or from.
|
||||
* @param string $context The context of whether the current revision is the old
|
||||
* or the new one. Either 'to' or 'from'.
|
||||
*/
|
||||
$content_from = $compare_from ? apply_filters( "_wp_post_revision_field_{$field}", $compare_from->$field, $field, $compare_from, 'from' ) : '';
|
||||
|
||||
/** This filter is documented in wp-admin/includes/revision.php */
|
||||
$content_to = apply_filters( "_wp_post_revision_field_{$field}", $compare_to->$field, $field, $compare_to, 'to' );
|
||||
|
||||
$args = array(
|
||||
'show_split_view' => true,
|
||||
'title_left' => __( 'Removed' ),
|
||||
'title_right' => __( 'Added' ),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters revisions text diff options.
|
||||
*
|
||||
* Filters the options passed to wp_text_diff() when viewing a post revision.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param array $args {
|
||||
* Associative array of options to pass to wp_text_diff().
|
||||
*
|
||||
* @type bool $show_split_view True for split view (two columns), false for
|
||||
* un-split view (single column). Default true.
|
||||
* }
|
||||
* @param string $field The current revision field.
|
||||
* @param WP_Post $compare_from The revision post to compare from.
|
||||
* @param WP_Post $compare_to The revision post to compare to.
|
||||
*/
|
||||
$args = apply_filters( 'revision_text_diff_options', $args, $field, $compare_from, $compare_to );
|
||||
|
||||
$diff = wp_text_diff( $content_from, $content_to, $args );
|
||||
|
||||
if ( ! $diff && 'post_title' === $field ) {
|
||||
/*
|
||||
* It's a better user experience to still show the Title, even if it didn't change.
|
||||
* No, you didn't see this.
|
||||
*/
|
||||
$diff = '<table class="diff"><colgroup><col class="content diffsplit left"><col class="content diffsplit middle"><col class="content diffsplit right"></colgroup><tbody><tr>';
|
||||
|
||||
// In split screen mode, show the title before/after side by side.
|
||||
if ( true === $args['show_split_view'] ) {
|
||||
$diff .= '<td>' . esc_html( $compare_from->post_title ) . '</td><td></td><td>' . esc_html( $compare_to->post_title ) . '</td>';
|
||||
} else {
|
||||
$diff .= '<td>' . esc_html( $compare_from->post_title ) . '</td>';
|
||||
|
||||
// In single column mode, only show the title once if unchanged.
|
||||
if ( $compare_from->post_title !== $compare_to->post_title ) {
|
||||
$diff .= '</tr><tr><td>' . esc_html( $compare_to->post_title ) . '</td>';
|
||||
}
|
||||
}
|
||||
|
||||
$diff .= '</tr></tbody>';
|
||||
$diff .= '</table>';
|
||||
}
|
||||
|
||||
if ( $diff ) {
|
||||
$return[] = array(
|
||||
'id' => $field,
|
||||
'name' => $name,
|
||||
'diff' => $diff,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the fields displayed in the post revision diff UI.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param array[] $return Array of revision UI fields. Each item is an array of id, name, and diff.
|
||||
* @param WP_Post $compare_from The revision post to compare from.
|
||||
* @param WP_Post $compare_to The revision post to compare to.
|
||||
*/
|
||||
return apply_filters( 'wp_get_revision_ui_diff', $return, $compare_from, $compare_to );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare revisions for JavaScript.
|
||||
*
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @param WP_Post|int $post The post object or post ID.
|
||||
* @param int $selected_revision_id The selected revision ID.
|
||||
* @param int $from Optional. The revision ID to compare from.
|
||||
* @return array An associative array of revision data and related settings.
|
||||
*/
|
||||
function wp_prepare_revisions_for_js( $post, $selected_revision_id, $from = null ) {
|
||||
$post = get_post( $post );
|
||||
$authors = array();
|
||||
$now_gmt = time();
|
||||
|
||||
$revisions = wp_get_post_revisions(
|
||||
$post->ID,
|
||||
array(
|
||||
'order' => 'ASC',
|
||||
'check_enabled' => false,
|
||||
)
|
||||
);
|
||||
// If revisions are disabled, we only want autosaves and the current post.
|
||||
if ( ! wp_revisions_enabled( $post ) ) {
|
||||
foreach ( $revisions as $revision_id => $revision ) {
|
||||
if ( ! wp_is_post_autosave( $revision ) ) {
|
||||
unset( $revisions[ $revision_id ] );
|
||||
}
|
||||
}
|
||||
$revisions = array( $post->ID => $post ) + $revisions;
|
||||
}
|
||||
|
||||
$show_avatars = get_option( 'show_avatars' );
|
||||
|
||||
update_post_author_caches( $revisions );
|
||||
|
||||
$can_restore = current_user_can( 'edit_post', $post->ID );
|
||||
$current_id = false;
|
||||
|
||||
foreach ( $revisions as $revision ) {
|
||||
$modified = strtotime( $revision->post_modified );
|
||||
$modified_gmt = strtotime( $revision->post_modified_gmt . ' +0000' );
|
||||
if ( $can_restore ) {
|
||||
$restore_link = str_replace(
|
||||
'&',
|
||||
'&',
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'revision' => $revision->ID,
|
||||
'action' => 'restore',
|
||||
),
|
||||
admin_url( 'revision.php' )
|
||||
),
|
||||
"restore-post_{$revision->ID}"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! isset( $authors[ $revision->post_author ] ) ) {
|
||||
$authors[ $revision->post_author ] = array(
|
||||
'id' => (int) $revision->post_author,
|
||||
'avatar' => $show_avatars ? get_avatar( $revision->post_author, 32 ) : '',
|
||||
'name' => get_the_author_meta( 'display_name', $revision->post_author ),
|
||||
);
|
||||
}
|
||||
|
||||
$autosave = (bool) wp_is_post_autosave( $revision );
|
||||
$current = ! $autosave && $revision->post_modified_gmt === $post->post_modified_gmt;
|
||||
if ( $current && ! empty( $current_id ) ) {
|
||||
// If multiple revisions have the same post_modified_gmt, highest ID is current.
|
||||
if ( $current_id < $revision->ID ) {
|
||||
$revisions[ $current_id ]['current'] = false;
|
||||
$current_id = $revision->ID;
|
||||
} else {
|
||||
$current = false;
|
||||
}
|
||||
} elseif ( $current ) {
|
||||
$current_id = $revision->ID;
|
||||
}
|
||||
|
||||
$revisions_data = array(
|
||||
'id' => $revision->ID,
|
||||
'title' => get_the_title( $post->ID ),
|
||||
'author' => $authors[ $revision->post_author ],
|
||||
'date' => date_i18n( __( 'M j, Y @ H:i' ), $modified ),
|
||||
'dateShort' => date_i18n( _x( 'j M @ H:i', 'revision date short format' ), $modified ),
|
||||
/* translators: %s: Human-readable time difference. */
|
||||
'timeAgo' => sprintf( __( '%s ago' ), human_time_diff( $modified_gmt, $now_gmt ) ),
|
||||
'autosave' => $autosave,
|
||||
'current' => $current,
|
||||
'restoreUrl' => $can_restore ? $restore_link : false,
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the array of revisions used on the revisions screen.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*
|
||||
* @param array $revisions_data {
|
||||
* The bootstrapped data for the revisions screen.
|
||||
*
|
||||
* @type int $id Revision ID.
|
||||
* @type string $title Title for the revision's parent WP_Post object.
|
||||
* @type int $author Revision post author ID.
|
||||
* @type string $date Date the revision was modified.
|
||||
* @type string $dateShort Short-form version of the date the revision was modified.
|
||||
* @type string $timeAgo GMT-aware amount of time ago the revision was modified.
|
||||
* @type bool $autosave Whether the revision is an autosave.
|
||||
* @type bool $current Whether the revision is both not an autosave and the post
|
||||
* modified date matches the revision modified date (GMT-aware).
|
||||
* @type bool|false $restoreUrl URL if the revision can be restored, false otherwise.
|
||||
* }
|
||||
* @param WP_Post $revision The revision's WP_Post object.
|
||||
* @param WP_Post $post The revision's parent WP_Post object.
|
||||
*/
|
||||
$revisions[ $revision->ID ] = apply_filters( 'wp_prepare_revision_for_js', $revisions_data, $revision, $post );
|
||||
}
|
||||
|
||||
/*
|
||||
* If we only have one revision, the initial revision is missing. This happens
|
||||
* when we have an autosave and the user has clicked 'View the Autosave'.
|
||||
*/
|
||||
if ( 1 === count( $revisions ) ) {
|
||||
$revisions[ $post->ID ] = array(
|
||||
'id' => $post->ID,
|
||||
'title' => get_the_title( $post->ID ),
|
||||
'author' => $authors[ $revision->post_author ],
|
||||
'date' => date_i18n( __( 'M j, Y @ H:i' ), strtotime( $post->post_modified ) ),
|
||||
'dateShort' => date_i18n( _x( 'j M @ H:i', 'revision date short format' ), strtotime( $post->post_modified ) ),
|
||||
/* translators: %s: Human-readable time difference. */
|
||||
'timeAgo' => sprintf( __( '%s ago' ), human_time_diff( strtotime( $post->post_modified_gmt ), $now_gmt ) ),
|
||||
'autosave' => false,
|
||||
'current' => true,
|
||||
'restoreUrl' => false,
|
||||
);
|
||||
$current_id = $post->ID;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a post has been saved since the latest revision (no revisioned fields
|
||||
* were changed), we may not have a "current" revision. Mark the latest
|
||||
* revision as "current".
|
||||
*/
|
||||
if ( empty( $current_id ) ) {
|
||||
if ( $revisions[ $revision->ID ]['autosave'] ) {
|
||||
$revision = end( $revisions );
|
||||
while ( $revision['autosave'] ) {
|
||||
$revision = prev( $revisions );
|
||||
}
|
||||
$current_id = $revision['id'];
|
||||
} else {
|
||||
$current_id = $revision->ID;
|
||||
}
|
||||
$revisions[ $current_id ]['current'] = true;
|
||||
}
|
||||
|
||||
// Now, grab the initial diff.
|
||||
$compare_two_mode = is_numeric( $from );
|
||||
if ( ! $compare_two_mode ) {
|
||||
$found = array_search( $selected_revision_id, array_keys( $revisions ), true );
|
||||
if ( $found ) {
|
||||
$from = array_keys( array_slice( $revisions, $found - 1, 1, true ) );
|
||||
$from = reset( $from );
|
||||
} else {
|
||||
$from = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$from = absint( $from );
|
||||
|
||||
$diffs = array(
|
||||
array(
|
||||
'id' => $from . ':' . $selected_revision_id,
|
||||
'fields' => wp_get_revision_ui_diff( $post->ID, $from, $selected_revision_id ),
|
||||
),
|
||||
);
|
||||
|
||||
return array(
|
||||
'postId' => $post->ID,
|
||||
'nonce' => wp_create_nonce( 'revisions-ajax-nonce' ),
|
||||
'revisionData' => array_values( $revisions ),
|
||||
'to' => $selected_revision_id,
|
||||
'from' => $from,
|
||||
'diffData' => $diffs,
|
||||
'baseUrl' => parse_url( admin_url( 'revision.php' ), PHP_URL_PATH ),
|
||||
'compareTwoMode' => absint( $compare_two_mode ), // Apparently booleans are not allowed.
|
||||
'revisionIds' => array_keys( $revisions ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print JavaScript templates required for the revisions experience.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @global WP_Post $post Global post object.
|
||||
*/
|
||||
function wp_print_revision_templates() {
|
||||
global $post;
|
||||
?><script id="tmpl-revisions-frame" type="text/html">
|
||||
<div class="revisions-control-frame"></div>
|
||||
<div class="revisions-diff-frame"></div>
|
||||
</script>
|
||||
|
||||
<script id="tmpl-revisions-buttons" type="text/html">
|
||||
<div class="revisions-previous">
|
||||
<input class="button" type="button" value="<?php echo esc_attr_x( 'Previous', 'Button label for a previous revision' ); ?>" />
|
||||
</div>
|
||||
|
||||
<div class="revisions-next">
|
||||
<input class="button" type="button" value="<?php echo esc_attr_x( 'Next', 'Button label for a next revision' ); ?>" />
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script id="tmpl-revisions-checkbox" type="text/html">
|
||||
<div class="revision-toggle-compare-mode">
|
||||
<label>
|
||||
<input type="checkbox" class="compare-two-revisions"
|
||||
<#
|
||||
if ( 'undefined' !== typeof data && data.model.attributes.compareTwoMode ) {
|
||||
#> checked="checked"<#
|
||||
}
|
||||
#>
|
||||
/>
|
||||
<?php esc_html_e( 'Compare any two revisions' ); ?>
|
||||
</label>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script id="tmpl-revisions-meta" type="text/html">
|
||||
<# if ( ! _.isUndefined( data.attributes ) ) { #>
|
||||
<div class="diff-title">
|
||||
<# if ( 'from' === data.type ) { #>
|
||||
<strong><?php _ex( 'From:', 'Followed by post revision info' ); ?></strong>
|
||||
<# } else if ( 'to' === data.type ) { #>
|
||||
<strong><?php _ex( 'To:', 'Followed by post revision info' ); ?></strong>
|
||||
<# } #>
|
||||
<div class="author-card<# if ( data.attributes.autosave ) { #> autosave<# } #>">
|
||||
{{{ data.attributes.author.avatar }}}
|
||||
<div class="author-info">
|
||||
<# if ( data.attributes.autosave ) { #>
|
||||
<span class="byline">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: User's display name. */
|
||||
__( 'Autosave by %s' ),
|
||||
'<span class="author-name">{{ data.attributes.author.name }}</span>'
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<# } else if ( data.attributes.current ) { #>
|
||||
<span class="byline">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: User's display name. */
|
||||
__( 'Current Revision by %s' ),
|
||||
'<span class="author-name">{{ data.attributes.author.name }}</span>'
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<# } else { #>
|
||||
<span class="byline">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: User's display name. */
|
||||
__( 'Revision by %s' ),
|
||||
'<span class="author-name">{{ data.attributes.author.name }}</span>'
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<# } #>
|
||||
<span class="time-ago">{{ data.attributes.timeAgo }}</span>
|
||||
<span class="date">({{ data.attributes.dateShort }})</span>
|
||||
</div>
|
||||
<# if ( 'to' === data.type && data.attributes.restoreUrl ) { #>
|
||||
<input <?php if ( wp_check_post_lock( $post->ID ) ) { ?>
|
||||
disabled="disabled"
|
||||
<?php } else { ?>
|
||||
<# if ( data.attributes.current ) { #>
|
||||
disabled="disabled"
|
||||
<# } #>
|
||||
<?php } ?>
|
||||
<# if ( data.attributes.autosave ) { #>
|
||||
type="button" class="restore-revision button button-primary" value="<?php esc_attr_e( 'Restore This Autosave' ); ?>" />
|
||||
<# } else { #>
|
||||
type="button" class="restore-revision button button-primary" value="<?php esc_attr_e( 'Restore This Revision' ); ?>" />
|
||||
<# } #>
|
||||
<# } #>
|
||||
</div>
|
||||
<# if ( 'tooltip' === data.type ) { #>
|
||||
<div class="revisions-tooltip-arrow"><span></span></div>
|
||||
<# } #>
|
||||
<# } #>
|
||||
</script>
|
||||
|
||||
<script id="tmpl-revisions-diff" type="text/html">
|
||||
<div class="loading-indicator"><span class="spinner"></span></div>
|
||||
<div class="diff-error"><?php _e( 'Sorry, something went wrong. The requested comparison could not be loaded.' ); ?></div>
|
||||
<div class="diff">
|
||||
<# _.each( data.fields, function( field ) { #>
|
||||
<h3>{{ field.name }}</h3>
|
||||
{{{ field.diff }}}
|
||||
<# }); #>
|
||||
</div>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* WordPress Administration Revisions API
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
* @since 3.6.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the revision UI diff.
|
||||
*
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @param WP_Post|int $post The post object or post ID.
|
||||
* @param int $compare_from The revision ID to compare from.
|
||||
* @param int $compare_to The revision ID to come to.
|
||||
* @return array|false Associative array of a post's revisioned fields and their diffs.
|
||||
* Or, false on failure.
|
||||
*/
|
||||
function wp_get_revision_ui_diff( $post, $compare_from, $compare_to ) {
|
||||
$post = get_post( $post );
|
||||
if ( ! $post ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $compare_from ) {
|
||||
$compare_from = get_post( $compare_from );
|
||||
if ( ! $compare_from ) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// If we're dealing with the first revision...
|
||||
$compare_from = false;
|
||||
}
|
||||
|
||||
$compare_to = get_post( $compare_to );
|
||||
if ( ! $compare_to ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If comparing revisions, make sure we are dealing with the right post parent.
|
||||
* The parent post may be a 'revision' when revisions are disabled and we're looking at autosaves.
|
||||
*/
|
||||
if ( $compare_from && $compare_from->post_parent !== $post->ID && $compare_from->ID !== $post->ID ) {
|
||||
return false;
|
||||
}
|
||||
if ( $compare_to->post_parent !== $post->ID && $compare_to->ID !== $post->ID ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $compare_from && strtotime( $compare_from->post_date_gmt ) > strtotime( $compare_to->post_date_gmt ) ) {
|
||||
$temp = $compare_from;
|
||||
$compare_from = $compare_to;
|
||||
$compare_to = $temp;
|
||||
}
|
||||
|
||||
// Add default title if title field is empty.
|
||||
if ( $compare_from && empty( $compare_from->post_title ) ) {
|
||||
$compare_from->post_title = __( '(no title)' );
|
||||
}
|
||||
if ( empty( $compare_to->post_title ) ) {
|
||||
$compare_to->post_title = __( '(no title)' );
|
||||
}
|
||||
|
||||
$return = array();
|
||||
|
||||
foreach ( _wp_post_revision_fields( $post ) as $field => $name ) {
|
||||
/**
|
||||
* Contextually filter a post revision field.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$field`, corresponds to a name of a
|
||||
* field of the revision object.
|
||||
*
|
||||
* Possible hook names include:
|
||||
*
|
||||
* - `_wp_post_revision_field_post_title`
|
||||
* - `_wp_post_revision_field_post_content`
|
||||
* - `_wp_post_revision_field_post_excerpt`
|
||||
*
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @param string $revision_field The current revision field to compare to or from.
|
||||
* @param string $field The current revision field.
|
||||
* @param WP_Post $compare_from The revision post object to compare to or from.
|
||||
* @param string $context The context of whether the current revision is the old
|
||||
* or the new one. Either 'to' or 'from'.
|
||||
*/
|
||||
$content_from = $compare_from ? apply_filters( "_wp_post_revision_field_{$field}", $compare_from->$field, $field, $compare_from, 'from' ) : '';
|
||||
|
||||
/** This filter is documented in wp-admin/includes/revision.php */
|
||||
$content_to = apply_filters( "_wp_post_revision_field_{$field}", $compare_to->$field, $field, $compare_to, 'to' );
|
||||
|
||||
$args = array(
|
||||
'show_split_view' => true,
|
||||
'title_left' => __( 'Removed' ),
|
||||
'title_right' => __( 'Added' ),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters revisions text diff options.
|
||||
*
|
||||
* Filters the options passed to wp_text_diff() when viewing a post revision.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param array $args {
|
||||
* Associative array of options to pass to wp_text_diff().
|
||||
*
|
||||
* @type bool $show_split_view True for split view (two columns), false for
|
||||
* un-split view (single column). Default true.
|
||||
* }
|
||||
* @param string $field The current revision field.
|
||||
* @param WP_Post $compare_from The revision post to compare from.
|
||||
* @param WP_Post $compare_to The revision post to compare to.
|
||||
*/
|
||||
$args = apply_filters( 'revision_text_diff_options', $args, $field, $compare_from, $compare_to );
|
||||
|
||||
$diff = wp_text_diff( $content_from, $content_to, $args );
|
||||
|
||||
if ( ! $diff && 'post_title' === $field ) {
|
||||
/*
|
||||
* It's a better user experience to still show the Title, even if it didn't change.
|
||||
* No, you didn't see this.
|
||||
*/
|
||||
$diff = '<table class="diff"><colgroup><col class="content diffsplit left"><col class="content diffsplit middle"><col class="content diffsplit right"></colgroup><tbody><tr>';
|
||||
|
||||
// In split screen mode, show the title before/after side by side.
|
||||
if ( true === $args['show_split_view'] ) {
|
||||
$diff .= '<td>' . esc_html( $compare_from->post_title ) . '</td><td></td><td>' . esc_html( $compare_to->post_title ) . '</td>';
|
||||
} else {
|
||||
$diff .= '<td>' . esc_html( $compare_from->post_title ) . '</td>';
|
||||
|
||||
// In single column mode, only show the title once if unchanged.
|
||||
if ( $compare_from->post_title !== $compare_to->post_title ) {
|
||||
$diff .= '</tr><tr><td>' . esc_html( $compare_to->post_title ) . '</td>';
|
||||
}
|
||||
}
|
||||
|
||||
$diff .= '</tr></tbody>';
|
||||
$diff .= '</table>';
|
||||
}
|
||||
|
||||
if ( $diff ) {
|
||||
$return[] = array(
|
||||
'id' => $field,
|
||||
'name' => $name,
|
||||
'diff' => $diff,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the fields displayed in the post revision diff UI.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param array[] $return Array of revision UI fields. Each item is an array of id, name, and diff.
|
||||
* @param WP_Post $compare_from The revision post to compare from.
|
||||
* @param WP_Post $compare_to The revision post to compare to.
|
||||
*/
|
||||
return apply_filters( 'wp_get_revision_ui_diff', $return, $compare_from, $compare_to );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare revisions for JavaScript.
|
||||
*
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @param WP_Post|int $post The post object or post ID.
|
||||
* @param int $selected_revision_id The selected revision ID.
|
||||
* @param int $from Optional. The revision ID to compare from.
|
||||
* @return array An associative array of revision data and related settings.
|
||||
*/
|
||||
function wp_prepare_revisions_for_js( $post, $selected_revision_id, $from = null ) {
|
||||
$post = get_post( $post );
|
||||
$authors = array();
|
||||
$now_gmt = time();
|
||||
|
||||
$revisions = wp_get_post_revisions(
|
||||
$post->ID,
|
||||
array(
|
||||
'order' => 'ASC',
|
||||
'check_enabled' => false,
|
||||
)
|
||||
);
|
||||
// If revisions are disabled, we only want autosaves and the current post.
|
||||
if ( ! wp_revisions_enabled( $post ) ) {
|
||||
foreach ( $revisions as $revision_id => $revision ) {
|
||||
if ( ! wp_is_post_autosave( $revision ) ) {
|
||||
unset( $revisions[ $revision_id ] );
|
||||
}
|
||||
}
|
||||
$revisions = array( $post->ID => $post ) + $revisions;
|
||||
}
|
||||
|
||||
$show_avatars = get_option( 'show_avatars' );
|
||||
|
||||
update_post_author_caches( $revisions );
|
||||
|
||||
$can_restore = current_user_can( 'edit_post', $post->ID );
|
||||
$current_id = false;
|
||||
|
||||
foreach ( $revisions as $revision ) {
|
||||
$modified = strtotime( $revision->post_modified );
|
||||
$modified_gmt = strtotime( $revision->post_modified_gmt . ' +0000' );
|
||||
if ( $can_restore ) {
|
||||
$restore_link = str_replace(
|
||||
'&',
|
||||
'&',
|
||||
wp_nonce_url(
|
||||
add_query_arg(
|
||||
array(
|
||||
'revision' => $revision->ID,
|
||||
'action' => 'restore',
|
||||
),
|
||||
admin_url( 'revision.php' )
|
||||
),
|
||||
"restore-post_{$revision->ID}"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! isset( $authors[ $revision->post_author ] ) ) {
|
||||
$authors[ $revision->post_author ] = array(
|
||||
'id' => (int) $revision->post_author,
|
||||
'avatar' => $show_avatars ? get_avatar( $revision->post_author, 32 ) : '',
|
||||
'name' => get_the_author_meta( 'display_name', $revision->post_author ),
|
||||
);
|
||||
}
|
||||
|
||||
$autosave = (bool) wp_is_post_autosave( $revision );
|
||||
$current = ! $autosave && $revision->post_modified_gmt === $post->post_modified_gmt;
|
||||
if ( $current && ! empty( $current_id ) ) {
|
||||
// If multiple revisions have the same post_modified_gmt, highest ID is current.
|
||||
if ( $current_id < $revision->ID ) {
|
||||
$revisions[ $current_id ]['current'] = false;
|
||||
$current_id = $revision->ID;
|
||||
} else {
|
||||
$current = false;
|
||||
}
|
||||
} elseif ( $current ) {
|
||||
$current_id = $revision->ID;
|
||||
}
|
||||
|
||||
$revisions_data = array(
|
||||
'id' => $revision->ID,
|
||||
'title' => get_the_title( $post->ID ),
|
||||
'author' => $authors[ $revision->post_author ],
|
||||
'date' => date_i18n( __( 'M j, Y @ H:i' ), $modified ),
|
||||
'dateShort' => date_i18n( _x( 'j M @ H:i', 'revision date short format' ), $modified ),
|
||||
/* translators: %s: Human-readable time difference. */
|
||||
'timeAgo' => sprintf( __( '%s ago' ), human_time_diff( $modified_gmt, $now_gmt ) ),
|
||||
'autosave' => $autosave,
|
||||
'current' => $current,
|
||||
'restoreUrl' => $can_restore ? $restore_link : false,
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the array of revisions used on the revisions screen.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*
|
||||
* @param array $revisions_data {
|
||||
* The bootstrapped data for the revisions screen.
|
||||
*
|
||||
* @type int $id Revision ID.
|
||||
* @type string $title Title for the revision's parent WP_Post object.
|
||||
* @type int $author Revision post author ID.
|
||||
* @type string $date Date the revision was modified.
|
||||
* @type string $dateShort Short-form version of the date the revision was modified.
|
||||
* @type string $timeAgo GMT-aware amount of time ago the revision was modified.
|
||||
* @type bool $autosave Whether the revision is an autosave.
|
||||
* @type bool $current Whether the revision is both not an autosave and the post
|
||||
* modified date matches the revision modified date (GMT-aware).
|
||||
* @type bool|false $restoreUrl URL if the revision can be restored, false otherwise.
|
||||
* }
|
||||
* @param WP_Post $revision The revision's WP_Post object.
|
||||
* @param WP_Post $post The revision's parent WP_Post object.
|
||||
*/
|
||||
$revisions[ $revision->ID ] = apply_filters( 'wp_prepare_revision_for_js', $revisions_data, $revision, $post );
|
||||
}
|
||||
|
||||
/*
|
||||
* If we only have one revision, the initial revision is missing. This happens
|
||||
* when we have an autosave and the user has clicked 'View the Autosave'.
|
||||
*/
|
||||
if ( 1 === count( $revisions ) ) {
|
||||
$revisions[ $post->ID ] = array(
|
||||
'id' => $post->ID,
|
||||
'title' => get_the_title( $post->ID ),
|
||||
'author' => $authors[ $revision->post_author ],
|
||||
'date' => date_i18n( __( 'M j, Y @ H:i' ), strtotime( $post->post_modified ) ),
|
||||
'dateShort' => date_i18n( _x( 'j M @ H:i', 'revision date short format' ), strtotime( $post->post_modified ) ),
|
||||
/* translators: %s: Human-readable time difference. */
|
||||
'timeAgo' => sprintf( __( '%s ago' ), human_time_diff( strtotime( $post->post_modified_gmt ), $now_gmt ) ),
|
||||
'autosave' => false,
|
||||
'current' => true,
|
||||
'restoreUrl' => false,
|
||||
);
|
||||
$current_id = $post->ID;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a post has been saved since the latest revision (no revisioned fields
|
||||
* were changed), we may not have a "current" revision. Mark the latest
|
||||
* revision as "current".
|
||||
*/
|
||||
if ( empty( $current_id ) ) {
|
||||
if ( $revisions[ $revision->ID ]['autosave'] ) {
|
||||
$revision = end( $revisions );
|
||||
while ( $revision['autosave'] ) {
|
||||
$revision = prev( $revisions );
|
||||
}
|
||||
$current_id = $revision['id'];
|
||||
} else {
|
||||
$current_id = $revision->ID;
|
||||
}
|
||||
$revisions[ $current_id ]['current'] = true;
|
||||
}
|
||||
|
||||
// Now, grab the initial diff.
|
||||
$compare_two_mode = is_numeric( $from );
|
||||
if ( ! $compare_two_mode ) {
|
||||
$found = array_search( $selected_revision_id, array_keys( $revisions ), true );
|
||||
if ( $found ) {
|
||||
$from = array_keys( array_slice( $revisions, $found - 1, 1, true ) );
|
||||
$from = reset( $from );
|
||||
} else {
|
||||
$from = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$from = absint( $from );
|
||||
|
||||
$diffs = array(
|
||||
array(
|
||||
'id' => $from . ':' . $selected_revision_id,
|
||||
'fields' => wp_get_revision_ui_diff( $post->ID, $from, $selected_revision_id ),
|
||||
),
|
||||
);
|
||||
|
||||
return array(
|
||||
'postId' => $post->ID,
|
||||
'nonce' => wp_create_nonce( 'revisions-ajax-nonce' ),
|
||||
'revisionData' => array_values( $revisions ),
|
||||
'to' => $selected_revision_id,
|
||||
'from' => $from,
|
||||
'diffData' => $diffs,
|
||||
'baseUrl' => parse_url( admin_url( 'revision.php' ), PHP_URL_PATH ),
|
||||
'compareTwoMode' => absint( $compare_two_mode ), // Apparently booleans are not allowed.
|
||||
'revisionIds' => array_keys( $revisions ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print JavaScript templates required for the revisions experience.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @global WP_Post $post Global post object.
|
||||
*/
|
||||
function wp_print_revision_templates() {
|
||||
global $post;
|
||||
?><script id="tmpl-revisions-frame" type="text/html">
|
||||
<div class="revisions-control-frame"></div>
|
||||
<div class="revisions-diff-frame"></div>
|
||||
</script>
|
||||
|
||||
<script id="tmpl-revisions-buttons" type="text/html">
|
||||
<div class="revisions-previous">
|
||||
<input class="button" type="button" value="<?php echo esc_attr_x( 'Previous', 'Button label for a previous revision' ); ?>" />
|
||||
</div>
|
||||
|
||||
<div class="revisions-next">
|
||||
<input class="button" type="button" value="<?php echo esc_attr_x( 'Next', 'Button label for a next revision' ); ?>" />
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script id="tmpl-revisions-checkbox" type="text/html">
|
||||
<div class="revision-toggle-compare-mode">
|
||||
<label>
|
||||
<input type="checkbox" class="compare-two-revisions"
|
||||
<#
|
||||
if ( 'undefined' !== typeof data && data.model.attributes.compareTwoMode ) {
|
||||
#> checked="checked"<#
|
||||
}
|
||||
#>
|
||||
/>
|
||||
<?php esc_html_e( 'Compare any two revisions' ); ?>
|
||||
</label>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script id="tmpl-revisions-meta" type="text/html">
|
||||
<# if ( ! _.isUndefined( data.attributes ) ) { #>
|
||||
<div class="diff-title">
|
||||
<# if ( 'from' === data.type ) { #>
|
||||
<strong><?php _ex( 'From:', 'Followed by post revision info' ); ?></strong>
|
||||
<# } else if ( 'to' === data.type ) { #>
|
||||
<strong><?php _ex( 'To:', 'Followed by post revision info' ); ?></strong>
|
||||
<# } #>
|
||||
<div class="author-card<# if ( data.attributes.autosave ) { #> autosave<# } #>">
|
||||
{{{ data.attributes.author.avatar }}}
|
||||
<div class="author-info">
|
||||
<# if ( data.attributes.autosave ) { #>
|
||||
<span class="byline">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: User's display name. */
|
||||
__( 'Autosave by %s' ),
|
||||
'<span class="author-name">{{ data.attributes.author.name }}</span>'
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<# } else if ( data.attributes.current ) { #>
|
||||
<span class="byline">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: User's display name. */
|
||||
__( 'Current Revision by %s' ),
|
||||
'<span class="author-name">{{ data.attributes.author.name }}</span>'
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<# } else { #>
|
||||
<span class="byline">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: User's display name. */
|
||||
__( 'Revision by %s' ),
|
||||
'<span class="author-name">{{ data.attributes.author.name }}</span>'
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<# } #>
|
||||
<span class="time-ago">{{ data.attributes.timeAgo }}</span>
|
||||
<span class="date">({{ data.attributes.dateShort }})</span>
|
||||
</div>
|
||||
<# if ( 'to' === data.type && data.attributes.restoreUrl ) { #>
|
||||
<input <?php if ( wp_check_post_lock( $post->ID ) ) { ?>
|
||||
disabled="disabled"
|
||||
<?php } else { ?>
|
||||
<# if ( data.attributes.current ) { #>
|
||||
disabled="disabled"
|
||||
<# } #>
|
||||
<?php } ?>
|
||||
<# if ( data.attributes.autosave ) { #>
|
||||
type="button" class="restore-revision button button-primary" value="<?php esc_attr_e( 'Restore This Autosave' ); ?>" />
|
||||
<# } else { #>
|
||||
type="button" class="restore-revision button button-primary" value="<?php esc_attr_e( 'Restore This Revision' ); ?>" />
|
||||
<# } #>
|
||||
<# } #>
|
||||
</div>
|
||||
<# if ( 'tooltip' === data.type ) { #>
|
||||
<div class="revisions-tooltip-arrow"><span></span></div>
|
||||
<# } #>
|
||||
<# } #>
|
||||
</script>
|
||||
|
||||
<script id="tmpl-revisions-diff" type="text/html">
|
||||
<div class="loading-indicator"><span class="spinner"></span></div>
|
||||
<div class="diff-error"><?php _e( 'Sorry, something went wrong. The requested comparison could not be loaded.' ); ?></div>
|
||||
<div class="diff">
|
||||
<# _.each( data.fields, function( field ) { #>
|
||||
<h3>{{ field.name }}</h3>
|
||||
{{{ field.diff }}}
|
||||
<# }); #>
|
||||
</div>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
+1383
-1383
File diff suppressed because it is too large
Load Diff
@@ -1,244 +1,244 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Administration Screen API.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the column headers for a screen
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string|WP_Screen $screen The screen you want the headers for
|
||||
* @return string[] The column header labels keyed by column ID.
|
||||
*/
|
||||
function get_column_headers( $screen ) {
|
||||
static $column_headers = array();
|
||||
|
||||
if ( is_string( $screen ) ) {
|
||||
$screen = convert_to_screen( $screen );
|
||||
}
|
||||
|
||||
if ( ! isset( $column_headers[ $screen->id ] ) ) {
|
||||
/**
|
||||
* Filters the column headers for a list table on a specific screen.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$screen->id`, refers to the
|
||||
* ID of a specific screen. For example, the screen ID for the Posts
|
||||
* list table is edit-post, so the filter for that screen would be
|
||||
* manage_edit-post_columns.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string[] $columns The column header labels keyed by column ID.
|
||||
*/
|
||||
$column_headers[ $screen->id ] = apply_filters( "manage_{$screen->id}_columns", array() );
|
||||
}
|
||||
|
||||
return $column_headers[ $screen->id ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of hidden columns.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string|WP_Screen $screen The screen you want the hidden columns for
|
||||
* @return string[] Array of IDs of hidden columns.
|
||||
*/
|
||||
function get_hidden_columns( $screen ) {
|
||||
if ( is_string( $screen ) ) {
|
||||
$screen = convert_to_screen( $screen );
|
||||
}
|
||||
|
||||
$hidden = get_user_option( 'manage' . $screen->id . 'columnshidden' );
|
||||
|
||||
$use_defaults = ! is_array( $hidden );
|
||||
|
||||
if ( $use_defaults ) {
|
||||
$hidden = array();
|
||||
|
||||
/**
|
||||
* Filters the default list of hidden columns.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*
|
||||
* @param string[] $hidden Array of IDs of columns hidden by default.
|
||||
* @param WP_Screen $screen WP_Screen object of the current screen.
|
||||
*/
|
||||
$hidden = apply_filters( 'default_hidden_columns', $hidden, $screen );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of hidden columns.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @since 4.4.1 Added the `use_defaults` parameter.
|
||||
*
|
||||
* @param string[] $hidden Array of IDs of hidden columns.
|
||||
* @param WP_Screen $screen WP_Screen object of the current screen.
|
||||
* @param bool $use_defaults Whether to show the default columns.
|
||||
*/
|
||||
return apply_filters( 'hidden_columns', $hidden, $screen, $use_defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the meta box preferences for screen meta.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @global array $wp_meta_boxes
|
||||
*
|
||||
* @param WP_Screen $screen
|
||||
*/
|
||||
function meta_box_prefs( $screen ) {
|
||||
global $wp_meta_boxes;
|
||||
|
||||
if ( is_string( $screen ) ) {
|
||||
$screen = convert_to_screen( $screen );
|
||||
}
|
||||
|
||||
if ( empty( $wp_meta_boxes[ $screen->id ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$hidden = get_hidden_meta_boxes( $screen );
|
||||
|
||||
foreach ( array_keys( $wp_meta_boxes[ $screen->id ] ) as $context ) {
|
||||
foreach ( array( 'high', 'core', 'default', 'low' ) as $priority ) {
|
||||
if ( ! isset( $wp_meta_boxes[ $screen->id ][ $context ][ $priority ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $wp_meta_boxes[ $screen->id ][ $context ][ $priority ] as $box ) {
|
||||
if ( false === $box || ! $box['title'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Submit box cannot be hidden.
|
||||
if ( 'submitdiv' === $box['id'] || 'linksubmitdiv' === $box['id'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$widget_title = $box['title'];
|
||||
|
||||
if ( is_array( $box['args'] ) && isset( $box['args']['__widget_basename'] ) ) {
|
||||
$widget_title = $box['args']['__widget_basename'];
|
||||
}
|
||||
|
||||
$is_hidden = in_array( $box['id'], $hidden, true );
|
||||
|
||||
printf(
|
||||
'<label for="%1$s-hide"><input class="hide-postbox-tog" name="%1$s-hide" type="checkbox" id="%1$s-hide" value="%1$s" %2$s />%3$s</label>',
|
||||
esc_attr( $box['id'] ),
|
||||
checked( $is_hidden, false, false ),
|
||||
$widget_title
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of IDs of hidden meta boxes.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string|WP_Screen $screen Screen identifier
|
||||
* @return string[] IDs of hidden meta boxes.
|
||||
*/
|
||||
function get_hidden_meta_boxes( $screen ) {
|
||||
if ( is_string( $screen ) ) {
|
||||
$screen = convert_to_screen( $screen );
|
||||
}
|
||||
|
||||
$hidden = get_user_option( "metaboxhidden_{$screen->id}" );
|
||||
|
||||
$use_defaults = ! is_array( $hidden );
|
||||
|
||||
// Hide slug boxes by default.
|
||||
if ( $use_defaults ) {
|
||||
$hidden = array();
|
||||
|
||||
if ( 'post' === $screen->base ) {
|
||||
if ( in_array( $screen->post_type, array( 'post', 'page', 'attachment' ), true ) ) {
|
||||
$hidden = array( 'slugdiv', 'trackbacksdiv', 'postcustom', 'postexcerpt', 'commentstatusdiv', 'commentsdiv', 'authordiv', 'revisionsdiv' );
|
||||
} else {
|
||||
$hidden = array( 'slugdiv' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the default list of hidden meta boxes.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string[] $hidden An array of IDs of meta boxes hidden by default.
|
||||
* @param WP_Screen $screen WP_Screen object of the current screen.
|
||||
*/
|
||||
$hidden = apply_filters( 'default_hidden_meta_boxes', $hidden, $screen );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of hidden meta boxes.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param string[] $hidden An array of IDs of hidden meta boxes.
|
||||
* @param WP_Screen $screen WP_Screen object of the current screen.
|
||||
* @param bool $use_defaults Whether to show the default meta boxes.
|
||||
* Default true.
|
||||
*/
|
||||
return apply_filters( 'hidden_meta_boxes', $hidden, $screen, $use_defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register and configure an admin screen option
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $option An option name.
|
||||
* @param mixed $args Option-dependent arguments.
|
||||
*/
|
||||
function add_screen_option( $option, $args = array() ) {
|
||||
$current_screen = get_current_screen();
|
||||
|
||||
if ( ! $current_screen ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$current_screen->add_option( $option, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current screen object
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @global WP_Screen $current_screen WordPress current screen object.
|
||||
*
|
||||
* @return WP_Screen|null Current screen object or null when screen not defined.
|
||||
*/
|
||||
function get_current_screen() {
|
||||
global $current_screen;
|
||||
|
||||
if ( ! isset( $current_screen ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $current_screen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current screen object
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string|WP_Screen $hook_name Optional. The hook name (also known as the hook suffix) used to determine the screen,
|
||||
* or an existing screen object.
|
||||
*/
|
||||
function set_current_screen( $hook_name = '' ) {
|
||||
WP_Screen::get( $hook_name )->set_current_screen();
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* WordPress Administration Screen API.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the column headers for a screen
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string|WP_Screen $screen The screen you want the headers for
|
||||
* @return string[] The column header labels keyed by column ID.
|
||||
*/
|
||||
function get_column_headers( $screen ) {
|
||||
static $column_headers = array();
|
||||
|
||||
if ( is_string( $screen ) ) {
|
||||
$screen = convert_to_screen( $screen );
|
||||
}
|
||||
|
||||
if ( ! isset( $column_headers[ $screen->id ] ) ) {
|
||||
/**
|
||||
* Filters the column headers for a list table on a specific screen.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$screen->id`, refers to the
|
||||
* ID of a specific screen. For example, the screen ID for the Posts
|
||||
* list table is edit-post, so the filter for that screen would be
|
||||
* manage_edit-post_columns.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string[] $columns The column header labels keyed by column ID.
|
||||
*/
|
||||
$column_headers[ $screen->id ] = apply_filters( "manage_{$screen->id}_columns", array() );
|
||||
}
|
||||
|
||||
return $column_headers[ $screen->id ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of hidden columns.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string|WP_Screen $screen The screen you want the hidden columns for
|
||||
* @return string[] Array of IDs of hidden columns.
|
||||
*/
|
||||
function get_hidden_columns( $screen ) {
|
||||
if ( is_string( $screen ) ) {
|
||||
$screen = convert_to_screen( $screen );
|
||||
}
|
||||
|
||||
$hidden = get_user_option( 'manage' . $screen->id . 'columnshidden' );
|
||||
|
||||
$use_defaults = ! is_array( $hidden );
|
||||
|
||||
if ( $use_defaults ) {
|
||||
$hidden = array();
|
||||
|
||||
/**
|
||||
* Filters the default list of hidden columns.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*
|
||||
* @param string[] $hidden Array of IDs of columns hidden by default.
|
||||
* @param WP_Screen $screen WP_Screen object of the current screen.
|
||||
*/
|
||||
$hidden = apply_filters( 'default_hidden_columns', $hidden, $screen );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of hidden columns.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @since 4.4.1 Added the `use_defaults` parameter.
|
||||
*
|
||||
* @param string[] $hidden Array of IDs of hidden columns.
|
||||
* @param WP_Screen $screen WP_Screen object of the current screen.
|
||||
* @param bool $use_defaults Whether to show the default columns.
|
||||
*/
|
||||
return apply_filters( 'hidden_columns', $hidden, $screen, $use_defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the meta box preferences for screen meta.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @global array $wp_meta_boxes
|
||||
*
|
||||
* @param WP_Screen $screen
|
||||
*/
|
||||
function meta_box_prefs( $screen ) {
|
||||
global $wp_meta_boxes;
|
||||
|
||||
if ( is_string( $screen ) ) {
|
||||
$screen = convert_to_screen( $screen );
|
||||
}
|
||||
|
||||
if ( empty( $wp_meta_boxes[ $screen->id ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$hidden = get_hidden_meta_boxes( $screen );
|
||||
|
||||
foreach ( array_keys( $wp_meta_boxes[ $screen->id ] ) as $context ) {
|
||||
foreach ( array( 'high', 'core', 'default', 'low' ) as $priority ) {
|
||||
if ( ! isset( $wp_meta_boxes[ $screen->id ][ $context ][ $priority ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $wp_meta_boxes[ $screen->id ][ $context ][ $priority ] as $box ) {
|
||||
if ( false === $box || ! $box['title'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Submit box cannot be hidden.
|
||||
if ( 'submitdiv' === $box['id'] || 'linksubmitdiv' === $box['id'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$widget_title = $box['title'];
|
||||
|
||||
if ( is_array( $box['args'] ) && isset( $box['args']['__widget_basename'] ) ) {
|
||||
$widget_title = $box['args']['__widget_basename'];
|
||||
}
|
||||
|
||||
$is_hidden = in_array( $box['id'], $hidden, true );
|
||||
|
||||
printf(
|
||||
'<label for="%1$s-hide"><input class="hide-postbox-tog" name="%1$s-hide" type="checkbox" id="%1$s-hide" value="%1$s" %2$s />%3$s</label>',
|
||||
esc_attr( $box['id'] ),
|
||||
checked( $is_hidden, false, false ),
|
||||
$widget_title
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of IDs of hidden meta boxes.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string|WP_Screen $screen Screen identifier
|
||||
* @return string[] IDs of hidden meta boxes.
|
||||
*/
|
||||
function get_hidden_meta_boxes( $screen ) {
|
||||
if ( is_string( $screen ) ) {
|
||||
$screen = convert_to_screen( $screen );
|
||||
}
|
||||
|
||||
$hidden = get_user_option( "metaboxhidden_{$screen->id}" );
|
||||
|
||||
$use_defaults = ! is_array( $hidden );
|
||||
|
||||
// Hide slug boxes by default.
|
||||
if ( $use_defaults ) {
|
||||
$hidden = array();
|
||||
|
||||
if ( 'post' === $screen->base ) {
|
||||
if ( in_array( $screen->post_type, array( 'post', 'page', 'attachment' ), true ) ) {
|
||||
$hidden = array( 'slugdiv', 'trackbacksdiv', 'postcustom', 'postexcerpt', 'commentstatusdiv', 'commentsdiv', 'authordiv', 'revisionsdiv' );
|
||||
} else {
|
||||
$hidden = array( 'slugdiv' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the default list of hidden meta boxes.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string[] $hidden An array of IDs of meta boxes hidden by default.
|
||||
* @param WP_Screen $screen WP_Screen object of the current screen.
|
||||
*/
|
||||
$hidden = apply_filters( 'default_hidden_meta_boxes', $hidden, $screen );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of hidden meta boxes.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param string[] $hidden An array of IDs of hidden meta boxes.
|
||||
* @param WP_Screen $screen WP_Screen object of the current screen.
|
||||
* @param bool $use_defaults Whether to show the default meta boxes.
|
||||
* Default true.
|
||||
*/
|
||||
return apply_filters( 'hidden_meta_boxes', $hidden, $screen, $use_defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register and configure an admin screen option
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $option An option name.
|
||||
* @param mixed $args Option-dependent arguments.
|
||||
*/
|
||||
function add_screen_option( $option, $args = array() ) {
|
||||
$current_screen = get_current_screen();
|
||||
|
||||
if ( ! $current_screen ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$current_screen->add_option( $option, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current screen object
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @global WP_Screen $current_screen WordPress current screen object.
|
||||
*
|
||||
* @return WP_Screen|null Current screen object or null when screen not defined.
|
||||
*/
|
||||
function get_current_screen() {
|
||||
global $current_screen;
|
||||
|
||||
if ( ! isset( $current_screen ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $current_screen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current screen object
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string|WP_Screen $hook_name Optional. The hook name (also known as the hook suffix) used to determine the screen,
|
||||
* or an existing screen object.
|
||||
*/
|
||||
function set_current_screen( $hook_name = '' ) {
|
||||
WP_Screen::get( $hook_name )->set_current_screen();
|
||||
}
|
||||
|
||||
@@ -1,316 +1,316 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Taxonomy Administration API.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
*/
|
||||
|
||||
//
|
||||
// Category.
|
||||
//
|
||||
|
||||
/**
|
||||
* Checks whether a category exists.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @see term_exists()
|
||||
*
|
||||
* @param int|string $cat_name Category name.
|
||||
* @param int $category_parent Optional. ID of parent category.
|
||||
* @return string|null Returns the category ID as a numeric string if the pairing exists, null if not.
|
||||
*/
|
||||
function category_exists( $cat_name, $category_parent = null ) {
|
||||
$id = term_exists( $cat_name, 'category', $category_parent );
|
||||
if ( is_array( $id ) ) {
|
||||
$id = $id['term_id'];
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets category object for given ID and 'edit' filter context.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $id
|
||||
* @return object
|
||||
*/
|
||||
function get_category_to_edit( $id ) {
|
||||
$category = get_term( $id, 'category', OBJECT, 'edit' );
|
||||
_make_cat_compat( $category );
|
||||
return $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new category to the database if it does not already exist.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int|string $cat_name Category name.
|
||||
* @param int $category_parent Optional. ID of parent category.
|
||||
* @return int|WP_Error
|
||||
*/
|
||||
function wp_create_category( $cat_name, $category_parent = 0 ) {
|
||||
$id = category_exists( $cat_name, $category_parent );
|
||||
if ( $id ) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
return wp_insert_category(
|
||||
array(
|
||||
'cat_name' => $cat_name,
|
||||
'category_parent' => $category_parent,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates categories for the given post.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string[] $categories Array of category names to create.
|
||||
* @param int $post_id Optional. The post ID. Default empty.
|
||||
* @return int[] Array of IDs of categories assigned to the given post.
|
||||
*/
|
||||
function wp_create_categories( $categories, $post_id = '' ) {
|
||||
$cat_ids = array();
|
||||
foreach ( $categories as $category ) {
|
||||
$id = category_exists( $category );
|
||||
if ( $id ) {
|
||||
$cat_ids[] = $id;
|
||||
} else {
|
||||
$id = wp_create_category( $category );
|
||||
if ( $id ) {
|
||||
$cat_ids[] = $id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $post_id ) {
|
||||
wp_set_post_categories( $post_id, $cat_ids );
|
||||
}
|
||||
|
||||
return $cat_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing Category or creates a new Category.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @since 2.5.0 $wp_error parameter was added.
|
||||
* @since 3.0.0 The 'taxonomy' argument was added.
|
||||
*
|
||||
* @param array $catarr {
|
||||
* Array of arguments for inserting a new category.
|
||||
*
|
||||
* @type int $cat_ID Category ID. A non-zero value updates an existing category.
|
||||
* Default 0.
|
||||
* @type string $taxonomy Taxonomy slug. Default 'category'.
|
||||
* @type string $cat_name Category name. Default empty.
|
||||
* @type string $category_description Category description. Default empty.
|
||||
* @type string $category_nicename Category nice (display) name. Default empty.
|
||||
* @type int|string $category_parent Category parent ID. Default empty.
|
||||
* }
|
||||
* @param bool $wp_error Optional. Default false.
|
||||
* @return int|WP_Error The ID number of the new or updated Category on success. Zero or a WP_Error on failure,
|
||||
* depending on param `$wp_error`.
|
||||
*/
|
||||
function wp_insert_category( $catarr, $wp_error = false ) {
|
||||
$cat_defaults = array(
|
||||
'cat_ID' => 0,
|
||||
'taxonomy' => 'category',
|
||||
'cat_name' => '',
|
||||
'category_description' => '',
|
||||
'category_nicename' => '',
|
||||
'category_parent' => '',
|
||||
);
|
||||
$catarr = wp_parse_args( $catarr, $cat_defaults );
|
||||
|
||||
if ( '' === trim( $catarr['cat_name'] ) ) {
|
||||
if ( ! $wp_error ) {
|
||||
return 0;
|
||||
} else {
|
||||
return new WP_Error( 'cat_name', __( 'You did not enter a category name.' ) );
|
||||
}
|
||||
}
|
||||
|
||||
$catarr['cat_ID'] = (int) $catarr['cat_ID'];
|
||||
|
||||
// Are we updating or creating?
|
||||
$update = ! empty( $catarr['cat_ID'] );
|
||||
|
||||
$name = $catarr['cat_name'];
|
||||
$description = $catarr['category_description'];
|
||||
$slug = $catarr['category_nicename'];
|
||||
$parent = (int) $catarr['category_parent'];
|
||||
if ( $parent < 0 ) {
|
||||
$parent = 0;
|
||||
}
|
||||
|
||||
if ( empty( $parent )
|
||||
|| ! term_exists( $parent, $catarr['taxonomy'] )
|
||||
|| ( $catarr['cat_ID'] && term_is_ancestor_of( $catarr['cat_ID'], $parent, $catarr['taxonomy'] ) ) ) {
|
||||
$parent = 0;
|
||||
}
|
||||
|
||||
$args = compact( 'name', 'slug', 'parent', 'description' );
|
||||
|
||||
if ( $update ) {
|
||||
$catarr['cat_ID'] = wp_update_term( $catarr['cat_ID'], $catarr['taxonomy'], $args );
|
||||
} else {
|
||||
$catarr['cat_ID'] = wp_insert_term( $catarr['cat_name'], $catarr['taxonomy'], $args );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $catarr['cat_ID'] ) ) {
|
||||
if ( $wp_error ) {
|
||||
return $catarr['cat_ID'];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return $catarr['cat_ID']['term_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Aliases wp_insert_category() with minimal args.
|
||||
*
|
||||
* If you want to update only some fields of an existing category, call this
|
||||
* function with only the new values set inside $catarr.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $catarr The 'cat_ID' value is required. All other keys are optional.
|
||||
* @return int|false The ID number of the new or updated Category on success. Zero or FALSE on failure.
|
||||
*/
|
||||
function wp_update_category( $catarr ) {
|
||||
$cat_id = (int) $catarr['cat_ID'];
|
||||
|
||||
if ( isset( $catarr['category_parent'] ) && ( $cat_id === (int) $catarr['category_parent'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// First, get all of the original fields.
|
||||
$category = get_term( $cat_id, 'category', ARRAY_A );
|
||||
_make_cat_compat( $category );
|
||||
|
||||
// Escape data pulled from DB.
|
||||
$category = wp_slash( $category );
|
||||
|
||||
// Merge old and new fields with new fields overwriting old ones.
|
||||
$catarr = array_merge( $category, $catarr );
|
||||
|
||||
return wp_insert_category( $catarr );
|
||||
}
|
||||
|
||||
//
|
||||
// Tags.
|
||||
//
|
||||
|
||||
/**
|
||||
* Checks whether a post tag with a given name exists.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param int|string $tag_name
|
||||
* @return mixed Returns null if the term does not exist.
|
||||
* Returns an array of the term ID and the term taxonomy ID if the pairing exists.
|
||||
* Returns 0 if term ID 0 is passed to the function.
|
||||
*/
|
||||
function tag_exists( $tag_name ) {
|
||||
return term_exists( $tag_name, 'post_tag' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new tag to the database if it does not already exist.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param int|string $tag_name
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
function wp_create_tag( $tag_name ) {
|
||||
return wp_create_term( $tag_name, 'post_tag' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets comma-separated list of tags available to edit.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param string $taxonomy Optional. The taxonomy for which to retrieve terms. Default 'post_tag'.
|
||||
* @return string|false|WP_Error
|
||||
*/
|
||||
function get_tags_to_edit( $post_id, $taxonomy = 'post_tag' ) {
|
||||
return get_terms_to_edit( $post_id, $taxonomy );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets comma-separated list of terms available to edit for the given post ID.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param string $taxonomy Optional. The taxonomy for which to retrieve terms. Default 'post_tag'.
|
||||
* @return string|false|WP_Error
|
||||
*/
|
||||
function get_terms_to_edit( $post_id, $taxonomy = 'post_tag' ) {
|
||||
$post_id = (int) $post_id;
|
||||
if ( ! $post_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$terms = get_object_term_cache( $post_id, $taxonomy );
|
||||
if ( false === $terms ) {
|
||||
$terms = wp_get_object_terms( $post_id, $taxonomy );
|
||||
wp_cache_add( $post_id, wp_list_pluck( $terms, 'term_id' ), $taxonomy . '_relationships' );
|
||||
}
|
||||
|
||||
if ( ! $terms ) {
|
||||
return false;
|
||||
}
|
||||
if ( is_wp_error( $terms ) ) {
|
||||
return $terms;
|
||||
}
|
||||
$term_names = array();
|
||||
foreach ( $terms as $term ) {
|
||||
$term_names[] = $term->name;
|
||||
}
|
||||
|
||||
$terms_to_edit = esc_attr( implode( ',', $term_names ) );
|
||||
|
||||
/**
|
||||
* Filters the comma-separated list of terms available to edit.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @see get_terms_to_edit()
|
||||
*
|
||||
* @param string $terms_to_edit A comma-separated list of term names.
|
||||
* @param string $taxonomy The taxonomy name for which to retrieve terms.
|
||||
*/
|
||||
$terms_to_edit = apply_filters( 'terms_to_edit', $terms_to_edit, $taxonomy );
|
||||
|
||||
return $terms_to_edit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new term to the database if it does not already exist.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string $tag_name The term name.
|
||||
* @param string $taxonomy Optional. The taxonomy within which to create the term. Default 'post_tag'.
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
function wp_create_term( $tag_name, $taxonomy = 'post_tag' ) {
|
||||
$id = term_exists( $tag_name, $taxonomy );
|
||||
if ( $id ) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
return wp_insert_term( $tag_name, $taxonomy );
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* WordPress Taxonomy Administration API.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
*/
|
||||
|
||||
//
|
||||
// Category.
|
||||
//
|
||||
|
||||
/**
|
||||
* Checks whether a category exists.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @see term_exists()
|
||||
*
|
||||
* @param int|string $cat_name Category name.
|
||||
* @param int $category_parent Optional. ID of parent category.
|
||||
* @return string|null Returns the category ID as a numeric string if the pairing exists, null if not.
|
||||
*/
|
||||
function category_exists( $cat_name, $category_parent = null ) {
|
||||
$id = term_exists( $cat_name, 'category', $category_parent );
|
||||
if ( is_array( $id ) ) {
|
||||
$id = $id['term_id'];
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets category object for given ID and 'edit' filter context.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int $id
|
||||
* @return object
|
||||
*/
|
||||
function get_category_to_edit( $id ) {
|
||||
$category = get_term( $id, 'category', OBJECT, 'edit' );
|
||||
_make_cat_compat( $category );
|
||||
return $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new category to the database if it does not already exist.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int|string $cat_name Category name.
|
||||
* @param int $category_parent Optional. ID of parent category.
|
||||
* @return int|WP_Error
|
||||
*/
|
||||
function wp_create_category( $cat_name, $category_parent = 0 ) {
|
||||
$id = category_exists( $cat_name, $category_parent );
|
||||
if ( $id ) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
return wp_insert_category(
|
||||
array(
|
||||
'cat_name' => $cat_name,
|
||||
'category_parent' => $category_parent,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates categories for the given post.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string[] $categories Array of category names to create.
|
||||
* @param int $post_id Optional. The post ID. Default empty.
|
||||
* @return int[] Array of IDs of categories assigned to the given post.
|
||||
*/
|
||||
function wp_create_categories( $categories, $post_id = '' ) {
|
||||
$cat_ids = array();
|
||||
foreach ( $categories as $category ) {
|
||||
$id = category_exists( $category );
|
||||
if ( $id ) {
|
||||
$cat_ids[] = $id;
|
||||
} else {
|
||||
$id = wp_create_category( $category );
|
||||
if ( $id ) {
|
||||
$cat_ids[] = $id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $post_id ) {
|
||||
wp_set_post_categories( $post_id, $cat_ids );
|
||||
}
|
||||
|
||||
return $cat_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing Category or creates a new Category.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @since 2.5.0 $wp_error parameter was added.
|
||||
* @since 3.0.0 The 'taxonomy' argument was added.
|
||||
*
|
||||
* @param array $catarr {
|
||||
* Array of arguments for inserting a new category.
|
||||
*
|
||||
* @type int $cat_ID Category ID. A non-zero value updates an existing category.
|
||||
* Default 0.
|
||||
* @type string $taxonomy Taxonomy slug. Default 'category'.
|
||||
* @type string $cat_name Category name. Default empty.
|
||||
* @type string $category_description Category description. Default empty.
|
||||
* @type string $category_nicename Category nice (display) name. Default empty.
|
||||
* @type int|string $category_parent Category parent ID. Default empty.
|
||||
* }
|
||||
* @param bool $wp_error Optional. Default false.
|
||||
* @return int|WP_Error The ID number of the new or updated Category on success. Zero or a WP_Error on failure,
|
||||
* depending on param `$wp_error`.
|
||||
*/
|
||||
function wp_insert_category( $catarr, $wp_error = false ) {
|
||||
$cat_defaults = array(
|
||||
'cat_ID' => 0,
|
||||
'taxonomy' => 'category',
|
||||
'cat_name' => '',
|
||||
'category_description' => '',
|
||||
'category_nicename' => '',
|
||||
'category_parent' => '',
|
||||
);
|
||||
$catarr = wp_parse_args( $catarr, $cat_defaults );
|
||||
|
||||
if ( '' === trim( $catarr['cat_name'] ) ) {
|
||||
if ( ! $wp_error ) {
|
||||
return 0;
|
||||
} else {
|
||||
return new WP_Error( 'cat_name', __( 'You did not enter a category name.' ) );
|
||||
}
|
||||
}
|
||||
|
||||
$catarr['cat_ID'] = (int) $catarr['cat_ID'];
|
||||
|
||||
// Are we updating or creating?
|
||||
$update = ! empty( $catarr['cat_ID'] );
|
||||
|
||||
$name = $catarr['cat_name'];
|
||||
$description = $catarr['category_description'];
|
||||
$slug = $catarr['category_nicename'];
|
||||
$parent = (int) $catarr['category_parent'];
|
||||
if ( $parent < 0 ) {
|
||||
$parent = 0;
|
||||
}
|
||||
|
||||
if ( empty( $parent )
|
||||
|| ! term_exists( $parent, $catarr['taxonomy'] )
|
||||
|| ( $catarr['cat_ID'] && term_is_ancestor_of( $catarr['cat_ID'], $parent, $catarr['taxonomy'] ) ) ) {
|
||||
$parent = 0;
|
||||
}
|
||||
|
||||
$args = compact( 'name', 'slug', 'parent', 'description' );
|
||||
|
||||
if ( $update ) {
|
||||
$catarr['cat_ID'] = wp_update_term( $catarr['cat_ID'], $catarr['taxonomy'], $args );
|
||||
} else {
|
||||
$catarr['cat_ID'] = wp_insert_term( $catarr['cat_name'], $catarr['taxonomy'], $args );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $catarr['cat_ID'] ) ) {
|
||||
if ( $wp_error ) {
|
||||
return $catarr['cat_ID'];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return $catarr['cat_ID']['term_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Aliases wp_insert_category() with minimal args.
|
||||
*
|
||||
* If you want to update only some fields of an existing category, call this
|
||||
* function with only the new values set inside $catarr.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $catarr The 'cat_ID' value is required. All other keys are optional.
|
||||
* @return int|false The ID number of the new or updated Category on success. Zero or FALSE on failure.
|
||||
*/
|
||||
function wp_update_category( $catarr ) {
|
||||
$cat_id = (int) $catarr['cat_ID'];
|
||||
|
||||
if ( isset( $catarr['category_parent'] ) && ( $cat_id === (int) $catarr['category_parent'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// First, get all of the original fields.
|
||||
$category = get_term( $cat_id, 'category', ARRAY_A );
|
||||
_make_cat_compat( $category );
|
||||
|
||||
// Escape data pulled from DB.
|
||||
$category = wp_slash( $category );
|
||||
|
||||
// Merge old and new fields with new fields overwriting old ones.
|
||||
$catarr = array_merge( $category, $catarr );
|
||||
|
||||
return wp_insert_category( $catarr );
|
||||
}
|
||||
|
||||
//
|
||||
// Tags.
|
||||
//
|
||||
|
||||
/**
|
||||
* Checks whether a post tag with a given name exists.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param int|string $tag_name
|
||||
* @return mixed Returns null if the term does not exist.
|
||||
* Returns an array of the term ID and the term taxonomy ID if the pairing exists.
|
||||
* Returns 0 if term ID 0 is passed to the function.
|
||||
*/
|
||||
function tag_exists( $tag_name ) {
|
||||
return term_exists( $tag_name, 'post_tag' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new tag to the database if it does not already exist.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param int|string $tag_name
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
function wp_create_tag( $tag_name ) {
|
||||
return wp_create_term( $tag_name, 'post_tag' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets comma-separated list of tags available to edit.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param string $taxonomy Optional. The taxonomy for which to retrieve terms. Default 'post_tag'.
|
||||
* @return string|false|WP_Error
|
||||
*/
|
||||
function get_tags_to_edit( $post_id, $taxonomy = 'post_tag' ) {
|
||||
return get_terms_to_edit( $post_id, $taxonomy );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets comma-separated list of terms available to edit for the given post ID.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param int $post_id
|
||||
* @param string $taxonomy Optional. The taxonomy for which to retrieve terms. Default 'post_tag'.
|
||||
* @return string|false|WP_Error
|
||||
*/
|
||||
function get_terms_to_edit( $post_id, $taxonomy = 'post_tag' ) {
|
||||
$post_id = (int) $post_id;
|
||||
if ( ! $post_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$terms = get_object_term_cache( $post_id, $taxonomy );
|
||||
if ( false === $terms ) {
|
||||
$terms = wp_get_object_terms( $post_id, $taxonomy );
|
||||
wp_cache_add( $post_id, wp_list_pluck( $terms, 'term_id' ), $taxonomy . '_relationships' );
|
||||
}
|
||||
|
||||
if ( ! $terms ) {
|
||||
return false;
|
||||
}
|
||||
if ( is_wp_error( $terms ) ) {
|
||||
return $terms;
|
||||
}
|
||||
$term_names = array();
|
||||
foreach ( $terms as $term ) {
|
||||
$term_names[] = $term->name;
|
||||
}
|
||||
|
||||
$terms_to_edit = esc_attr( implode( ',', $term_names ) );
|
||||
|
||||
/**
|
||||
* Filters the comma-separated list of terms available to edit.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @see get_terms_to_edit()
|
||||
*
|
||||
* @param string $terms_to_edit A comma-separated list of term names.
|
||||
* @param string $taxonomy The taxonomy name for which to retrieve terms.
|
||||
*/
|
||||
$terms_to_edit = apply_filters( 'terms_to_edit', $terms_to_edit, $taxonomy );
|
||||
|
||||
return $terms_to_edit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new term to the database if it does not already exist.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string $tag_name The term name.
|
||||
* @param string $taxonomy Optional. The taxonomy within which to create the term. Default 'post_tag'.
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
function wp_create_term( $tag_name, $taxonomy = 'post_tag' ) {
|
||||
$id = term_exists( $tag_name, $taxonomy );
|
||||
if ( $id ) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
return wp_insert_term( $tag_name, $taxonomy );
|
||||
}
|
||||
|
||||
+2821
-2821
File diff suppressed because it is too large
Load Diff
@@ -1,271 +1,271 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Theme Installation Administration API
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
*/
|
||||
|
||||
$themes_allowedtags = array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'title' => array(),
|
||||
'target' => array(),
|
||||
),
|
||||
'abbr' => array( 'title' => array() ),
|
||||
'acronym' => array( 'title' => array() ),
|
||||
'code' => array(),
|
||||
'pre' => array(),
|
||||
'em' => array(),
|
||||
'strong' => array(),
|
||||
'div' => array(),
|
||||
'p' => array(),
|
||||
'ul' => array(),
|
||||
'ol' => array(),
|
||||
'li' => array(),
|
||||
'h1' => array(),
|
||||
'h2' => array(),
|
||||
'h3' => array(),
|
||||
'h4' => array(),
|
||||
'h5' => array(),
|
||||
'h6' => array(),
|
||||
'img' => array(
|
||||
'src' => array(),
|
||||
'class' => array(),
|
||||
'alt' => array(),
|
||||
),
|
||||
);
|
||||
|
||||
$theme_field_defaults = array(
|
||||
'description' => true,
|
||||
'sections' => false,
|
||||
'tested' => true,
|
||||
'requires' => true,
|
||||
'rating' => true,
|
||||
'downloaded' => true,
|
||||
'downloadlink' => true,
|
||||
'last_updated' => true,
|
||||
'homepage' => true,
|
||||
'tags' => true,
|
||||
'num_ratings' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieves the list of WordPress theme features (aka theme tags).
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @deprecated 3.1.0 Use get_theme_feature_list() instead.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function install_themes_feature_list() {
|
||||
_deprecated_function( __FUNCTION__, '3.1.0', 'get_theme_feature_list()' );
|
||||
|
||||
$cache = get_transient( 'wporg_theme_feature_list' );
|
||||
if ( ! $cache ) {
|
||||
set_transient( 'wporg_theme_feature_list', array(), 3 * HOUR_IN_SECONDS );
|
||||
}
|
||||
|
||||
if ( $cache ) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
$feature_list = themes_api( 'feature_list', array() );
|
||||
if ( is_wp_error( $feature_list ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
set_transient( 'wporg_theme_feature_list', $feature_list, 3 * HOUR_IN_SECONDS );
|
||||
|
||||
return $feature_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays search form for searching themes.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param bool $type_selector
|
||||
*/
|
||||
function install_theme_search_form( $type_selector = true ) {
|
||||
$type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term';
|
||||
$term = isset( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : '';
|
||||
if ( ! $type_selector ) {
|
||||
echo '<p class="install-help">' . __( 'Search for themes by keyword.' ) . '</p>';
|
||||
}
|
||||
?>
|
||||
<form id="search-themes" method="get">
|
||||
<input type="hidden" name="tab" value="search" />
|
||||
<?php if ( $type_selector ) : ?>
|
||||
<label class="screen-reader-text" for="typeselector">
|
||||
<?php
|
||||
/* translators: Hidden accessibility text. */
|
||||
_e( 'Type of search' );
|
||||
?>
|
||||
</label>
|
||||
<select name="type" id="typeselector">
|
||||
<option value="term" <?php selected( 'term', $type ); ?>><?php _e( 'Keyword' ); ?></option>
|
||||
<option value="author" <?php selected( 'author', $type ); ?>><?php _e( 'Author' ); ?></option>
|
||||
<option value="tag" <?php selected( 'tag', $type ); ?>><?php _ex( 'Tag', 'Theme Installer' ); ?></option>
|
||||
</select>
|
||||
<label class="screen-reader-text" for="s">
|
||||
<?php
|
||||
switch ( $type ) {
|
||||
case 'term':
|
||||
/* translators: Hidden accessibility text. */
|
||||
_e( 'Search by keyword' );
|
||||
break;
|
||||
case 'author':
|
||||
/* translators: Hidden accessibility text. */
|
||||
_e( 'Search by author' );
|
||||
break;
|
||||
case 'tag':
|
||||
/* translators: Hidden accessibility text. */
|
||||
_e( 'Search by tag' );
|
||||
break;
|
||||
}
|
||||
?>
|
||||
</label>
|
||||
<?php else : ?>
|
||||
<label class="screen-reader-text" for="s">
|
||||
<?php
|
||||
/* translators: Hidden accessibility text. */
|
||||
_e( 'Search by keyword' );
|
||||
?>
|
||||
</label>
|
||||
<?php endif; ?>
|
||||
<input type="search" name="s" id="s" size="30" value="<?php echo esc_attr( $term ); ?>" autofocus="autofocus" />
|
||||
<?php submit_button( __( 'Search' ), '', 'search', false ); ?>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays tags filter for themes.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function install_themes_dashboard() {
|
||||
install_theme_search_form( false );
|
||||
?>
|
||||
<h4><?php _e( 'Feature Filter' ); ?></h4>
|
||||
<p class="install-help"><?php _e( 'Find a theme based on specific features.' ); ?></p>
|
||||
|
||||
<form method="get">
|
||||
<input type="hidden" name="tab" value="search" />
|
||||
<?php
|
||||
$feature_list = get_theme_feature_list();
|
||||
echo '<div class="feature-filter">';
|
||||
|
||||
foreach ( (array) $feature_list as $feature_name => $features ) {
|
||||
$feature_name = esc_html( $feature_name );
|
||||
echo '<div class="feature-name">' . $feature_name . '</div>';
|
||||
|
||||
echo '<ol class="feature-group">';
|
||||
foreach ( $features as $feature => $feature_name ) {
|
||||
$feature_name = esc_html( $feature_name );
|
||||
$feature = esc_attr( $feature );
|
||||
?>
|
||||
|
||||
<li>
|
||||
<input type="checkbox" name="features[]" id="feature-id-<?php echo $feature; ?>" value="<?php echo $feature; ?>" />
|
||||
<label for="feature-id-<?php echo $feature; ?>"><?php echo $feature_name; ?></label>
|
||||
</li>
|
||||
|
||||
<?php } ?>
|
||||
</ol>
|
||||
<br class="clear" />
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
<br class="clear" />
|
||||
<?php submit_button( __( 'Find Themes' ), '', 'search' ); ?>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a form to upload themes from zip files.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function install_themes_upload() {
|
||||
?>
|
||||
<p class="install-help"><?php _e( 'If you have a theme in a .zip format, you may install or update it by uploading it here.' ); ?></p>
|
||||
<form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo esc_url( self_admin_url( 'update.php?action=upload-theme' ) ); ?>">
|
||||
<?php wp_nonce_field( 'theme-upload' ); ?>
|
||||
<label class="screen-reader-text" for="themezip">
|
||||
<?php
|
||||
/* translators: Hidden accessibility text. */
|
||||
_e( 'Theme zip file' );
|
||||
?>
|
||||
</label>
|
||||
<input type="file" id="themezip" name="themezip" accept=".zip" />
|
||||
<?php submit_button( _x( 'Install Now', 'theme' ), '', 'install-theme-submit', false ); ?>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a theme on the Install Themes pages.
|
||||
*
|
||||
* @deprecated 3.4.0
|
||||
*
|
||||
* @global WP_Theme_Install_List_Table $wp_list_table
|
||||
*
|
||||
* @param object $theme
|
||||
*/
|
||||
function display_theme( $theme ) {
|
||||
_deprecated_function( __FUNCTION__, '3.4.0' );
|
||||
global $wp_list_table;
|
||||
if ( ! isset( $wp_list_table ) ) {
|
||||
$wp_list_table = _get_list_table( 'WP_Theme_Install_List_Table' );
|
||||
}
|
||||
$wp_list_table->prepare_items();
|
||||
$wp_list_table->single_row( $theme );
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays theme content based on theme list.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global WP_Theme_Install_List_Table $wp_list_table
|
||||
*/
|
||||
function display_themes() {
|
||||
global $wp_list_table;
|
||||
|
||||
if ( ! isset( $wp_list_table ) ) {
|
||||
$wp_list_table = _get_list_table( 'WP_Theme_Install_List_Table' );
|
||||
}
|
||||
$wp_list_table->prepare_items();
|
||||
$wp_list_table->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays theme information in dialog box form.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global WP_Theme_Install_List_Table $wp_list_table
|
||||
*/
|
||||
function install_theme_information() {
|
||||
global $wp_list_table;
|
||||
|
||||
$theme = themes_api( 'theme_information', array( 'slug' => wp_unslash( $_REQUEST['theme'] ) ) );
|
||||
|
||||
if ( is_wp_error( $theme ) ) {
|
||||
wp_die( $theme );
|
||||
}
|
||||
|
||||
iframe_header( __( 'Theme Installation' ) );
|
||||
if ( ! isset( $wp_list_table ) ) {
|
||||
$wp_list_table = _get_list_table( 'WP_Theme_Install_List_Table' );
|
||||
}
|
||||
$wp_list_table->theme_installer_single( $theme );
|
||||
iframe_footer();
|
||||
exit;
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* WordPress Theme Installation Administration API
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Administration
|
||||
*/
|
||||
|
||||
$themes_allowedtags = array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'title' => array(),
|
||||
'target' => array(),
|
||||
),
|
||||
'abbr' => array( 'title' => array() ),
|
||||
'acronym' => array( 'title' => array() ),
|
||||
'code' => array(),
|
||||
'pre' => array(),
|
||||
'em' => array(),
|
||||
'strong' => array(),
|
||||
'div' => array(),
|
||||
'p' => array(),
|
||||
'ul' => array(),
|
||||
'ol' => array(),
|
||||
'li' => array(),
|
||||
'h1' => array(),
|
||||
'h2' => array(),
|
||||
'h3' => array(),
|
||||
'h4' => array(),
|
||||
'h5' => array(),
|
||||
'h6' => array(),
|
||||
'img' => array(
|
||||
'src' => array(),
|
||||
'class' => array(),
|
||||
'alt' => array(),
|
||||
),
|
||||
);
|
||||
|
||||
$theme_field_defaults = array(
|
||||
'description' => true,
|
||||
'sections' => false,
|
||||
'tested' => true,
|
||||
'requires' => true,
|
||||
'rating' => true,
|
||||
'downloaded' => true,
|
||||
'downloadlink' => true,
|
||||
'last_updated' => true,
|
||||
'homepage' => true,
|
||||
'tags' => true,
|
||||
'num_ratings' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieves the list of WordPress theme features (aka theme tags).
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @deprecated 3.1.0 Use get_theme_feature_list() instead.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function install_themes_feature_list() {
|
||||
_deprecated_function( __FUNCTION__, '3.1.0', 'get_theme_feature_list()' );
|
||||
|
||||
$cache = get_transient( 'wporg_theme_feature_list' );
|
||||
if ( ! $cache ) {
|
||||
set_transient( 'wporg_theme_feature_list', array(), 3 * HOUR_IN_SECONDS );
|
||||
}
|
||||
|
||||
if ( $cache ) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
$feature_list = themes_api( 'feature_list', array() );
|
||||
if ( is_wp_error( $feature_list ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
set_transient( 'wporg_theme_feature_list', $feature_list, 3 * HOUR_IN_SECONDS );
|
||||
|
||||
return $feature_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays search form for searching themes.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param bool $type_selector
|
||||
*/
|
||||
function install_theme_search_form( $type_selector = true ) {
|
||||
$type = isset( $_REQUEST['type'] ) ? wp_unslash( $_REQUEST['type'] ) : 'term';
|
||||
$term = isset( $_REQUEST['s'] ) ? wp_unslash( $_REQUEST['s'] ) : '';
|
||||
if ( ! $type_selector ) {
|
||||
echo '<p class="install-help">' . __( 'Search for themes by keyword.' ) . '</p>';
|
||||
}
|
||||
?>
|
||||
<form id="search-themes" method="get">
|
||||
<input type="hidden" name="tab" value="search" />
|
||||
<?php if ( $type_selector ) : ?>
|
||||
<label class="screen-reader-text" for="typeselector">
|
||||
<?php
|
||||
/* translators: Hidden accessibility text. */
|
||||
_e( 'Type of search' );
|
||||
?>
|
||||
</label>
|
||||
<select name="type" id="typeselector">
|
||||
<option value="term" <?php selected( 'term', $type ); ?>><?php _e( 'Keyword' ); ?></option>
|
||||
<option value="author" <?php selected( 'author', $type ); ?>><?php _e( 'Author' ); ?></option>
|
||||
<option value="tag" <?php selected( 'tag', $type ); ?>><?php _ex( 'Tag', 'Theme Installer' ); ?></option>
|
||||
</select>
|
||||
<label class="screen-reader-text" for="s">
|
||||
<?php
|
||||
switch ( $type ) {
|
||||
case 'term':
|
||||
/* translators: Hidden accessibility text. */
|
||||
_e( 'Search by keyword' );
|
||||
break;
|
||||
case 'author':
|
||||
/* translators: Hidden accessibility text. */
|
||||
_e( 'Search by author' );
|
||||
break;
|
||||
case 'tag':
|
||||
/* translators: Hidden accessibility text. */
|
||||
_e( 'Search by tag' );
|
||||
break;
|
||||
}
|
||||
?>
|
||||
</label>
|
||||
<?php else : ?>
|
||||
<label class="screen-reader-text" for="s">
|
||||
<?php
|
||||
/* translators: Hidden accessibility text. */
|
||||
_e( 'Search by keyword' );
|
||||
?>
|
||||
</label>
|
||||
<?php endif; ?>
|
||||
<input type="search" name="s" id="s" size="30" value="<?php echo esc_attr( $term ); ?>" autofocus="autofocus" />
|
||||
<?php submit_button( __( 'Search' ), '', 'search', false ); ?>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays tags filter for themes.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function install_themes_dashboard() {
|
||||
install_theme_search_form( false );
|
||||
?>
|
||||
<h4><?php _e( 'Feature Filter' ); ?></h4>
|
||||
<p class="install-help"><?php _e( 'Find a theme based on specific features.' ); ?></p>
|
||||
|
||||
<form method="get">
|
||||
<input type="hidden" name="tab" value="search" />
|
||||
<?php
|
||||
$feature_list = get_theme_feature_list();
|
||||
echo '<div class="feature-filter">';
|
||||
|
||||
foreach ( (array) $feature_list as $feature_name => $features ) {
|
||||
$feature_name = esc_html( $feature_name );
|
||||
echo '<div class="feature-name">' . $feature_name . '</div>';
|
||||
|
||||
echo '<ol class="feature-group">';
|
||||
foreach ( $features as $feature => $feature_name ) {
|
||||
$feature_name = esc_html( $feature_name );
|
||||
$feature = esc_attr( $feature );
|
||||
?>
|
||||
|
||||
<li>
|
||||
<input type="checkbox" name="features[]" id="feature-id-<?php echo $feature; ?>" value="<?php echo $feature; ?>" />
|
||||
<label for="feature-id-<?php echo $feature; ?>"><?php echo $feature_name; ?></label>
|
||||
</li>
|
||||
|
||||
<?php } ?>
|
||||
</ol>
|
||||
<br class="clear" />
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
<br class="clear" />
|
||||
<?php submit_button( __( 'Find Themes' ), '', 'search' ); ?>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a form to upload themes from zip files.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function install_themes_upload() {
|
||||
?>
|
||||
<p class="install-help"><?php _e( 'If you have a theme in a .zip format, you may install or update it by uploading it here.' ); ?></p>
|
||||
<form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo esc_url( self_admin_url( 'update.php?action=upload-theme' ) ); ?>">
|
||||
<?php wp_nonce_field( 'theme-upload' ); ?>
|
||||
<label class="screen-reader-text" for="themezip">
|
||||
<?php
|
||||
/* translators: Hidden accessibility text. */
|
||||
_e( 'Theme zip file' );
|
||||
?>
|
||||
</label>
|
||||
<input type="file" id="themezip" name="themezip" accept=".zip" />
|
||||
<?php submit_button( _x( 'Install Now', 'theme' ), '', 'install-theme-submit', false ); ?>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a theme on the Install Themes pages.
|
||||
*
|
||||
* @deprecated 3.4.0
|
||||
*
|
||||
* @global WP_Theme_Install_List_Table $wp_list_table
|
||||
*
|
||||
* @param object $theme
|
||||
*/
|
||||
function display_theme( $theme ) {
|
||||
_deprecated_function( __FUNCTION__, '3.4.0' );
|
||||
global $wp_list_table;
|
||||
if ( ! isset( $wp_list_table ) ) {
|
||||
$wp_list_table = _get_list_table( 'WP_Theme_Install_List_Table' );
|
||||
}
|
||||
$wp_list_table->prepare_items();
|
||||
$wp_list_table->single_row( $theme );
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays theme content based on theme list.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global WP_Theme_Install_List_Table $wp_list_table
|
||||
*/
|
||||
function display_themes() {
|
||||
global $wp_list_table;
|
||||
|
||||
if ( ! isset( $wp_list_table ) ) {
|
||||
$wp_list_table = _get_list_table( 'WP_Theme_Install_List_Table' );
|
||||
}
|
||||
$wp_list_table->prepare_items();
|
||||
$wp_list_table->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays theme information in dialog box form.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global WP_Theme_Install_List_Table $wp_list_table
|
||||
*/
|
||||
function install_theme_information() {
|
||||
global $wp_list_table;
|
||||
|
||||
$theme = themes_api( 'theme_information', array( 'slug' => wp_unslash( $_REQUEST['theme'] ) ) );
|
||||
|
||||
if ( is_wp_error( $theme ) ) {
|
||||
wp_die( $theme );
|
||||
}
|
||||
|
||||
iframe_header( __( 'Theme Installation' ) );
|
||||
if ( ! isset( $wp_list_table ) ) {
|
||||
$wp_list_table = _get_list_table( 'WP_Theme_Install_List_Table' );
|
||||
}
|
||||
$wp_list_table->theme_installer_single( $theme );
|
||||
iframe_footer();
|
||||
exit;
|
||||
}
|
||||
|
||||
+1258
-1258
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user