512 lines
19 KiB
PHP
512 lines
19 KiB
PHP
<?php
|
|
|
|
class OneHomeSections {
|
|
|
|
const MARKETPLACE_SLUG = 'onecom-marketplace';
|
|
public function __construct() {
|
|
add_action( 'wp_ajax_oc_close_welcome_modal', array( $this, 'oc_close_welcome_modal' ) );
|
|
add_action('upgrader_process_complete', array($this, 'reset_transient_on_core_update'), 10, 2);
|
|
add_action('update_option_WPLANG', array($this, 'reset_transient_for_featured_list'), 10, 0);
|
|
add_action('upgrader_process_complete', array($this,'onecom_clear_marketplace_transient_on_update'), 10, 2);
|
|
|
|
add_action('activated_plugin', array($this,'onecom_clear_mp_catalog_transients'));
|
|
add_action('deactivated_plugin', array($this,'onecom_clear_mp_catalog_transients'));
|
|
}
|
|
|
|
function get_cards(): array {
|
|
return array(
|
|
array(
|
|
'title' => __( 'Health and Security', 'onecom-wp' ),
|
|
'subtitle' => __( 'Keep your site secure.', 'onecom-wp' ),
|
|
'url' => admin_url( 'admin.php?page=onecom-wp-health-monitor' ),
|
|
'icon' => 'health-monitor',
|
|
'event_track_class' => 'ocwp_ocp_home_health_security_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( 'Performance', 'onecom-wp' ),
|
|
'subtitle' => __( 'Make sure your website loads fast.', 'onecom-wp' ),
|
|
'url' => $this->get_performance_plugin_url(),
|
|
'icon' => 'external-server',
|
|
'event_track_class' => 'ocwp_ocp_home_performance_link_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( 'Staging', 'onecom-wp' ),
|
|
'subtitle' => __( 'Test changes in staging.', 'onecom-wp' ),
|
|
'url' => admin_url( 'admin.php?page=onecom-wp-staging' ),
|
|
'icon' => 'staging',
|
|
'event_track_class' => 'ocwp_ocp_home_staging_link_clicked_event'
|
|
),
|
|
);
|
|
}
|
|
|
|
function get_help_cards(): array {
|
|
return array(
|
|
array(
|
|
'title' => __( 'Help Centre', 'onecom-wp' ),
|
|
'subtitle' => __( 'Find answers quickly in our Help Centre.', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com',
|
|
'icon' => 'help',
|
|
'event_track_class' => 'ocwp_ocp_home_help_centre_link_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( 'Email support', 'onecom-wp' ),
|
|
'subtitle' => __( 'We will respond within 24 hours, all year round.', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/requests/new',
|
|
'icon' => 'library_books',
|
|
'event_track_class' => 'ocwp_ocp_home_email_support_link_clicked_event'
|
|
),
|
|
);
|
|
}
|
|
|
|
function get_articles_mwp(): array {
|
|
return array(
|
|
array(
|
|
'title' => __( 'How to build your WordPress website', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/articles/360001788897',
|
|
'event_track_class' => 'ocwp_ocp_home_build_wp_site_link_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( 'What is the one.com plugin?', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/articles/115005593945',
|
|
'event_track_class' => 'ocwp_ocp_home_what_is_ocp_plugin_link_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( 'What is Maintenance Mode', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/articles/8096988382353',
|
|
'event_track_class' => 'ocwp_ocp_home_what_is_mm_link_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( 'Using the one.com Staging feature for WordPress', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/articles/360000020617',
|
|
'event_track_class' => 'ocwp_ocp_home_using_staging_link_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( 'How to use the Performance Cache plugin for WordPress', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/articles/360000080458',
|
|
'event_track_class' => 'ocwp_ocp_home_using_pcache_link_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( 'How can I improve the speed of my WordPress site', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/articles/6555011842705-How-can-I-improve-the-speed-of-my-WordPress-site',
|
|
'event_track_class' => 'ocwp_ocp_home_special_mwp_support_link_clicked_event'
|
|
),
|
|
);
|
|
}
|
|
|
|
function get_articles_basic(): array {
|
|
return array(
|
|
array(
|
|
'title' => __( 'How to build your WordPress website', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/articles/360001788897',
|
|
'event_track_class' => 'ocwp_ocp_home_build_wp_site_link_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( 'What is the one.com plugin?', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/articles/115005593945',
|
|
'event_track_class' => 'ocwp_ocp_home_what_is_ocp_plugin_link_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( "What is one.com's Managed WordPress", 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/articles/360020315097',
|
|
'event_track_class' => 'ocwp_ocp_home_what_is_ocp_mwp_link_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( 'What is Maintenance Mode', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/articles/8096988382353',
|
|
'event_track_class' => 'ocwp_ocp_home_what_is_mm_link_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( 'How to use the Performance Cache plugin for WordPress', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/articles/360000080458',
|
|
'event_track_class' => 'ocwp_ocp_home_using_pcache_link_clicked_event'
|
|
),
|
|
array(
|
|
'title' => __( 'What is WP Rocket', 'onecom-wp' ),
|
|
'url' => 'https://help.one.com/hc/en-us/articles/5927991871761',
|
|
'event_track_class' => 'ocwp_ocp_home_what_is_wpr_link_clicked_event'
|
|
),
|
|
);
|
|
}
|
|
|
|
|
|
function get_cp_url() {
|
|
$domain = $_SERVER['HTTP_X_GROUPONE_HOST'] ?? '';
|
|
return esc_url( 'https://www.one.com/admin/managedwp/' . $domain . '/managed-wp-dashboard.do' );
|
|
}
|
|
|
|
function get_performance_plugin_url() {
|
|
if ( in_array( 'onecom-vcache/vcaching.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
|
|
return admin_url( 'admin.php?page=onecom-vcache-plugin' );
|
|
} else {
|
|
return admin_url( 'admin.php?page=onecom-wp-rocket' );
|
|
}
|
|
}
|
|
|
|
function oc_close_welcome_modal() {
|
|
|
|
$user_id = get_current_user_id();
|
|
|
|
if ( $user_id ) {
|
|
// Update the user meta for the currently logged-in user
|
|
$update_meta = update_user_meta( $user_id, 'oc-welcome-modal-closed', true );
|
|
|
|
if ( $update_meta || is_integer( $update_meta ) ) {
|
|
// Send a success response
|
|
wp_send_json_success( array( 'message' => 'Welcome modal successfully closed' ) );
|
|
} else {
|
|
// Send a failure response
|
|
wp_send_json_error( array( 'message' => 'Failed to update the welcome modal user meta' ) );
|
|
}
|
|
} else {
|
|
// Send an error response if no user is logged in
|
|
wp_send_json_error( array( 'message' => 'User not logged in' ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetch products from API
|
|
* @param bool $force
|
|
* @param string $domain
|
|
* @return array|mixed|WP_Error
|
|
*/
|
|
public function fetch_products_from_api(bool $force = false, string $domain = '' ): mixed
|
|
{
|
|
// check transient
|
|
$featured_products_info = get_site_transient( 'onecom_marketplace_catalog' );
|
|
if ( is_array( $featured_products_info ) &&
|
|
! empty( $featured_products_info['success'] ) &&
|
|
isset( $featured_products_info['data']['catalog'] ) &&
|
|
is_array( $featured_products_info['data']['catalog']) && false === $force ) {
|
|
error_log( '[MP_ONECOM_PLUGIN] Using cached featured products info' );
|
|
return $featured_products_info;
|
|
}
|
|
|
|
//prepare headers for a domain model
|
|
$api_url = MIDDLEWARE_URL .'/marketplace/products/catalog';
|
|
|
|
$wpAdminEnvInfo = $this->get_admin_env_info();
|
|
|
|
// Set default locale if empty
|
|
if ( empty( get_locale() ) ) {
|
|
$wpAdminEnvInfo['locale'] = 'en_GB';
|
|
}
|
|
|
|
// Add locale, php_version and wp_version as query parameter
|
|
$url = add_query_arg( 'locale', $wpAdminEnvInfo['locale'], $api_url );
|
|
$url = add_query_arg( 'php', $wpAdminEnvInfo['php_version'], $url );
|
|
$url = add_query_arg( 'wp', $wpAdminEnvInfo['wp_version'], $url );
|
|
|
|
// headers and api url based on cluster domain or not
|
|
add_filter('http_request_args', 'oc_add_http_headers', 10, 2);
|
|
|
|
$response = wp_remote_get($url, array('timeout' => 60));
|
|
|
|
remove_filter('http_request_args', 'oc_add_http_headers');
|
|
|
|
if ( is_wp_error( $response ) ) {
|
|
error_log( '[MP_ONECOM_PLUGIN] Error fetching featured products info from API: ');
|
|
return array(
|
|
'data' => array(),
|
|
'error' => __( 'Some error occurred, please reload the page and try again.', 'validator' ),
|
|
'success' => false,
|
|
);
|
|
}
|
|
|
|
$response = json_decode( wp_remote_retrieve_body( $response ), true );
|
|
|
|
if (
|
|
! empty( $response['success'] ) &&
|
|
isset( $response['data']['catalog'] ) &&
|
|
is_array( $response['data']['catalog'] )
|
|
){
|
|
// save transient for next calls and return the latest response
|
|
set_site_transient( 'onecom_marketplace_catalog', $response, 15 * MINUTE_IN_SECONDS );
|
|
error_log( '[MP_ONECOM_PLUGIN] Successfully fetched featured products info from API' );
|
|
return $response;
|
|
} else {
|
|
return array(
|
|
'data' => array(),
|
|
'error' => __( 'Some error occurred, please reload the page and try again.', 'validator' ),
|
|
'success' => false,
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get featured products only
|
|
*
|
|
* @return array Array of featured products
|
|
*/
|
|
public function get_featured_products(): array
|
|
{
|
|
// Fetch products from API and return the data, we can also use true for force parameter to fetch fresh data
|
|
//For now fetch on each page load
|
|
$response = $this->fetch_products_from_api();
|
|
|
|
|
|
// Check if the response has the expected structure
|
|
if ( ! is_array( $response['data'] ) || empty( $response['data']) ) {
|
|
error_log( '[MP_ONECOM_PLUGIN] Error fetching featured products info from API: Invalid response structure' );
|
|
return array(
|
|
'catalog' => [],
|
|
'uiI18n' => '',
|
|
);
|
|
}
|
|
|
|
$catalog = $response['data']['catalog'] ?? [];
|
|
|
|
// Check if Rank Math free version is active
|
|
$is_rank_math_free_active = $this->is_plugin_active_by_slug('seo-by-rank-math');
|
|
|
|
// Filter products where featured === true
|
|
$featured_products = array_filter( $catalog, function( $product ) use ( $is_rank_math_free_active ) {
|
|
if (!isset($product['featured']) || $product['featured'] !== true || $this->is_plugin_active_by_slug($product['slug'])) {
|
|
return false;
|
|
}
|
|
|
|
// Special filter for Rank Math: if free version is not active, exclude pro version
|
|
if (!$is_rank_math_free_active && $product['slug'] === 'seo-by-rank-math-pro') {
|
|
return false;
|
|
}
|
|
|
|
// If a product has mustHavePlugins dependency, check it
|
|
if (isset($product['rules']['mustHavePlugins']) && is_array($product['rules']['mustHavePlugins'])) {
|
|
return $this->are_plugin_dependencies_active($product['rules']['mustHavePlugins']);
|
|
}
|
|
// If a product has mustHaveThemesByAuthor dependency, check it
|
|
if (isset($product['rules']['mustHaveThemesByAuthor'])) {
|
|
return $this->are_theme_dependencies_active($product['rules']);
|
|
}
|
|
// Default for other plugins
|
|
return true;
|
|
} );
|
|
|
|
$featured_products = array_values( $featured_products );
|
|
|
|
// Sort by displayOrder key (ascending)
|
|
usort( $featured_products, function( $a, $b ) {
|
|
$order_a = isset( $a['displayOrder'] ) ? (int) $a['displayOrder'] : PHP_INT_MAX;
|
|
$order_b = isset( $b['displayOrder'] ) ? (int) $b['displayOrder'] : PHP_INT_MAX;
|
|
return $order_a <=> $order_b;
|
|
} );
|
|
|
|
// Re-index array
|
|
return array(
|
|
'catalog' => $featured_products,
|
|
'uiI18n' => $response['data']['uiI18n'] ?? [],
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if a plugin is active by its slug
|
|
* @param $plugin_slug
|
|
* @return bool
|
|
*/
|
|
public function is_plugin_active_by_slug( $plugin_slug ): bool
|
|
{
|
|
$plugins = get_option( 'active_plugins' );
|
|
|
|
foreach ( $plugins as $key => $plugin_path ) {
|
|
// Example $plugin_path = "rank-math/rank-math.php"
|
|
if ( strpos( $plugin_path, $plugin_slug . '/' ) === 0 ) {
|
|
|
|
// Found plugin inside folder "<slug>/..."
|
|
if ( is_plugin_active( $plugin_path ) ) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Example cURL request for the API endpoint
|
|
* Usage: Call this from the command line or use as a reference
|
|
*
|
|
* curl -X GET "https://local-ssh.mwp.1prod.one/wp-content/wp-mp.json?locale=en_US" \
|
|
* -H "Accept: application/json"
|
|
*/
|
|
|
|
public function get_recommended_products_list(): bool|string
|
|
{
|
|
|
|
ob_start();
|
|
$products = $this->get_featured_products();
|
|
$featured_products = $products['catalog'];
|
|
$uiI18n = $products['uiI18n']['featuredCta'] ?? __( 'Get started', 'onecom-wp' );
|
|
|
|
if(empty($featured_products) || !is_array($featured_products)){
|
|
error_log('[MP_ONECOM_PLUGIN] No featured products found or all feature products are already installed and activated.');
|
|
return ob_get_clean();
|
|
}
|
|
|
|
$plugin_attr = array_column($featured_products, 'slug');//Get plugin slugs
|
|
$referrer = ( isset( $_SERVER['HTTP_REFERER'] ) ? parse_url( $_SERVER['HTTP_REFERER'], PHP_URL_QUERY ) : '' );
|
|
( class_exists( OCPUSHSTATS ) ? \OCPushStats::push_stats_event_themes_and_plugins( 'recommended_products_viewed', 'misc' , 'onecom_home', "$referrer", ["products" => implode(',', $plugin_attr)] ) : '' );
|
|
?>
|
|
<div class="gv-grid gv-grid-cols-2 gv-pb-md gv-pt-lg">
|
|
<strong class="gv-text-lg oc-dicover-wp"><?php echo __( 'Recommended WordPress products', 'onecom-wp' ); ?></strong>
|
|
<div class="gv-flex gv-justify-end">
|
|
<a href="<?php echo admin_url( 'admin.php?page='.OneHomeSections::MARKETPLACE_SLUG );?>"
|
|
class="gv-button gv-button-primary gv-mode-condensed ocwp_ocp_home_all_products_link_clicked_event">
|
|
<span class="oc-all-articles"><?php echo __( 'ui.button.seeAllProducts', 'onecom-wp' ); ?></span>
|
|
<img src="<?php echo ONECOM_WP_URL; ?>modules/home/assets/icons/white-arrow.svg" class
|
|
="ocwp_ocp_home_all_products_link_clicked_event gv-ml-sm" height="14px" width="14px" alt="<?php echo __( 'ui.button.seeAllProducts', 'onecom-wp' ); ?>"/>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="gv-grid gv-gap-lg gv-tab-grid-cols-2 gv-desk-grid-cols-3 recommendations-grid">
|
|
<?php
|
|
//Filter only 3 featured products
|
|
$featured_products = array_slice($featured_products, 0, 3);
|
|
if ( ! empty( $featured_products ) ) {
|
|
foreach ( $featured_products as $product ) {
|
|
$icon_url = esc_url( $product['bannerUrl'] );
|
|
$product_name = esc_html( $product['i18n']['featuredTitle'] );
|
|
$product_description = esc_html( $product['i18n']['featuredContent'] );
|
|
$install_button_text = $uiI18n;
|
|
$product_slug = esc_attr( $product['slug'] );
|
|
?>
|
|
<div class="gv-card" data-product-slug="<?php echo $product_slug; ?>">
|
|
<div class="gv-card-image">
|
|
<img
|
|
src="<?php echo $icon_url; ?>"
|
|
alt="<?php echo $product_name; ?>"
|
|
/>
|
|
</div>
|
|
<div class="gv-card-content">
|
|
<h3 class="gv-card-title"><?php echo $product_name; ?></h3>
|
|
<p><?php echo $product_description; ?></p>
|
|
</div>
|
|
<div class="gv-card-footer">
|
|
<a href="<?php echo admin_url( 'admin.php?page='.OneHomeSections::MARKETPLACE_SLUG.'&plugin='.$product_slug );?>" class="gv-button gv-button-secondary gv-button-sm ocwp_ocp_home_<?php echo $product_slug;?>_link_clicked_event">
|
|
<span><?php echo $install_button_text; ?></span>
|
|
<img src="<?php echo ONECOM_WP_URL; ?>/modules/home/assets/icons/arrow_forward.svg" aria-hidden="true" height="24px" width="24px" alt="<?php echo $install_button_text; ?>"/>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
}
|
|
} ?>
|
|
</div>
|
|
<?php
|
|
return ob_get_clean();
|
|
}
|
|
|
|
/**
|
|
* Retrieve WordPress admin environment information.
|
|
*
|
|
* @return array Associative array containing environment details including locale, user locale, WordPress version, and PHP version.
|
|
*/
|
|
public function get_admin_env_info(): array
|
|
{
|
|
return [
|
|
'locale' => get_locale(),
|
|
'user_locale' => get_user_locale(),
|
|
'wp_version' => get_bloginfo('version'),
|
|
'php_version' => phpversion(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Resets the transient cache for the featured list.
|
|
*
|
|
* This method deletes the site transient related to featured products information, ensuring that the data is refreshed.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function reset_transient_for_featured_list(): void
|
|
{
|
|
error_log('[MP_ONECOM_PLUGIN] Reset transient for featured products list on locale change');
|
|
delete_site_transient( 'onecom_marketplace_catalog' );
|
|
}
|
|
|
|
/**
|
|
* Resets the transient cache for the featured list on core update.
|
|
* @param $upgrader
|
|
* @param $hook_extra
|
|
* @return void
|
|
*/
|
|
public function reset_transient_on_core_update($upgrader, $hook_extra): void
|
|
{
|
|
if (
|
|
empty( $hook_extra['action'] ) || 'update' !== $hook_extra['action'] ||
|
|
empty( $hook_extra['type'] ) || 'core' !== $hook_extra['type']
|
|
) {
|
|
return;
|
|
}
|
|
|
|
error_log('[MP_ONECOM_PLUGIN] Reset transient for featured products list on core update.');
|
|
delete_site_transient( 'onecom_marketplace_catalog' );
|
|
}
|
|
|
|
/**
|
|
* Checks if any required plugin from the mustHavePlugins array is installed and active.
|
|
* Uses is_plugin_active_by_slug for each slug.
|
|
*
|
|
* @param array $mustHavePlugins Array of plugin slugs (e.g., 'wpforms-lite', 'gravityforms')
|
|
* @return bool True if at least one required plugin is active, false otherwise.
|
|
*/
|
|
public function are_plugin_dependencies_active(array $mustHavePlugins = array()): bool
|
|
{
|
|
if (empty($mustHavePlugins) || !is_array($mustHavePlugins)) {
|
|
return false;
|
|
}
|
|
foreach ($mustHavePlugins as $plugin_slug) {
|
|
if ($this->is_plugin_active_by_slug($plugin_slug)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Checks if the required theme dependency is met based on the mustHaveThemesByAuthor rule.
|
|
*
|
|
* @param array $rules Product rules array
|
|
* @return bool True if the theme author matches, false otherwise.
|
|
*/
|
|
public function are_theme_dependencies_active(array $rules = array()): bool
|
|
{
|
|
$theme = wp_get_theme();
|
|
if (isset($rules['mustHaveThemesByAuthor']) && $rules['mustHaveThemesByAuthor']) {
|
|
$author = $theme->get('Author');
|
|
if (strtolower($author) === strtolower($rules['mustHaveThemesByAuthor'])) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Clear marketplace catalog transient on onecom-themes-plugins update
|
|
* @param $upgrader_object
|
|
* @param $options
|
|
* @return void
|
|
*/
|
|
public function onecom_clear_marketplace_transient_on_update($upgrader_object, $options): void
|
|
{
|
|
if ($options['action'] !== 'update' || $options['type'] !== 'plugin') {
|
|
return;
|
|
}
|
|
|
|
$plugin_slug = 'onecom-themes-plugins/onecom-themes-plugins.php';
|
|
|
|
if (!empty($options['plugins']) && in_array($plugin_slug, $options['plugins'], true)) {
|
|
error_log('[MP_ONECOM_PLUGIN] Reset transient marketplace catalog on onecom-themes-plugins update.');
|
|
delete_site_transient('onecom_marketplace_catalog');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear marketplace catalog transient on plugin activation/deactivation
|
|
* @param $plugin
|
|
* @return void
|
|
*/
|
|
public function onecom_clear_mp_catalog_transients($plugin): void {
|
|
if ($plugin === 'onecom-themes-plugins/onecom-themes-plugins.php') {
|
|
error_log('[MP_ONECOM_PLUGIN] Reset transient marketplace catalog on onecom-themes-plugins activation/deactivation.');
|
|
delete_site_transient('onecom_marketplace_catalog');
|
|
}
|
|
}
|
|
}
|