Initial Commit
This commit is contained in:
32
inc/compat/class-as-admin-view.php
Normal file
32
inc/compat/class-as-admin-view.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* Replaces the AS Admin View page to hide it on sub-sites.
|
||||
*
|
||||
* @see inc/admin-pages/class-jobs-list-admin-page.php
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Compat
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Replaces the admin view class with an empty shell.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class AS_Admin_View {
|
||||
|
||||
/**
|
||||
* Empty initialization.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return void
|
||||
*/
|
||||
public function init() {} // end init;
|
||||
|
||||
} // end class AS_Admin_View;
|
89
inc/compat/class-discount-code-compat.php
Normal file
89
inc/compat/class-discount-code-compat.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* Discount Code Compatibility Layer
|
||||
*
|
||||
* Handles discount code compatibility back-ports to WP Ultimo 1.X builds.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Compat/Discount_Code_Compat
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Handles discount code compatibility back-ports to WP Ultimo 1.X builds.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Discount_Code_Compat {
|
||||
|
||||
use \WP_Ultimo\Traits\Singleton;
|
||||
|
||||
/**
|
||||
* Instantiate the necessary hooks.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
add_filter('update_post_metadata', array($this, 'check_update_coupon'), 10, 5);
|
||||
|
||||
} // end init;
|
||||
|
||||
/**
|
||||
* Saves meta data from old plugins on the new plugin.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param null $null Short-circuit control.
|
||||
* @param int $object_id Object ID, in this case, of the Post object.
|
||||
* @param string $meta_key The meta key being saved.
|
||||
* @param mixed $meta_value The meta value.
|
||||
* @param mixed $prev_value The previous value.
|
||||
* @return null
|
||||
*/
|
||||
public function check_update_coupon($null, $object_id, $meta_key, $meta_value, $prev_value) {
|
||||
/*
|
||||
* Check if we are in the main site of the network.
|
||||
*/
|
||||
if (!is_main_site()) {
|
||||
|
||||
return;
|
||||
|
||||
} // end if;
|
||||
|
||||
/*
|
||||
* Check if we have a new entity with this ID.
|
||||
*/
|
||||
$migrated_discount_code = wu_get_discount_code($object_id);
|
||||
|
||||
if (!$migrated_discount_code) {
|
||||
|
||||
return;
|
||||
|
||||
} // end if;
|
||||
|
||||
/*
|
||||
* Prevent double prefixing.
|
||||
*/
|
||||
$meta_key = str_replace('wpu_', '', $meta_key);
|
||||
|
||||
/*
|
||||
* Save using the new meta table.
|
||||
*/
|
||||
$migrated_discount_code->update_meta('wpu_' . $meta_key, maybe_serialize($meta_value));
|
||||
|
||||
/**
|
||||
* Explicitly returns null so we don't forget that
|
||||
* returning anything else will prevent meta data from being saved.
|
||||
*/
|
||||
return null;
|
||||
|
||||
} // end check_update_coupon;
|
||||
|
||||
} // end class Discount_Code_Compat;
|
36
inc/compat/class-domain-mapping-compat.php
Normal file
36
inc/compat/class-domain-mapping-compat.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* General Compatibility Layer
|
||||
*
|
||||
* Handles General Support
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Compat/Domain_Mapping_Compat
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Handles General Support
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Domain_Mapping_Compat {
|
||||
|
||||
use \WP_Ultimo\Traits\Singleton;
|
||||
|
||||
/**
|
||||
* Instantiate the necessary hooks.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
} // end init;
|
||||
|
||||
} // end class Domain_Mapping_Compat;
|
112
inc/compat/class-elementor-compat.php
Normal file
112
inc/compat/class-elementor-compat.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* Elementor Compatibility Layer
|
||||
*
|
||||
* Handles Elementor Support
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Compat/Elementor_Compat
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Handles Elementor Support
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Elementor_Compat {
|
||||
|
||||
use \WP_Ultimo\Traits\Singleton;
|
||||
|
||||
/**
|
||||
* Instantiate the necessary hooks.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
add_action('wu_duplicate_site', array($this, 'regenerate_css'));
|
||||
|
||||
add_filter('wu_should_redirect_to_primary_domain', array($this, 'maybe_prevent_redirection'));
|
||||
|
||||
add_action('elementor/widget/shortcode/skins_init', array($this, 'maybe_setup_preview'));
|
||||
|
||||
} // end init;
|
||||
|
||||
/**
|
||||
* Makes sure we force elementor to regenerate the styles when necessary.
|
||||
*
|
||||
* @since 1.10.10
|
||||
* @param array $site Info about the duplicated site.
|
||||
* @return void
|
||||
*/
|
||||
public function regenerate_css($site) {
|
||||
|
||||
if (!class_exists('\Elementor\Plugin')) {
|
||||
|
||||
return;
|
||||
|
||||
} // end if;
|
||||
|
||||
if (!isset($site['site_id'])) {
|
||||
|
||||
return;
|
||||
|
||||
} // end if;
|
||||
|
||||
switch_to_blog($site['site_id']);
|
||||
|
||||
$file_manager = \Elementor\Plugin::$instance->files_manager; // phpcs:ignore
|
||||
|
||||
if (!empty($file_manager)) {
|
||||
|
||||
$file_manager->clear_cache();
|
||||
|
||||
} // end if;
|
||||
|
||||
restore_current_blog();
|
||||
|
||||
} // end regenerate_css;
|
||||
|
||||
/**
|
||||
* Prevents redirection to primary domain when in Elementor preview mode.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param bool $should_redirect If we should redirect or not.
|
||||
* @return bool
|
||||
*/
|
||||
public function maybe_prevent_redirection($should_redirect) {
|
||||
|
||||
return wu_request('elementor-preview', false) === false ? $should_redirect : false;
|
||||
|
||||
} // end maybe_prevent_redirection;
|
||||
|
||||
/**
|
||||
* Maybe adds the setup preview for elements inside elementor.
|
||||
*
|
||||
* @since 2.0.5
|
||||
* @return void
|
||||
*/
|
||||
public function maybe_setup_preview() {
|
||||
|
||||
$elementor_actions = array(
|
||||
'elementor',
|
||||
'elementor_ajax',
|
||||
);
|
||||
|
||||
if (in_array(wu_request('action'), $elementor_actions, true)) {
|
||||
|
||||
wu_element_setup_preview();
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end maybe_setup_preview;
|
||||
|
||||
} // end class Elementor_Compat;
|
612
inc/compat/class-general-compat.php
Normal file
612
inc/compat/class-general-compat.php
Normal file
@ -0,0 +1,612 @@
|
||||
<?php
|
||||
/**
|
||||
* General Compatibility Layer
|
||||
*
|
||||
* Handles General Support
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Compat/General_Compat
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Handles General Support
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class General_Compat {
|
||||
|
||||
use \WP_Ultimo\Traits\Singleton;
|
||||
|
||||
/**
|
||||
* Instantiate the necessary hooks.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
/**
|
||||
* Woocommerce
|
||||
*
|
||||
* Removes the default woocommerce hook on switch_blog to another more performant
|
||||
*
|
||||
* @see https://wordpress.org/plugins/woocommerce/
|
||||
*/
|
||||
add_action('woocommerce_loaded', array($this, 'replace_wc_wpdb_table_fix'));
|
||||
|
||||
/**
|
||||
* WP Typography.
|
||||
*
|
||||
* @see https://de.wordpress.org/plugins/wp-typography/
|
||||
*/
|
||||
add_action('load-settings_page_wp-typography', array($this, 'add_wp_typography_warning_message'));
|
||||
|
||||
add_filter('typo_settings', array($this, 'fix_wp_typography'));
|
||||
|
||||
/**
|
||||
* Brizy Page Builder.
|
||||
*
|
||||
* @see https://wordpress.org/plugins/brizy/
|
||||
*/
|
||||
add_filter('wu_append_preview_parameter', array($this, 'fix_brizy_preview_url'));
|
||||
|
||||
add_filter('wu_should_redirect_to_primary_domain', array($this, 'fix_brizy_editor_screen'));
|
||||
|
||||
/**
|
||||
* Divi Page Builder.
|
||||
*
|
||||
* @see https://www.elegantthemes.com/
|
||||
*/
|
||||
add_filter('wu_should_redirect_to_primary_domain', array($this, 'fix_divi_editor_screen'));
|
||||
|
||||
/**
|
||||
* WP Hide Pro
|
||||
*
|
||||
* @see https://wp-hide.com/
|
||||
*/
|
||||
add_filter('wu_append_preview_parameter', array($this, 'fix_wp_hide_preview_url'));
|
||||
|
||||
/**
|
||||
* Frontend Admin.
|
||||
*
|
||||
* @see https://wpfrontendadmin.com/
|
||||
*/
|
||||
add_filter('wp_frontend_admin/shortcode/admin_page_final_url', array($this, 'fix_frontend_admin_loading_url'), 10, 3);
|
||||
|
||||
/**
|
||||
* Oxygen Builder.
|
||||
*
|
||||
* 1. Handles content parsing to decide if we should load our elements;
|
||||
* 2. Prevent Oxygen from removing all the wp_head hooks on the template preview page;
|
||||
*
|
||||
* @see https://oxygenbuilder.com/
|
||||
*/
|
||||
add_filter('wu_element_should_enqueue_scripts', array($this, 'maybe_parse_oxygen_content'), 10, 3);
|
||||
|
||||
add_action('wu_template_previewer', array($this, 'prevent_oxygen_cleanup_on_template_previewer'));
|
||||
|
||||
/**
|
||||
* WP Maintenance Mode. Adds SSO to WPMM, if enabled.
|
||||
*
|
||||
* @see https://wordpress.org/plugins/wp-maintenance-mode/
|
||||
*/
|
||||
add_filter('wu_sso_loaded_on_init', array($this, 'add_sso_to_maintenance_mode'));
|
||||
|
||||
/**
|
||||
* Avada Theme.
|
||||
*
|
||||
* 1. Fix the issue with the Avada theme that causes the template previewer to not load.
|
||||
* 2. Handle cache on domain update.
|
||||
*
|
||||
* @see https://themeforest.net/item/avada-responsive-multipurpose-theme/
|
||||
*/
|
||||
add_filter('wu_template_previewer_before', array($this, 'run_wp_on_template_previewer'));
|
||||
add_filter('wu_domain_post_save', array($this, 'clear_avada_cache'));
|
||||
|
||||
/**
|
||||
* FluentCRM Pro
|
||||
*
|
||||
* 1. Fix the FluentCRM Pro on site duplication
|
||||
*
|
||||
* @see https://fluentcrm.com/
|
||||
*/
|
||||
add_action('wp_insert_site', array($this, 'fix_fluent_pro_site_duplication'));
|
||||
|
||||
/**
|
||||
* Rank Math (Free and Pro)
|
||||
*
|
||||
* 1. Remove rankmath auto activation hook to prevent database errors on site creation process
|
||||
*
|
||||
* @see https://rankmath.com/
|
||||
*/
|
||||
add_action('wp_initialize_site', array($this, 'fix_rank_math_site_creation'), 1);
|
||||
|
||||
/**
|
||||
* WP E-Signature and WP E-Signature Business add-ons
|
||||
*
|
||||
* 1. Remove e-signature auto activation hook to prevent database errors on site creation process
|
||||
*
|
||||
* @see https://www.approveme.com/
|
||||
*/
|
||||
add_action('wp_initialize_site', array($this, 'fix_wp_e_signature_site_creation'), 1);
|
||||
|
||||
/**
|
||||
* KeyPress DSN Manager backwards compatibility.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @see https://getkeypress.com/dns-manager/
|
||||
*/
|
||||
add_action('wu_before_pending_site_published', function() {
|
||||
|
||||
if (function_exists('KPDNS')) {
|
||||
|
||||
KPDNS(); // phpcs:ignore
|
||||
|
||||
} // end if;
|
||||
|
||||
}, 5); // need to hook before 10
|
||||
|
||||
/**
|
||||
* Perfmatters.
|
||||
*
|
||||
* 1. Remove action from perfamatters that disabled password strength meter script.
|
||||
*
|
||||
* @since 2.1.1
|
||||
* @see https://perfmatters.io/
|
||||
*/
|
||||
add_filter('wp_print_scripts', array($this, 'remove_perfmatters_checkout_dep'), 99);
|
||||
|
||||
/**
|
||||
* Adds the setup preview for elements on DIVI.
|
||||
*
|
||||
* @since 2.0.5
|
||||
*/
|
||||
add_action('wp', function() {
|
||||
|
||||
if (wu_request('et_pb_preview')) {
|
||||
|
||||
wu_element_setup_preview();
|
||||
|
||||
} // end if;
|
||||
|
||||
});
|
||||
|
||||
} // end init;
|
||||
|
||||
/**
|
||||
* Fixes a performance problem with Woocommerce.
|
||||
*
|
||||
* The default Woocommerce filter adds more elements to wpdb
|
||||
* element without necessit and brings a overload when loading
|
||||
* multiple sites data.
|
||||
*
|
||||
* @see https://wordpress.org/plugins/woocommerce/
|
||||
* @since 2.0.14
|
||||
*/
|
||||
public function replace_wc_wpdb_table_fix() {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
remove_action('switch_blog', array(WC(), 'wpdb_table_fix'), 0);
|
||||
|
||||
// List of tables without prefixes.
|
||||
$tables = array(
|
||||
'payment_tokenmeta' => 'woocommerce_payment_tokenmeta',
|
||||
'order_itemmeta' => 'woocommerce_order_itemmeta',
|
||||
'wc_product_meta_lookup' => 'wc_product_meta_lookup',
|
||||
'wc_tax_rate_classes' => 'wc_tax_rate_classes',
|
||||
'wc_reserved_stock' => 'wc_reserved_stock',
|
||||
);
|
||||
|
||||
foreach ( $tables as $name => $table ) {
|
||||
|
||||
$wpdb->tables[] = $table;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
add_action('switch_blog', function() use ($wpdb, $tables) {
|
||||
|
||||
foreach ( $tables as $name => $table ) {
|
||||
|
||||
$wpdb->$name = $wpdb->prefix . $table;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
}, 0);
|
||||
|
||||
} // end replace_wc_wpdb_table_fix;
|
||||
|
||||
/**
|
||||
* Fixes incompatibility with the plugin WP Typography.
|
||||
*
|
||||
* This plugin has a setting that replaces quotes on the content.
|
||||
* This breaks our moment configuration strings, and is generally
|
||||
* not compatible with WP Ultimo vue templates.
|
||||
*
|
||||
* Here on this filter, we manually disable the smart quotes
|
||||
* settings to prevent that kind of processing, as well as add
|
||||
* an admin message telling admins that this is not supported.
|
||||
*
|
||||
* @see https://de.wordpress.org/plugins/wp-typography/
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $settings The wp-typography settings.
|
||||
* @return array
|
||||
*/
|
||||
public function fix_wp_typography($settings) {
|
||||
|
||||
$settings['smartQuotes'] = false;
|
||||
|
||||
return $settings;
|
||||
|
||||
} // end fix_wp_typography;
|
||||
|
||||
/**
|
||||
* Adds a warning message to let customers know why smart quotes are not working.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return void
|
||||
*/
|
||||
public function add_wp_typography_warning_message() {
|
||||
|
||||
WP_Ultimo()->notices->add(__('WP Typography "Smart Quotes" replacement is not compatible with WP Ultimo and will be automatically disabled.', 'wp-ultimo'), 'warning');
|
||||
|
||||
} // end add_wp_typography_warning_message;
|
||||
|
||||
/**
|
||||
* Fixes brizy media URLs while on Ultimo's template preview
|
||||
*
|
||||
* In pages created with Brizy, the URLs break when
|
||||
* we add the preview=1 parameter to urls.
|
||||
*
|
||||
* This fix prevent that addition.
|
||||
* It is far from an optimal solution, but it will do
|
||||
* for now.
|
||||
*
|
||||
* @todo Find a better way to exclude only Brizy urls.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @param bool $value The current filter value.
|
||||
* @return bool
|
||||
*/
|
||||
public function fix_brizy_preview_url($value) {
|
||||
|
||||
return class_exists('Brizy_Editor') ? false : $value;
|
||||
|
||||
} // end fix_brizy_preview_url;
|
||||
|
||||
/**
|
||||
* Fix the Brizy editor with domain mapping.
|
||||
*
|
||||
* @since 2.0.10
|
||||
*
|
||||
* @param bool $should_redirect If we should redirect to the mapped domain.
|
||||
* @return bool
|
||||
*/
|
||||
public function fix_brizy_editor_screen($should_redirect) {
|
||||
|
||||
if (class_exists('\Brizy_Editor')) {
|
||||
|
||||
$key = \Brizy_Editor::prefix('-edit-iframe');
|
||||
|
||||
if (wu_request($key, null) !== null) {
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end if;
|
||||
|
||||
return $should_redirect;
|
||||
|
||||
} // end fix_brizy_editor_screen;
|
||||
|
||||
/**
|
||||
* Fix the Divi editor with domain mapping.
|
||||
*
|
||||
* @since 2.1.4
|
||||
*
|
||||
* @param bool $should_redirect If we should redirect to the mapped domain.
|
||||
* @return bool
|
||||
*/
|
||||
public function fix_divi_editor_screen(bool $should_redirect): bool {
|
||||
|
||||
if (isset($_GET['et_fb']) && (bool) $_GET['et_fb']) {
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
return $should_redirect;
|
||||
|
||||
} // end fix_divi_editor_screen;
|
||||
|
||||
/**
|
||||
* Fixes WP Hide Pro URLs while on Ultimo's template preview
|
||||
*
|
||||
* @since 2.0.20
|
||||
* @param bool $value The current filter value.
|
||||
* @return bool
|
||||
*/
|
||||
public function fix_wp_hide_preview_url($value) {
|
||||
|
||||
return class_exists('WPH') ? false : $value;
|
||||
|
||||
} // end fix_wp_hide_preview_url;
|
||||
|
||||
/**
|
||||
* Fix the load URL for WP Frontend Admin.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $final_url The URL WFA wants to load.
|
||||
* @param string $page_path_only The page path.
|
||||
* @param int $blog_id The blog ID.
|
||||
* @return string
|
||||
*/
|
||||
public function fix_frontend_admin_loading_url($final_url, $page_path_only, $blog_id) {
|
||||
|
||||
return wu_restore_original_url($final_url, $blog_id);
|
||||
|
||||
} // end fix_frontend_admin_loading_url;
|
||||
|
||||
/**
|
||||
* Oxygen renders things very strangely, so we need to handle it separately.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param bool $should_enqueue If we should include the elements scripts.
|
||||
* @param \WP_Post $post The post object.
|
||||
* @param string $shortcode_tag The shortcode.
|
||||
* @return bool
|
||||
*/
|
||||
public function maybe_parse_oxygen_content($should_enqueue, $post, $shortcode_tag) {
|
||||
|
||||
if (function_exists('oxygen_vsb_current_user_can_access') === false) {
|
||||
|
||||
return $should_enqueue;
|
||||
|
||||
} // end if;
|
||||
|
||||
$shortcode_content = get_post_meta($post->ID, 'ct_builder_shortcodes', true);
|
||||
|
||||
$has_shortcode = has_shortcode($shortcode_content, $shortcode_tag);
|
||||
|
||||
/*
|
||||
* Oxygen now base64 encodes shortcodes for some reason...
|
||||
* Supporting third-party page builders is such a pain.
|
||||
*/
|
||||
if (!$has_shortcode) {
|
||||
|
||||
$base64 = base64_encode("[$shortcode_tag]");
|
||||
|
||||
$has_shortcode = strpos((string) $shortcode_content, $base64);
|
||||
|
||||
} // end if;
|
||||
|
||||
return $has_shortcode;
|
||||
|
||||
} // end maybe_parse_oxygen_content;
|
||||
|
||||
/**
|
||||
* Prevent Oxygen from removing the real wp_head hook from the template
|
||||
* previewer page.
|
||||
*
|
||||
* @since 2.0.4
|
||||
* @return void
|
||||
*/
|
||||
public function prevent_oxygen_cleanup_on_template_previewer() {
|
||||
|
||||
add_action('wp_head', function() {
|
||||
|
||||
remove_action('wp_head', 'oxy_print_cached_css', 999999);
|
||||
|
||||
}, 10);
|
||||
|
||||
} // end prevent_oxygen_cleanup_on_template_previewer;
|
||||
|
||||
/**
|
||||
* Adds SSO to WP Maintenance Mode.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param \WP_Ultimo\Domain_Mapping\SSO $sso The SSO class instance.
|
||||
* @return void
|
||||
*/
|
||||
public function add_sso_to_maintenance_mode($sso) {
|
||||
|
||||
add_action('wpmm_head', array($sso, 'enqueue_script'));
|
||||
|
||||
} // end add_sso_to_maintenance_mode;
|
||||
|
||||
/**
|
||||
* Run wp action on template previewer to prevent some errors like
|
||||
* images not loading due lazy loading funcionality
|
||||
*
|
||||
* @since 2.0.11
|
||||
*/
|
||||
public function run_wp_on_template_previewer() {
|
||||
|
||||
if (class_exists('Avada')) {
|
||||
|
||||
do_action('wp'); //phpcs:disable
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end run_wp_on_template_previewer;
|
||||
|
||||
/**
|
||||
* Run wp action on template previewer to prevent some errors like
|
||||
* images not loading due lazy loading functionality
|
||||
*
|
||||
* @since 2.0.11
|
||||
*/
|
||||
public function clear_avada_cache($data) {
|
||||
|
||||
switch_to_blog($data['blog_id']);
|
||||
|
||||
if (function_exists('fusion_reset_all_caches')) {
|
||||
|
||||
fusion_reset_all_caches();
|
||||
|
||||
} else {
|
||||
|
||||
$theme = strtolower(wp_get_theme()) === 'avada' ? 'avada' : strtolower(wp_get_theme()->parent());
|
||||
|
||||
$file_path = get_parent_theme_file_path('includes/lib/inc/functions.php');
|
||||
|
||||
if ($theme === 'avada' && file_exists($file_path)) {
|
||||
|
||||
require_once get_parent_theme_file_path('includes/lib/inc/functions.php');
|
||||
|
||||
fusion_reset_all_caches();
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end if;
|
||||
|
||||
restore_current_blog();
|
||||
|
||||
} // end clear_avada_cache;
|
||||
|
||||
/**
|
||||
* Fix the FluentCRM Pro on site duplication due to fc_meta table not exist
|
||||
* The function causing problem should run after a user receive a role on the
|
||||
* site to tag him on CRM as a customer.
|
||||
*
|
||||
* @since 2.0.11
|
||||
*/
|
||||
public function fix_fluent_pro_site_duplication() {
|
||||
|
||||
$class_name = 'FluentCampaign\App\Hooks\Handlers\IntegrationHandler';
|
||||
|
||||
if (class_exists($class_name)) {
|
||||
|
||||
// Here we use this function due FluentCrm($class_name) returns an instance not working with remove_action
|
||||
$this->hard_remove_action('set_user_role', array($class_name, 'maybeAutoAlterTags'), 11);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end fix_fluent_pro_site_duplication;
|
||||
|
||||
/**
|
||||
* Removes RankMath and RankMath Pro Installer::wpmu_new_blog action
|
||||
* This registered action causes error on database during site creation
|
||||
* and serves only to force activate the plugin
|
||||
*
|
||||
* @since 2.0.20
|
||||
*/
|
||||
public function fix_rank_math_site_creation() {
|
||||
|
||||
$class_names = array(
|
||||
'RankMath\Installer',
|
||||
'RankMathPro\Installer',
|
||||
);
|
||||
|
||||
foreach ($class_names as $class_name) {
|
||||
|
||||
if (class_exists($class_name)) {
|
||||
|
||||
// HankMath does not provide a instance of the activation class
|
||||
$this->hard_remove_action('wpmu_new_blog', array($class_name, 'activate_blog'), 10);
|
||||
$this->hard_remove_action('wp_initialize_site', array($class_name, 'initialize_site'), 10);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
} // end fix_rank_math_site_creation;
|
||||
|
||||
/**
|
||||
* Removes WP E-Signature and WP E-Signature Business add-ons
|
||||
* ESIG_SAD::wpmu_new_blog and ESIG_SIF::wpmu_new_blog actions
|
||||
* This registered action causes error on database during site creation
|
||||
* and serves only to force activate the plugin
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
public function fix_wp_e_signature_site_creation() {
|
||||
|
||||
$class_names = array(
|
||||
'ESIG_SAD',
|
||||
'ESIG_SIF',
|
||||
);
|
||||
|
||||
foreach ($class_names as $class_name) {
|
||||
|
||||
if (class_exists($class_name)) {
|
||||
|
||||
// WP E-Signature does not provide a instance of the activation class
|
||||
$this->hard_remove_action('wpmu_new_blog', array($class_name, 'activate_new_site'), 10);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
} // end fix_wp_e_signature_site_creation;
|
||||
|
||||
/**
|
||||
* A way to remove an action if instance is not available
|
||||
*
|
||||
* @since 2.0.11
|
||||
*
|
||||
* @param string $tag The class name.
|
||||
* @param array $handler The action handler.
|
||||
* @param int $priority The The action priority.
|
||||
* @return void
|
||||
*/
|
||||
public function hard_remove_action($tag, $handler, $priority) {
|
||||
|
||||
global $wp_filter;
|
||||
|
||||
if (!isset($wp_filter[$tag][$priority])) {
|
||||
|
||||
return;
|
||||
|
||||
} // end if;
|
||||
|
||||
$handler_id = '';
|
||||
|
||||
foreach($wp_filter[$tag][$priority] as $handler_key => $filter_handler) {
|
||||
|
||||
if(strpos((string) $handler_key, (string) $handler[1]) !== false && is_array($filter_handler['function']) && is_a($filter_handler['function'][0], $handler[0]) && $filter_handler['function'][1] === $handler[1]) {
|
||||
|
||||
$handler_id = $handler_key;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
if (!empty($handler_id)) {
|
||||
|
||||
remove_filter( $tag, $handler_id, $priority );
|
||||
|
||||
} // end if;
|
||||
|
||||
return;
|
||||
|
||||
} // end hard_remove_action;
|
||||
|
||||
/**
|
||||
* Remove action from perfamatters that disabled password strength meter script.
|
||||
*
|
||||
* @since 2.1.1
|
||||
* @return void
|
||||
*/
|
||||
public function remove_perfmatters_checkout_dep() {
|
||||
|
||||
if (is_main_site() || is_admin()) {
|
||||
|
||||
remove_action('wp_print_scripts', 'perfmatters_disable_password_strength_meter', 100);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end remove_perfmatters_checkout_dep;
|
||||
|
||||
} // end class General_Compat;
|
85
inc/compat/class-gutenberg-support.php
Normal file
85
inc/compat/class-gutenberg-support.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* Gutenberg Support
|
||||
*
|
||||
* Allows WP Ultimo to filter Gutenberg thingys.
|
||||
*
|
||||
* @since 1.9.14
|
||||
* @author Arindo Duque
|
||||
* @category Admin
|
||||
* @package WP_Ultimo/Compat
|
||||
* @version 0.0.1
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Adds support to Gutenberg filters.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Gutenberg_Support {
|
||||
|
||||
use \WP_Ultimo\Traits\Singleton;
|
||||
|
||||
/**
|
||||
* Filterable function that let users decide if they want to remove
|
||||
* Gutenberg support and modifications by Ultimo.
|
||||
*
|
||||
* @since 1.9.14
|
||||
* @return bool
|
||||
*/
|
||||
public function should_load() {
|
||||
|
||||
if (function_exists('has_blocks')) {
|
||||
|
||||
return true;
|
||||
|
||||
} // end if;
|
||||
|
||||
return apply_filters('wu_gutenberg_support_should_load', true);
|
||||
|
||||
} // end should_load;
|
||||
|
||||
/**
|
||||
* Initializes the Class, if we need it.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
if ($this->should_load()) {
|
||||
|
||||
add_action('admin_enqueue_scripts', array($this, 'add_scripts'));
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end init;
|
||||
|
||||
/**
|
||||
* Adds the Gutenberg Filters scripts.
|
||||
*
|
||||
* @since 1.9.14
|
||||
* @return void
|
||||
*/
|
||||
public function add_scripts() {
|
||||
|
||||
wp_register_script('wu-gutenberg-support', wu_get_asset('gutenberg-support.js', 'js'), array('jquery'), wu_get_version(), true);
|
||||
|
||||
// translators: the placeholder is replaced with the network name.
|
||||
$preview_message = apply_filters('wu_gutenberg_support_preview_message', sprintf(__('<strong>%s</strong> is generating the preview...', 'wp-ultimo'), get_network_option(null, 'site_name')));
|
||||
|
||||
wp_localize_script('wu-gutenberg-support', 'wu_gutenberg', array(
|
||||
'logo' => esc_url(wu_get_network_logo()),
|
||||
'replacement_message' => $preview_message,
|
||||
));
|
||||
|
||||
wp_enqueue_script('wu-gutenberg-support');
|
||||
|
||||
} // end add_scripts;
|
||||
|
||||
} // end class Gutenberg_Support;
|
615
inc/compat/class-legacy-shortcodes.php
Normal file
615
inc/compat/class-legacy-shortcodes.php
Normal file
@ -0,0 +1,615 @@
|
||||
<?php
|
||||
/**
|
||||
* Legacy Shortcodes
|
||||
*
|
||||
* Handles WP Ultimo 1.X Legacy Shortcodes
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Compat
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
use WP_Ultimo\Database\Memberships\Membership_Status;
|
||||
|
||||
/**
|
||||
* Handles WP Ultimo 1.X Legacy Shortcodes
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Legacy_Shortcodes {
|
||||
|
||||
use \WP_Ultimo\Traits\Singleton;
|
||||
|
||||
/**
|
||||
* Control array for the template list shortcode
|
||||
*
|
||||
* @since 1.7.4
|
||||
* @var array|boolean
|
||||
*/
|
||||
public $templates = false;
|
||||
|
||||
/**
|
||||
* Defines all the legacy shortcodes.
|
||||
*
|
||||
* @since 1.0.0 Adds Pricing Table and Paying customers.
|
||||
* @since 1.2.1 Adds Plan Link Shortcode.
|
||||
* @since 1.2.2 Adds Template Display.
|
||||
* @since 1.4.0 Adds User meta getter.
|
||||
* @since 1.5.0 Adds Restricted content.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
add_shortcode('wu_paying_users', array($this, 'paying_users'));
|
||||
|
||||
add_shortcode('wu_user_meta', array($this, 'user_meta'));
|
||||
|
||||
add_shortcode('wu_plan_link', array($this, 'plan_link'));
|
||||
|
||||
add_shortcode('wu_restricted_content', array($this, 'restricted_content'));
|
||||
|
||||
add_shortcode('wu_pricing_table', array($this, 'pricing_table'));
|
||||
|
||||
add_shortcode('wu_templates_list', array($this, 'templates_list'));
|
||||
|
||||
} // end init;
|
||||
|
||||
/**
|
||||
* Return the value of a user meta on the database.
|
||||
* This is useful to fetch data saved from custom sign-up fields during sign-up.
|
||||
*
|
||||
* @since 1.4.0
|
||||
* @since 2.0.0 Search customer meta first before trying to fetch the info from the user table.
|
||||
*
|
||||
* @param array $atts Shortcode attributes.
|
||||
* @return string
|
||||
*/
|
||||
public function user_meta($atts) {
|
||||
|
||||
$customer_id = 0;
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
|
||||
$site = wu_get_current_site();
|
||||
|
||||
$customer = $site->get_customer();
|
||||
|
||||
if ($customer) {
|
||||
|
||||
$customer_id = $customer->get_id();
|
||||
|
||||
$user_id = $customer->get_user_id();
|
||||
|
||||
} // end if;
|
||||
|
||||
$atts = shortcode_atts(array(
|
||||
'user_id' => $user_id,
|
||||
'meta_name' => 'first_name',
|
||||
'default' => false,
|
||||
'unique' => true,
|
||||
), $atts, 'wu_user_meta');
|
||||
|
||||
if ($customer_id) {
|
||||
|
||||
$value = $customer->get_meta($atts['meta_name']);
|
||||
|
||||
} else {
|
||||
|
||||
$value = get_user_meta($atts['user_id'], $atts['meta_name'], $atts['unique']);
|
||||
|
||||
} // end if;
|
||||
|
||||
if (is_array($value)) {
|
||||
|
||||
$value = implode(', ', $value);
|
||||
|
||||
} // end if;
|
||||
|
||||
return $value ? $value : '--';
|
||||
|
||||
} // end user_meta;
|
||||
|
||||
/**
|
||||
* Returns the number of paying users on the platform.
|
||||
*
|
||||
* @since 1.X
|
||||
*
|
||||
* @param array $atts Shortcode attributes.
|
||||
* @return string
|
||||
*/
|
||||
public function paying_users($atts) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$atts = shortcode_atts(array(), $atts, 'wu_paying_users');
|
||||
|
||||
$paying_customers = wu_get_customers(array(
|
||||
'count' => true,
|
||||
));
|
||||
|
||||
return $paying_customers;
|
||||
|
||||
} // end paying_users;
|
||||
|
||||
/**
|
||||
* Plan Link shortcode.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $atts Shortcode attributes.
|
||||
* @return string
|
||||
*/
|
||||
public function plan_link($atts) {
|
||||
|
||||
$atts = shortcode_atts(array(
|
||||
'plan_id' => 0,
|
||||
'plan_freq' => 1,
|
||||
'skip_plan' => 1,
|
||||
), $atts, 'wu_plan_link');
|
||||
|
||||
/**
|
||||
* Treat the results to make sure we are getting numbers out of it
|
||||
*
|
||||
* @since 1.5.1
|
||||
*/
|
||||
foreach (array('plan_id', 'plan_freq') as $att) {
|
||||
|
||||
$atts[$att] = wu_extract_number($atts[$att]);
|
||||
|
||||
} // end foreach;
|
||||
|
||||
$path = '';
|
||||
|
||||
/*
|
||||
* First pass: try to get via the migrated_from_id property
|
||||
* to make sure we don't break links for legacy customers.
|
||||
*/
|
||||
$plan = wu_get_product_by('migrated_from_id', $atts['plan_id']);
|
||||
|
||||
if ($plan) {
|
||||
|
||||
$path = $plan->get_slug();
|
||||
|
||||
} // end if;
|
||||
|
||||
/**
|
||||
* Second pass: try via the real ID, if new customers
|
||||
* decide to use the old shortcode.
|
||||
*/
|
||||
if (empty($path)) {
|
||||
|
||||
$plan = wu_get_product($atts['plan_id']);
|
||||
|
||||
if ($plan) {
|
||||
|
||||
$path = $plan->get_slug();
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end if;
|
||||
|
||||
return wu_get_registration_url($path);
|
||||
|
||||
} // end plan_link;
|
||||
|
||||
/**
|
||||
* Renders the restrict content shortcode.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $atts Shortcode attributes.
|
||||
* @param string $content The content inside the shortcode.
|
||||
* @return string
|
||||
*/
|
||||
public function restricted_content($atts, $content) {
|
||||
|
||||
$atts = shortcode_atts(array(
|
||||
'plan_id' => false,
|
||||
'product_id' => false,
|
||||
'only_active' => true,
|
||||
'only_logged' => false,
|
||||
'exclude_trials' => false,
|
||||
'from_request' => false,
|
||||
), $atts, 'wu_restricted_content');
|
||||
|
||||
$atts['plan_id'] = !empty($atts['product_id']) ? $atts['product_id'] : $atts['plan_id'];
|
||||
|
||||
if (empty($atts) || !$atts['plan_id']) {
|
||||
|
||||
return __('You need to pass a valid plan ID.', 'wp-ultimo');
|
||||
|
||||
} // end if;
|
||||
|
||||
$query_products = get_query_var('products', array());
|
||||
|
||||
$request_products = array();
|
||||
|
||||
foreach ($query_products as $product) {
|
||||
|
||||
$product = wu_get_product($product);
|
||||
|
||||
if (!$product) {
|
||||
|
||||
continue;
|
||||
|
||||
} // end if;
|
||||
|
||||
$request_products[] = $product->get_id();
|
||||
|
||||
} // end foreach;
|
||||
|
||||
$plan_ids = explode(',', $atts['plan_id']);
|
||||
$plan_ids = array_map('trim', $plan_ids);
|
||||
$plan_ids = array_map('intval', $plan_ids);
|
||||
|
||||
$else = '[wu_default_content]';
|
||||
|
||||
if (strpos($content, $else) !== false) {
|
||||
|
||||
list($if, $else) = explode($else, $content, 2);
|
||||
|
||||
} else {
|
||||
|
||||
$if = $content;
|
||||
|
||||
$else = '';
|
||||
|
||||
} // end if;
|
||||
|
||||
$condition = false;
|
||||
|
||||
$membership = WP_Ultimo()->currents->get_membership();
|
||||
|
||||
$user_logged_in = is_user_logged_in();
|
||||
|
||||
$should_check = !(bool) $atts['only_logged'] || $user_logged_in;
|
||||
|
||||
$from_request = $atts['from_request'] && count(array_intersect($plan_ids, $request_products)) > 0;
|
||||
|
||||
if ($membership && $should_check && !$from_request) {
|
||||
|
||||
$membership_products = array_merge(
|
||||
array($membership->get_plan_id()),
|
||||
$membership->get_addon_ids()
|
||||
);
|
||||
|
||||
$condition = in_array('all', $plan_ids, true) || count(array_intersect($membership_products, $plan_ids)) > 0;
|
||||
|
||||
if ((bool) $atts['only_active']) {
|
||||
|
||||
$condition = $condition && ($membership->is_active() || $membership->get_status() === 'trialing');
|
||||
|
||||
} // end if;
|
||||
|
||||
if ((bool) $atts['exclude_trials']) {
|
||||
|
||||
$condition = $condition && !$membership->is_trialing();
|
||||
|
||||
} // end if;
|
||||
|
||||
} else {
|
||||
|
||||
$condition = $from_request && $should_check;
|
||||
|
||||
} // end if;
|
||||
|
||||
$final_content = wpautop($condition ? $if : $else);
|
||||
|
||||
return do_shortcode($final_content);
|
||||
|
||||
} // end restricted_content;
|
||||
|
||||
/**
|
||||
* Adds the pricing table shortcode.
|
||||
*
|
||||
* This method is intended to be able to support both legacy shortcodes, as well
|
||||
* as display new layouts.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $atts Parsed shortcode attributes.
|
||||
* @param string $content Shortcode content.
|
||||
* @return string
|
||||
*/
|
||||
public function pricing_table($atts, $content) {
|
||||
|
||||
global $post;
|
||||
|
||||
$atts = shortcode_atts(array(
|
||||
'primary_color' => wu_get_setting('primary_color', '#00a1ff'),
|
||||
'accent_color' => wu_get_setting('accent_color', '#78b336'),
|
||||
'default_pricing_option' => wu_get_setting('default_pricing_option', 1),
|
||||
'plan_id' => false,
|
||||
'show_selector' => true,
|
||||
// New Options
|
||||
'layout' => 'legacy',
|
||||
'period_selector_layout' => 'legacy',
|
||||
), $atts, 'wu_pricing_table');
|
||||
|
||||
/**
|
||||
* In the case of the legacy layout, we need to load extra styles.
|
||||
*/
|
||||
if ($atts['layout'] === 'legacy') {
|
||||
|
||||
wp_enqueue_style('legacy-signup', wu_get_asset('legacy-signup.css', 'css'));
|
||||
|
||||
wp_add_inline_style('legacy-signup', \WP_Ultimo\Checkout\Legacy_Checkout::get_instance()->get_legacy_dynamic_styles());
|
||||
|
||||
} // end if;
|
||||
|
||||
do_action('wu_checkout_scripts', $post);
|
||||
|
||||
do_action('wu_setup_checkout');
|
||||
|
||||
$atts['plan_id'] = is_string($atts['plan_id']) && $atts['plan_id'] !== 'all' ? explode(',', $atts['plan_id']) : false;
|
||||
|
||||
$checkout_form = new \WP_Ultimo\Models\Checkout_Form;
|
||||
|
||||
$fields = array();
|
||||
|
||||
$search_arguments = array(
|
||||
'fields' => 'ids',
|
||||
);
|
||||
|
||||
if ($atts['plan_id']) {
|
||||
|
||||
$search_arguments['id__in'] = $atts['plan_id'];
|
||||
|
||||
} // end if;
|
||||
|
||||
if ($atts['show_selector']) {
|
||||
|
||||
$fields[] = array(
|
||||
'step' => 'checkout',
|
||||
'name' => '',
|
||||
'type' => 'period_selection',
|
||||
'id' => 'period_selection',
|
||||
'period_selection_template' => $atts['period_selector_layout'],
|
||||
'period_options' => array(
|
||||
array(
|
||||
'duration' => 1,
|
||||
'duration_unit' => 'month',
|
||||
'label' => __('Monthly', 'wp-ultimo'),
|
||||
),
|
||||
array(
|
||||
'duration' => 3,
|
||||
'duration_unit' => 'month',
|
||||
'label' => __('Quarterly', 'wp-ultimo'),
|
||||
),
|
||||
array(
|
||||
'duration' => 1,
|
||||
'duration_unit' => 'year',
|
||||
'label' => __('Yearly', 'wp-ultimo'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
} // end if;
|
||||
|
||||
$layout = $atts['layout'];
|
||||
|
||||
$fields[] = array(
|
||||
'step' => 'checkout',
|
||||
'name' => __('Plans', 'wp-ultimo'),
|
||||
'type' => 'pricing_table',
|
||||
'id' => 'pricing_table',
|
||||
'required' => true,
|
||||
'pricing_table_products' => implode(',', wu_get_plans($search_arguments)),
|
||||
'pricing_table_template' => $layout,
|
||||
'element_classes' => $layout === 'legacy' ? 'wu-content-plan' : '',
|
||||
);
|
||||
|
||||
/**
|
||||
* If not using the legacy checkout,
|
||||
* we'll need a submit field.
|
||||
*/
|
||||
if ($layout !== 'legacy') {
|
||||
|
||||
$fields[] = array (
|
||||
'step' => 'checkout',
|
||||
'name' => __('Get Started →', 'wp-ultimo'),
|
||||
'type' => 'submit_button',
|
||||
'id' => 'checkout',
|
||||
);
|
||||
|
||||
} // end if;
|
||||
|
||||
$steps = array (
|
||||
array (
|
||||
'id' => 'checkout',
|
||||
'name' => __('Checkout', 'wp-ultimo'),
|
||||
'desc' => '',
|
||||
'fields' => $fields,
|
||||
),
|
||||
);
|
||||
|
||||
$checkout = \WP_Ultimo\Checkout\Checkout::get_instance();
|
||||
|
||||
$steps = apply_filters('wu_checkout_form_shortcode_pricing_table_fields', $steps);
|
||||
|
||||
$checkout_form->set_settings($steps);
|
||||
|
||||
$auto_submittable_field = $checkout->contains_auto_submittable_field($checkout_form->get_step('checkout', true)['fields']);
|
||||
|
||||
do_action('wu_checkout_scripts', $post);
|
||||
|
||||
do_action('wu_setup_checkout');
|
||||
|
||||
wp_add_inline_script('wu-checkout', sprintf('
|
||||
|
||||
/**
|
||||
* Set the auto-submittable field, if one exists.
|
||||
*/
|
||||
window.wu_auto_submittable_field = %s;
|
||||
|
||||
', json_encode($auto_submittable_field)), 'after');
|
||||
|
||||
$final_fields = wu_create_checkout_fields($checkout_form->get_step('checkout', true)['fields']);
|
||||
|
||||
/*
|
||||
* Adds the product fields to keep them.
|
||||
*/
|
||||
$final_fields['products[]'] = array(
|
||||
'type' => 'hidden',
|
||||
'html_attr' => array(
|
||||
'v-for' => '(product, index) in unique_products',
|
||||
'v-model' => 'products[index]',
|
||||
'v-bind:id' => '"products-" + index',
|
||||
),
|
||||
);
|
||||
|
||||
$final_fields['pre-flight'] = array(
|
||||
'type' => 'hidden',
|
||||
'value' => 1,
|
||||
);
|
||||
|
||||
return wu_get_template_contents('checkout/form', array(
|
||||
'step' => $checkout_form->get_step('checkout', true),
|
||||
'step_name' => 'checkout',
|
||||
'checkout_form_name' => 'wu_pricing_table',
|
||||
'checkout_form_action' => add_query_arg('pre-flight', 1, wu_get_registration_url()),
|
||||
'display_title' => '',
|
||||
'final_fields' => $final_fields,
|
||||
));
|
||||
|
||||
} // end pricing_table;
|
||||
|
||||
/**
|
||||
* Adds the template sites shortcode.
|
||||
*
|
||||
* This method is intended to be able to support both legacy shortcodes, as well
|
||||
* as display new layouts.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $atts Parsed shortcode attributes.
|
||||
* @param string $content Shortcode content.
|
||||
* @return string
|
||||
*/
|
||||
public function templates_list($atts, $content) {
|
||||
|
||||
global $post;
|
||||
|
||||
$atts = shortcode_atts(array(
|
||||
'show_filters' => true,
|
||||
'show_title' => true,
|
||||
'templates' => false,
|
||||
'cols' => 3,
|
||||
'layout' => 'legacy',
|
||||
'checkout_page' => wu_guess_registration_page(),
|
||||
), $atts, 'wu_templates_list');
|
||||
|
||||
/**
|
||||
* Hide header, if necessary
|
||||
*/
|
||||
add_filter('wu_step_template_display_header', $atts['show_title'] ? '__return_true' : '__return_false');
|
||||
|
||||
/**
|
||||
* Filters the template list to be used
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
$templates = $atts['templates'] ? $this->treat_template_list($atts['templates']) : false;
|
||||
|
||||
/**
|
||||
* In the case of the legacy layout, we need to load extra styles.
|
||||
*/
|
||||
if ($atts['layout'] === 'legacy') {
|
||||
|
||||
wp_enqueue_style('legacy-signup', wu_get_asset('legacy-signup.css', 'css'));
|
||||
|
||||
wp_add_inline_style('legacy-signup', \WP_Ultimo\Checkout\Legacy_Checkout::get_instance()->get_legacy_dynamic_styles());
|
||||
|
||||
} // end if;
|
||||
|
||||
$checkout_form = new \WP_Ultimo\Models\Checkout_Form;
|
||||
|
||||
$fields = array();
|
||||
|
||||
$search_arguments = array(
|
||||
'fields' => 'ids',
|
||||
);
|
||||
|
||||
$layout = $atts['layout'];
|
||||
|
||||
$fields[] = array(
|
||||
'step' => 'checkout',
|
||||
'name' => __('Templates', 'wp-ultimo'),
|
||||
'type' => 'template_selection',
|
||||
'id' => 'template_selection',
|
||||
'template_selection_sites' => implode(',', $templates ? $templates : wu_get_site_templates($search_arguments)),
|
||||
'template_selection_template' => $layout,
|
||||
'cols' => $atts['cols'],
|
||||
'element_classes' => $layout === 'legacy' ? 'wu-content-templates' : '',
|
||||
);
|
||||
|
||||
$steps = array (
|
||||
array (
|
||||
'id' => 'checkout',
|
||||
'name' => __('Checkout', 'wp-ultimo'),
|
||||
'desc' => '',
|
||||
'fields' => $fields,
|
||||
),
|
||||
);
|
||||
|
||||
$checkout = \WP_Ultimo\Checkout\Checkout::get_instance();
|
||||
|
||||
$steps = apply_filters('wu_checkout_form_shortcode_templates_list_fields', $steps);
|
||||
|
||||
$checkout_form->set_settings($steps);
|
||||
|
||||
$final_fields = wu_create_checkout_fields($checkout_form->get_step('checkout', true)['fields']);
|
||||
|
||||
$auto_submittable_field = $checkout->contains_auto_submittable_field($checkout_form->get_step('checkout', true)['fields']);
|
||||
|
||||
do_action('wu_checkout_scripts', $post);
|
||||
|
||||
do_action('wu_setup_checkout');
|
||||
|
||||
wp_add_inline_script('wu-checkout', sprintf('
|
||||
|
||||
/**
|
||||
* Set the auto-submittable field, if one exists.
|
||||
*/
|
||||
window.wu_auto_submittable_field = %s;
|
||||
|
||||
', json_encode($auto_submittable_field)), 'after');
|
||||
|
||||
$final_fields['pre-flight'] = array(
|
||||
'type' => 'hidden',
|
||||
'value' => 1,
|
||||
);
|
||||
|
||||
$page_url = wu_switch_blog_and_run(fn() => get_permalink($atts['checkout_page']));
|
||||
|
||||
return wu_get_template_contents('checkout/form', array(
|
||||
'step' => $checkout_form->get_step('checkout', true),
|
||||
'step_name' => 'checkout',
|
||||
'checkout_form_name' => 'wu_templates_list',
|
||||
'checkout_form_action' => add_query_arg('pre-flight', 1, $page_url),
|
||||
'display_title' => '',
|
||||
'final_fields' => $final_fields,
|
||||
));
|
||||
|
||||
} // end templates_list;
|
||||
/**
|
||||
* Makes sure we don't return any invalid values.
|
||||
*
|
||||
* @since 1.7.4
|
||||
* @param string $templates The template list as a string.
|
||||
*/
|
||||
protected function treat_template_list($templates): array {
|
||||
|
||||
$list = array_map('trim', explode(',', $templates));
|
||||
|
||||
return array_filter($list);
|
||||
|
||||
} // end treat_template_list;
|
||||
|
||||
} // end class Legacy_Shortcodes;
|
530
inc/compat/class-multiple-accounts-compat.php
Normal file
530
inc/compat/class-multiple-accounts-compat.php
Normal file
@ -0,0 +1,530 @@
|
||||
<?php
|
||||
/**
|
||||
* Adds support to multiple accounts for plugins such as WooCommerce.
|
||||
*
|
||||
* WordPress, even in multisite mode, has only one User database table.
|
||||
* This can cause problems in a WaaS environment.
|
||||
*
|
||||
* Image the following scenario:
|
||||
*
|
||||
* - You two e-commerce stores on your network: Store A and Store B;
|
||||
* - A potential customer comes to Store A and purchases an item, to do that
|
||||
* they need to create an account.
|
||||
* - A month later, that same customer stumbles upon Store B, and decides to make
|
||||
* another purchase. This time, however, they get an 'email already in use error'
|
||||
* during checkout.
|
||||
* - This happens because the user database is shared across sites, but it can
|
||||
* cause a lot of confusion.
|
||||
*
|
||||
* This class attempts to handle situations like this gracefully.
|
||||
* It will allow the customer to create a second user account with the same email address,
|
||||
* and will scope that user to the sub-site where it was created only.
|
||||
*
|
||||
* Right now, it supports:
|
||||
* - Default WordPress registration;
|
||||
* - WooCommerce.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Compat/Multiple_Accounts_Compat
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Adds support to multiple accounts for plugins such as WooCommerce.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Multiple_Accounts_Compat {
|
||||
|
||||
use \WP_Ultimo\Traits\Singleton;
|
||||
|
||||
/**
|
||||
* Instantiate the necessary hooks.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
// Add the settings to enable or disable this feature.
|
||||
add_action('wu_settings_login', array($this, 'add_settings'), 10);
|
||||
|
||||
if ($this->should_load()) {
|
||||
|
||||
// Fix the object cache
|
||||
$this->fix_object_cache_on_multiple_accounts();
|
||||
|
||||
// Unset user, if the current one is not part of the site.
|
||||
add_action('plugins_loaded', array($this, 'maybe_unset_current_user'), -10);
|
||||
|
||||
// prevents woocommerce from adding customers to sites without our knowledge
|
||||
add_action('woocommerce_process_login_errors', array($this, 'prevent_woo_from_adding_to_blog'), -10);
|
||||
|
||||
// Add the filter to prevent email blocking
|
||||
add_filter('email_exists', array($this, 'allow_duplicate_emails'), 10, 2);
|
||||
|
||||
// Add the filter to prevent email blocking
|
||||
add_filter('query', array($this, 'fix_user_query'), -999);
|
||||
|
||||
// Action in the login to debug the login info
|
||||
add_filter('authenticate', array($this, 'fix_login'), 50000, 3);
|
||||
|
||||
// Now we handle the password thing
|
||||
add_action('init', array($this, 'handle_reset_password'), 2000);
|
||||
|
||||
// Now we add a custom column in that table to allow the admin to control them
|
||||
add_filter('wpmu_users_columns', array($this, 'add_multiple_account_column'));
|
||||
|
||||
// Adds the number of additional accounts.
|
||||
add_filter('manage_users_custom_column', array($this, 'add_column_content'), 10, 3);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end init;
|
||||
|
||||
/**
|
||||
* Fixes the object cache to allow multiple accounts.
|
||||
* Unsets user email from Object Cache so that we can retrieve the user from our
|
||||
* fixed query for consulting the database.
|
||||
*
|
||||
* @since 2.1.4
|
||||
* @return void
|
||||
*/
|
||||
public function fix_object_cache_on_multiple_accounts(): void {
|
||||
|
||||
$to_remove = array(
|
||||
'useremail'
|
||||
);
|
||||
|
||||
if (function_exists('wp_cache_add_non_persistent_groups')) {
|
||||
|
||||
wp_cache_add_non_persistent_groups($to_remove);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end fix_object_cache_on_multiple_accounts;
|
||||
|
||||
/**
|
||||
* Filters the database query so that we can get the right user.
|
||||
*
|
||||
* @since 2.1.4
|
||||
*
|
||||
* @param string $query Database query.
|
||||
* @return string Filtered database query.
|
||||
*/
|
||||
public function fix_user_query(string $query): string {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$search = "\$db->get_row(\"SELECT * FROM $wpdb->users WHERE user_email";
|
||||
|
||||
if ( strpos($wpdb->func_call, $search) === 0) {
|
||||
|
||||
$prefix = "SELECT * FROM $wpdb->users WHERE user_email";
|
||||
|
||||
$last = substr($query, strlen($prefix));
|
||||
|
||||
$site_id = get_current_blog_id();
|
||||
|
||||
/**
|
||||
* We can't use the $wpdb->prepare() method here because it will
|
||||
* escape the %s placeholder, which will break the query.
|
||||
*/
|
||||
return sprintf("SELECT u.*
|
||||
FROM $wpdb->users u
|
||||
JOIN $wpdb->usermeta m on u.id = m.user_id
|
||||
WHERE m.meta_key = \"wp_%d_capabilities\"
|
||||
AND u.user_email%s", $site_id, $last);
|
||||
|
||||
} // end if;
|
||||
|
||||
return $query;
|
||||
|
||||
} // end fix_user_query;
|
||||
|
||||
/**
|
||||
* Hooks into email_exists verification to allow duplicate emails in different sites.
|
||||
*
|
||||
* @since 2.1.4
|
||||
*
|
||||
* @param int|bool $user_id The user ID.
|
||||
* @param string $email The email address.
|
||||
* @return int|bool The user ID.
|
||||
*/
|
||||
public function allow_duplicate_emails($user_id, string $email) {
|
||||
|
||||
if ($user_id) {
|
||||
|
||||
$site_user = $this->get_right_user($email);
|
||||
|
||||
return $site_user ? $site_user->ID : false;
|
||||
|
||||
} // end if;
|
||||
|
||||
return $user_id;
|
||||
|
||||
} // end allow_duplicate_emails;
|
||||
|
||||
/**
|
||||
* Prevent WooCommerce from adding users to site without us knowing.
|
||||
*
|
||||
* We only use the filter 'woocommerce_process_login_errors', because
|
||||
* that's it guaranteed to only run inside the login handler.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param mixed $results Arbitrary item being return by the filter chosen.
|
||||
* @return mixed
|
||||
*/
|
||||
public function prevent_woo_from_adding_to_blog($results) {
|
||||
|
||||
add_filter('can_add_user_to_blog', '__return_false');
|
||||
|
||||
return $results;
|
||||
|
||||
} // end prevent_woo_from_adding_to_blog;
|
||||
|
||||
/**
|
||||
* Checks if the user belongs to a site they are currently viewing and unset them if they don't.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return void
|
||||
*/
|
||||
public function maybe_unset_current_user() {
|
||||
|
||||
global $current_user;
|
||||
|
||||
if (is_admin() || is_main_site() || current_user_can('manage_network')) {
|
||||
|
||||
return;
|
||||
|
||||
} // end if;
|
||||
|
||||
/**
|
||||
* Allow developers to bypass the unset current user code.
|
||||
*
|
||||
* Returning anything other than null will bypass the unset
|
||||
* of the current user logged in.
|
||||
*
|
||||
* This can be useful in some scenarios, for example,
|
||||
* when dealing with sub-sites that are being used as
|
||||
* admin panels.
|
||||
*
|
||||
* @since 2.0.11
|
||||
*
|
||||
* @param mixed $null_or_bypass Null to move on, anything else to bypass it.
|
||||
* @param false|\WP_User $current_user The current user object.
|
||||
* @return mixed
|
||||
*/
|
||||
if (apply_filters('wu_bypass_unset_current_user', null, $current_user) !== null) {
|
||||
|
||||
return;
|
||||
|
||||
} // end if;
|
||||
|
||||
$user = wp_get_current_user();
|
||||
|
||||
$has_user = $this->check_for_user_in_site($user->user_email, $user->ID);
|
||||
|
||||
/*
|
||||
* Despite being currently logged in, this account does not
|
||||
* belong to the sub-site in question, so we unset the user
|
||||
* currently logged in.
|
||||
*/
|
||||
if ($has_user === false) {
|
||||
|
||||
wu_x_header('X-Ultimo-Multiple-Accounts: user-unset');
|
||||
|
||||
$current_user = null;
|
||||
|
||||
wp_set_current_user(0);
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end maybe_unset_current_user;
|
||||
|
||||
/**
|
||||
* Allow plugin developers to disable this functionality to prevent compatibility issues.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function should_load() {
|
||||
|
||||
return apply_filters('wu_should_load_multiple_accounts_support', wu_get_setting('enable_multiple_accounts', true));
|
||||
|
||||
} // end should_load;
|
||||
|
||||
// Methods
|
||||
|
||||
/**
|
||||
* Add multiple accounts setting to enable or disable this feature.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return void.
|
||||
*/
|
||||
public function add_settings() {
|
||||
|
||||
wu_register_settings_field('login-and-registration', 'multiple_accounts_header', array(
|
||||
'title' => __('Multiple Accounts', 'wp-ultimo'),
|
||||
'desc' => __('Options related to the Multiple Accounts feature.', 'wp-ultimo'),
|
||||
'type' => 'header',
|
||||
));
|
||||
|
||||
wu_register_settings_field('login-and-registration', 'enable_multiple_accounts', array(
|
||||
'title' => __('Enable Multiple Accounts', 'wp-ultimo'),
|
||||
'desc' => __('Allow users to have accounts in different sites with the same email address. This is useful when running stores with WooCommerce and other plugins, for example.', 'wp-ultimo') . ' ' . sprintf('<a href="%s" target="_blank">%s</a>', wu_get_documentation_url('multiple-accounts'), __('Read More', 'wp-ultimo')),
|
||||
'type' => 'toggle',
|
||||
'default' => 0,
|
||||
));
|
||||
|
||||
} // end add_settings;
|
||||
|
||||
/**
|
||||
* Adds the Multiple accounts column to the users table.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $columns Original columns.
|
||||
* @return array
|
||||
*/
|
||||
public function add_multiple_account_column($columns) {
|
||||
|
||||
$columns['multiple_accounts'] = __('Multiple Accounts', 'wp-ultimo');
|
||||
|
||||
return $columns;
|
||||
|
||||
} // end add_multiple_account_column;
|
||||
|
||||
/**
|
||||
* Renders the content of our custom column.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param null $null No idea.
|
||||
* @param string $column The name of the column.
|
||||
* @param int $user_id The ID of the user.
|
||||
* @return void
|
||||
*/
|
||||
public function add_column_content($null, $column, $user_id) {
|
||||
|
||||
if ($column === 'multiple_accounts') {
|
||||
|
||||
// Get user email
|
||||
$user = get_user_by('ID', $user_id);
|
||||
|
||||
// Get all the accounts with the same email
|
||||
$users = new \WP_User_Query(array(
|
||||
'blog_id' => 0,
|
||||
'search' => $user->user_email,
|
||||
'fields' => array('ID', 'user_login'),
|
||||
));
|
||||
|
||||
// translators: the %d is the account count for that email address.
|
||||
$html = sprintf(__('<strong>%d</strong> accounts using this email.', 'wp-ultimo'), $users->total_users);
|
||||
|
||||
$html .= sprintf("<br><a href='%s' class=''>" . __('See all', 'wp-ultimo') . ' »</a>', network_admin_url('users.php?s=' . $user->user_email));
|
||||
|
||||
echo $html;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end add_column_content;
|
||||
|
||||
/**
|
||||
* Handles password resetting.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return void
|
||||
*/
|
||||
public function handle_reset_password() {
|
||||
|
||||
// Only run in the right case
|
||||
if (wu_request('action') === 'retrievepassword' || wu_request('wc_reset_password')) {
|
||||
|
||||
// Only do thing if is login by email
|
||||
if (is_email($_REQUEST['user_login'])) {
|
||||
|
||||
$user = $this->get_right_user($_REQUEST['user_login']);
|
||||
|
||||
$_REQUEST['user_login'] = $user->user_login;
|
||||
|
||||
$_POST['user_login'] = $user->user_login;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end handle_reset_password;
|
||||
|
||||
/**
|
||||
* Checks if a given user is a member in the site.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $email The user email address.
|
||||
* @param int $user_id The user ID to check.
|
||||
* @return bool
|
||||
*/
|
||||
public function check_for_user_in_site($email, $user_id = 0) {
|
||||
|
||||
// Sets the right user to be returned;
|
||||
$has_user = false;
|
||||
|
||||
$query = array(
|
||||
'search' => $email,
|
||||
);
|
||||
|
||||
/**
|
||||
* When the user id is present, we use it
|
||||
* to disambiguate the users, as the same user
|
||||
* with the same email address can have users
|
||||
* registered on different sub-sites.
|
||||
*
|
||||
* @since 2.0.11
|
||||
*/
|
||||
if ($user_id) {
|
||||
|
||||
$query['include'] = array(
|
||||
absint($user_id),
|
||||
);
|
||||
|
||||
} // end if;
|
||||
|
||||
// Now we search for the correct user based on the password and the blog information
|
||||
$users = new \WP_User_Query($query);
|
||||
|
||||
// Loop the results and check which one is in this group
|
||||
foreach ($users->results as $user_with_email) {
|
||||
|
||||
// Check for the pertinence of that user in this site
|
||||
if ($this->user_can_for_blog($user_with_email, get_current_blog_id(), 'read')) {
|
||||
|
||||
$has_user = true;
|
||||
|
||||
break;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
// If nothing was found return false;
|
||||
return $has_user;
|
||||
|
||||
} // end check_for_user_in_site;
|
||||
/**
|
||||
* Gets the right user when logging-in.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param null|\WP_User|\WP_Error $user The current user object. Usually false.
|
||||
* @param string $username The username to search for.
|
||||
* @param string $password The user password.
|
||||
* @return null|\WP_User|\WP_Error
|
||||
*/
|
||||
public function fix_login($user, $username, $password) {
|
||||
|
||||
if (!is_email($username)) {
|
||||
|
||||
return $user;
|
||||
|
||||
} // end if;
|
||||
|
||||
// Sets the right user to be returned;
|
||||
$user = $this->get_right_user($username, $password);
|
||||
|
||||
return $user ? $user : null;
|
||||
|
||||
} // end fix_login;
|
||||
|
||||
/**
|
||||
* Check if user can do something in a specific blog.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param \WP_User $user The user object.
|
||||
* @param int $blog_id The blog id.
|
||||
* @param string $capability Capability to check against.
|
||||
* @return boolean
|
||||
*/
|
||||
public function user_can_for_blog($user, $blog_id, $capability) {
|
||||
|
||||
$switched = is_multisite() ? switch_to_blog($blog_id) : false;
|
||||
|
||||
$current_user = $user;
|
||||
|
||||
if (empty($current_user)) {
|
||||
|
||||
if ($switched) {
|
||||
|
||||
restore_current_blog();
|
||||
|
||||
} // end if;
|
||||
|
||||
return false;
|
||||
|
||||
} // end if;
|
||||
|
||||
$args = array_slice(func_get_args(), 2);
|
||||
|
||||
$args = array_merge(array($capability), $args);
|
||||
|
||||
$can = call_user_func_array(\Closure::fromCallable([$current_user, 'has_cap']), $args);
|
||||
|
||||
if ($switched) {
|
||||
|
||||
restore_current_blog();
|
||||
|
||||
} // end if;
|
||||
|
||||
return $can;
|
||||
|
||||
} // end user_can_for_blog;
|
||||
/**
|
||||
* Gets the right user for a given domain.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $email User email address.
|
||||
* @param boolean $password User password.
|
||||
* @return \WP_User|false
|
||||
*/
|
||||
protected function get_right_user($email, $password = false) {
|
||||
|
||||
// Sets the right user to be returned;
|
||||
$right_user = false;
|
||||
|
||||
// $hash = wp_hash_password($password);
|
||||
// Now we search for the correct user based on the password and the blog information
|
||||
$users = new \WP_User_Query(array('search' => $email));
|
||||
|
||||
// Loop the results and check which one is in this group
|
||||
foreach ($users->results as $user_with_email) {
|
||||
|
||||
$conditions = $password == false ? true : wp_check_password($password, $user_with_email->user_pass, $user_with_email->ID);
|
||||
|
||||
// Check for the pertinence of that user in this site
|
||||
if ($conditions && $this->user_can_for_blog($user_with_email, get_current_blog_id(), 'read')) {
|
||||
|
||||
// Set right user
|
||||
$right_user = $user_with_email;
|
||||
|
||||
continue;
|
||||
|
||||
} // end if;
|
||||
|
||||
} // end foreach;
|
||||
|
||||
// Return right user
|
||||
return $right_user;
|
||||
|
||||
} // end get_right_user;
|
||||
|
||||
} // end class Multiple_Accounts_Compat;
|
148
inc/compat/class-product-compat.php
Normal file
148
inc/compat/class-product-compat.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/**
|
||||
* Products Compatibility Layer
|
||||
*
|
||||
* Handles product compatibility back-ports to WP Ultimo 1.X builds.
|
||||
*
|
||||
* @package WP_Ultimo
|
||||
* @subpackage Compat/Product_Compat
|
||||
* @since 2.0.0
|
||||
*/
|
||||
|
||||
namespace WP_Ultimo\Compat;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Handles product compatibility back-ports to WP Ultimo 1.X builds.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Product_Compat {
|
||||
|
||||
use \WP_Ultimo\Traits\Singleton;
|
||||
|
||||
/**
|
||||
* Instantiate the necessary hooks.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return void
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
add_filter('wu_product_options_sections', array($this, 'add_legacy_section'), 100, 2);
|
||||
|
||||
add_filter('update_post_metadata', array($this, 'check_update_plan'), 10, 5);
|
||||
|
||||
} // end init;
|
||||
|
||||
/**
|
||||
* Saves meta data from old plugins on the new plugin.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param null $null Short-circuit control.
|
||||
* @param int $object_id Object ID, in this case, of the Post object.
|
||||
* @param string $meta_key The meta key being saved.
|
||||
* @param mixed $meta_value The meta value.
|
||||
* @param mixed $prev_value The previous value.
|
||||
* @return null
|
||||
*/
|
||||
public function check_update_plan($null, $object_id, $meta_key, $meta_value, $prev_value) {
|
||||
/*
|
||||
* Check if we are in the main site of the network.
|
||||
*/
|
||||
if (!is_main_site()) {
|
||||
|
||||
return;
|
||||
|
||||
} // end if;
|
||||
|
||||
/*
|
||||
* Check if we have a new entity with this ID.
|
||||
*/
|
||||
$migrated_product = wu_get_product($object_id);
|
||||
|
||||
if (!$migrated_product) {
|
||||
|
||||
return;
|
||||
|
||||
} // end if;
|
||||
|
||||
/*
|
||||
* Prevent double prefixing.
|
||||
*/
|
||||
$meta_key = str_replace('wpu_', '', $meta_key);
|
||||
|
||||
/*
|
||||
* Save using the new meta table.
|
||||
*/
|
||||
$migrated_product->update_meta('wpu_' . $meta_key, maybe_serialize($meta_value));
|
||||
|
||||
/**
|
||||
* Explicitly returns null so we don't forget that
|
||||
* returning anything else will prevent meta data from being saved.
|
||||
*/
|
||||
return null;
|
||||
|
||||
} // end check_update_plan;
|
||||
|
||||
/**
|
||||
* Injects the compatibility panels to products Advanced Options.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $sections List of tabbed widget sections.
|
||||
* @param \WP_Ultimo\Models\Product $object The model being edited.
|
||||
* @return array
|
||||
*/
|
||||
public function add_legacy_section($sections, $object) {
|
||||
|
||||
$sections['legacy_options_core'] = array(
|
||||
'title' => __('Legacy Options', 'wp-ultimo'),
|
||||
'desc' => __('Options used by old 1.X versions. ', 'wp-ultimo'),
|
||||
'icon' => 'dashicons-wu-spreadsheet',
|
||||
'state' => array(
|
||||
'legacy_options' => $object->get_legacy_options(),
|
||||
),
|
||||
'fields' => array(
|
||||
'legacy_options' => array(
|
||||
'type' => 'toggle',
|
||||
'value' => $object->get_legacy_options(),
|
||||
'title' => __('Toggle Legacy Options', 'wp-ultimo'),
|
||||
'desc' => __('Toggle this option to edit legacy options.', 'wp-ultimo'),
|
||||
'html_attr' => array(
|
||||
'v-model' => 'legacy_options',
|
||||
),
|
||||
),
|
||||
'featured_plan' => array(
|
||||
'type' => 'toggle',
|
||||
'value' => $object->is_featured_plan(),
|
||||
'title' => __('Featured Plan', 'wp-ultimo'),
|
||||
'desc' => __('Toggle this option to mark this product as featured on the legacy pricing tables.', 'wp-ultimo'),
|
||||
'wrapper_html_attr' => array(
|
||||
'v-show' => 'legacy_options',
|
||||
),
|
||||
),
|
||||
'feature_list' => array(
|
||||
'type' => 'textarea',
|
||||
'title' => __('Features List', 'wp-ultimo'),
|
||||
'placeholder' => __('E.g. Feature 1', 'wp-ultimo') . PHP_EOL . __('Feature 2', 'wp-ultimo'),
|
||||
'desc' => __('Add a feature per line. These will be shown on the pricing tables.', 'wp-ultimo'),
|
||||
'value' => $object->get_feature_list(),
|
||||
'wrapper_html_attr' => array(
|
||||
'v-show' => 'legacy_options',
|
||||
),
|
||||
'html_attr' => array(
|
||||
'rows' => 6,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $sections;
|
||||
|
||||
} // end add_legacy_section;
|
||||
|
||||
} // end class Product_Compat;
|
Reference in New Issue
Block a user