plugin updates
This commit is contained in:
@@ -0,0 +1,495 @@
|
||||
<?php
|
||||
/**
|
||||
* The ACF Update Class, responsible for talking to the connect API server and injecting PRO's update data into WordPress.
|
||||
*
|
||||
* @package ACF
|
||||
*/
|
||||
|
||||
namespace ACF;
|
||||
|
||||
use WP_Error;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Updater' ) ) {
|
||||
|
||||
/**
|
||||
* class for handling API services.
|
||||
*/
|
||||
class Updater {
|
||||
|
||||
/**
|
||||
* The Updater version
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $version = '3.0';
|
||||
|
||||
/**
|
||||
* The array of registered plugins
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $plugins = array();
|
||||
|
||||
/**
|
||||
* Counts the number of plugin update checks
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $checked = 0;
|
||||
|
||||
/**
|
||||
* Sets up the class functionality.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
// disable showing PRO updates if show updates is hidden.
|
||||
if ( acf_is_pro() && ! acf_pro_is_updates_page_visible() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// append update information to transient.
|
||||
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'modify_plugins_transient' ), 10, 1 );
|
||||
|
||||
// modify plugin data visible in the 'View details' popup.
|
||||
add_filter( 'plugins_api', array( $this, 'modify_plugin_details' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registeres a plugin for updates.
|
||||
*
|
||||
* @since 5.5.10
|
||||
*
|
||||
* @param array $plugin The plugin array.
|
||||
* @return void
|
||||
*/
|
||||
public function add_plugin( $plugin ) {
|
||||
|
||||
// validate.
|
||||
$plugin = wp_parse_args(
|
||||
$plugin,
|
||||
array(
|
||||
'id' => '',
|
||||
'key' => '',
|
||||
'slug' => '',
|
||||
'basename' => '',
|
||||
'version' => '',
|
||||
)
|
||||
);
|
||||
|
||||
// Check if is_plugin_active() function exists. This is required on the front end of the
|
||||
// site, since it is in a file that is normally only loaded in the admin.
|
||||
if ( ! function_exists( 'is_plugin_active' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
// add if is active plugin (not included in theme).
|
||||
if ( is_plugin_active( $plugin['basename'] ) ) {
|
||||
$this->plugins[ $plugin['basename'] ] = $plugin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a registered plugin for the give key and value.
|
||||
*
|
||||
* @since 5.7.2
|
||||
*
|
||||
* @param string $key The array key to compare.
|
||||
* @param string $value The value to compare against.
|
||||
* @return array|false
|
||||
*/
|
||||
public function get_plugin_by( $key = '', $value = null ) {
|
||||
foreach ( $this->plugins as $plugin ) {
|
||||
if ( $plugin[ $key ] === $value ) {
|
||||
return $plugin;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to the ACF connect server.
|
||||
*
|
||||
* @since 5.5.10
|
||||
*
|
||||
* @param string $endpoint The API endpoint.
|
||||
* @param array $body The body to post.
|
||||
* @return (array|string|WP_Error)
|
||||
*/
|
||||
public function request( $endpoint = '', $body = null ) {
|
||||
|
||||
$site_url = acf_get_home_url();
|
||||
if ( empty( $site_url ) || ! is_string( $site_url ) ) {
|
||||
$site_url = '';
|
||||
}
|
||||
|
||||
$headers = array(
|
||||
'X-ACF-Version' => ACF_VERSION,
|
||||
'X-ACF-URL' => $site_url,
|
||||
);
|
||||
|
||||
$url = "https://connect.advancedcustomfields.com/$endpoint";
|
||||
|
||||
// Staging environment.
|
||||
if ( defined( 'ACF_DEV_API' ) && ACF_DEV_API ) {
|
||||
$url = trailingslashit( ACF_DEV_API ) . $endpoint;
|
||||
acf_log( $url, $body );
|
||||
}
|
||||
|
||||
// Determine URL.
|
||||
if ( acf_is_pro() ) {
|
||||
$license_key = acf_pro_get_license_key();
|
||||
if ( empty( $license_key ) || ! is_string( $license_key ) ) {
|
||||
$license_key = '';
|
||||
}
|
||||
$headers['X-ACF-License'] = $license_key;
|
||||
$headers['X-ACF-Plugin'] = 'pro';
|
||||
} else {
|
||||
$headers['X-ACF-Plugin'] = 'acf';
|
||||
}
|
||||
|
||||
// Make request.
|
||||
$raw_response = wp_remote_post(
|
||||
$url,
|
||||
array(
|
||||
'timeout' => 20,
|
||||
'body' => $body,
|
||||
'headers' => $headers,
|
||||
)
|
||||
);
|
||||
|
||||
// Handle response error.
|
||||
if ( is_wp_error( $raw_response ) ) {
|
||||
return $raw_response;
|
||||
|
||||
// Handle http error.
|
||||
} elseif ( wp_remote_retrieve_response_code( $raw_response ) !== 200 ) {
|
||||
return new WP_Error( 'server_error', wp_remote_retrieve_response_message( $raw_response ) );
|
||||
}
|
||||
|
||||
// Decode JSON response.
|
||||
$json = json_decode( wp_remote_retrieve_body( $raw_response ), true );
|
||||
|
||||
// Allow non json value.
|
||||
if ( $json === null ) {
|
||||
return wp_remote_retrieve_body( $raw_response );
|
||||
}
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns update information for the given plugin id.
|
||||
*
|
||||
* @since 5.5.10
|
||||
*
|
||||
* @param string $id The plugin id such as 'pro'.
|
||||
* @param boolean $force_check Bypasses cached result. Defaults to false.
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function get_plugin_info( $id = '', $force_check = false ) {
|
||||
$transient_name = 'acf_plugin_info_' . $id;
|
||||
|
||||
// check cache but allow for $force_check override.
|
||||
if ( ! $force_check ) {
|
||||
$transient = get_transient( $transient_name );
|
||||
if ( $transient !== false ) {
|
||||
return $transient;
|
||||
}
|
||||
}
|
||||
|
||||
$response = $this->request( 'v2/plugins/get-info?p=' . $id );
|
||||
|
||||
// convert string (misc error) to WP_Error object.
|
||||
if ( is_string( $response ) ) {
|
||||
$response = new WP_Error( 'server_error', esc_html( $response ) );
|
||||
}
|
||||
|
||||
// allow json to include expiration but force minimum and max for safety.
|
||||
$expiration = $this->get_expiration( $response, DAY_IN_SECONDS );
|
||||
|
||||
// update transient.
|
||||
set_transient( $transient_name, $response, $expiration );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns specific data from the 'update-check' response.
|
||||
*
|
||||
* @since 5.7.2
|
||||
*
|
||||
* @param string $basename The plugin basename.
|
||||
* @param boolean $force_check Bypasses cached result. Defaults to false.
|
||||
* @return array|false
|
||||
*/
|
||||
public function get_plugin_update( $basename = '', $force_check = false ) {
|
||||
// get updates.
|
||||
$updates = $this->get_plugin_updates( $force_check );
|
||||
|
||||
// check for and return update.
|
||||
if ( is_array( $updates ) && isset( $updates['plugins'][ $basename ] ) ) {
|
||||
return $updates['plugins'][ $basename ];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an update is available, but can't be updated to.
|
||||
*
|
||||
* @since 6.2.1
|
||||
*
|
||||
* @param string $basename The plugin basename.
|
||||
* @param boolean $force_check Bypasses cached result. Defaults to false.
|
||||
* @return array|false
|
||||
*/
|
||||
public function get_no_update( $basename = '', $force_check = false ) {
|
||||
// get updates.
|
||||
$updates = $this->get_plugin_updates( $force_check );
|
||||
|
||||
// check for and return update.
|
||||
if ( is_array( $updates ) && isset( $updates['no_update'][ $basename ] ) ) {
|
||||
return $updates['no_update'][ $basename ];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks for plugin updates.
|
||||
*
|
||||
* @since 5.6.9
|
||||
* @since 5.7.2 Added 'checked' comparison
|
||||
*
|
||||
* @param boolean $force_check Bypasses cached result. Defaults to false.
|
||||
* @return array|WP_Error.
|
||||
*/
|
||||
public function get_plugin_updates( $force_check = false ) {
|
||||
$transient_name = 'acf_plugin_updates';
|
||||
|
||||
// Don't call our site if no plugins have registered updates.
|
||||
if ( empty( $this->plugins ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Construct array of 'checked' plugins.
|
||||
// Sort by key to avoid detecting change due to "include order".
|
||||
$checked = array();
|
||||
foreach ( $this->plugins as $basename => $plugin ) {
|
||||
$checked[ $basename ] = $plugin['version'];
|
||||
}
|
||||
ksort( $checked );
|
||||
|
||||
// $force_check prevents transient lookup.
|
||||
if ( ! $force_check ) {
|
||||
$transient = get_transient( $transient_name );
|
||||
|
||||
// If cached response was found, compare $transient['checked'] against $checked and ignore if they don't match (plugins/versions have changed).
|
||||
if ( is_array( $transient ) ) {
|
||||
$transient_checked = isset( $transient['checked'] ) ? $transient['checked'] : array();
|
||||
if ( wp_json_encode( $checked ) !== wp_json_encode( $transient_checked ) ) {
|
||||
$transient = false;
|
||||
}
|
||||
}
|
||||
if ( $transient !== false ) {
|
||||
return $transient;
|
||||
}
|
||||
}
|
||||
|
||||
$post = array(
|
||||
'plugins' => wp_json_encode( $this->plugins ),
|
||||
'wp' => wp_json_encode(
|
||||
array(
|
||||
'wp_name' => get_bloginfo( 'name' ),
|
||||
'wp_url' => acf_get_home_url(),
|
||||
'wp_version' => get_bloginfo( 'version' ),
|
||||
'wp_language' => get_bloginfo( 'language' ),
|
||||
'wp_timezone' => get_option( 'timezone_string' ),
|
||||
'wp_multisite' => (int) is_multisite(),
|
||||
'php_version' => PHP_VERSION,
|
||||
)
|
||||
),
|
||||
'acf' => wp_json_encode(
|
||||
array(
|
||||
'acf_version' => get_option( 'acf_version' ),
|
||||
'acf_pro' => acf_is_pro(),
|
||||
'block_count' => function_exists( 'acf_pro_get_registered_block_count' ) ? acf_pro_get_registered_block_count() : 0,
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
// Check update from connect.
|
||||
$response = $this->request( 'v2/plugins/update-check', $post );
|
||||
|
||||
// Append checked reference.
|
||||
if ( is_array( $response ) ) {
|
||||
$response['checked'] = $checked;
|
||||
|
||||
if ( isset( $response['license_status'] ) && function_exists( 'acf_pro_update_license_status' ) ) {
|
||||
acf_pro_update_license_status( $response['license_status'] );
|
||||
unset( $response['license_status'] );
|
||||
}
|
||||
}
|
||||
|
||||
// Allow json to include expiration but force minimum and max for safety.
|
||||
$expiration = $this->get_expiration( $response );
|
||||
|
||||
// Update transient and return.
|
||||
set_transient( $transient_name, $response, $expiration );
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function safely gets the expiration value from a response.
|
||||
*
|
||||
* @since 5.6.9
|
||||
*
|
||||
* @param mixed $response The response from the server. Default false.
|
||||
* @param integer $min The minimum expiration limit. Default 3 hours.
|
||||
* @param integer $max The maximum expiration limit. Default 7 days.
|
||||
* @return integer
|
||||
*/
|
||||
public function get_expiration( $response = false, $min = 10800, $max = 604800 ) {
|
||||
$expiration = 0;
|
||||
|
||||
// Check possible error conditions.
|
||||
if ( is_wp_error( $response ) || is_string( $response ) ) {
|
||||
return 15 * MINUTE_IN_SECONDS;
|
||||
}
|
||||
|
||||
// Use the server requested expiration if present.
|
||||
if ( is_array( $response ) && isset( $response['expiration'] ) ) {
|
||||
$expiration = (int) $response['expiration'];
|
||||
}
|
||||
|
||||
// Use the minimum if neither check matches, or ensure the server expiration isn't lower than our minimum.
|
||||
if ( $expiration < $min ) {
|
||||
return $min;
|
||||
}
|
||||
|
||||
// Ensure the server expiration isn't higher than our max.
|
||||
if ( $expiration > $max ) {
|
||||
return $max;
|
||||
}
|
||||
|
||||
return $expiration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes transients and allows a fresh lookup.
|
||||
*
|
||||
* @since 5.5.10
|
||||
*/
|
||||
public function refresh_plugins_transient() {
|
||||
delete_site_transient( 'update_plugins' );
|
||||
delete_transient( 'acf_plugin_updates' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when WP updates the 'update_plugins' site transient. Used to inject ACF plugin update info.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param object $transient The current transient value.
|
||||
* @return object $transient The modified transient value.
|
||||
*/
|
||||
public function modify_plugins_transient( $transient ) {
|
||||
|
||||
// Bail early if no response (error).
|
||||
if ( ! isset( $transient->response ) ) {
|
||||
return $transient;
|
||||
}
|
||||
|
||||
// Ensure no_update is set for back compat.
|
||||
if ( ! isset( $transient->no_update ) ) {
|
||||
$transient->no_update = array();
|
||||
}
|
||||
|
||||
// Force-check (only once).
|
||||
$force_check = ( $this->checked == 0 ) ? ! empty( $_GET['force-check'] ) : false; // phpcs:ignore -- False positive, value not used.
|
||||
|
||||
// Fetch updates (this filter is called multiple times during a single page load).
|
||||
$updates = $this->get_plugin_updates( $force_check );
|
||||
|
||||
// Append ACF pro plugins.
|
||||
if ( is_array( $updates ) ) {
|
||||
if ( ! empty( $updates['plugins'] ) ) {
|
||||
foreach ( $updates['plugins'] as $basename => $update ) {
|
||||
$transient->response[ $basename ] = (object) $update;
|
||||
}
|
||||
}
|
||||
if ( ! empty( $updates['no_update'] ) ) {
|
||||
foreach ( $updates['no_update'] as $basename => $update ) {
|
||||
$transient->no_update[ $basename ] = (object) $update;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++$this->checked;
|
||||
|
||||
return $transient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugin data visible in the 'View details' popup
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param object $result The current result of plugin data.
|
||||
* @param string $action The action being performed.
|
||||
* @param object $args Data about the plugin being retried.
|
||||
* @return $result
|
||||
*/
|
||||
public function modify_plugin_details( $result, $action = null, $args = null ) {
|
||||
|
||||
$plugin = false;
|
||||
|
||||
// Only for 'plugin_information' action.
|
||||
if ( $action !== 'plugin_information' ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Find plugin via slug.
|
||||
$plugin = $this->get_plugin_by( 'slug', $args->slug );
|
||||
if ( ! $plugin ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Get data from connect or cache.
|
||||
$response = $this->get_plugin_info( $plugin['id'] );
|
||||
|
||||
// Bail early if no response.
|
||||
if ( ! is_array( $response ) ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Remove tags (different context).
|
||||
unset( $response['tags'] );
|
||||
|
||||
// Convert to object.
|
||||
$response = (object) $response;
|
||||
|
||||
$sections = array(
|
||||
'description' => '',
|
||||
'installation' => '',
|
||||
'changelog' => '',
|
||||
'upgrade_notice' => '',
|
||||
);
|
||||
foreach ( $sections as $k => $v ) {
|
||||
$sections[ $k ] = $response->$k;
|
||||
}
|
||||
$response->sections = $sections;
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// There are many ways to WordPress.
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace ACF\Upgrades;
|
||||
|
||||
/**
|
||||
* Initialize the checking for plugin updates for ACF non-PRO.
|
||||
*/
|
||||
function check_for_acf_upgrades() {
|
||||
$properties = array(
|
||||
// This must match the key in "https://wpe-plugin-updates.wpengine.com/plugins.json".
|
||||
'plugin_slug' => 'advanced-custom-fields',
|
||||
'plugin_basename' => ACF_BASENAME,
|
||||
);
|
||||
|
||||
new \ACF\Upgrades\PluginUpdater( $properties );
|
||||
}
|
||||
add_action( 'admin_init', __NAMESPACE__ . '\check_for_acf_upgrades' );
|
||||
@@ -312,6 +312,15 @@ if ( ! class_exists( 'ACF_Admin_Post_Type' ) ) :
|
||||
$_POST['acf_post_type']['ID'] = $post_id;
|
||||
$_POST['acf_post_type']['title'] = isset( $_POST['acf_post_type']['labels']['name'] ) ? $_POST['acf_post_type']['labels']['name'] : '';
|
||||
|
||||
if ( ! acf_get_setting( 'enable_meta_box_cb_edit' ) ) {
|
||||
$_POST['acf_post_type']['register_meta_box_cb'] = '';
|
||||
|
||||
$existing_post = acf_maybe_unserialize( $post->post_content );
|
||||
if ( ! empty( $existing_post['register_meta_box_cb'] ) ) {
|
||||
$_POST['acf_post_type']['register_meta_box_cb'] = $existing_post['register_meta_box_cb'];
|
||||
}
|
||||
}
|
||||
|
||||
// Save the post type.
|
||||
acf_update_internal_post_type( $_POST['acf_post_type'], $this->post_type ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Validated in verify_save_post
|
||||
// phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
|
||||
@@ -314,6 +314,29 @@ if ( ! class_exists( 'ACF_Admin_Taxonomy' ) ) :
|
||||
$_POST['acf_taxonomy']['ID'] = $post_id;
|
||||
$_POST['acf_taxonomy']['title'] = isset( $_POST['acf_taxonomy']['labels']['name'] ) ? $_POST['acf_taxonomy']['labels']['name'] : '';
|
||||
|
||||
if ( ! acf_get_setting( 'enable_meta_box_cb_edit' ) ) {
|
||||
$_POST['acf_taxonomy']['meta_box_cb'] = '';
|
||||
$_POST['acf_taxonomy']['meta_box_sanitize_cb'] = '';
|
||||
|
||||
if ( ! empty( $_POST['acf_taxonomy']['meta_box'] ) && 'custom' === $_POST['acf_taxonomy']['meta_box'] ) {
|
||||
$_POST['acf_taxonomy']['meta_box'] = 'default';
|
||||
}
|
||||
|
||||
$existing_post = acf_maybe_unserialize( $post->post_content );
|
||||
|
||||
if ( ! empty( $existing_post['meta_box'] ) ) {
|
||||
$_POST['acf_taxonomy']['meta_box'] = $existing_post['meta_box'];
|
||||
}
|
||||
|
||||
if ( ! empty( $existing_post['meta_box_cb'] ) ) {
|
||||
$_POST['acf_taxonomy']['meta_box_cb'] = $existing_post['meta_box_cb'];
|
||||
}
|
||||
|
||||
if ( ! empty( $existing_post['meta_box_sanitize_cb'] ) ) {
|
||||
$_POST['acf_taxonomy']['meta_box_sanitize_cb'] = $existing_post['meta_box_sanitize_cb'];
|
||||
}
|
||||
}
|
||||
|
||||
// Save the taxonomy.
|
||||
acf_update_internal_post_type( $_POST['acf_taxonomy'], $this->post_type ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Validated in verify_save_post
|
||||
// phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
|
||||
@@ -319,6 +319,7 @@ if ( isset( $field['conditional_logic'] ) && is_array( $field['conditional_logic
|
||||
?>
|
||||
<div class="acf-field-settings-footer">
|
||||
<a class="button close-field edit-field" title="<?php esc_attr_e( 'Close Field', 'acf' ); ?>" href="#"><?php esc_html_e( 'Close Field', 'acf' ); ?></a>
|
||||
<a class="acf-btn acf-btn-secondary close-add-field" title="<?php esc_attr_e( 'Close and Add Field', 'acf' ); ?>" href="#"><?php esc_html_e( 'Close and Add Field', 'acf' ); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -98,7 +98,7 @@ if ( $is_subfield ) {
|
||||
|
||||
<ul class="acf-hl acf-tfoot">
|
||||
<li class="acf-fr">
|
||||
<a href="#" class="acf-btn acf-btn-secondary add-field"><i class="acf-icon acf-icon-plus"></i><?php esc_html_e( 'Add Field', 'acf' ); ?></a>
|
||||
<a href="#" class="acf-btn acf-btn-sm add-field"><i class="acf-icon acf-icon-plus"></i><?php esc_html_e( 'Add Field', 'acf' ); ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -838,24 +838,39 @@ foreach ( acf_get_combined_post_type_settings_tabs() as $tab_key => $tab_label )
|
||||
'field'
|
||||
);
|
||||
|
||||
acf_render_field_wrap(
|
||||
array(
|
||||
'type' => 'text',
|
||||
'name' => 'register_meta_box_cb',
|
||||
'key' => 'register_meta_box_cb',
|
||||
'prefix' => 'acf_post_type',
|
||||
'value' => $acf_post_type['register_meta_box_cb'],
|
||||
'label' => __( 'Custom Meta Box Callback', 'acf' ),
|
||||
'instructions' => __( 'A PHP function name to be called when setting up the meta boxes for the edit screen. For security, this callback will be executed in a special context without access to any superglobals like $_POST or $_GET.', 'acf' ),
|
||||
'conditions' => array(
|
||||
'field' => 'show_ui',
|
||||
'operator' => '==',
|
||||
'value' => '1',
|
||||
$acf_enable_meta_box_cb_edit = acf_get_setting( 'enable_meta_box_cb_edit' );
|
||||
$acf_meta_box_cb_instructions = __( 'A PHP function name to be called when setting up the meta boxes for the edit screen. For security, this callback will be executed in a special context without access to any superglobals like $_POST or $_GET.', 'acf' );
|
||||
|
||||
// Only show if user is allowed to update, or if it already has a value.
|
||||
if ( $acf_enable_meta_box_cb_edit || ! empty( $acf_post_type['register_meta_box_cb'] ) ) {
|
||||
if ( ! $acf_enable_meta_box_cb_edit ) {
|
||||
if ( is_multisite() ) {
|
||||
$acf_meta_box_cb_instructions .= ' ' . __( 'By default only super admin users can edit this setting.', 'acf' );
|
||||
} else {
|
||||
$acf_meta_box_cb_instructions .= ' ' . __( 'By default only admin users can edit this setting.', 'acf' );
|
||||
}
|
||||
}
|
||||
|
||||
acf_render_field_wrap(
|
||||
array(
|
||||
'type' => 'text',
|
||||
'name' => 'register_meta_box_cb',
|
||||
'key' => 'register_meta_box_cb',
|
||||
'prefix' => 'acf_post_type',
|
||||
'value' => $acf_post_type['register_meta_box_cb'],
|
||||
'label' => __( 'Custom Meta Box Callback', 'acf' ),
|
||||
'instructions' => $acf_meta_box_cb_instructions,
|
||||
'readonly' => ! $acf_enable_meta_box_cb_edit,
|
||||
'conditions' => array(
|
||||
'field' => 'show_ui',
|
||||
'operator' => '==',
|
||||
'value' => '1',
|
||||
),
|
||||
),
|
||||
),
|
||||
'div',
|
||||
'field'
|
||||
);
|
||||
'div',
|
||||
'field'
|
||||
);
|
||||
}
|
||||
|
||||
acf_render_field_wrap(
|
||||
array(
|
||||
|
||||
@@ -745,6 +745,16 @@ foreach ( acf_get_combined_taxonomy_settings_tabs() as $tab_key => $tab_label )
|
||||
$acf_tags_meta_box_text = __( 'Tags Meta Box', 'acf' );
|
||||
$acf_categories_meta_box_text = __( 'Categories Meta Box', 'acf' );
|
||||
$acf_default_meta_box_text = empty( $acf_taxonomy['hierarchical'] ) ? $acf_tags_meta_box_text : $acf_categories_meta_box_text;
|
||||
$acf_enable_meta_box_cb_edit = acf_get_setting( 'enable_meta_box_cb_edit' );
|
||||
$acf_meta_box_choices = array(
|
||||
'default' => $acf_default_meta_box_text,
|
||||
'custom' => __( 'Custom Meta Box', 'acf' ),
|
||||
'disabled' => __( 'No Meta Box', 'acf' ),
|
||||
);
|
||||
|
||||
if ( ! $acf_enable_meta_box_cb_edit && 'custom' !== $acf_taxonomy['meta_box'] ) {
|
||||
unset( $acf_meta_box_choices['custom'] );
|
||||
}
|
||||
|
||||
acf_render_field_wrap(
|
||||
array(
|
||||
@@ -757,11 +767,7 @@ foreach ( acf_get_combined_taxonomy_settings_tabs() as $tab_key => $tab_label )
|
||||
'label' => __( 'Meta Box', 'acf' ),
|
||||
'instructions' => __( 'Controls the meta box on the content editor screen. By default, the Categories meta box is shown for hierarchical taxonomies, and the Tags meta box is shown for non-hierarchical taxonomies.', 'acf' ),
|
||||
'hide_search' => true,
|
||||
'choices' => array(
|
||||
'default' => $acf_default_meta_box_text,
|
||||
'custom' => __( 'Custom Meta Box', 'acf' ),
|
||||
'disabled' => __( 'No Meta Box', 'acf' ),
|
||||
),
|
||||
'choices' => $acf_meta_box_choices,
|
||||
'data' => array(
|
||||
'tags_meta_box' => __( 'Tags Meta Box', 'acf' ),
|
||||
'categories_meta_box' => __( 'Categories Meta Box', 'acf' ),
|
||||
@@ -794,54 +800,68 @@ foreach ( acf_get_combined_taxonomy_settings_tabs() as $tab_key => $tab_label )
|
||||
)
|
||||
);
|
||||
|
||||
acf_render_field_wrap(
|
||||
array(
|
||||
'type' => 'text',
|
||||
'name' => 'meta_box_cb',
|
||||
'key' => 'meta_box_cb',
|
||||
'prefix' => 'acf_taxonomy',
|
||||
'value' => $acf_taxonomy['meta_box_cb'],
|
||||
'label' => __( 'Register Meta Box Callback', 'acf' ),
|
||||
'instructions' => __( 'A PHP function name to be called to handle the content of a meta box on your taxonomy. For security, this callback will be executed in a special context without access to any superglobals like $_POST or $_GET.', 'acf' ),
|
||||
'conditions' => array(
|
||||
'field' => 'meta_box',
|
||||
'operator' => '==',
|
||||
'value' => 'custom',
|
||||
),
|
||||
),
|
||||
'div',
|
||||
'field'
|
||||
);
|
||||
if ( $acf_enable_meta_box_cb_edit || 'custom' === $acf_taxonomy['meta_box'] ) {
|
||||
$acf_meta_box_cb_instructions = __( 'A PHP function name to be called to handle the content of a meta box on your taxonomy. For security, this callback will be executed in a special context without access to any superglobals like $_POST or $_GET.', 'acf' );
|
||||
|
||||
acf_render_field_wrap(
|
||||
array(
|
||||
'type' => 'text',
|
||||
'name' => 'meta_box_sanitize_cb',
|
||||
'key' => 'meta_box_sanitize_cb',
|
||||
'prefix' => 'acf_taxonomy',
|
||||
'value' => $acf_taxonomy['meta_box_sanitize_cb'],
|
||||
'label' => __( 'Meta Box Sanitization Callback', 'acf' ),
|
||||
'instructions' => __( 'A PHP function name to be called for sanitizing taxonomy data saved from a meta box.', 'acf' ),
|
||||
'conditions' => array(
|
||||
'field' => 'meta_box',
|
||||
'operator' => '==',
|
||||
'value' => 'custom',
|
||||
),
|
||||
),
|
||||
'div',
|
||||
'field'
|
||||
);
|
||||
if ( ! $acf_enable_meta_box_cb_edit ) {
|
||||
if ( is_multisite() ) {
|
||||
$acf_meta_box_cb_instructions .= ' ' . __( 'By default only super admin users can edit this setting.', 'acf' );
|
||||
} else {
|
||||
$acf_meta_box_cb_instructions .= ' ' . __( 'By default only admin users can edit this setting.', 'acf' );
|
||||
}
|
||||
}
|
||||
|
||||
acf_render_field_wrap(
|
||||
array(
|
||||
'type' => 'seperator',
|
||||
'conditions' => array(
|
||||
'field' => 'meta_box',
|
||||
'operator' => '==',
|
||||
'value' => 'custom',
|
||||
acf_render_field_wrap(
|
||||
array(
|
||||
'type' => 'text',
|
||||
'name' => 'meta_box_cb',
|
||||
'key' => 'meta_box_cb',
|
||||
'prefix' => 'acf_taxonomy',
|
||||
'value' => $acf_taxonomy['meta_box_cb'],
|
||||
'label' => __( 'Register Meta Box Callback', 'acf' ),
|
||||
'instructions' => $acf_meta_box_cb_instructions,
|
||||
'readonly' => ! $acf_enable_meta_box_cb_edit,
|
||||
'conditions' => array(
|
||||
'field' => 'meta_box',
|
||||
'operator' => '==',
|
||||
'value' => 'custom',
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
'div',
|
||||
'field'
|
||||
);
|
||||
|
||||
acf_render_field_wrap(
|
||||
array(
|
||||
'type' => 'text',
|
||||
'name' => 'meta_box_sanitize_cb',
|
||||
'key' => 'meta_box_sanitize_cb',
|
||||
'prefix' => 'acf_taxonomy',
|
||||
'value' => $acf_taxonomy['meta_box_sanitize_cb'],
|
||||
'label' => __( 'Meta Box Sanitization Callback', 'acf' ),
|
||||
'instructions' => __( 'A PHP function name to be called for sanitizing taxonomy data saved from a meta box.', 'acf' ),
|
||||
'readonly' => ! $acf_enable_meta_box_cb_edit,
|
||||
'conditions' => array(
|
||||
'field' => 'meta_box',
|
||||
'operator' => '==',
|
||||
'value' => 'custom',
|
||||
),
|
||||
),
|
||||
'div',
|
||||
'field'
|
||||
);
|
||||
|
||||
acf_render_field_wrap(
|
||||
array(
|
||||
'type' => 'seperator',
|
||||
'conditions' => array(
|
||||
'field' => 'meta_box',
|
||||
'operator' => '==',
|
||||
'value' => 'custom',
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
acf_render_field_wrap(
|
||||
array(
|
||||
|
||||
@@ -24,8 +24,9 @@ if ( ! class_exists( 'ACF_Ajax_Query_Users' ) ) :
|
||||
return new WP_Error( 'acf_invalid_args', __( 'Invalid request args.', 'acf' ), array( 'status' => 404 ) );
|
||||
}
|
||||
|
||||
$nonce = $request['nonce'];
|
||||
$action = $request['field_key'];
|
||||
$nonce = $request['nonce'];
|
||||
$action = $request['field_key'];
|
||||
$field_action = true;
|
||||
|
||||
if ( isset( $request['conditional_logic'] ) && true === (bool) $request['conditional_logic'] ) {
|
||||
if ( ! acf_current_user_can_admin() ) {
|
||||
@@ -33,11 +34,12 @@ if ( ! class_exists( 'ACF_Ajax_Query_Users' ) ) :
|
||||
}
|
||||
|
||||
// Use the standard ACF admin nonce.
|
||||
$nonce = '';
|
||||
$action = '';
|
||||
$nonce = '';
|
||||
$action = '';
|
||||
$field_action = false;
|
||||
}
|
||||
|
||||
if ( ! acf_verify_ajax( $nonce, $action ) ) {
|
||||
if ( ! acf_verify_ajax( $nonce, $action, $field_action ) ) {
|
||||
return new WP_Error( 'acf_invalid_nonce', __( 'Invalid nonce.', 'acf' ), array( 'status' => 404 ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -687,16 +687,32 @@ function acf_verify_nonce( $value ) {
|
||||
*
|
||||
* @since 5.2.3
|
||||
*
|
||||
* @param string $nonce The nonce to check.
|
||||
* @param string $action The action of the nonce.
|
||||
* @param string $nonce The nonce to check.
|
||||
* @param string $action The action of the nonce.
|
||||
* @param boolean $action_is_field If the action is a field, modify the action to match validate the field type.
|
||||
* @return boolean
|
||||
*/
|
||||
function acf_verify_ajax( $nonce = '', $action = '' ) {
|
||||
function acf_verify_ajax( $nonce = '', $action = '', $action_is_field = false ) {
|
||||
// Bail early if we don't have a nonce to check.
|
||||
if ( empty( $nonce ) && empty( $_REQUEST['nonce'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Build the action if we're trying to validate a specific field nonce.
|
||||
if ( $action_is_field ) {
|
||||
if ( ! acf_is_field_key( $action ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$field = acf_get_field( $action );
|
||||
|
||||
if ( empty( $field['type'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$action = 'acf_field_' . $field['type'] . '_' . $action;
|
||||
}
|
||||
|
||||
$nonce_to_check = ! empty( $nonce ) ? $nonce : $_REQUEST['nonce']; // phpcs:ignore WordPress.Security -- We're verifying a nonce here.
|
||||
$nonce_action = ! empty( $action ) ? $action : 'acf_nonce';
|
||||
|
||||
@@ -3974,3 +3990,20 @@ function acf_is_multisite_main_site() {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow filterable permissions metabox callbacks.
|
||||
*
|
||||
* @since 6.3.10
|
||||
*
|
||||
* @param boolean $enable_meta_box_cb_edit Can the current user edit metabox callbacks.
|
||||
* @return boolean
|
||||
*/
|
||||
function acf_settings_enable_meta_box_cb_edit( $enable_meta_box_cb_edit ): bool {
|
||||
if ( ! is_super_admin() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) $enable_meta_box_cb_edit;
|
||||
}
|
||||
add_filter( 'acf/settings/enable_meta_box_cb_edit', 'acf_settings_enable_meta_box_cb_edit', 1 );
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* The PluginUpdater class which can be used to pull plugin updates from a new location.
|
||||
* @package advanced-custom-fields
|
||||
*/
|
||||
|
||||
namespace ACF\Upgrades;
|
||||
|
||||
// Exit if accessed directly.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* The PluginUpdater class which can be used to pull plugin updates from a new location.
|
||||
*/
|
||||
class PluginUpdater {
|
||||
/**
|
||||
* The URL where the api is located.
|
||||
* @var ApiUrl
|
||||
*/
|
||||
private $api_url;
|
||||
|
||||
/**
|
||||
* The amount of time to wait before checking for new updates.
|
||||
* @var CacheTime
|
||||
*/
|
||||
private $cache_time;
|
||||
|
||||
/**
|
||||
* These properties are passed in when instantiating to identify the plugin and it's update location.
|
||||
* @var Properties
|
||||
*/
|
||||
private $properties;
|
||||
|
||||
/**
|
||||
* Get the class constructed.
|
||||
*
|
||||
* @param Properties $properties These properties are passed in when instantiating to identify the plugin and it's update location.
|
||||
*/
|
||||
public function __construct( $properties ) {
|
||||
if (
|
||||
// This must match the key in "https://wpe-plugin-updates.wpengine.com/plugins.json".
|
||||
empty( $properties['plugin_slug'] ) ||
|
||||
|
||||
// This must be the result of calling plugin_basename( __FILE__ ); in the main plugin root file.
|
||||
empty( $properties['plugin_basename'] )
|
||||
) {
|
||||
// If any of the values we require were not passed, throw a fatal.
|
||||
error_log( 'WPE Secure Plugin Updater received a malformed request.' );
|
||||
return;
|
||||
}
|
||||
|
||||
$this->api_url = 'https://wpe-plugin-updates.wpengine.com/';
|
||||
|
||||
$this->cache_time = time() + HOUR_IN_SECONDS * 5;
|
||||
|
||||
$this->properties = $this->get_full_plugin_properties( $properties, $this->api_url );
|
||||
|
||||
if ( ! $this->properties ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->register();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full plugin properties, including the directory name, version, basename, and add a transient name.
|
||||
*
|
||||
* @param Properties $properties These properties are passed in when instantiating to identify the plugin and it's update location.
|
||||
* @param ApiUrl $api_url The URL where the api is located.
|
||||
*/
|
||||
public function get_full_plugin_properties( $properties, $api_url ) {
|
||||
$plugins = \get_plugins();
|
||||
|
||||
// Scan through all plugins installed and find the one which matches this one in question.
|
||||
foreach ( $plugins as $plugin_basename => $plugin_data ) {
|
||||
// Match using the passed-in plugin's basename.
|
||||
if ( $plugin_basename === $properties['plugin_basename'] ) {
|
||||
// Add the values we need to the properties.
|
||||
$properties['plugin_dirname'] = dirname( $plugin_basename );
|
||||
$properties['plugin_version'] = $plugin_data['Version'];
|
||||
$properties['plugin_update_transient_name'] = 'wpesu-plugin-' . sanitize_title( $properties['plugin_dirname'] );
|
||||
$properties['plugin_update_transient_exp_name'] = 'wpesu-plugin-' . sanitize_title( $properties['plugin_dirname'] ) . '-expiry';
|
||||
$properties['plugin_manifest_url'] = trailingslashit( $api_url ) . trailingslashit( $properties['plugin_slug'] ) . 'info.json';
|
||||
|
||||
return $properties;
|
||||
}
|
||||
}
|
||||
|
||||
// No matching plugin was found installed.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register hooks.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register() {
|
||||
add_filter( 'plugins_api', array( $this, 'filter_plugin_update_info' ), 20, 3 );
|
||||
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'filter_plugin_update_transient' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the plugin update transient to take over update notifications.
|
||||
*
|
||||
* @param object $transient The site_transient_update_plugins transient.
|
||||
*
|
||||
* @handles site_transient_update_plugins
|
||||
* @return object
|
||||
*/
|
||||
public function filter_plugin_update_transient( $transient ) {
|
||||
// No update object exists. Return early.
|
||||
if ( empty( $transient ) ) {
|
||||
return $transient;
|
||||
}
|
||||
|
||||
$result = $this->fetch_plugin_info();
|
||||
|
||||
if ( false === $result ) {
|
||||
return $transient;
|
||||
}
|
||||
|
||||
$res = $this->parse_plugin_info( $result );
|
||||
|
||||
if ( version_compare( $this->properties['plugin_version'], $result->version, '<' ) ) {
|
||||
$transient->response[ $res->plugin ] = $res;
|
||||
$transient->checked[ $res->plugin ] = $result->version;
|
||||
} else {
|
||||
$transient->no_update[ $res->plugin ] = $res;
|
||||
}
|
||||
|
||||
return $transient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the plugin update information.
|
||||
*
|
||||
* @param object $res The response to be modified for the plugin in question.
|
||||
* @param string $action The action in question.
|
||||
* @param object $args The arguments for the plugin in question.
|
||||
*
|
||||
* @handles plugins_api
|
||||
* @return object
|
||||
*/
|
||||
public function filter_plugin_update_info( $res, $action, $args ) {
|
||||
// Do nothing if this is not about getting plugin information.
|
||||
if ( 'plugin_information' !== $action ) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
// Do nothing if it is not our plugin.
|
||||
if ( $this->properties['plugin_dirname'] !== $args->slug ) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
$result = $this->fetch_plugin_info();
|
||||
|
||||
// Do nothing if we don't get the correct response from the server.
|
||||
if ( false === $result ) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
return $this->parse_plugin_info( $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the plugin update object from the WP Product Info API.
|
||||
*
|
||||
* @return object|false
|
||||
*/
|
||||
private function fetch_plugin_info() {
|
||||
// Fetch cache first.
|
||||
$expiry = get_option( $this->properties['plugin_update_transient_exp_name'], 0 );
|
||||
$response = get_option( $this->properties['plugin_update_transient_name'] );
|
||||
|
||||
if ( empty( $expiry ) || time() > $expiry || empty( $response ) ) {
|
||||
$response = wp_remote_get(
|
||||
$this->properties['plugin_manifest_url'],
|
||||
array(
|
||||
'timeout' => 10,
|
||||
'headers' => array(
|
||||
'Accept' => 'application/json',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
if (
|
||||
is_wp_error( $response ) ||
|
||||
200 !== wp_remote_retrieve_response_code( $response ) ||
|
||||
empty( wp_remote_retrieve_body( $response ) )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = wp_remote_retrieve_body( $response );
|
||||
|
||||
// Cache the response.
|
||||
update_option( $this->properties['plugin_update_transient_exp_name'], $this->cache_time, false );
|
||||
update_option( $this->properties['plugin_update_transient_name'], $response, false );
|
||||
}
|
||||
|
||||
$decoded_response = json_decode( $response );
|
||||
|
||||
if ( json_last_error() !== JSON_ERROR_NONE ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $decoded_response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the product info response into an object that WordPress would be able to understand.
|
||||
*
|
||||
* @param object $response The response object.
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
private function parse_plugin_info( $response ) {
|
||||
|
||||
global $wp_version;
|
||||
|
||||
$res = new stdClass();
|
||||
$res->name = $response->name;
|
||||
$res->slug = $response->slug;
|
||||
$res->version = $response->version;
|
||||
$res->requires = $response->requires;
|
||||
$res->download_link = $response->download_link;
|
||||
$res->trunk = $response->download_link;
|
||||
$res->new_version = $response->version;
|
||||
$res->plugin = $this->properties['plugin_basename'];
|
||||
$res->package = $response->download_link;
|
||||
|
||||
// Plugin information modal and core update table use a strict version comparison, which is weird.
|
||||
// If we're genuinely not compatible with the point release, use our WP tested up to version.
|
||||
// otherwise use exact same version as WP to avoid false positive.
|
||||
$res->tested = 1 === version_compare( substr( $wp_version, 0, 3 ), $response->tested )
|
||||
? $response->tested
|
||||
: $wp_version;
|
||||
|
||||
$res->sections = array(
|
||||
'description' => $response->sections->description,
|
||||
'changelog' => $response->sections->changelog,
|
||||
);
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@ if ( ! class_exists( 'acf_field_oembed' ) ) :
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'] ) ) {
|
||||
if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'], true ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ if ( ! class_exists( 'acf_field_oembed' ) ) :
|
||||
public function render_field( $field ) {
|
||||
$atts = array(
|
||||
'class' => 'acf-oembed',
|
||||
'data-nonce' => wp_create_nonce( $field['key'] ),
|
||||
'data-nonce' => wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] ),
|
||||
);
|
||||
|
||||
if ( $field['value'] ) {
|
||||
|
||||
@@ -81,7 +81,7 @@ if ( ! class_exists( 'acf_field_page_link' ) ) :
|
||||
$key = '';
|
||||
}
|
||||
|
||||
if ( ! acf_verify_ajax( $nonce, $key ) ) {
|
||||
if ( ! acf_verify_ajax( $nonce, $key, ! $conditional_logic ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ if ( ! class_exists( 'acf_field_page_link' ) ) :
|
||||
$field['ui'] = 1;
|
||||
$field['ajax'] = 1;
|
||||
$field['choices'] = array();
|
||||
$field['nonce'] = wp_create_nonce( $field['key'] );
|
||||
$field['nonce'] = wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] );
|
||||
|
||||
// populate choices if value exists
|
||||
if ( ! empty( $field['value'] ) ) {
|
||||
|
||||
@@ -76,7 +76,7 @@ if ( ! class_exists( 'acf_field_post_object' ) ) :
|
||||
$key = '';
|
||||
}
|
||||
|
||||
if ( ! acf_verify_ajax( $nonce, $key ) ) {
|
||||
if ( ! acf_verify_ajax( $nonce, $key, ! $conditional_logic ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ if ( ! class_exists( 'acf_field_post_object' ) ) :
|
||||
$field['type'] = 'select';
|
||||
$field['ui'] = 1;
|
||||
$field['ajax'] = 1;
|
||||
$field['nonce'] = wp_create_nonce( $field['key'] );
|
||||
$field['nonce'] = wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] );
|
||||
$field['choices'] = array();
|
||||
|
||||
// load posts
|
||||
|
||||
@@ -102,7 +102,7 @@ if ( ! class_exists( 'acf_field_relationship' ) ) :
|
||||
$key = '';
|
||||
}
|
||||
|
||||
if ( ! acf_verify_ajax( $nonce, $key ) ) {
|
||||
if ( ! acf_verify_ajax( $nonce, $key, ! $conditional_logic ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
@@ -417,7 +417,7 @@ if ( ! class_exists( 'acf_field_relationship' ) ) :
|
||||
'data-paged' => 1,
|
||||
'data-post_type' => '',
|
||||
'data-taxonomy' => '',
|
||||
'data-nonce' => wp_create_nonce( $field['key'] ),
|
||||
'data-nonce' => wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] ),
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
@@ -115,13 +115,19 @@ if ( ! class_exists( 'acf_field_select' ) ) :
|
||||
$nonce = acf_request_arg( 'nonce', '' );
|
||||
$key = acf_request_arg( 'field_key', '' );
|
||||
|
||||
$is_field_key = acf_is_field_key( $key );
|
||||
|
||||
// Back-compat for field settings.
|
||||
if ( ! acf_is_field_key( $key ) ) {
|
||||
if ( ! $is_field_key ) {
|
||||
if ( ! acf_current_user_can_admin() ) {
|
||||
die();
|
||||
}
|
||||
|
||||
$nonce = '';
|
||||
$key = '';
|
||||
}
|
||||
|
||||
if ( ! acf_verify_ajax( $nonce, $key ) ) {
|
||||
if ( ! acf_verify_ajax( $nonce, $key, $is_field_key ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
@@ -286,7 +292,7 @@ if ( ! class_exists( 'acf_field_select' ) ) :
|
||||
$select['data-nonce'] = $field['nonce'];
|
||||
}
|
||||
if ( $field['ajax'] && empty( $field['nonce'] ) && acf_is_field_key( $field['key'] ) ) {
|
||||
$select['data-nonce'] = wp_create_nonce( $field['key'] );
|
||||
$select['data-nonce'] = wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] );
|
||||
}
|
||||
if ( ! empty( $field['hide_search'] ) ) {
|
||||
$select['data-minimum-results-for-search'] = '-1';
|
||||
|
||||
@@ -70,7 +70,7 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
|
||||
$key = '';
|
||||
}
|
||||
|
||||
if ( ! acf_verify_ajax( $nonce, $key ) ) {
|
||||
if ( ! acf_verify_ajax( $nonce, $key, ! $conditional_logic ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
@@ -470,6 +470,8 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
|
||||
// force value to array
|
||||
$field['value'] = acf_get_array( $field['value'] );
|
||||
|
||||
$nonce = wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] );
|
||||
|
||||
// vars
|
||||
$div = array(
|
||||
'class' => 'acf-taxonomy-field',
|
||||
@@ -477,7 +479,7 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
|
||||
'data-ftype' => $field['field_type'],
|
||||
'data-taxonomy' => $field['taxonomy'],
|
||||
'data-allow_null' => $field['allow_null'],
|
||||
'data-nonce' => wp_create_nonce( $field['key'] ),
|
||||
'data-nonce' => $nonce,
|
||||
);
|
||||
// get taxonomy
|
||||
$taxonomy = get_taxonomy( $field['taxonomy'] );
|
||||
@@ -499,11 +501,11 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
|
||||
if ( $field['field_type'] == 'select' ) {
|
||||
$field['multiple'] = 0;
|
||||
|
||||
$this->render_field_select( $field );
|
||||
$this->render_field_select( $field, $nonce );
|
||||
} elseif ( $field['field_type'] == 'multi_select' ) {
|
||||
$field['multiple'] = 1;
|
||||
|
||||
$this->render_field_select( $field );
|
||||
$this->render_field_select( $field, $nonce );
|
||||
} elseif ( $field['field_type'] == 'radio' ) {
|
||||
$this->render_field_checkbox( $field );
|
||||
} elseif ( $field['field_type'] == 'checkbox' ) {
|
||||
@@ -524,12 +526,13 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
|
||||
*
|
||||
* @param $field - an array holding all the field's data
|
||||
*/
|
||||
function render_field_select( $field ) {
|
||||
function render_field_select( $field, $nonce ) {
|
||||
|
||||
// Change Field into a select
|
||||
$field['type'] = 'select';
|
||||
$field['ui'] = 1;
|
||||
$field['ajax'] = 1;
|
||||
$field['nonce'] = $nonce;
|
||||
$field['choices'] = array();
|
||||
|
||||
// value
|
||||
@@ -766,7 +769,7 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'] ) ) {
|
||||
if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'], true ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ if ( ! class_exists( 'ACF_Field_User' ) ) :
|
||||
$field['ui'] = 1;
|
||||
$field['ajax'] = 1;
|
||||
$field['choices'] = array();
|
||||
$field['nonce'] = wp_create_nonce( $field['key'] );
|
||||
$field['nonce'] = wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] );
|
||||
|
||||
// Populate choices.
|
||||
if ( $field['value'] ) {
|
||||
@@ -404,7 +404,7 @@ if ( ! class_exists( 'ACF_Field_User' ) ) :
|
||||
$nonce = acf_request_arg( 'nonce', '' );
|
||||
$key = acf_request_arg( 'field_key', '' );
|
||||
|
||||
if ( ! acf_verify_ajax( $nonce, $key ) ) {
|
||||
if ( ! acf_verify_ajax( $nonce, $key, true ) ) {
|
||||
$query->send( new WP_Error( 'acf_invalid_request', __( 'Invalid request.', 'acf' ), array( 'status' => 404 ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -691,6 +691,12 @@ if ( ! class_exists( 'ACF_Post_Type' ) ) {
|
||||
// Validate and prepare the post for export.
|
||||
$post = $this->validate_post( $post );
|
||||
$args = $this->get_post_type_args( $post, false );
|
||||
|
||||
// Restore original metabox callback.
|
||||
if ( ! empty( $args['register_meta_box_cb'] ) && ! empty( $post['register_meta_box_cb'] ) ) {
|
||||
$args['register_meta_box_cb'] = (string) $post['register_meta_box_cb'];
|
||||
}
|
||||
|
||||
$code = var_export( $args, true ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions -- Used for PHP export.
|
||||
|
||||
if ( ! $code ) {
|
||||
@@ -767,6 +773,30 @@ if ( ! class_exists( 'ACF_Post_Type' ) ) {
|
||||
return $post;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares an ACF post type for import.
|
||||
*
|
||||
* @since 6.3.10
|
||||
*
|
||||
* @param array $post The ACF post array.
|
||||
* @return array
|
||||
*/
|
||||
public function prepare_post_for_import( $post ) {
|
||||
if ( ! acf_get_setting( 'enable_meta_box_cb_edit' ) && ! empty( $post['register_meta_box_cb'] ) ) {
|
||||
$post['register_meta_box_cb'] = '';
|
||||
|
||||
if ( ! empty( $post['ID'] ) ) {
|
||||
$existing_post = $this->get_post( $post['ID'] );
|
||||
|
||||
if ( is_array( $existing_post ) ) {
|
||||
$post['register_meta_box_cb'] = ! empty( $existing_post['register_meta_box_cb'] ) ? (string) $existing_post['register_meta_box_cb'] : '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::prepare_post_for_import( $post );
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a post type from CPTUI.
|
||||
*
|
||||
|
||||
@@ -577,7 +577,13 @@ if ( ! class_exists( 'ACF_Taxonomy' ) ) {
|
||||
$objects = (array) $post['object_type'];
|
||||
$objects = var_export( $objects, true ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions -- Used for PHP export.
|
||||
$args = $this->get_taxonomy_args( $post, false );
|
||||
$args = var_export( $args, true ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions -- Used for PHP export.
|
||||
|
||||
// Restore original metabox callback.
|
||||
if ( ! empty( $args['meta_box_cb'] ) && ! empty( $post['meta_box_cb'] ) ) {
|
||||
$args['meta_box_cb'] = $post['meta_box_cb'];
|
||||
}
|
||||
|
||||
$args = var_export( $args, true ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions -- Used for PHP export.
|
||||
|
||||
if ( ! $args ) {
|
||||
return $return;
|
||||
@@ -654,6 +660,37 @@ if ( ! class_exists( 'ACF_Taxonomy' ) ) {
|
||||
return $post;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares an ACF taxonomy for import.
|
||||
*
|
||||
* @since 6.3.10
|
||||
*
|
||||
* @param array $post The ACF post array.
|
||||
* @return array
|
||||
*/
|
||||
public function prepare_post_for_import( $post ) {
|
||||
if ( ! acf_get_setting( 'enable_meta_box_cb_edit' ) && ( ! empty( $post['meta_box_cb'] ) || ! empty( $post['meta_box_sanitize_cb'] ) ) ) {
|
||||
$post['meta_box_cb'] = '';
|
||||
$post['meta_box_sanitize_cb'] = '';
|
||||
|
||||
if ( ! empty( $post['meta_box'] ) && 'custom' === $post['meta_box'] ) {
|
||||
$post['meta_box'] = 'default';
|
||||
}
|
||||
|
||||
if ( ! empty( $post['ID'] ) ) {
|
||||
$existing_post = $this->get_post( $post['ID'] );
|
||||
|
||||
if ( is_array( $existing_post ) ) {
|
||||
$post['meta_box'] = ! empty( $existing_post['meta_box'] ) ? (string) $existing_post['meta_box'] : '';
|
||||
$post['meta_box_cb'] = ! empty( $existing_post['meta_box_cb'] ) ? (string) $existing_post['meta_box_cb'] : '';
|
||||
$post['meta_box_sanitize_cb'] = ! empty( $existing_post['meta_box_sanitize_cb'] ) ? (string) $existing_post['meta_box_sanitize_cb'] : '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::prepare_post_for_import( $post );
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a taxonomy from CPTUI.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user