diff --git a/includes/class-pp-dependencies.php b/includes/class-pp-dependencies.php index 0d766bf..64e079d 100755 --- a/includes/class-pp-dependencies.php +++ b/includes/class-pp-dependencies.php @@ -2,194 +2,192 @@ if ( ! class_exists( 'PP_Dependencies' ) ) : -/** - * Prospress Dependency Checker - * - * Checks if WooCommerce and Subscriptions are enabled - */ -class PP_Dependencies { + /** + * Prospress Dependency Checker + * + * Checks if WooCommerce and Subscriptions are enabled + */ + class PP_Dependencies { - protected static $admin_notices = array(); + protected static $admin_notices = array(); - protected static $plugin_filenames = array(); + protected static $plugin_filenames = array(); - public static function init() { - add_action( 'admin_notices', __CLASS__ . '::maybe_display_admin_notices' ); - } + public static function init() { + add_action( 'admin_notices', __CLASS__ . '::maybe_display_admin_notices' ); + } - /** API Functions **/ + /** API Functions **/ - /** - * Check if the if the WooCommerce plugin is installed and active. - * - * @since 1.0.0 - * @return boolean - */ - public static function is_woocommerce_active( $minimum_version = false ) { - return self::is_plugin_active( 'woocommerce.php', $minimum_version, 'woocommerce_db_version' ); - } + /** + * Check if the if the WooCommerce plugin is installed and active. + * + * @since 1.0.0 + * @return boolean + */ + public static function is_woocommerce_active( $minimum_version = false ) { + return self::is_plugin_active( 'woocommerce.php', $minimum_version, 'woocommerce_db_version' ); + } - /** - * Check if the if the WooCommerce Subscriptions plugin is installed and active. - * - * @since 1.0.0 - * @return boolean - */ - public static function is_subscriptions_active( $minimum_version = false ) { - return self::is_plugin_active( 'woocommerce-subscriptions.php', $minimum_version, 'woocommerce_subscriptions_active_version' ); - } + /** + * Check if the if the WooCommerce Subscriptions plugin is installed and active. + * + * @since 1.0.0 + * @return boolean + */ + public static function is_subscriptions_active( $minimum_version = false ) { + return self::is_plugin_active( 'woocommerce-subscriptions.php', $minimum_version, 'woocommerce_subscriptions_active_version' ); + } - /** Admin Notices **/ + /** Admin Notices **/ - /** - * Display any admin notices about plugin dependency failures to admins in the admin area. - * - * @since 1.0.0 - */ - public static function maybe_display_admin_notices() { - if ( ! empty( self::$admin_notices ) && current_user_can( 'activate_plugins' ) ) { - foreach ( self::$admin_notices as $admin_notice ) { ?> + /** + * Display any admin notices about plugin dependency failures to admins in the admin area. + * + * @since 1.0.0 + */ + public static function maybe_display_admin_notices() { + if ( ! empty( self::$admin_notices ) && current_user_can( 'activate_plugins' ) ) { + foreach ( self::$admin_notices as $admin_notice ) { ?>
-

+ ' . esc_html( $admin_notice['plugin_name'] ) . '', esc_html( $admin_notice['dependency_name'] ), esc_html( $admin_notice['version_dependency'] ), '', '' ); } else { // translators: 1$-2$: opening and closing tags, 3$ plugin name, 4$ required plugin version, 5$-6$: opening and closing link tags, leads to plugins.php in admin - printf( esc_html( '%1$s is inactive. %1$s requires %2$s to work correctly. %3$sPlease install or activate %2$s »%4$s' ), '' . esc_html( $admin_notice['plugin_name'] ) . '', esc_html( $admin_notice['dependency_name'] ) , '', '' ); - } ?> + printf( esc_html( '%1$s is inactive. %1$s requires %2$s to work correctly. %3$sPlease install or activate %2$s »%4$s' ), '' . esc_html( $admin_notice['plugin_name'] ) . '', esc_html( $admin_notice['dependency_name'] ), '', '' ); + } + ?>

- $plugin_name, - 'dependency_name' => $dependency_name, - 'version_dependency' => $version_dependency, - ); - } + /** + * Queue an admin notice about a plugin dependency failure. + * + * Not passed through i18n functions because we cant use a dynamic text domain. + * + * @since 1.0.0 + * @param string $plugin_name The name displayed to the store owner to identify the plugin requiring another plugin. + * @param string $dependency_name The required plugin that is not active, as displayed to the store owner. + * @param bool|string $version_dependency The minimum version of the plugin required, if any. + * @return boolean true if the named plugin is installed and active + */ + public static function enqueue_admin_notice( $plugin_name, $dependency_name, $version_dependency = false ) { + self::$admin_notices[] = array( + 'plugin_name' => $plugin_name, + 'dependency_name' => $dependency_name, + 'version_dependency' => $version_dependency, + ); + } - /** Helper functions **/ + /** Helper functions **/ - /** - * Helper function to determine whether a plugin is active in the most reliably way possible. - * - * Based on SkyVerge's WooCommerce Plugin Framework - SV_WC_Plugin class. - * - * @since 1.0.0 - * @param string $plugin_name plugin name, as the plugin-filename.php - * @param string $minimum_version (optional) Check if the plugin is active that a certain minimum version is also active. - * @param string $version_option_name (optional) The key used to identify the plugin's active version in the wp_options table. - * @return boolean true if the named plugin is installed and active - */ - protected static function is_plugin_active( $plugin_name, $minimum_version = false, $version_option_name = '' ) { + /** + * Helper function to determine whether a plugin is active in the most reliably way possible. + * + * Based on SkyVerge's WooCommerce Plugin Framework - SV_WC_Plugin class. + * + * @since 1.0.0 + * @param string $plugin_name plugin name, as the plugin-filename.php + * @param string $minimum_version (optional) Check if the plugin is active that a certain minimum version is also active. + * @param string $version_option_name (optional) The key used to identify the plugin's active version in the wp_options table. + * @return boolean true if the named plugin is installed and active + */ + protected static function is_plugin_active( $plugin_name, $minimum_version = false, $version_option_name = '' ) { - if ( empty( self::$plugin_filenames ) ) { + if ( empty( self::$plugin_filenames ) ) { - $active_plugins = (array) get_option( 'active_plugins', array() ); + $active_plugins = (array) get_option( 'active_plugins', array() ); - if ( is_multisite() ) { - $active_plugins = array_merge( $active_plugins, array_keys( get_site_option( 'active_sitewide_plugins', array() ) ) ); - } + if ( is_multisite() ) { + $active_plugins = array_merge( $active_plugins, array_keys( get_site_option( 'active_sitewide_plugins', array() ) ) ); + } - foreach ( $active_plugins as $plugin ) { + foreach ( $active_plugins as $plugin ) { - if ( self::str_exists( $plugin, '/' ) ) { + if ( self::str_exists( $plugin, '/' ) ) { - // normal plugin name (plugin-dir/plugin-filename.php) - list( , $filename ) = explode( '/', $plugin ); + // normal plugin name (plugin-dir/plugin-filename.php) + list( , $filename ) = explode( '/', $plugin ); - } else { + } else { - // no directory, just plugin file - $filename = $plugin; + // no directory, just plugin file + $filename = $plugin; - } + } - self::$plugin_filenames[] = $filename; + self::$plugin_filenames[] = $filename; + } } - } - $is_plugin_active = in_array( $plugin_name, self::$plugin_filenames ); + $is_plugin_active = in_array( $plugin_name, self::$plugin_filenames, true ); - if ( $minimum_version ) { - return $is_plugin_active && version_compare( get_option( $version_option_name ), $minimum_version, '>=' ); - } else { - return $is_plugin_active; + if ( $minimum_version ) { + return $is_plugin_active && version_compare( get_option( $version_option_name ), $minimum_version, '>=' ); + } else { + return $is_plugin_active; + } } - } - - /** - * Returns true if the needle exists in haystack - * - * Note: case-sensitive - * - * Based on SkyVerge's WooCommerce Plugin Framework - SV_WC_Helper class. - * - * @since 1.0.0 - * @param string $haystack - * @param string $needle - * @return bool - */ - protected static function str_exists( $haystack, $needle ) { - if ( extension_loaded( 'mbstring' ) ) { + /** + * Returns true if the needle exists in haystack + * + * Note: case-sensitive + * + * Based on SkyVerge's WooCommerce Plugin Framework - SV_WC_Helper class. + * + * @since 1.0.0 + * @param string $haystack + * @param string $needle + * @return bool + */ + protected static function str_exists( $haystack, $needle ) { + + if ( extension_loaded( 'mbstring' ) ) { + + if ( '' === $needle ) { + return false; + } - if ( '' === $needle ) { - return false; - } + return false !== mb_strpos( $haystack, $needle, 0, 'UTF-8' ); - return false !== mb_strpos( $haystack, $needle, 0, 'UTF-8' ); + } else { - } else { + $needle = self::str_to_ascii( $needle ); - $needle = self::str_to_ascii( $needle ); + if ( '' === $needle ) { + return false; + } - if ( '' === $needle ) { - return false; + return false !== strpos( self::str_to_ascii( $haystack ), self::str_to_ascii( $needle ) ); } - - return false !== strpos( self::str_to_ascii( $haystack ), self::str_to_ascii( $needle ) ); } - } - /** - * Returns a string with all non-ASCII characters removed. This is useful - * for any string functions that expect only ASCII chars and can't - * safely handle UTF-8. Note this only allows ASCII chars in the range - * 33-126 (newlines/carriage returns are stripped) - * - * Based on SkyVerge's WooCommerce Plugin Framework - SV_WC_Helper class. - * - * @since 1.0.0 - * @param string $string string to make ASCII - * @return string - */ - protected static function str_to_ascii( $string ) { - - // strip ASCII chars 32 and under - $string = filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW ); + /** + * Returns a string with all non-ASCII characters removed. This is useful + * for any string functions that expect only ASCII chars and can't + * safely handle UTF-8. + * + * @since 1.0.0 + * @param string $string string to make ASCII + * @return string + */ + protected static function str_to_ascii( $string ) { + // Remove non-ASCII characters + $string = preg_replace( '/[^\x20-\x7E]/', '', $string ); + + // Return the cleaned string + return $string; + } - // strip ASCII chars 127 and higher - return filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH ); } -} - -PP_Dependencies::init(); + PP_Dependencies::init(); -endif; \ No newline at end of file +endif; diff --git a/woocommerce-subscriptions-custom-pricestring.php b/woocommerce-subscriptions-custom-pricestring.php index d961ea0..56e7058 100755 --- a/woocommerce-subscriptions-custom-pricestring.php +++ b/woocommerce-subscriptions-custom-pricestring.php @@ -1,20 +1,17 @@ . * * @package WooCommerce Subscriptions - Custom Price String - * @author Prospress Inc. + * @author WooCommerce * @since 1.0 */ - /* -TODO: -- Should the custom price string for simple/variable products (not subscriptions) be displayed on the cart page too? -- Check the scope of the custom strings (product page, cart, checkout, emails, backend, orders, renewals, etc) -*/ +/* + TODO: + - Should the custom price string for simple/variable products (not subscriptions) be displayed on the cart page too? + - Check the scope of the custom strings (product page, cart, checkout, emails, backend, orders, renewals, etc) + */ // add_filter("woocommerce_subscription_price_string", "wcs_custom_price_strings_cart", 10, 2); +// Declare HPOS compat per https://github.com/woocommerce/woocommerce/wiki/High-Performance-Order-Storage-Upgrade-Recipe-Book#declaring-extension-incompatibility +add_action( 'before_woocommerce_init', function() { + if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { + \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true ); + } +} ); require_once 'includes/class-pp-dependencies.php'; @@ -79,7 +82,13 @@ function wcs_cps_admin_field() { if ( 'subscription' === $p_type || 'variable-subscription' === $p_type ) { $price = WC_Subscriptions_Product::get_price( $product ); $custom_price_string = WC_Subscriptions_Product::get_price_string( $post->ID, array( 'price' => $price ) ); - $original_price_string = WC_Subscriptions_Product::get_price_string( $post->ID, array( 'price' => $price, 'custom' => false ) ); + $original_price_string = WC_Subscriptions_Product::get_price_string( + $post->ID, + array( + 'price' => $price, + 'custom' => false, + ) + ); } else { $original_price_string = $product->get_price(); $custom_price_string = get_post_meta( $post->ID, '_custom_price_string', true ); @@ -121,10 +130,16 @@ function wcs_cps_variation_admin_field( $loop, $variation_data, $variation ) { if ( 'variable-subscription' === $wc_variation->get_type() ) { $custom_price_string = WC_Subscriptions_Product::get_price_string( ( $variation->ID ), array( 'price' => $price ) ); - $original_price_string = WC_Subscriptions_Product::get_price_string( ( $variation->ID ), array( 'price' => $price, 'custom' => false ) ); + $original_price_string = WC_Subscriptions_Product::get_price_string( + ( $variation->ID ), + array( + 'price' => $price, + 'custom' => false, + ) + ); } else { $original_price_string = $wc_variation->get_price(); - $custom_price_string = get_post_meta( $variation->ID, '_custom_price_string', true ); + $custom_price_string = get_post_meta( $variation->ID, '_custom_price_string', true ); } if ( $original_price_string === $custom_price_string ) { @@ -196,7 +211,7 @@ function wcs_cps_from_field() { * @return string $price_string_value */ function strip_tags_of_custom_price_value( $price_string_value ) { - return strip_tags( $price_string_value ); + return wp_strip_all_tags( $price_string_value ); } add_filter( 'wcs_custom_price_string_value', 'strip_tags_of_custom_price_value', 10, 1 ); @@ -312,7 +327,7 @@ function wcs_cps_from_string( $price, $product ) { 'booking', ); - if ( in_array( $product->get_type(), $target_product_types ) ) { + if ( in_array( $product->get_type(), $target_product_types, true ) ) { $custom_from_string = get_post_meta( $product->get_id(), '_custom_from_string', true ); if ( '' !== $custom_from_string ) { $price = $custom_from_string;