plugin updates

This commit is contained in:
Tony Volpe
2024-10-29 13:49:07 -04:00
parent 66268c4512
commit 9000316050
41 changed files with 916 additions and 570 deletions

View File

@@ -9,7 +9,7 @@
* Plugin Name: Advanced Custom Fields PRO * Plugin Name: Advanced Custom Fields PRO
* Plugin URI: https://www.advancedcustomfields.com * Plugin URI: https://www.advancedcustomfields.com
* Description: Customize WordPress with powerful, professional and intuitive fields. * Description: Customize WordPress with powerful, professional and intuitive fields.
* Version: 6.3.9 * Version: 6.3.10
* Author: WP Engine * Author: WP Engine
* Author URI: https://wpengine.com/?utm_source=wordpress.org&utm_medium=referral&utm_campaign=plugin_directory&utm_content=advanced_custom_fields * Author URI: https://wpengine.com/?utm_source=wordpress.org&utm_medium=referral&utm_campaign=plugin_directory&utm_content=advanced_custom_fields
* Update URI: false * Update URI: false
@@ -36,7 +36,7 @@ if ( ! class_exists( 'ACF' ) ) {
* *
* @var string * @var string
*/ */
public $version = '6.3.9'; public $version = '6.3.10';
/** /**
* The plugin settings array. * The plugin settings array.
@@ -130,6 +130,7 @@ if ( ! class_exists( 'ACF' ) ) {
'enable_shortcode' => true, 'enable_shortcode' => true,
'enable_bidirection' => true, 'enable_bidirection' => true,
'enable_block_bindings' => true, 'enable_block_bindings' => true,
'enable_meta_box_cb_edit' => true,
); );
// Include utility functions. // Include utility functions.
@@ -227,15 +228,13 @@ if ( ! class_exists( 'ACF' ) ) {
// Include legacy. // Include legacy.
acf_include( 'includes/legacy/legacy-locations.php' ); acf_include( 'includes/legacy/legacy-locations.php' );
// Include updater.
acf_include( 'includes/Updater/Updater.php' );
// Include PRO. // Include PRO.
acf_include( 'pro/acf-pro.php' ); acf_include( 'pro/acf-pro.php' );
if ( is_admin() && function_exists( 'acf_is_pro' ) && ! acf_is_pro() ) { if ( is_admin() && function_exists( 'acf_is_pro' ) && ! acf_is_pro() ) {
// Include WPE update system.
acf_include( 'includes/class-PluginUpdater.php' );
acf_include( 'includes/acf-upgrades.php' );
acf_include( 'includes/admin/admin-options-pages-preview.php' ); acf_include( 'includes/admin/admin-options-pages-preview.php' );
} }
@@ -396,12 +395,24 @@ if ( ! class_exists( 'ACF' ) ) {
*/ */
do_action( 'acf/include_taxonomies', ACF_MAJOR_VERSION ); do_action( 'acf/include_taxonomies', ACF_MAJOR_VERSION );
// If we're on 6.5 or newer, load block bindings. This will move to an autoloader in 6.3. // If we're on 6.5 or newer, load block bindings. This will move to an autoloader in 6.4.
if ( version_compare( get_bloginfo( 'version' ), '6.5-beta1', '>=' ) ) { if ( version_compare( get_bloginfo( 'version' ), '6.5-beta1', '>=' ) ) {
acf_include( 'includes/Blocks/Bindings.php' ); acf_include( 'includes/Blocks/Bindings.php' );
new ACF\Blocks\Bindings(); new ACF\Blocks\Bindings();
} }
// If we're ACF free, register the updater.
if ( function_exists( 'acf_is_pro' ) && ! acf_is_pro() ) {
acf_register_plugin_update(
array(
'id' => 'acf',
'slug' => acf_get_setting( 'slug' ),
'basename' => acf_get_setting( 'basename' ),
'version' => acf_get_setting( 'version' ),
)
);
}
/** /**
* Fires after ACF is completely "initialized". * Fires after ACF is completely "initialized".
* *
@@ -788,6 +799,66 @@ if ( ! class_exists( 'ACF' ) ) {
} }
} }
/**
* The main function responsible for returning the acf_updates singleton.
* Use this function like you would a global variable, except without needing to declare the global.
*
* Example: <?php $acf_updates = acf_updates(); ?>
*
* @since 5.5.12
*
* @return ACF\Updater The singleton instance of Updater.
*/
function acf_updates() {
global $acf_updates;
if ( ! isset( $acf_updates ) ) {
$acf_updates = new ACF\Updater();
}
return $acf_updates;
}
/**
* Alias of acf_updates()->add_plugin().
*
* @since 5.5.10
*
* @param array $plugin Plugin data array.
*/
function acf_register_plugin_update( $plugin ) {
acf_updates()->add_plugin( $plugin );
}
/**
* An ACF specific getter to replace `home_url` in our license checks to ensure we can avoid third party filters.
*
* @since 6.0.1
* @since 6.2.8 - Renamed to acf_pro_get_home_url to match pro exclusive function naming.
* @since 6.3.10 - Renamed to acf_get_home_url now updater logic applies to free.
*
* @return string $home_url The output from home_url, sans known third party filters which cause license activation issues.
*/
function acf_get_home_url() {
// Disable WPML and TranslatePress's home url overrides for our license check.
add_filter( 'wpml_get_home_url', 'acf_pro_license_ml_intercept', 99, 2 );
add_filter( 'trp_home_url', 'acf_pro_license_ml_intercept', 99, 2 );
if ( acf_is_pro() ) {
if ( acf_pro_is_legacy_multisite() && acf_is_multisite_sub_site() ) {
$home_url = get_home_url( get_main_site_id() );
} else {
$home_url = home_url();
}
} else {
$home_url = home_url();
}
// Re-enable WPML and TranslatePress's home url overrides.
remove_filter( 'wpml_get_home_url', 'acf_pro_license_ml_intercept', 99 );
remove_filter( 'trp_home_url', 'acf_pro_license_ml_intercept', 99 );
return $home_url;
}
/** /**
* The main function responsible for returning the one true acf Instance to functions everywhere. * The main function responsible for returning the one true acf Instance to functions everywhere.
* Use this function like you would a global variable, except without needing to declare the global. * Use this function like you would a global variable, except without needing to declare the global.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -5,24 +5,28 @@
* @package ACF * @package ACF
*/ */
namespace ACF;
use WP_Error;
// Exit if accessed directly. // Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
if ( ! class_exists( 'ACF_Updates' ) ) { if ( ! class_exists( 'Updater' ) ) {
/** /**
* class for handling API services. * class for handling API services.
*/ */
class ACF_Updates { class Updater {
/** /**
* The ACF_Updates version * The Updater version
* *
* @var string * @var string
*/ */
public $version = '2.4'; public $version = '3.0';
/** /**
* The array of registered plugins * The array of registered plugins
@@ -45,8 +49,8 @@ if ( ! class_exists( 'ACF_Updates' ) ) {
*/ */
public function __construct() { public function __construct() {
// disable showing updates if show updates is hidden. // disable showing PRO updates if show updates is hidden.
if ( ! acf_pro_is_updates_page_visible() ) { if ( acf_is_pro() && ! acf_pro_is_updates_page_visible() ) {
return; return;
} }
@@ -120,7 +124,16 @@ if ( ! class_exists( 'ACF_Updates' ) ) {
*/ */
public function request( $endpoint = '', $body = null ) { public function request( $endpoint = '', $body = null ) {
// Determine URL. $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"; $url = "https://connect.advancedcustomfields.com/$endpoint";
// Staging environment. // Staging environment.
@@ -129,27 +142,25 @@ if ( ! class_exists( 'ACF_Updates' ) ) {
acf_log( $url, $body ); acf_log( $url, $body );
} }
$license_key = acf_pro_get_license_key(); // Determine URL.
if ( ! $license_key ) { if ( acf_is_pro() ) {
$license_key = ''; $license_key = acf_pro_get_license_key();
} if ( empty( $license_key ) || ! is_string( $license_key ) ) {
$license_key = '';
$site_url = acf_pro_get_home_url(); }
if ( ! $site_url ) { $headers['X-ACF-License'] = $license_key;
$site_url = ''; $headers['X-ACF-Plugin'] = 'pro';
} else {
$headers['X-ACF-Plugin'] = 'acf';
} }
// Make request. // Make request.
$raw_response = wp_remote_post( $raw_response = wp_remote_post(
$url, $url,
array( array(
'timeout' => 28, 'timeout' => 20,
'body' => $body, 'body' => $body,
'headers' => array( 'headers' => $headers,
'X-ACF-Version' => ACF_VERSION,
'X-ACF-License' => $license_key,
'X-ACF-URL' => $site_url,
),
) )
); );
@@ -298,7 +309,7 @@ if ( ! class_exists( 'ACF_Updates' ) ) {
'wp' => wp_json_encode( 'wp' => wp_json_encode(
array( array(
'wp_name' => get_bloginfo( 'name' ), 'wp_name' => get_bloginfo( 'name' ),
'wp_url' => acf_pro_get_home_url(), 'wp_url' => acf_get_home_url(),
'wp_version' => get_bloginfo( 'version' ), 'wp_version' => get_bloginfo( 'version' ),
'wp_language' => get_bloginfo( 'language' ), 'wp_language' => get_bloginfo( 'language' ),
'wp_timezone' => get_option( 'timezone_string' ), 'wp_timezone' => get_option( 'timezone_string' ),
@@ -310,7 +321,7 @@ if ( ! class_exists( 'ACF_Updates' ) ) {
array( array(
'acf_version' => get_option( 'acf_version' ), 'acf_version' => get_option( 'acf_version' ),
'acf_pro' => acf_is_pro(), 'acf_pro' => acf_is_pro(),
'block_count' => acf_pro_get_registered_block_count(), 'block_count' => function_exists( 'acf_pro_get_registered_block_count' ) ? acf_pro_get_registered_block_count() : 0,
) )
), ),
); );
@@ -481,34 +492,4 @@ if ( ! class_exists( 'ACF_Updates' ) ) {
} }
} }
/**
* The main function responsible for returning the acf_updates singleton.
* Use this function like you would a global variable, except without needing to declare the global.
*
* Example: <?php $acf_updates = acf_updates(); ?>
*
* @since 5.5.12
*
* @return ACF_Updates The singleton instance of ACF_Updates.
*/
function acf_updates() {
global $acf_updates;
if ( ! isset( $acf_updates ) ) {
$acf_updates = new ACF_Updates();
}
return $acf_updates;
}
/**
* Alias of acf_updates()->add_plugin().
*
* @since 5.5.10
*
* @param array $plugin Plugin data array.
*/
function acf_register_plugin_update( $plugin ) {
acf_updates()->add_plugin( $plugin );
}
} }

View File

@@ -0,0 +1,2 @@
<?php
// There are many ways to WordPress.

View File

@@ -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' );

View File

@@ -312,6 +312,15 @@ if ( ! class_exists( 'ACF_Admin_Post_Type' ) ) :
$_POST['acf_post_type']['ID'] = $post_id; $_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'] : ''; $_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. // 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 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 // phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

View File

@@ -314,6 +314,29 @@ if ( ! class_exists( 'ACF_Admin_Taxonomy' ) ) :
$_POST['acf_taxonomy']['ID'] = $post_id; $_POST['acf_taxonomy']['ID'] = $post_id;
$_POST['acf_taxonomy']['title'] = isset( $_POST['acf_taxonomy']['labels']['name'] ) ? $_POST['acf_taxonomy']['labels']['name'] : ''; $_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. // 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 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 // phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

View File

@@ -319,6 +319,7 @@ if ( isset( $field['conditional_logic'] ) && is_array( $field['conditional_logic
?> ?>
<div class="acf-field-settings-footer"> <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="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> </div>
</div> </div>

View File

@@ -98,7 +98,7 @@ if ( $is_subfield ) {
<ul class="acf-hl acf-tfoot"> <ul class="acf-hl acf-tfoot">
<li class="acf-fr"> <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> </li>
</ul> </ul>

View File

@@ -838,24 +838,39 @@ foreach ( acf_get_combined_post_type_settings_tabs() as $tab_key => $tab_label )
'field' 'field'
); );
acf_render_field_wrap( $acf_enable_meta_box_cb_edit = acf_get_setting( 'enable_meta_box_cb_edit' );
array( $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' );
'type' => 'text',
'name' => 'register_meta_box_cb', // Only show if user is allowed to update, or if it already has a value.
'key' => 'register_meta_box_cb', if ( $acf_enable_meta_box_cb_edit || ! empty( $acf_post_type['register_meta_box_cb'] ) ) {
'prefix' => 'acf_post_type', if ( ! $acf_enable_meta_box_cb_edit ) {
'value' => $acf_post_type['register_meta_box_cb'], if ( is_multisite() ) {
'label' => __( 'Custom Meta Box Callback', 'acf' ), $acf_meta_box_cb_instructions .= ' ' . __( 'By default only super admin users can edit this setting.', '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' ), } else {
'conditions' => array( $acf_meta_box_cb_instructions .= ' ' . __( 'By default only admin users can edit this setting.', 'acf' );
'field' => 'show_ui', }
'operator' => '==', }
'value' => '1',
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',
'div', 'field'
'field' );
); }
acf_render_field_wrap( acf_render_field_wrap(
array( array(

View File

@@ -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_tags_meta_box_text = __( 'Tags Meta Box', 'acf' );
$acf_categories_meta_box_text = __( 'Categories 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_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( acf_render_field_wrap(
array( array(
@@ -757,11 +767,7 @@ foreach ( acf_get_combined_taxonomy_settings_tabs() as $tab_key => $tab_label )
'label' => __( 'Meta Box', 'acf' ), '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' ), '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, 'hide_search' => true,
'choices' => array( 'choices' => $acf_meta_box_choices,
'default' => $acf_default_meta_box_text,
'custom' => __( 'Custom Meta Box', 'acf' ),
'disabled' => __( 'No Meta Box', 'acf' ),
),
'data' => array( 'data' => array(
'tags_meta_box' => __( 'Tags Meta Box', 'acf' ), 'tags_meta_box' => __( 'Tags Meta Box', 'acf' ),
'categories_meta_box' => __( 'Categories 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( if ( $acf_enable_meta_box_cb_edit || 'custom' === $acf_taxonomy['meta_box'] ) {
array( $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' );
'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'
);
acf_render_field_wrap( if ( ! $acf_enable_meta_box_cb_edit ) {
array( if ( is_multisite() ) {
'type' => 'text', $acf_meta_box_cb_instructions .= ' ' . __( 'By default only super admin users can edit this setting.', 'acf' );
'name' => 'meta_box_sanitize_cb', } else {
'key' => 'meta_box_sanitize_cb', $acf_meta_box_cb_instructions .= ' ' . __( 'By default only admin users can edit this setting.', 'acf' );
'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'
);
acf_render_field_wrap( acf_render_field_wrap(
array( array(
'type' => 'seperator', 'type' => 'text',
'conditions' => array( 'name' => 'meta_box_cb',
'field' => 'meta_box', 'key' => 'meta_box_cb',
'operator' => '==', 'prefix' => 'acf_taxonomy',
'value' => 'custom', '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( acf_render_field_wrap(
array( array(

View File

@@ -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 ) ); return new WP_Error( 'acf_invalid_args', __( 'Invalid request args.', 'acf' ), array( 'status' => 404 ) );
} }
$nonce = $request['nonce']; $nonce = $request['nonce'];
$action = $request['field_key']; $action = $request['field_key'];
$field_action = true;
if ( isset( $request['conditional_logic'] ) && true === (bool) $request['conditional_logic'] ) { if ( isset( $request['conditional_logic'] ) && true === (bool) $request['conditional_logic'] ) {
if ( ! acf_current_user_can_admin() ) { if ( ! acf_current_user_can_admin() ) {
@@ -33,11 +34,12 @@ if ( ! class_exists( 'ACF_Ajax_Query_Users' ) ) :
} }
// Use the standard ACF admin nonce. // Use the standard ACF admin nonce.
$nonce = ''; $nonce = '';
$action = ''; $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 ) ); return new WP_Error( 'acf_invalid_nonce', __( 'Invalid nonce.', 'acf' ), array( 'status' => 404 ) );
} }

View File

@@ -687,16 +687,32 @@ function acf_verify_nonce( $value ) {
* *
* @since 5.2.3 * @since 5.2.3
* *
* @param string $nonce The nonce to check. * @param string $nonce The nonce to check.
* @param string $action The action of the nonce. * @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 * @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. // Bail early if we don't have a nonce to check.
if ( empty( $nonce ) && empty( $_REQUEST['nonce'] ) ) { if ( empty( $nonce ) && empty( $_REQUEST['nonce'] ) ) {
return false; 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_to_check = ! empty( $nonce ) ? $nonce : $_REQUEST['nonce']; // phpcs:ignore WordPress.Security -- We're verifying a nonce here.
$nonce_action = ! empty( $action ) ? $action : 'acf_nonce'; $nonce_action = ! empty( $action ) ? $action : 'acf_nonce';
@@ -3974,3 +3990,20 @@ function acf_is_multisite_main_site() {
} }
return false; 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 );

View File

@@ -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;
}
}

View File

@@ -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(); die();
} }
@@ -169,7 +169,7 @@ if ( ! class_exists( 'acf_field_oembed' ) ) :
public function render_field( $field ) { public function render_field( $field ) {
$atts = array( $atts = array(
'class' => 'acf-oembed', 'class' => 'acf-oembed',
'data-nonce' => wp_create_nonce( $field['key'] ), 'data-nonce' => wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] ),
); );
if ( $field['value'] ) { if ( $field['value'] ) {

View File

@@ -81,7 +81,7 @@ if ( ! class_exists( 'acf_field_page_link' ) ) :
$key = ''; $key = '';
} }
if ( ! acf_verify_ajax( $nonce, $key ) ) { if ( ! acf_verify_ajax( $nonce, $key, ! $conditional_logic ) ) {
die(); die();
} }
@@ -392,7 +392,7 @@ if ( ! class_exists( 'acf_field_page_link' ) ) :
$field['ui'] = 1; $field['ui'] = 1;
$field['ajax'] = 1; $field['ajax'] = 1;
$field['choices'] = array(); $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 // populate choices if value exists
if ( ! empty( $field['value'] ) ) { if ( ! empty( $field['value'] ) ) {

View File

@@ -76,7 +76,7 @@ if ( ! class_exists( 'acf_field_post_object' ) ) :
$key = ''; $key = '';
} }
if ( ! acf_verify_ajax( $nonce, $key ) ) { if ( ! acf_verify_ajax( $nonce, $key, ! $conditional_logic ) ) {
die(); die();
} }
@@ -314,7 +314,7 @@ if ( ! class_exists( 'acf_field_post_object' ) ) :
$field['type'] = 'select'; $field['type'] = 'select';
$field['ui'] = 1; $field['ui'] = 1;
$field['ajax'] = 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(); $field['choices'] = array();
// load posts // load posts

View File

@@ -102,7 +102,7 @@ if ( ! class_exists( 'acf_field_relationship' ) ) :
$key = ''; $key = '';
} }
if ( ! acf_verify_ajax( $nonce, $key ) ) { if ( ! acf_verify_ajax( $nonce, $key, ! $conditional_logic ) ) {
die(); die();
} }
@@ -417,7 +417,7 @@ if ( ! class_exists( 'acf_field_relationship' ) ) :
'data-paged' => 1, 'data-paged' => 1,
'data-post_type' => '', 'data-post_type' => '',
'data-taxonomy' => '', 'data-taxonomy' => '',
'data-nonce' => wp_create_nonce( $field['key'] ), 'data-nonce' => wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] ),
); );
?> ?>

View File

@@ -115,13 +115,19 @@ if ( ! class_exists( 'acf_field_select' ) ) :
$nonce = acf_request_arg( 'nonce', '' ); $nonce = acf_request_arg( 'nonce', '' );
$key = acf_request_arg( 'field_key', '' ); $key = acf_request_arg( 'field_key', '' );
$is_field_key = acf_is_field_key( $key );
// Back-compat for field settings. // Back-compat for field settings.
if ( ! acf_is_field_key( $key ) ) { if ( ! $is_field_key ) {
if ( ! acf_current_user_can_admin() ) {
die();
}
$nonce = ''; $nonce = '';
$key = ''; $key = '';
} }
if ( ! acf_verify_ajax( $nonce, $key ) ) { if ( ! acf_verify_ajax( $nonce, $key, $is_field_key ) ) {
die(); die();
} }
@@ -286,7 +292,7 @@ if ( ! class_exists( 'acf_field_select' ) ) :
$select['data-nonce'] = $field['nonce']; $select['data-nonce'] = $field['nonce'];
} }
if ( $field['ajax'] && empty( $field['nonce'] ) && acf_is_field_key( $field['key'] ) ) { 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'] ) ) { if ( ! empty( $field['hide_search'] ) ) {
$select['data-minimum-results-for-search'] = '-1'; $select['data-minimum-results-for-search'] = '-1';

View File

@@ -70,7 +70,7 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
$key = ''; $key = '';
} }
if ( ! acf_verify_ajax( $nonce, $key ) ) { if ( ! acf_verify_ajax( $nonce, $key, ! $conditional_logic ) ) {
die(); die();
} }
@@ -470,6 +470,8 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
// force value to array // force value to array
$field['value'] = acf_get_array( $field['value'] ); $field['value'] = acf_get_array( $field['value'] );
$nonce = wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] );
// vars // vars
$div = array( $div = array(
'class' => 'acf-taxonomy-field', 'class' => 'acf-taxonomy-field',
@@ -477,7 +479,7 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
'data-ftype' => $field['field_type'], 'data-ftype' => $field['field_type'],
'data-taxonomy' => $field['taxonomy'], 'data-taxonomy' => $field['taxonomy'],
'data-allow_null' => $field['allow_null'], 'data-allow_null' => $field['allow_null'],
'data-nonce' => wp_create_nonce( $field['key'] ), 'data-nonce' => $nonce,
); );
// get taxonomy // get taxonomy
$taxonomy = get_taxonomy( $field['taxonomy'] ); $taxonomy = get_taxonomy( $field['taxonomy'] );
@@ -499,11 +501,11 @@ if ( ! class_exists( 'acf_field_taxonomy' ) ) :
if ( $field['field_type'] == 'select' ) { if ( $field['field_type'] == 'select' ) {
$field['multiple'] = 0; $field['multiple'] = 0;
$this->render_field_select( $field ); $this->render_field_select( $field, $nonce );
} elseif ( $field['field_type'] == 'multi_select' ) { } elseif ( $field['field_type'] == 'multi_select' ) {
$field['multiple'] = 1; $field['multiple'] = 1;
$this->render_field_select( $field ); $this->render_field_select( $field, $nonce );
} elseif ( $field['field_type'] == 'radio' ) { } elseif ( $field['field_type'] == 'radio' ) {
$this->render_field_checkbox( $field ); $this->render_field_checkbox( $field );
} elseif ( $field['field_type'] == 'checkbox' ) { } 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 * @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 // Change Field into a select
$field['type'] = 'select'; $field['type'] = 'select';
$field['ui'] = 1; $field['ui'] = 1;
$field['ajax'] = 1; $field['ajax'] = 1;
$field['nonce'] = $nonce;
$field['choices'] = array(); $field['choices'] = array();
// value // 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(); die();
} }

View File

@@ -164,7 +164,7 @@ if ( ! class_exists( 'ACF_Field_User' ) ) :
$field['ui'] = 1; $field['ui'] = 1;
$field['ajax'] = 1; $field['ajax'] = 1;
$field['choices'] = array(); $field['choices'] = array();
$field['nonce'] = wp_create_nonce( $field['key'] ); $field['nonce'] = wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] );
// Populate choices. // Populate choices.
if ( $field['value'] ) { if ( $field['value'] ) {
@@ -404,7 +404,7 @@ if ( ! class_exists( 'ACF_Field_User' ) ) :
$nonce = acf_request_arg( 'nonce', '' ); $nonce = acf_request_arg( 'nonce', '' );
$key = acf_request_arg( 'field_key', '' ); $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 ) ) ); $query->send( new WP_Error( 'acf_invalid_request', __( 'Invalid request.', 'acf' ), array( 'status' => 404 ) ) );
} }
} }

View File

@@ -691,6 +691,12 @@ if ( ! class_exists( 'ACF_Post_Type' ) ) {
// Validate and prepare the post for export. // Validate and prepare the post for export.
$post = $this->validate_post( $post ); $post = $this->validate_post( $post );
$args = $this->get_post_type_args( $post, false ); $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. $code = var_export( $args, true ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions -- Used for PHP export.
if ( ! $code ) { if ( ! $code ) {
@@ -767,6 +773,30 @@ if ( ! class_exists( 'ACF_Post_Type' ) ) {
return $post; 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. * Imports a post type from CPTUI.
* *

View File

@@ -577,7 +577,13 @@ if ( ! class_exists( 'ACF_Taxonomy' ) ) {
$objects = (array) $post['object_type']; $objects = (array) $post['object_type'];
$objects = var_export( $objects, true ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions -- Used for PHP export. $objects = var_export( $objects, true ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions -- Used for PHP export.
$args = $this->get_taxonomy_args( $post, false ); $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 ) { if ( ! $args ) {
return $return; return $return;
@@ -654,6 +660,37 @@ if ( ! class_exists( 'ACF_Taxonomy' ) ) {
return $post; 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. * Imports a taxonomy from CPTUI.
* *

View File

@@ -24,7 +24,6 @@ if ( ! class_exists( 'acf_pro' ) ) :
acf_include( 'pro/blocks.php' ); acf_include( 'pro/blocks.php' );
acf_include( 'pro/options-page.php' ); acf_include( 'pro/options-page.php' );
acf_include( 'pro/acf-ui-options-page-functions.php' ); acf_include( 'pro/acf-ui-options-page-functions.php' );
acf_include( 'pro/class-acf-updates.php' );
acf_include( 'pro/updates.php' ); acf_include( 'pro/updates.php' );
if ( is_admin() ) { if ( is_admin() ) {

View File

@@ -93,7 +93,7 @@ if ( ! class_exists( 'acf_field_gallery' ) ) :
); );
// Validate request. // Validate request.
if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'] ) ) { if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'], true ) ) {
die(); die();
} }
@@ -131,7 +131,7 @@ if ( ! class_exists( 'acf_field_gallery' ) ) :
) )
); );
if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'] ) ) { if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'], true ) ) {
wp_send_json_error(); wp_send_json_error();
} }
@@ -209,7 +209,7 @@ if ( ! class_exists( 'acf_field_gallery' ) ) :
) )
); );
if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'] ) ) { if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'], true ) ) {
wp_send_json_error(); wp_send_json_error();
} }
@@ -387,7 +387,7 @@ if ( ! class_exists( 'acf_field_gallery' ) ) :
'data-mime_types' => $field['mime_types'], 'data-mime_types' => $field['mime_types'],
'data-insert' => $field['insert'], 'data-insert' => $field['insert'],
'data-columns' => 4, 'data-columns' => 4,
'data-nonce' => wp_create_nonce( $field['key'] ), 'data-nonce' => wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] ),
); );
// Set gallery height with deafult of 400px and minimum of 200px. // Set gallery height with deafult of 400px and minimum of 200px.

View File

@@ -1046,7 +1046,7 @@ if ( ! class_exists( 'acf_field_repeater' ) ) :
) )
); );
if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'] ) ) { if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'], true ) ) {
$error = array( 'error' => __( 'Invalid nonce.', 'acf' ) ); $error = array( 'error' => __( 'Invalid nonce.', 'acf' ) );
wp_send_json_error( $error, 401 ); wp_send_json_error( $error, 401 );
} }

View File

@@ -164,7 +164,7 @@ class ACF_Repeater_Table {
$div['data-per_page'] = $this->field['rows_per_page']; $div['data-per_page'] = $this->field['rows_per_page'];
$div['data-total_rows'] = $this->field['total_rows']; $div['data-total_rows'] = $this->field['total_rows'];
$div['data-orig_name'] = $this->field['orig_name']; $div['data-orig_name'] = $this->field['orig_name'];
$div['data-nonce'] = wp_create_nonce( $this->field['key'] ); $div['data-nonce'] = wp_create_nonce( 'acf_field_' . $this->field['type'] . '_' . $this->field['key'] );
} }
if ( empty( $this->value ) ) { if ( empty( $this->value ) ) {

View File

@@ -374,32 +374,6 @@ function acf_pro_get_license() {
return $license; return $license;
} }
/**
* An ACF specific getter to replace `home_url` in our license checks to ensure we can avoid third party filters.
*
* @since 6.0.1
* @since 6.2.8 - Renamed to acf_pro_get_home_url to match pro exclusive function naming.
*
* @return string $home_url The output from home_url, sans known third party filters which cause license activation issues.
*/
function acf_pro_get_home_url() {
// Disable WPML and TranslatePress's home url overrides for our license check.
add_filter( 'wpml_get_home_url', 'acf_pro_license_ml_intercept', 99, 2 );
add_filter( 'trp_home_url', 'acf_pro_license_ml_intercept', 99, 2 );
if ( acf_pro_is_legacy_multisite() && acf_is_multisite_sub_site() ) {
$home_url = get_home_url( get_main_site_id() );
} else {
$home_url = home_url();
}
// Re-enable WPML and TranslatePress's home url overrides.
remove_filter( 'wpml_get_home_url', 'acf_pro_license_ml_intercept', 99 );
remove_filter( 'trp_home_url', 'acf_pro_license_ml_intercept', 99 );
return $home_url;
}
/** /**
* Return the original home url inside ACF's home url getter. * Return the original home url inside ACF's home url getter.
* *
@@ -477,7 +451,7 @@ function acf_pro_update_license( $key = '' ) {
// vars // vars
$data = array( $data = array(
'key' => $key, 'key' => $key,
'url' => acf_pro_get_home_url(), 'url' => acf_get_home_url(),
); );
// encode // encode
@@ -526,7 +500,7 @@ function acf_pro_activate_license( $license_key, $silent = false, $automatic = f
'acf_license' => trim( $license_key ), 'acf_license' => trim( $license_key ),
'acf_version' => acf_get_setting( 'version' ), 'acf_version' => acf_get_setting( 'version' ),
'wp_name' => get_bloginfo( 'name' ), 'wp_name' => get_bloginfo( 'name' ),
'wp_url' => acf_pro_get_home_url(), 'wp_url' => acf_get_home_url(),
'wp_version' => get_bloginfo( 'version' ), 'wp_version' => get_bloginfo( 'version' ),
'wp_language' => get_bloginfo( 'language' ), 'wp_language' => get_bloginfo( 'language' ),
'wp_timezone' => get_option( 'timezone_string' ), 'wp_timezone' => get_option( 'timezone_string' ),
@@ -624,7 +598,7 @@ function acf_pro_deactivate_license( $silent = false ) {
// Connect to API. // Connect to API.
$post = array( $post = array(
'acf_license' => $license, 'acf_license' => $license,
'wp_url' => acf_pro_get_home_url(), 'wp_url' => acf_get_home_url(),
); );
$response = acf_updates()->request( 'v2/plugins/deactivate?p=pro', $post ); $response = acf_updates()->request( 'v2/plugins/deactivate?p=pro', $post );
@@ -729,7 +703,7 @@ function acf_pro_get_license_status( $force_check = false ) {
$post = array( $post = array(
'acf_license' => $license, 'acf_license' => $license,
'wp_url' => acf_pro_get_home_url(), 'wp_url' => acf_get_home_url(),
); );
$response = acf_updates()->request( 'v2/plugins/validate?p=pro', $post ); $response = acf_updates()->request( 'v2/plugins/validate?p=pro', $post );
@@ -894,7 +868,7 @@ function acf_pro_was_license_refunded( $status = array() ) {
*/ */
function acf_pro_has_license_url_changed( $license = array(), $url = '' ) { function acf_pro_has_license_url_changed( $license = array(), $url = '' ) {
$license = ! empty( $license ) ? $license : acf_pro_get_license(); $license = ! empty( $license ) ? $license : acf_pro_get_license();
$home_url = ! empty( $url ) ? $url : acf_pro_get_home_url(); $home_url = ! empty( $url ) ? $url : acf_get_home_url();
// We can't know without a license, so let's assume not. // We can't know without a license, so let's assume not.
if ( ! is_array( $license ) || empty( $license['url'] ) ) { if ( ! is_array( $license ) || empty( $license['url'] ) ) {

View File

@@ -4,7 +4,6 @@ Tags: acf, fields, custom fields, meta, repeater
Requires at least: 6.0 Requires at least: 6.0
Tested up to: 6.6 Tested up to: 6.6
Requires PHP: 7.4 Requires PHP: 7.4
Stable tag: 6.3.8
License: GPLv2 or later License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -94,6 +93,15 @@ From your WordPress dashboard
== Changelog == == Changelog ==
= 6.3.10 =
*Release Date 29th October 2024*
* Security - Setting a metabox callback for custom post types and taxonomies now requires being an admin, or super admin for multisite installs
* Security - Field specific ACF nonces are now prefixed, resolving an issue where third party nonces could be treated as valid for AJAX calls
* Enhancement - A new “Close and Add Field” option is now available when editing a field group, inserting a new field inline after the field being edited
* Enhancement - ACF and ACF PRO now share the same plugin updater for improved reliability and performance
* Fix - Exporting post types and taxonomies containing metabox callbacks now correctly exports the user defined callback
= 6.3.9 = = 6.3.9 =
*Release Date 15th October 2024* *Release Date 15th October 2024*

View File

@@ -15,12 +15,55 @@
url('../fonts/MaterialIcons-Regular.ttf') format('truetype'); url('../fonts/MaterialIcons-Regular.ttf') format('truetype');
} }
/* Remote video CSS */ /* Tagify */
.tagify {
width: 100%;
}
.tagify--outside {
border: 0;
}
.tagify--outside .tagify__input {
order: -1;
flex: 100%;
border: 1px solid var(--tags-border-color);
margin-bottom: 1em;
transition: .1s;
}
.tagify--outside .tagify__input:hover {
border-color: var(--tags-hover-border-color);
}
.tagify--outside.tagify--focus .tagify__input {
transition: 0s;
border-color: var(--tags-focus-border-color);
}
.tagify__dropdown {
z-index: 999999999 !important;
}
.wpmf-dialog-text .tagify__input {
margin: 5px 0;
}
.wpmf-dialog-text .tagify__tag>div {
padding-left: 0 !important;
}
.wpmf-dialog-text .tagify__tag {
margin-left: 0;
margin-right: 5px;
}
/* Remote video, add tag CSS */
#wpmf-add-video-dialog { #wpmf-add-video-dialog {
z-index: 9999 !important; z-index: 9999 !important;
} }
#wpmf-add-video-dialog h5 { #wpmf-add-video-dialog h5, #wpmf-add-tag-dialog h5 {
font-size: 16px; font-size: 16px;
margin-bottom: 0 !important; margin-bottom: 0 !important;
} }
@@ -29,8 +72,8 @@
max-width: 600px; max-width: 600px;
} }
#wpmf-add-video-dialog_content { #tagcloud-wpmf_tag .wp-tag-cloud a {
max-width: 600px; font-size: 14px !important;
} }
.add_video_msg { .add_video_msg {

File diff suppressed because one or more lines are too long

View File

@@ -489,6 +489,21 @@ var wpmfFoldersTreeModule = void 0;
if ($(e.target).hasClass('wpmf-arrow') || $(e.target).hasClass('wpmf-tree-checkbox')) { if ($(e.target).hasClass('wpmf-arrow') || $(e.target).hasClass('wpmf-tree-checkbox')) {
return; return;
} }
// Set cookie filter tag
var this_url = new URL(location.href);
var get_taxonomy = this_url.searchParams.get("taxonomy");
var get_term = this_url.searchParams.get("term");
var get_wpmf_tag = this_url.searchParams.get("wpmf_tag");
var wpmf_tag = 0;
if ((get_taxonomy && get_term && get_taxonomy == 'wpmf_tag') || get_wpmf_tag) {
if (get_term) {
wpmf_tag = get_term;
}
if (get_wpmf_tag) {
wpmf_tag = get_wpmf_tag;
}
wpmfFoldersModule.setCookie('wpmf_tag', wpmf_tag, 365);
}
// single click // single click
var id = $(this).data('id'); var id = $(this).data('id');
if (parseInt(id) !== parseInt(wpmfFoldersModule.last_selected_folder)) { if (parseInt(id) !== parseInt(wpmfFoldersModule.last_selected_folder)) {

View File

@@ -5,6 +5,11 @@
*/ */
var wpmfFoldersFiltersModule = void 0; var wpmfFoldersFiltersModule = void 0;
(function ($) { (function ($) {
var this_url = new URL(location.href);
var get_taxonomy = this_url.searchParams.get("taxonomy");
var get_term = this_url.searchParams.get("term");
var get_wpmf_tag = this_url.searchParams.get("wpmf_tag");
var wpmf_tag = 0;
wpmfFoldersFiltersModule = { wpmfFoldersFiltersModule = {
events: [], // event handling events: [], // event handling
@@ -928,6 +933,17 @@ var wpmfFoldersFiltersModule = void 0;
* @param value * @param value
*/ */
selectFilter: function selectFilter(filter_elem, value) { selectFilter: function selectFilter(filter_elem, value) {
// Check filter tags
if ((get_taxonomy && get_term && get_taxonomy == 'wpmf_tag') || get_wpmf_tag) {
if (get_term) {
wpmf_tag = get_term;
}
if (get_wpmf_tag) {
wpmf_tag = get_wpmf_tag;
}
wpmfFoldersModule.setCookie('wpmf_tag', wpmf_tag, 365);
}
var multiple = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var multiple = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var selector = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; var selector = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
var query_param = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : ''; var query_param = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : '';
@@ -1187,6 +1203,9 @@ var wpmfFoldersFiltersModule = void 0;
* Clear all filters * Clear all filters
*/ */
clearFilters: function clearFilters() { clearFilters: function clearFilters() {
// delete cookie filter tag
wpmfFoldersModule.setCookie('wpmf_tag', '0');
$(['wpmf_post_mime_type', 'attachment-filter', 'wpmf_wpmf_date', 'wpmf_wpmf_size', 'wpmf_wpmf_weight', 'media-order-folder', 'media-order-media', 'wpmf-display-media-filters', 'wpmf_all_media']).each(function () { $(['wpmf_post_mime_type', 'attachment-filter', 'wpmf_wpmf_date', 'wpmf_wpmf_size', 'wpmf_wpmf_weight', 'media-order-folder', 'media-order-media', 'wpmf-display-media-filters', 'wpmf_all_media']).each(function () {
// delete cookie filter // delete cookie filter
wpmfFoldersModule.setCookie(this.toString() + wpmf.vars.host, 'all', 365); wpmfFoldersModule.setCookie(this.toString() + wpmf.vars.host, 'all', 365);
@@ -1223,6 +1242,10 @@ var wpmfFoldersFiltersModule = void 0;
wpmfFoldersModule.renderFolders(); wpmfFoldersModule.renderFolders();
// Reload the dropdown // Reload the dropdown
wpmfFoldersFiltersModule.initDropdown(wpmfFoldersModule.getFrame()); wpmfFoldersFiltersModule.initDropdown(wpmfFoldersModule.getFrame());
if (wpmfFoldersModule.page_type === 'upload-grid') {
wpmfFoldersModule.setCookie('wpmf_tag', '0');
location.href = wpmf.vars.site_url + '/wp-admin/upload.php';
}
}, },
/** /**
@@ -1283,4 +1306,38 @@ var wpmfFoldersFiltersModule = void 0;
wpmfFoldersModule.on('afterFiltersInitialization', function () { wpmfFoldersModule.on('afterFiltersInitialization', function () {
wpmfFoldersFiltersModule.initModule(wpmfFoldersModule.page_type); wpmfFoldersFiltersModule.initModule(wpmfFoldersModule.page_type);
}); });
jQuery(document).ready(function ($) {
if (get_wpmf_tag) {
wpmfFoldersModule.setCookie('lastAccessFolder_' + wpmf.vars.host, 0);
wpmfFoldersModule.setCookie('wpmf_all_media' + wpmf.vars.host, 1);
wpmfFoldersModule.setCookie('wpmf_tag', get_wpmf_tag, 365);
};
// Count tag button
var element_count_tag = $('#the-list .column-posts').attr('data-colname');
if (element_count_tag && element_count_tag.toLowerCase() == 'count') {
$('#the-list .column-posts a').on('click', function(e){
e.preventDefault();
let url = $(this).attr('href');
let url_array = url.split("=");
let wpmf_tag_array = null;
let wpmf_tag_filter = null;
if (url_array) {
wpmf_tag_array = url_array[1].split("&");
if (wpmf_tag_array) {
wpmf_tag_filter = wpmf_tag_array[0];
}
}
if (url) {
wpmfFoldersModule.setCookie('lastAccessFolder_' + wpmf.vars.host, 0);
wpmfFoldersModule.setCookie('wpmf_all_media' + wpmf.vars.host, 1);
if (wpmf_tag_filter) {
wpmfFoldersModule.setCookie('wpmf_tag', wpmf_tag_filter, 365);
}
location.href = url;
}
});
}
});
})(jQuery); })(jQuery);

View File

@@ -181,6 +181,125 @@ var wpmfFoldersModule = void 0,
$('.page-title-action').after('<a href="#" class="wpmf_btn_upload_folder">' + wpmf.l18n.upload_folder_label + '</a><input name="id_category" class="wpmf_id_category" type="hidden" value="0">'); $('.page-title-action').after('<a href="#" class="wpmf_btn_upload_folder">' + wpmf.l18n.upload_folder_label + '</a><input name="id_category" class="wpmf_id_category" type="hidden" value="0">');
} }
//Select tag for media
$('#doaction').on('click', function (e) {
var action = $('#bulk-action-selector-top').val();
if (wpmf.vars.wpmf_pagenow === 'upload.php' && action == 'tag') {
e.preventDefault();
//get list post id
var cboxes = document.getElementsByName('media[]');
var post_ids = [];
var len = cboxes.length;
if (cboxes !== 'undefined') {
for (var i=0; i<len; i++) {
if(cboxes[i].checked) {
post_ids.push(cboxes[i].value);
}
}
}
if (post_ids.length > 0) {
var html = "<p class='tag-note'>To select a tag, first choose one from the existing list. If the tag you need isn't there, you can create a new one.</p>";
html += '<input name="tags-outside" class="tagify--outside" value="" placeholder="Write tags to add below">';
//show tagify for tags
showDialog({
id: 'wpmf-add-tag-dialog',
title: wpmf.l18n.create_or_select_tag,
text: html,
negative: {
title: wpmf.l18n.cancel
},
positive: {
title: wpmf.l18n.add,
onClick: function onClick(e) {
var value = $('input[name=tags-outside]').val();
if (value) {
var array_value = JSON.parse(value);
var tag_name = [];
array_value.forEach(element => {
tag_name.push(element.value);
});
//save tag
if (tag_name.length) {
$.ajax({
method: "POST",
dataType: "json",
url: wpmf.vars.ajaxurl,
data: {
action: "wpmf",
task: "save_tag_item",
tag_name: tag_name,
post_ids: post_ids,
wpmf_nonce: wpmf.vars.wpmf_nonce
},
success: function success(response) {
if (response.status) {
window.location.reload();
} else {
console.log(response.status);
}
}
});
}
}
}
}
});
//set tagify
var input = document.querySelector('input[name=tags-outside]')
var tagify = new Tagify(input, {
focusable: false,
dropdown: {
position: 'input',
enabled: 0 // always opens dropdown when input gets focus
}
});
//get 10 tag items
$.ajax({
method: "POST",
dataType: "json",
url: wpmf.vars.ajaxurl,
data: {
action: "wpmf",
task: "get_tag_item",
wpmf_nonce: wpmf.vars.wpmf_nonce
},
success: function success(response) {
if (response.status) {
tagify.whitelist = response.list_tags; // update whitelist
}
}
});
//search tag
document.querySelector('.tagify__input').addEventListener("keyup", function (e) {
var tag_name = $(this).html();
if (tag_name.length > 1) {
$.ajax({
method: "POST",
dataType: "json",
url: wpmf.vars.ajaxurl,
data: {
action: "wpmf",
task: "get_tag_item",
tag_name : tag_name,
wpmf_nonce: wpmf.vars.wpmf_nonce
},
success: function success(response) {
if (response.status) {
tagify.whitelist = response.list_tags // update whitelist
}
}
});
}
});
} else {
showDialog({
text: wpmf.l18n.select_file_required,
closeicon: true
});
}
}
});
// add bulk upload to s3 button // add bulk upload to s3 button
if (parseInt(wpmf.vars.copy_files_to_bucket) === 1) { if (parseInt(wpmf.vars.copy_files_to_bucket) === 1) {
if (!$current_frame.find('.bulk-upload-s3-btn').length) { if (!$current_frame.find('.bulk-upload-s3-btn').length) {

File diff suppressed because one or more lines are too long

View File

@@ -116,7 +116,11 @@ class WpMediaFolder
add_filter('wp_insert_post_empty_content', array($this, 'disableSave'), 999999, 2); add_filter('wp_insert_post_empty_content', array($this, 'disableSave'), 999999, 2);
add_action('pre-upload-ui', array( $this, 'selectFolderUpload')); add_action('pre-upload-ui', array( $this, 'selectFolderUpload'));
add_filter('add_attachment', array($this, 'moveFileUploadToSelectFolder'), 0, 1); add_filter('add_attachment', array($this, 'moveFileUploadToSelectFolder'), 0, 1);
add_filter('bulk_actions-upload', array($this, 'registerTagBulkAction'), 10, 1);
add_action('wp_enqueue_media', array($this, 'removeDatabaseWhenCloudDisconnected')); add_action('wp_enqueue_media', array($this, 'removeDatabaseWhenCloudDisconnected'));
add_action('pre_get_posts', array($this, 'addTagFilter'), 10, 1);
add_filter('attachment_fields_to_edit', array($this, 'changeTagSlugToName'), 10, 2);
add_filter('attachment_fields_to_edit', array($this, 'addTagHelps'), 10, 2);
} }
/** /**
@@ -623,6 +627,12 @@ class WpMediaFolder
case 'auto_load_video_thumbnail': case 'auto_load_video_thumbnail':
$this->autoLoadVideoThumbnail(); $this->autoLoadVideoThumbnail();
break; break;
case 'get_tag_item':
$this->getTagItem();
break;
case 'save_tag_item':
$this->saveTagItem();
break;
} }
} }
} }
@@ -1174,6 +1184,13 @@ class WpMediaFolder
WPMF_VERSION WPMF_VERSION
); );
wp_enqueue_style(
'wpmf-tagify-style',
plugins_url('/assets/css/tagify.css', dirname(__FILE__)),
array(),
WPMF_VERSION
);
wp_enqueue_script( wp_enqueue_script(
'wpmf-gallery-popup', 'wpmf-gallery-popup',
plugins_url('/assets/js/display-gallery/jquery.magnific-popup.min.js', dirname(__FILE__)), plugins_url('/assets/js/display-gallery/jquery.magnific-popup.min.js', dirname(__FILE__)),
@@ -1199,6 +1216,15 @@ class WpMediaFolder
); );
} }
wp_register_script(
'wpmf-tagify',
plugins_url('/assets/js/tagify.js', dirname(__FILE__)),
array(),
WPMF_VERSION
);
wp_enqueue_script('wpmf-tagify');
wp_enqueue_script('resumable', plugins_url('/assets/js/resumable.js', dirname(__FILE__)), array('jquery'), WPMF_VERSION); wp_enqueue_script('resumable', plugins_url('/assets/js/resumable.js', dirname(__FILE__)), array('jquery'), WPMF_VERSION);
wp_register_script( wp_register_script(
'wpmf-base', 'wpmf-base',
@@ -1327,7 +1353,7 @@ class WpMediaFolder
*/ */
$wpmf_capability = apply_filters('wpmf_user_can', current_user_can('upload_files'), 'load_script_style'); $wpmf_capability = apply_filters('wpmf_user_can', current_user_can('upload_files'), 'load_script_style');
if ($wpmf_capability) { if ($wpmf_capability) {
if ($pagenow === 'upload.php') { if ($pagenow === 'upload.php' || $pagenow === 'edit-tags.php') {
$mode = get_user_option('media_library_mode', get_current_user_id()) ? get_user_option('media_library_mode', get_current_user_id()) : 'grid'; $mode = get_user_option('media_library_mode', get_current_user_id()) ? get_user_option('media_library_mode', get_current_user_id()) : 'grid';
if ($mode === 'list') { if ($mode === 'list') {
$this->loadAssets(); $this->loadAssets();
@@ -1591,6 +1617,14 @@ class WpMediaFolder
$enable_permissions_settings = ((isset($current_user->allcaps['wpmf_enable_permissions_settings']) && $current_user->allcaps['wpmf_enable_permissions_settings']) || in_array('administrator', $current_user->roles)); $enable_permissions_settings = ((isset($current_user->allcaps['wpmf_enable_permissions_settings']) && $current_user->allcaps['wpmf_enable_permissions_settings']) || in_array('administrator', $current_user->roles));
} }
$enable_all_files_button = in_array('administrator', $current_user->roles) || !$active_media_access ;
/**
* Filter to enable "Display all files" button for specific user roles
*
* @return boolean
*/
$show_all_files_button = apply_filters('wpmf_enable_all_files_button', $enable_all_files_button) ? 1 : 0;
$l18n = $this->translation(); $l18n = $this->translation();
$vars = array( $vars = array(
'site_url' => site_url(), 'site_url' => site_url(),
@@ -1660,7 +1694,7 @@ class WpMediaFolder
'img_url' => WPMF_PLUGIN_URL . 'assets/images/', 'img_url' => WPMF_PLUGIN_URL . 'assets/images/',
'copy_files_to_bucket' => (!empty($configs['copy_files_to_bucket']) && is_plugin_active('wp-media-folder-addon/wp-media-folder-addon.php')) ? 1 : 0, 'copy_files_to_bucket' => (!empty($configs['copy_files_to_bucket']) && is_plugin_active('wp-media-folder-addon/wp-media-folder-addon.php')) ? 1 : 0,
'hide_own_media_button' => current_user_can('wpmf_hide_own_media_button') ? 1 : 0, 'hide_own_media_button' => current_user_can('wpmf_hide_own_media_button') ? 1 : 0,
'show_all_files_button' => in_array('administrator', $current_user->roles) || !$active_media_access ? 1 : 0 'show_all_files_button' => $show_all_files_button
); );
return array('l18n' => $l18n, 'vars' => $vars); return array('l18n' => $l18n, 'vars' => $vars);
@@ -1755,6 +1789,9 @@ class WpMediaFolder
'wpmf_remove_filter' => __('Media filters removed', 'wpmf'), 'wpmf_remove_filter' => __('Media filters removed', 'wpmf'),
'cancel' => __('Cancel', 'wpmf'), 'cancel' => __('Cancel', 'wpmf'),
'create' => __('Create', 'wpmf'), 'create' => __('Create', 'wpmf'),
'add' => __('Add', 'wpmf'),
'add_tag' => __('Add tags', 'wpmf'),
'create_or_select_tag' => __('Create or select tags', 'wpmf'),
'save' => __('Save', 'wpmf'), 'save' => __('Save', 'wpmf'),
'save_close' => __('Save and close', 'wpmf'), 'save_close' => __('Save and close', 'wpmf'),
'ok' => __('OK', 'wpmf'), 'ok' => __('OK', 'wpmf'),
@@ -1966,7 +2003,8 @@ class WpMediaFolder
'by_user' => esc_html__('By User', 'wpmf'), 'by_user' => esc_html__('By User', 'wpmf'),
'remove_file_permission_msg' => esc_html__('You do not have permission to delete this file. Refresh folder to see image again', 'wpmf'), 'remove_file_permission_msg' => esc_html__('You do not have permission to delete this file. Refresh folder to see image again', 'wpmf'),
'remove_file_permission_msg1' => esc_html__('You do not have permission to delete this file', 'wpmf'), 'remove_file_permission_msg1' => esc_html__('You do not have permission to delete this file', 'wpmf'),
'update_file_permission_msg' => esc_html__('You do not have permission to update this file', 'wpmf') 'update_file_permission_msg' => esc_html__('You do not have permission to update this file', 'wpmf'),
'select_file_required' => esc_html__('Please select file to do this action', 'wpmf')
); );
return $l18n; return $l18n;
@@ -5813,6 +5851,72 @@ class WpMediaFolder
} }
} }
/**
* Add bulk select tag
*
* @param array $bulk_actions List bulk actions
*
* @return array
*/
public function registerTagBulkAction($bulk_actions)
{
$bulk_actions['tag'] = __('Add tags', 'wpmf');
return $bulk_actions;
}
/**
* Get list tags
*
* @return void
*/
public function getTagItem()
{
if (empty($_POST['wpmf_nonce'])
|| !wp_verify_nonce($_POST['wpmf_nonce'], 'wpmf_nonce')) {
die();
}
global $wpdb;
if (isset($_POST['tag_name']) && !empty($_POST['tag_name'])) {
$list_tags = $wpdb->get_results($wpdb->prepare('SELECT t.name FROM ' . $wpdb->terms . ' as t INNER JOIN ' . $wpdb->term_taxonomy . ' AS tt ON tt.term_id = t.term_id WHERE tt.taxonomy="wpmf_tag" AND t.name LIKE %s LIMIT %d', array('%' . $_POST['tag_name'] . '%',(int)10)));
} else {
$list_tags = $wpdb->get_results($wpdb->prepare('SELECT t.name FROM ' . $wpdb->terms . ' as t INNER JOIN ' . $wpdb->term_taxonomy . ' AS tt ON tt.term_id = t.term_id WHERE tt.taxonomy="wpmf_tag" ORDER BY RAND() LIMIT %d', array((int)10)));
}
if ($list_tags) {
$list_tags = array_column($list_tags, 'name');
wp_send_json(array('status' => true, 'list_tags' => $list_tags));
} else {
wp_send_json(array('status' => false));
}
}
/**
* Save tags
*
* @return void
*/
public function saveTagItem()
{
if (empty($_POST['wpmf_nonce'])
|| !wp_verify_nonce($_POST['wpmf_nonce'], 'wpmf_nonce')) {
die();
}
if (isset($_POST['tag_name']) && !empty($_POST['tag_name']) && isset($_POST['post_ids'])) {
foreach ($_POST['post_ids'] as $post_id) {
$old_terms = array();
$terms = wp_get_post_terms($post_id, 'wpmf_tag');
if ($terms) {
$old_terms = array_column($terms, 'name');
}
$new_term = array_unique(array_merge($_POST['tag_name'], $old_terms));
wp_set_post_terms($post_id, $new_term, 'wpmf_tag');
}
wp_send_json(array('status' => true));
}
wp_send_json(array('status' => false));
}
/** /**
* Delete files and folders information in database if cloud was disconnected * Delete files and folders information in database if cloud was disconnected
* *
@@ -5851,4 +5955,59 @@ class WpMediaFolder
$this->doRemoveFolders((int)$folder_next_cloud[0]->term_id); $this->doRemoveFolders((int)$folder_next_cloud[0]->term_id);
} }
} }
/**
* Add tag helps
*
* @param array $form_fields Array of post fields.
*
* @return array
*/
public function addTagHelps($form_fields)
{
$form_fields['wpmf_tag']['helps'] = 'Separate tags with commas';
return $form_fields;
}
/**
* Add tag filter
*
* @param object $query Query params.
*
* @return void
*/
public function addTagFilter($query)
{
$query->unset('wpmf_tag');
if (isset($_COOKIE['wpmf_tag']) && !empty($_COOKIE['wpmf_tag'])) {
$query->set('wpmf_tag', $_COOKIE['wpmf_tag']);
} else {
$query->unset('wpmf_tag');
}
}
/**
* Change value of tags from slug to name
*
* @param array $form_fields Form fields.
* @param object $post Post.
*
* @return array
*/
public function changeTagSlugToName($form_fields, $post)
{
global $wpdb;
$terms = $wpdb->get_results($wpdb->prepare('SELECT tr.object_id, t.name FROM ' . $wpdb->terms . ' as t INNER JOIN ' . $wpdb->term_taxonomy . ' as tt ON tt.term_id = t.term_id INNER JOIN ' . $wpdb->term_relationships . ' as tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy="wpmf_tag" AND tr.object_id = %s', array($post->ID)));
$values = array();
foreach ($terms as $term) {
$values[] = $term->name;
}
$form_fields['wpmf_tag']['value'] = implode(', ', $values);
return $form_fields;
}
} }

View File

@@ -72,15 +72,25 @@ class WpmfGalleryAddonDivi extends ET_Builder_Module
) )
); );
if (count($galleries) < 100) {
$galleries = wpmfParentSort($galleries); $galleries = wpmfParentSort($galleries);
$term_ids = array();
foreach ($galleries as $gallery) {
$term_ids[] = (int)$gallery->term_id;
}
$galleries_types = array();
if (file_exists(WPMF_GALLERY_ADDON_PLUGIN_DIR . 'admin/class/helper.php')) {
require_once WPMF_GALLERY_ADDON_PLUGIN_DIR . 'admin/class/helper.php';
$WpmfGlrAddonHelper = new WpmfGlrAddonHelper();
$galleries_types = $WpmfGlrAddonHelper->getGalleriesType($term_ids);
} }
$galleries_list = array(); $galleries_list = array();
$galleries_list[0] = esc_html__('WP Media Folder Gallery', 'wpmf'); $galleries_list[0] = esc_html__('WP Media Folder Gallery', 'wpmf');
$i = 0; $i = 0;
foreach ($galleries as $gallery) { foreach ($galleries as $gallery) {
$gallery_type = get_term_meta((int)$gallery->term_id, 'gallery_type', true); $gallery_type = isset($galleries_types[(int)$gallery->term_id])? $galleries_types[(int)$gallery->term_id] : '' ;
if (!empty($gallery_type) && ($gallery_type === 'photographer' || $gallery_type === 'archive')) { if (!empty($gallery_type) && ($gallery_type === 'photographer' || $gallery_type === 'archive')) {
continue; continue;
} }
@@ -89,13 +99,14 @@ class WpmfGalleryAddonDivi extends ET_Builder_Module
$i++; $i++;
} }
//List photographer galleries
$root = get_term_by('slug', 'photographer-gallery', WPMF_GALLERY_ADDON_TAXO);
foreach ($galleries as $gallery) { foreach ($galleries as $gallery) {
$gallery_type = get_term_meta((int)$gallery->term_id, 'gallery_type', true); $gallery_type = isset($galleries_types[(int)$gallery->term_id])? $galleries_types[(int)$gallery->term_id] : '' ;
if (!empty($gallery_type) && $gallery_type === 'archive') { if (!empty($gallery_type) && $gallery_type === 'archive') {
continue; continue;
} }
if (!empty($gallery_type) && $gallery_type === 'photographer') { if (!empty($gallery_type) && $gallery_type === 'photographer') {
$root = get_term_by('slug', 'photographer-gallery', WPMF_GALLERY_ADDON_TAXO);
if ((int)$root->term_id === (int)$gallery->term_id) { if ((int)$root->term_id === (int)$gallery->term_id) {
$galleries_list[$i . '-' . $gallery->term_id] = esc_html__('Photographer Gallery', 'wpmf'); $galleries_list[$i . '-' . $gallery->term_id] = esc_html__('Photographer Gallery', 'wpmf');
} else { } else {

View File

@@ -3,7 +3,7 @@ Tags: media, folder
Requires at least: 4.7.0 Requires at least: 4.7.0
Tested up to: 6.6 Tested up to: 6.6
Requires PHP: 5.6 Requires PHP: 5.6
Stable tag: 5.9.7 Stable tag: 5.9.8
License: GPLv2 or later License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -20,6 +20,11 @@ Stop searching for an image through thousand of media, just navigate like you do
= Changelog = = Changelog =
= 5.9.8 =
* Add : Create tags: Possibility to create tags for media files
* Add : Bulk add tags: You can add tags to multiple media files at once.
* Add : Filter by tag: Filter your media files by tag
= 5.9.7 = = 5.9.7 =
* Fix : Error while using Elementor theme builder * Fix : Error while using Elementor theme builder
@@ -125,7 +130,7 @@ Stop searching for an image through thousand of media, just navigate like you do
= 5.6.0 = = 5.6.0 =
* Add : Download a folder in the media library using right click * Add : Download a folder in the media library using right click
* Add : Folder bulk selet and remove in folder tree * Add : Folder bulk select and remove in folder tree
* Add : New uploader styling and notifications * Add : New uploader styling and notifications
* Add : Media download button in block editor improvement * Add : Media download button in block editor improvement
* Fix : Single file download style * Fix : Single file download style

View File

@@ -4,7 +4,7 @@
Plugin URI: http://www.joomunited.com Plugin URI: http://www.joomunited.com
Description: WP media Folder is a WordPress plugin that enhance the WordPress media manager by adding a folder manager inside. Description: WP media Folder is a WordPress plugin that enhance the WordPress media manager by adding a folder manager inside.
Author: Joomunited Author: Joomunited
Version: 5.9.7 Version: 5.9.8
Update URI: https://www.joomunited.com/juupdater_files/wp-media-folder.json Update URI: https://www.joomunited.com/juupdater_files/wp-media-folder.json
Author URI: http://www.joomunited.com Author URI: http://www.joomunited.com
Text Domain: wpmf Text Domain: wpmf
@@ -79,7 +79,7 @@ if (!defined('WPMF_TAXO')) {
define('_WPMF_GALLERY_PREFIX', '_wpmf_gallery_'); define('_WPMF_GALLERY_PREFIX', '_wpmf_gallery_');
define('WPMF_PLUGIN_URL', plugin_dir_url(__FILE__)); define('WPMF_PLUGIN_URL', plugin_dir_url(__FILE__));
define('WPMF_DOMAIN', 'wpmf'); define('WPMF_DOMAIN', 'wpmf');
define('WPMF_VERSION', '5.9.7'); define('WPMF_VERSION', '5.9.8');
define('WPMF_HIDE_USER_MEDIA_FOLDER_ROOT', true); define('WPMF_HIDE_USER_MEDIA_FOLDER_ROOT', true);
include_once(ABSPATH . 'wp-admin/includes/plugin.php'); include_once(ABSPATH . 'wp-admin/includes/plugin.php');
@@ -472,98 +472,20 @@ function wpmfUnInstall()
global $wpdb; global $wpdb;
$wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'wpmf_s3_queue'); $wpdb->query('DROP TABLE IF EXISTS ' . $wpdb->prefix . 'wpmf_s3_queue');
// delete option // delete all options with prefix 'wpmf_';
$wpdb->query('DELETE FROM '.$wpdb->options. " WHERE option_name LIKE '%wpmf_%'");
// delete all options with prefix '_wpmfAddon_';
$wpdb->query('DELETE FROM '.$wpdb->options. " WHERE option_name LIKE '%_wpmfAddon_%'");
// delete other options
$options_list = array( $options_list = array(
'wpmf_addon_version', '_wpmf_import_notice_flag',
'wpmf_folder_root_id',
'wpmf_update_count',
'wpmf_version',
'wpmf_gallery_image_size_value',
'wpmf_padding_masonry',
'wpmf_padding_portfolio',
'wpmf_usegellery',
'wpmf_useorder',
'wpmf_create_folder',
'wpmf_option_override',
'wpmf_option_duplicate',
'wpmf_active_media',
'wpmf_folder_option2',
'wpmf_usegellery_lightbox',
'wpmf_media_rename',
'wpmf_patern_rename',
'wpmf_rename_number',
'wpmf_option_media_remove',
'wpmf_default_dimension',
'wpmf_selected_dimension',
'wpmf_weight_default',
'wpmf_weight_selected',
'wpmf_color_singlefile',
'wpmf_option_singlefile',
'wpmf_option_sync_media',
'wpmf_option_sync_media_external',
'wpmf_list_sync_media',
'wpmf_time_sync',
'wpmf_lastRun_sync',
'wpmf_slider_animation',
'wpmf_option_mediafolder',
'wpmf_option_countfiles',
'wpmf_option_lightboximage',
'wpmf_option_hoverimg',
'wpmf_options_format_title',
'wpmf_image_watermark_apply',
'wpmf_option_image_watermark',
'wpmf_watermark_position',
'wpmf_watermark_image',
'wpmf_watermark_image_id',
'wpmf_gallery_settings',
'_wpmf_import_order_notice_flag', '_wpmf_import_order_notice_flag',
'_wpmfAddon_cloud_config', '_wpmf_import_size_notice_flag',
'_wpmfAddon_dropbox_config', '_wpmf_activation_redirect',
'wpmf_onedrive_business',
'_wpmfAddon_aws3_config',
'wpmf_gallery_img_per_page',
'wpmfgrl_relationships_media', 'wpmfgrl_relationships_media',
'wpmfgrl_relationships', 'wpmfgrl_relationships',
'wpmf_galleries', 'wp-media-folder-addon-tables'
'wpmf_import_nextgen_gallery',
'wpmf_onedrive_business_files',
'wpmf_odv_business_files',
'wpmf_odv_allfiles',
'wpmf_google_folders',
'wpmf_google_allfiles',
'wpmf_dropbox_allfiles',
'wpmf_dropbox_folders',
'wpmf_odv_folders',
'wpmf_odv_business_folders',
'wpmf_odv_business_allfiles',
'_wpmfAddon_onedrive_business_config',
'wpmf_onedrive_notice',
'_wpmfAddon_onedrive_config',
'wpmf_google_folder_id',
'wpmf_dropbox_folder_id',
'wpmf_odv_business_folder_id',
'wpmf_odv_folder_id',
'wpmf_cloud_connection_notice',
'wp-media-folder-addon-tables',
'_wpmf_activation_redirect',
'wpmf_use_taxonomy',
'wpmf_cloud_time_last_sync',
'wpmf_dropbox_attachments',
'wpmf_dropbox_folders',
'wpmf_dropbox_allfiles',
'wpmf_google_attachments',
'wpmf_google_folders',
'wpmf_google_allfiles',
'wpmf_odv_attachments',
'wpmf_odv_folders',
'wpmf_odv_allfiles',
'wpmf_odv_business_attachments',
'wpmf_odv_business_folders',
'wpmf_odv_business_allfiles',
'wpmf_cloud_name_syncing',
'wpmf_ftp_sync_time',
'wpmf_ftp_sync_token',
'wpmf_settings'
); );
foreach ($options_list as $option) { foreach ($options_list as $option) {
@@ -2027,3 +1949,42 @@ function wpmfDownloadFile()
} }
} }
} }
/* Register wpmf_tag taxonomy */
add_action('init', 'wpmfTagRegisterTaxonomy', 0);
/**
* Register gallery taxonomy
*
* @return void
*/
function wpmfTagRegisterTaxonomy()
{
if (!taxonomy_exists('wpmf_tag')) {
register_taxonomy(
'wpmf_tag',
'attachment',
array(
'hierarchical' => false,
'show_in_nav_menus' => false,
'show_admin_column' => true,
'show_ui' => true,
'public' => true,
'update_count_callback' => '_update_generic_term_count',
'labels' => array(
'name' => __('Tags', 'wpmf'),
'singular_name' => __('Tags', 'wpmf'),
'menu_name' => __('Media Folder Tags', 'wpmf'),
'all_items' => __('All Tags', 'wpmf'),
'edit_item' => __('Edit Tag', 'wpmf'),
'view_item' => __('View Tag', 'wpmf'),
'update_item' => __('Update Tag', 'wpmf'),
'add_new_item' => __('Add New Tag', 'wpmf'),
'new_item_name' => __('New Tag Name', 'wpmf'),
'parent_item' => __('Parent Tag', 'wpmf'),
'parent_item_colon' => __('Parent Tag:', 'wpmf'),
'search_items' => __('Search Tag', 'wpmf'),
)
)
);
}
}