first commit

This commit is contained in:
User A0264400
2026-04-01 23:20:16 +03:00
commit a766acdc90
23071 changed files with 4933189 additions and 0 deletions

View File

@@ -0,0 +1,423 @@
<?php
/**
* UAGB Block Analytics Manager.
*
* Class to manage block usage analytics collection and reporting.
*
* @since 2.19.13
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'UAGB_Block_Analytics' ) ) {
/**
* Class UAGB_Block_Analytics
*
* Manages block usage analytics collection and reporting.
*
* @since 2.19.13
* @package UAGB
*/
class UAGB_Block_Analytics {
/**
* Member Variable
*
* @var UAGB_Block_Analytics|null
* @since 2.19.13
*/
private static $instance;
/**
* Block stats processor instance.
*
* @var UAGB_Block_Stats_Processor
* @since 2.19.13
*/
private $stats_processor;
/**
* Incremental block tracker instance.
*
* @var UAGB_Incremental_Block_Tracker
* @since 2.19.13
*/
private $incremental_tracker;
/**
* Initiator
*
* @since 2.19.13
* @return UAGB_Block_Analytics
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*
* @since 2.19.13
* @return void
*/
public function __construct() {
// Load the stats processor and incremental tracker.
require_once UAGB_DIR . 'classes/analytics/class-uagb-block-stats-processor.php';
require_once UAGB_DIR . 'classes/analytics/class-uagb-incremental-block-tracker.php';
$this->stats_processor = new UAGB_Block_Stats_Processor();
$this->incremental_tracker = UAGB_Incremental_Block_Tracker::get_instance();
// Hook into analytics option changes.
add_action( 'update_option_spectra_usage_optin', array( $this, 'handle_analytics_optin_change' ), 10, 3 );
add_action( 'add_option_spectra_usage_optin', array( $this, 'handle_analytics_optin_add' ), 10, 2 );
// Hook into plugin activation for first-run stats collection.
add_action( 'init', array( $this, 'maybe_start_first_run_collection' ) );
}
/**
* Handle analytics opt-in option update.
*
* @param string $old_value Old value.
* @param string $value New value.
* @param string $option Option name.
* @since 2.19.13
* @return void
*/
public function handle_analytics_optin_change( $old_value, $value, $option ) {
if ( 'yes' === $value && 'yes' !== $old_value ) {
// Analytics was just enabled, start collection.
$this->start_stats_collection();
}
}
/**
* Handle analytics opt-in option addition.
*
* @param string $option Option name.
* @param string $value Option value.
* @since 2.19.13
* @return void
*/
public function handle_analytics_optin_add( $option, $value ) {
if ( 'yes' === $value ) {
// Analytics was enabled, start collection.
$this->start_stats_collection();
}
}
/**
* Maybe start first-run stats collection.
*
* This is called during plugin initialization to check if this is a first-run
* installation and start stats collection.
*
* @since 2.19.13
* @return void
*/
public function maybe_start_first_run_collection() {
// Check if this is a first-run (plugin just installed).
$status = get_option( 'uagb_block_usage_status', array() );
if ( ! is_array( $status ) ) {
$status = array();
}
if ( empty( $status['first_run_check'] ) ) {
// Mark first run check as done.
$status['first_run_check'] = true;
update_option( 'uagb_block_usage_status', $status );
// Start initial stats collection and setup incremental tracking.
$this->start_initial_setup();
}
}
/**
* Start block usage stats collection (initial scan only).
*
* This method triggers the background process ONLY for initial setup.
* After initial setup, all tracking is done via real-time incremental updates.
*
* @since 2.19.13
* @return void
*/
public function start_stats_collection() {
// Only start if analytics is enabled or this is first run.
$analytics_enabled = get_option( 'spectra_usage_optin', 'no' ) === 'yes';
$status = get_option( 'uagb_block_usage_status', array() );
if ( ! is_array( $status ) ) {
$status = array();
}
$is_first_run = empty( $status['first_run_check'] );
if ( ! $analytics_enabled && ! $is_first_run ) {
return;
}
// Check if collection is already in progress.
if ( ! empty( $status['is_processing'] ) ) {
return;
}
// Only run background scan if we don't have existing stats or this is forced refresh.
$analytics_data = get_option( 'uagb_block_usage_data', array() );
if ( ! is_array( $analytics_data ) ) {
$analytics_data = array();
}
$has_existing_stats = ! empty( $analytics_data['block_usage_stats'] );
// Skip background scan if we already have stats and this isn't first run.
if ( $has_existing_stats && ! $is_first_run ) {
return;
}
// Start the background collection process.
$this->stats_processor->start_collection();
}
/**
* Get block usage statistics for analytics reporting.
*
* This method merges block usage statistics with existing spectra stats,
* ensuring numeric_values are added (not replaced) if they already exist.
*
* @since 2.19.13
* @param array $existing_stats Existing spectra stats to merge with.
* @return array Merged stats with block usage data.
*/
public function get_block_stats_for_analytics( $existing_stats = array() ) {
// Only return stats if analytics is enabled.
if ( get_option( 'spectra_usage_optin', 'no' ) !== 'yes' ) {
return $existing_stats;
}
$stats = UAGB_Block_Stats_Processor::get_block_stats();
$collection_complete = UAGB_Block_Stats_Processor::is_collection_complete();
$last_collection = UAGB_Block_Stats_Processor::get_last_collection_time();
// Format block usage stats to add 'block_usage_' prefix to the keys.
$formatted_block_usage_stats = array_combine(
array_map(
function ( $key ) {
return 'block_usage_' . $key;
},
array_keys( $stats )
),
array_values( $stats )
);
// Ensure array_combine succeeded, otherwise use empty array.
if ( ! is_array( $formatted_block_usage_stats ) ) {
$formatted_block_usage_stats = array();
}
// Get site activity level for Active Site / Super Site KPIs.
$site_activity = $this->get_site_activity_level();
// Prepare advanced stats structure.
$advanced_stats = array(
'numeric_values' => $formatted_block_usage_stats,
'block_usage_stats_metadata' => array(
'collection_complete' => $collection_complete,
'last_collected' => $last_collection ? gmdate( 'Y-m-d H:i:s', $last_collection ) : null,
'total_blocks_tracked' => count( array_filter( $stats ) ),
'most_used_blocks' => $this->get_most_used_blocks( $stats, 10 ),
),
'site_activity' => $site_activity,
);
// Merge numeric_values by adding numbers if they already exist.
// Check if numeric_values array exists in existing_stats and validate it's an array.
if ( isset( $existing_stats['numeric_values'] ) && is_array( $existing_stats['numeric_values'] ) ) {
// Loop through each block's usage count from advanced_stats.
foreach ( $advanced_stats['numeric_values'] as $key => $value ) {
// If the key exists in existing_stats and both values are numeric, add them together.
// Otherwise, use the new value from advanced_stats (either new key or non-numeric value).
$existing_stats['numeric_values'][ $key ] = ( isset( $existing_stats['numeric_values'][ $key ] )
&& is_numeric( $value )
&& is_numeric( $existing_stats['numeric_values'][ $key ] ) )
? $existing_stats['numeric_values'][ $key ] + $value
: $value;
}
// Remove numeric_values from advanced_stats to prevent duplication in array_merge_recursive below.
unset( $advanced_stats['numeric_values'] );
}
// Merge remaining advanced stats (metadata, etc.) with existing stats.
return array_merge_recursive( $existing_stats, $advanced_stats );
}
/**
* Get the most used blocks from stats.
*
* @param array $stats Block usage statistics.
* @param int $limit Number of top blocks to return.
* @since 2.19.13
* @return array Top used blocks.
*/
private function get_most_used_blocks( $stats, $limit = 10 ) {
// Filter out blocks with 0 usage and sort by usage count.
$filtered_stats = array_filter( $stats );
arsort( $filtered_stats );
// Return top blocks.
return array_slice( $filtered_stats, 0, $limit, true );
}
/**
* Force refresh block statistics (for data validation only).
*
* This method should only be used for manual data validation or troubleshooting.
* Normal operation relies on real-time incremental tracking.
*
* @since 2.19.13
* @return void
*/
public function force_refresh_stats() {
// Clear existing processing flag to allow new collection.
$status = get_option( 'uagb_block_usage_status', array() );
if ( ! is_array( $status ) ) {
$status = array();
}
$status['is_processing'] = false;
update_option( 'uagb_block_usage_status', $status );
// Reinitialize post tracking metadata.
$this->incremental_tracker->initialize_existing_posts();
// Start full collection for validation.
$this->start_stats_collection();
}
/**
* Start initial setup combining background scan and incremental tracking.
*
* This method is called on first-run to both scan existing content
* and setup incremental tracking for future changes.
*
* @since 2.19.13
* @return void
*/
public function start_initial_setup() {
// Only setup if analytics is enabled or this is first run.
$analytics_enabled = get_option( 'spectra_usage_optin', 'no' ) === 'yes';
$status = get_option( 'uagb_block_usage_status', array() );
if ( ! is_array( $status ) ) {
$status = array();
}
$is_first_run = empty( $status['first_run_check'] );
if ( ! $analytics_enabled && ! $is_first_run ) {
return;
}
// Initialize existing posts for incremental tracking.
$this->incremental_tracker->initialize_existing_posts();
// Start the background collection process to build initial stats.
$this->start_stats_collection();
}
/**
* Get stats collection status.
*
* @since 2.19.13
* @return array Status information about stats collection.
*/
public function get_collection_status() {
$status = get_option( 'uagb_block_usage_status', array() );
$analytics_data = get_option( 'uagb_block_usage_data', array() );
if ( ! is_array( $status ) ) {
$status = array();
}
if ( ! is_array( $analytics_data ) ) {
$analytics_data = array();
}
return array(
'is_processing' => ! empty( $status['is_processing'] ),
'is_complete' => ! empty( $status['collection_complete'] ),
'last_collected' => isset( $status['last_collected'] ) ? $status['last_collected'] : false,
'last_updated' => isset( $analytics_data['last_updated'] ) ? $analytics_data['last_updated'] : false,
'analytics_enabled' => get_option( 'spectra_usage_optin', 'no' ) === 'yes',
'first_run_done' => ! empty( $status['first_run_check'] ),
'has_stats' => ! empty( $analytics_data['block_usage_stats'] ),
'tracking_method' => 'incremental', // Now using incremental tracking instead of batch processing.
'total_tracked_blocks' => ! empty( $analytics_data['block_usage_stats'] ) && is_array( $analytics_data['block_usage_stats'] ) ? count( array_filter( $analytics_data['block_usage_stats'] ) ) : 0,
);
}
/**
* Get site activity level based on Spectra block edits in the last 180 days.
*
* Calculates KPIs for:
* - Active Site: Spectra blocks manually added/edited on at least 1 page in last 180 days
* - Super Site: Spectra blocks manually added/edited on at least 15 pages in last 180 days
*
* @since 2.19.19
* @return array Site activity data with classification.
*/
public function get_site_activity_level() {
$days_threshold = 180;
$cutoff_time = time() - ( $days_threshold * DAY_IN_SECONDS );
$post_types = get_post_types( array( 'public' => true ), 'names' );
// Query posts where Spectra blocks have been edited in the last 180 days.
$posts = get_posts(
array(
'post_type' => $post_types,
'post_status' => array( 'publish', 'private', 'draft' ),
'posts_per_page' => -1,
'fields' => 'ids',
'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Required for site activity KPI calculation.
array(
'key' => '_uagb_last_spectra_edit',
'value' => $cutoff_time,
'compare' => '>=',
'type' => 'NUMERIC',
),
),
)
);
$active_pages_count = count( $posts );
// Determine site classification.
$site_type = 'inactive';
if ( $active_pages_count >= 15 ) {
$site_type = 'super_site';
} elseif ( $active_pages_count >= 1 ) {
$site_type = 'active_site';
}
return array(
'active_pages_180d' => $active_pages_count,
'site_type' => $site_type,
'is_active_site' => $active_pages_count >= 1,
'is_super_site' => $active_pages_count >= 15,
);
}
}
}

View File

@@ -0,0 +1,357 @@
<?php
/**
* UAGB Block Stats Background Processor.
*
* Class to execute background processing for block usage analytics.
*
* @since 2.19.13
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WP_Async_Request' ) ) {
require_once UAGB_DIR . 'lib/batch-processing/class-wp-async-request.php';
}
if ( ! class_exists( 'WP_Background_Process' ) ) {
require_once UAGB_DIR . 'lib/batch-processing/class-wp-background-process.php';
}
if ( ! class_exists( 'UAGB_Block_Stats_Processor' ) ) {
/**
* Class UAGB_Block_Stats_Processor
*
* Handles background processing for block usage statistics collection.
*
* @since 2.19.13
* @package UAGB
*/
class UAGB_Block_Stats_Processor extends WP_Background_Process {
/**
* Action name.
*
* @var string
* @since 2.19.13
*/
protected $action = 'uagb_block_stats_collection';
/**
* List of all Spectra blocks to track (Core + Pro).
*
* @var array
* @since 2.19.13
*/
private $spectra_blocks = array(
// Spectra Core Blocks.
'uagb/advanced-heading',
'uagb/blockquote',
'uagb/buttons',
'uagb/buttons-child',
'uagb/call-to-action',
'uagb/cf7-styler',
'uagb/column',
'uagb/columns',
'uagb/container',
'uagb/content-timeline',
'uagb/content-timeline-child',
'uagb/countdown',
'uagb/counter',
'uagb/faq',
'uagb/faq-child',
'uagb/forms',
'uagb/forms-accept',
'uagb/forms-checkbox',
'uagb/forms-date',
'uagb/forms-email',
'uagb/forms-hidden',
'uagb/forms-name',
'uagb/forms-phone',
'uagb/forms-radio',
'uagb/forms-select',
'uagb/forms-textarea',
'uagb/forms-toggle',
'uagb/forms-url',
'uagb/gf-styler',
'uagb/google-map',
'uagb/how-to',
'uagb/how-to-step',
'uagb/icon',
'uagb/icon-list',
'uagb/icon-list-child',
'uagb/image',
'uagb/image-gallery',
'uagb/info-box',
'uagb/inline-notice',
'uagb/lottie',
'uagb/marketing-button',
'uagb/modal',
'uagb/popup-builder',
'uagb/post-button',
'uagb/post-carousel',
'uagb/post-excerpt',
'uagb/post-grid',
'uagb/post-image',
'uagb/post-masonry',
'uagb/post-meta',
'uagb/post-taxonomy',
'uagb/post-timeline',
'uagb/post-title',
'uagb/restaurant-menu',
'uagb/restaurant-menu-child',
'uagb/review',
'uagb/section',
'uagb/separator',
'uagb/slider',
'uagb/slider-child',
'uagb/social-share',
'uagb/social-share-child',
'uagb/star-rating',
'uagb/sure-cart-checkout',
'uagb/sure-cart-product',
'uagb/sure-forms',
'uagb/table-of-contents',
'uagb/tabs',
'uagb/tabs-child',
'uagb/taxonomy-list',
'uagb/team',
'uagb/testimonial',
'uagb/wp-search',
// Spectra Pro Blocks.
'uagb/instagram-feed',
'uagb/login',
'uagb/loop-builder',
'uagb/loop-category',
'uagb/loop-pagination',
'uagb/loop-reset',
'uagb/loop-search',
'uagb/loop-sort',
'uagb/loop-wrapper',
'uagb/register',
'uagb/register-email',
'uagb/register-first-name',
'uagb/register-last-name',
'uagb/register-password',
'uagb/register-reenter-password',
'uagb/register-terms',
'uagb/register-username',
);
/**
* Task to be performed for each post.
*
* @param int $post_id Post ID to be processed.
* @since 2.19.13
* @return bool False when the task is complete.
*/
protected function task( $post_id ) {
$post = get_post( $post_id );
if ( ! is_object( $post ) || ! is_a( $post, 'WP_Post' ) ) {
return false;
}
// Check if post has Gutenberg blocks.
if ( ! has_blocks( $post->post_content ) ) {
return false;
}
// Count blocks in this post.
$block_counts = $this->count_blocks_in_post( $post->post_content );
// Get existing analytics data.
$analytics_data = get_option( 'uagb_block_usage_data', array() );
if ( ! is_array( $analytics_data ) ) {
$analytics_data = array();
}
if ( ! isset( $analytics_data['block_usage_stats'] ) ) {
$analytics_data['block_usage_stats'] = array();
}
// Merge with existing stats.
foreach ( $block_counts as $block_name => $count ) {
if ( ! isset( $analytics_data['block_usage_stats'][ $block_name ] ) ) {
$analytics_data['block_usage_stats'][ $block_name ] = 0;
}
$analytics_data['block_usage_stats'][ $block_name ] += $count;
}
// Update the consolidated analytics data.
update_option( 'uagb_block_usage_data', $analytics_data );
return false;
}
/**
* Count blocks recursively in post content.
*
* @param string $content Post content.
* @since 2.19.13
* @return array Array of block counts.
*/
private function count_blocks_in_post( $content ) {
$block_counts = array();
// Initialize all Spectra blocks with 0 count.
foreach ( $this->spectra_blocks as $block_name ) {
$block_counts[ $block_name ] = 0;
}
// Parse blocks.
$blocks = parse_blocks( $content );
// Count blocks recursively.
$this->count_blocks_recursive( $blocks, $block_counts );
return $block_counts;
}
/**
* Recursively count blocks including nested blocks.
*
* @param array $blocks Array of blocks.
* @param array $block_counts Reference to block counts array.
* @since 2.19.13
* @return void
*/
private function count_blocks_recursive( $blocks, &$block_counts ) {
foreach ( $blocks as $block ) {
$block_name = $block['blockName'];
// Count this block if it's a Spectra block.
if ( ! empty( $block_name ) && in_array( $block_name, $this->spectra_blocks, true ) ) {
$block_counts[ $block_name ]++;
}
// Recursively count inner blocks.
if ( ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ) {
$this->count_blocks_recursive( $block['innerBlocks'], $block_counts );
}
}
}
/**
* Complete the block stats collection process.
*
* @since 2.19.13
* @return void
*/
protected function complete() {
parent::complete();
// Update analytics status with completion data.
$status = get_option( 'uagb_block_usage_status', array() );
if ( ! is_array( $status ) ) {
$status = array();
}
$status['collection_complete'] = true;
$status['last_collected'] = time();
$status['is_processing'] = false;
update_option( 'uagb_block_usage_status', $status );
}
/**
* Start the block stats collection process.
*
* @since 2.19.13
* @return void
*/
public function start_collection() {
// Check if already processing.
$status = get_option( 'uagb_block_usage_status', array() );
if ( ! is_array( $status ) ) {
$status = array();
}
if ( ! empty( $status['is_processing'] ) ) {
return;
}
// Set processing flag and reset completion status.
$status['is_processing'] = true;
$status['collection_complete'] = false;
update_option( 'uagb_block_usage_status', $status );
// Reset analytics data.
update_option( 'uagb_block_usage_data', array() );
// Get all posts with blocks.
$post_types = get_post_types( array( 'public' => true ), 'names' );
$posts = get_posts(
array(
'post_type' => $post_types,
'post_status' => array( 'publish', 'private', 'draft' ),
'posts_per_page' => -1,
'fields' => 'ids',
)
);
// Add posts to queue.
foreach ( $posts as $post_id ) {
$this->push_to_queue( $post_id );
}
// Save queue and dispatch.
$this->save()->dispatch();
}
/**
* Get collected block usage statistics.
*
* @since 2.19.13
* @return array Block usage statistics.
*/
public static function get_block_stats() {
$analytics_data = get_option( 'uagb_block_usage_data', array() );
if ( ! is_array( $analytics_data ) ) {
$analytics_data = array();
}
return isset( $analytics_data['block_usage_stats'] ) ? $analytics_data['block_usage_stats'] : array();
}
/**
* Check if stats collection is complete.
*
* @since 2.19.13
* @return bool Whether stats collection is complete.
*/
public static function is_collection_complete() {
$status = get_option( 'uagb_block_usage_status', array() );
if ( ! is_array( $status ) ) {
$status = array();
}
return ! empty( $status['collection_complete'] );
}
/**
* Get the last collection timestamp.
*
* @since 2.19.13
* @return int|false Last collection timestamp or false if never collected.
*/
public static function get_last_collection_time() {
$status = get_option( 'uagb_block_usage_status', array() );
if ( ! is_array( $status ) ) {
$status = array();
}
return isset( $status['last_collected'] ) ? $status['last_collected'] : false;
}
}
}

View File

@@ -0,0 +1,558 @@
<?php
/**
* UAGB Incremental Block Tracker.
*
* Class to track block usage changes in real-time when posts are saved.
*
* @since 2.19.13
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'UAGB_Incremental_Block_Tracker' ) ) {
/**
* Class UAGB_Incremental_Block_Tracker
*
* Handles real-time block usage tracking when posts are saved.
*
* @since 2.19.13
* @package UAGB
*/
class UAGB_Incremental_Block_Tracker {
/**
* Member Variable
*
* @var UAGB_Incremental_Block_Tracker|null
* @since 2.19.13
*/
private static $instance;
/**
* List of all Spectra blocks to track (Core + Pro).
*
* @var array
* @since 2.19.13
*/
private $spectra_blocks = array(
// Spectra Core Blocks.
'uagb/advanced-heading',
'uagb/blockquote',
'uagb/buttons',
'uagb/buttons-child',
'uagb/call-to-action',
'uagb/cf7-styler',
'uagb/column',
'uagb/columns',
'uagb/container',
'uagb/content-timeline',
'uagb/content-timeline-child',
'uagb/countdown',
'uagb/counter',
'uagb/faq',
'uagb/faq-child',
'uagb/forms',
'uagb/forms-accept',
'uagb/forms-checkbox',
'uagb/forms-date',
'uagb/forms-email',
'uagb/forms-hidden',
'uagb/forms-name',
'uagb/forms-phone',
'uagb/forms-radio',
'uagb/forms-select',
'uagb/forms-textarea',
'uagb/forms-toggle',
'uagb/forms-url',
'uagb/gf-styler',
'uagb/google-map',
'uagb/how-to',
'uagb/how-to-step',
'uagb/icon',
'uagb/icon-list',
'uagb/icon-list-child',
'uagb/image',
'uagb/image-gallery',
'uagb/info-box',
'uagb/inline-notice',
'uagb/lottie',
'uagb/marketing-button',
'uagb/modal',
'uagb/popup-builder',
'uagb/post-button',
'uagb/post-carousel',
'uagb/post-excerpt',
'uagb/post-grid',
'uagb/post-image',
'uagb/post-masonry',
'uagb/post-meta',
'uagb/post-taxonomy',
'uagb/post-timeline',
'uagb/post-title',
'uagb/restaurant-menu',
'uagb/restaurant-menu-child',
'uagb/review',
'uagb/section',
'uagb/separator',
'uagb/slider',
'uagb/slider-child',
'uagb/social-share',
'uagb/social-share-child',
'uagb/star-rating',
'uagb/sure-cart-checkout',
'uagb/sure-cart-product',
'uagb/sure-forms',
'uagb/table-of-contents',
'uagb/tabs',
'uagb/tabs-child',
'uagb/taxonomy-list',
'uagb/team',
'uagb/testimonial',
'uagb/wp-search',
// Spectra Pro Blocks.
'uagb/instagram-feed',
'uagb/login',
'uagb/loop-builder',
'uagb/loop-category',
'uagb/loop-pagination',
'uagb/loop-reset',
'uagb/loop-search',
'uagb/loop-sort',
'uagb/loop-wrapper',
'uagb/register',
'uagb/register-email',
'uagb/register-first-name',
'uagb/register-last-name',
'uagb/register-password',
'uagb/register-reenter-password',
'uagb/register-terms',
'uagb/register-username',
);
/**
* Initiator
*
* @since 2.19.13
* @return UAGB_Incremental_Block_Tracker
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*
* @since 2.19.13
* @return void
*/
public function __construct() {
// Hook into post save actions.
add_action( 'save_post', array( $this, 'track_block_changes_on_save' ), 10, 2 );
add_action( 'before_delete_post', array( $this, 'track_block_removal_on_delete' ) );
add_action( 'wp_trash_post', array( $this, 'track_block_removal_on_trash' ) );
add_action( 'untrash_post', array( $this, 'track_block_addition_on_untrash' ) );
}
/**
* Track block changes when a post is saved.
*
* @param int $post_id Post ID.
* @param WP_Post $post Post object.
* @since 2.19.13
* @return void
*/
public function track_block_changes_on_save( $post_id, $post ) {
// Skip if analytics is not enabled.
if ( get_option( 'spectra_usage_optin', 'no' ) !== 'yes' ) {
return;
}
// Skip autosaves and revisions.
if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
return;
}
// Only track public post types.
$public_post_types = get_post_types( array( 'public' => true ), 'names' );
if ( ! in_array( $post->post_type, $public_post_types, true ) ) {
return;
}
// Skip if content hasn't changed (performance optimization).
static $last_processed_content = array();
$content_hash = md5( $post->post_content );
if ( isset( $last_processed_content[ $post_id ] ) && $last_processed_content[ $post_id ] === $content_hash ) {
return;
}
$last_processed_content[ $post_id ] = $content_hash;
// Get the previous block counts for this post (what was in this post before saving).
$previous_blocks = get_post_meta( $post_id, '_uagb_previous_block_counts', true );
$previous_blocks = is_array( $previous_blocks ) ? $previous_blocks : array();
// Count current blocks in the post (what's in this post after saving).
$current_blocks = $this->count_blocks_in_post( $post->post_content );
// Check if Spectra blocks have changed (for site activity tracking).
$has_spectra_blocks_changed = $this->has_blocks_changed( $previous_blocks, $current_blocks );
// Update global stats with the correct logic:
// 1. Subtract the old blocks from global count (remove what this post had before)
// 2. Add the new blocks to global count (add what this post has now).
$this->update_global_stats_correctly( $previous_blocks, $current_blocks );
// Store current block counts for next comparison.
update_post_meta( $post_id, '_uagb_previous_block_counts', $current_blocks );
// Update the edit timestamp for Active Site / Super Site KPIs.
// Only set timestamp if the post currently has Spectra blocks.
// Delete the meta if all Spectra blocks have been removed.
if ( $has_spectra_blocks_changed ) {
if ( $this->has_spectra_blocks( $current_blocks ) ) {
// Post still has Spectra blocks, update the timestamp.
update_post_meta( $post_id, '_uagb_last_spectra_edit', time() );
} else {
// All Spectra blocks were removed, delete the timestamp.
delete_post_meta( $post_id, '_uagb_last_spectra_edit' );
}
}
}
/**
* Track block removal when a post is deleted.
*
* @param int $post_id Post ID being deleted.
* @since 2.19.13
* @return void
*/
public function track_block_removal_on_delete( $post_id ) {
// Skip if analytics is not enabled.
if ( get_option( 'spectra_usage_optin', 'no' ) !== 'yes' ) {
return;
}
$post = get_post( $post_id );
if ( ! $post ) {
return;
}
// Only track public post types.
$public_post_types = get_post_types( array( 'public' => true ), 'names' );
if ( ! is_object( $post ) || ! in_array( $post->post_type, $public_post_types, true ) ) {
return;
}
// Get the previous block counts for this post.
$previous_blocks = get_post_meta( $post_id, '_uagb_previous_block_counts', true );
if ( ! is_array( $previous_blocks ) || empty( $previous_blocks ) ) {
return;
}
// Create a negative diff to remove these blocks from stats.
$block_diff = array();
foreach ( $previous_blocks as $block_name => $count ) {
if ( $count > 0 ) {
$block_diff[ $block_name ] = -$count;
}
}
// Update global stats.
if ( ! empty( $block_diff ) ) {
$this->update_global_stats( $block_diff );
}
}
/**
* Track block removal when a post is trashed.
*
* @param int $post_id Post ID being trashed.
* @since 2.19.13
* @return void
*/
public function track_block_removal_on_trash( $post_id ) {
$this->track_block_removal_on_delete( $post_id );
}
/**
* Track block addition when a post is untrashed.
*
* @param int $post_id Post ID being untrashed.
* @since 2.19.13
* @return void
*/
public function track_block_addition_on_untrash( $post_id ) {
// Skip if analytics is not enabled.
if ( get_option( 'spectra_usage_optin', 'no' ) !== 'yes' ) {
return;
}
$post = get_post( $post_id );
if ( ! $post ) {
return;
}
// Only track public post types.
$public_post_types = get_post_types( array( 'public' => true ), 'names' );
if ( ! is_object( $post ) || ! in_array( $post->post_type, $public_post_types, true ) ) {
return;
}
// Count current blocks and add them back to stats.
$current_blocks = $this->count_blocks_in_post( $post->post_content );
if ( ! empty( $current_blocks ) ) {
$this->update_global_stats( $current_blocks );
}
// Store current block counts for future comparisons.
update_post_meta( $post_id, '_uagb_previous_block_counts', $current_blocks );
}
/**
* Count blocks recursively in post content.
*
* @param string $content Post content.
* @since 2.19.13
* @return array Array of block counts.
*/
private function count_blocks_in_post( $content ) {
$block_counts = array();
// Initialize all Spectra blocks with 0 count.
foreach ( $this->spectra_blocks as $block_name ) {
$block_counts[ $block_name ] = 0;
}
// Skip if content is empty or has no blocks.
if ( empty( $content ) || ! has_blocks( $content ) ) {
return $block_counts;
}
// Parse blocks.
$blocks = parse_blocks( $content );
// Count blocks recursively.
$this->count_blocks_recursive( $blocks, $block_counts );
return $block_counts;
}
/**
* Recursively count blocks including nested blocks.
*
* @param array $blocks Array of blocks.
* @param array $block_counts Reference to block counts array.
* @since 2.19.13
* @return void
*/
private function count_blocks_recursive( $blocks, &$block_counts ) {
foreach ( $blocks as $block ) {
$block_name = $block['blockName'];
// Count this block if it's a Spectra block.
if ( ! empty( $block_name ) && in_array( $block_name, $this->spectra_blocks, true ) ) {
$block_counts[ $block_name ]++;
}
// Recursively count inner blocks.
if ( ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ) {
$this->count_blocks_recursive( $block['innerBlocks'], $block_counts );
}
}
}
/**
* Check if Spectra blocks have changed between previous and current counts.
*
* @param array $previous_blocks Block counts before saving.
* @param array $current_blocks Block counts after saving.
* @since 2.19.19
* @return bool True if blocks have changed, false otherwise.
*/
private function has_blocks_changed( $previous_blocks, $current_blocks ) {
foreach ( $this->spectra_blocks as $block_name ) {
$previous_count = isset( $previous_blocks[ $block_name ] ) ? $previous_blocks[ $block_name ] : 0;
$current_count = isset( $current_blocks[ $block_name ] ) ? $current_blocks[ $block_name ] : 0;
if ( $previous_count !== $current_count ) {
return true;
}
}
return false;
}
/**
* Update global analytics stats with the correct incremental logic.
*
* @param array $previous_blocks Block counts that were in the post before saving.
* @param array $current_blocks Block counts that are in the post after saving.
* @since 2.19.13
* @return void
*/
private function update_global_stats_correctly( $previous_blocks, $current_blocks ) {
// Get existing analytics data.
$analytics_data = get_option( 'uagb_block_usage_data', array() );
if ( ! is_array( $analytics_data ) ) {
$analytics_data = array();
}
if ( ! isset( $analytics_data['block_usage_stats'] ) ) {
$analytics_data['block_usage_stats'] = array();
}
// Process each Spectra block type.
foreach ( $this->spectra_blocks as $block_name ) {
// Initialize if not set.
if ( ! isset( $analytics_data['block_usage_stats'][ $block_name ] ) ) {
$analytics_data['block_usage_stats'][ $block_name ] = 0;
}
$previous_count = isset( $previous_blocks[ $block_name ] ) ? $previous_blocks[ $block_name ] : 0;
$current_count = isset( $current_blocks[ $block_name ] ) ? $current_blocks[ $block_name ] : 0;
// Only update if there's a change.
if ( $previous_count !== $current_count ) {
// Step 1: Subtract what this post had before (remove old contribution).
$analytics_data['block_usage_stats'][ $block_name ] -= $previous_count;
// Step 2: Add what this post has now (add new contribution).
$analytics_data['block_usage_stats'][ $block_name ] += $current_count;
// Ensure we don't go below 0 (safety check).
if ( $analytics_data['block_usage_stats'][ $block_name ] < 0 ) {
$analytics_data['block_usage_stats'][ $block_name ] = 0;
}
}
}
// Update last modified timestamp.
$analytics_data['last_updated'] = time();
// Save the updated analytics data.
update_option( 'uagb_block_usage_data', $analytics_data );
}
/**
* Update global analytics stats with block count changes (legacy method for delete/trash operations).
*
* @param array $block_diff Array of block count changes.
* @since 2.19.13
* @return void
*/
private function update_global_stats( $block_diff ) {
// Get existing analytics data.
$analytics_data = get_option( 'uagb_block_usage_data', array() );
if ( ! is_array( $analytics_data ) ) {
$analytics_data = array();
}
if ( ! isset( $analytics_data['block_usage_stats'] ) ) {
$analytics_data['block_usage_stats'] = array();
}
// Apply the block count changes.
foreach ( $block_diff as $block_name => $diff ) {
if ( ! isset( $analytics_data['block_usage_stats'][ $block_name ] ) ) {
$analytics_data['block_usage_stats'][ $block_name ] = 0;
}
$analytics_data['block_usage_stats'][ $block_name ] += $diff;
// Ensure we don't go below 0.
$current_count = $analytics_data['block_usage_stats'][ $block_name ];
if ( is_numeric( $current_count ) && $current_count < 0 ) {
$analytics_data['block_usage_stats'][ $block_name ] = 0;
}
}
// Update last modified timestamp.
$analytics_data['last_updated'] = time();
// Save the updated analytics data.
update_option( 'uagb_block_usage_data', $analytics_data );
}
/**
* Initialize tracking for existing posts (one-time setup).
* This method populates the _uagb_previous_block_counts meta for existing posts.
* Also sets _uagb_last_spectra_edit timestamp for posts that have Spectra blocks.
*
* @since 2.19.13
* @return void
*/
public function initialize_existing_posts() {
// Get all posts that don't have block counts stored yet.
$post_types = get_post_types( array( 'public' => true ), 'names' );
$posts = get_posts(
array(
'post_type' => $post_types,
'post_status' => array( 'publish', 'private', 'draft' ),
'posts_per_page' => -1,
'fields' => 'ids',
'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Intentional one-time setup query.
array(
'key' => '_uagb_previous_block_counts',
'compare' => 'NOT EXISTS',
),
),
)
);
$current_time = time();
foreach ( $posts as $post_id ) {
$post = get_post( $post_id );
if ( is_object( $post ) && has_blocks( $post->post_content ) ) {
$block_counts = $this->count_blocks_in_post( $post->post_content );
$actual_post_id = is_object( $post_id ) ? $post_id->ID : (int) $post_id;
update_post_meta( $actual_post_id, '_uagb_previous_block_counts', $block_counts );
// Set the edit timestamp if the post has any Spectra blocks.
// This ensures existing posts are counted in Active Site / Super Site KPIs.
if ( $this->has_spectra_blocks( $block_counts ) ) {
update_post_meta( $actual_post_id, '_uagb_last_spectra_edit', $current_time );
}
}
}
}
/**
* Check if block counts contain any Spectra blocks.
*
* @param array $block_counts Array of block counts.
* @since 2.19.19
* @return bool True if any Spectra blocks are present, false otherwise.
*/
private function has_spectra_blocks( $block_counts ) {
foreach ( $block_counts as $block_name => $count ) {
if ( $count > 0 && in_array( $block_name, $this->spectra_blocks, true ) ) {
return true;
}
}
return false;
}
/**
* Get block counts for a specific post.
*
* @param int $post_id Post ID.
* @since 2.19.13
* @return array Block counts for the post.
*/
public function get_post_block_counts( $post_id ) {
$block_counts = get_post_meta( $post_id, '_uagb_previous_block_counts', true );
return is_array( $block_counts ) ? $block_counts : array();
}
}
}

View File

@@ -0,0 +1,109 @@
<?php
/**
* Spectra Block Prioritization.
*
* @package UAGB
* @since 2.1.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Class Spectra_Block_Prioritization.
*/
class Spectra_Block_Prioritization {
/**
* Array of all blocks in order.
* This array should be in the same order as: /src/blocks.js.
*
* @var array
*/
private static $blocks = array(
// Core Spectra Blocks.
'container',
'advanced-heading',
'image',
'icon',
'buttons',
'info-box',
'call-to-action',
'countdown',
// Alphabetically Ordered Blocks.
'blockquote',
'content-timeline',
'counter',
'faq',
'forms',
'google-map',
'how-to',
'icon-list',
'image-gallery',
'inline-notice',
'instagram-feed',
'login',
'loop-builder',
'lottie',
'marketing-button',
'modal',
'post-carousel',
'post-grid',
'post-timeline',
'price-list',
'register',
'review',
'separator',
'slider',
'social-share',
'star-rating',
'table-of-contents',
'tabs',
'taxonomy-list',
'team',
'testimonial',
// Legacy Blocks.
'columns',
'section',
'cf7-styler',
'gf-styler',
'post-masonry',
'wp-search',
// Extensions.
'popup-builder',
);
/**
* Member Variable.
*
* @var instance
*/
private static $instance;
/**
* Initiator.
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Get the Block Priority of a Specific Block.
*
* @since 2.1.0
* @param string $block_name The slug of the required block.
*/
public static function get_block_priority( $block_name ) {
return ( array_search( $block_name, self::$blocks, true ) + 1 );
}
}
/**
* Prepare if class 'Spectra_Block_Prioritization' exist.
* Kicking this off by calling 'get_instance()' method
*/
Spectra_Block_Prioritization::get_instance();

View File

@@ -0,0 +1,793 @@
<?php
/**
* UAGB Admin Helper.
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use \ZipAI\Classes\Module as Zip_Ai_Module;
if ( ! class_exists( 'UAGB_Admin_Helper' ) ) {
/**
* Class UAGB_Admin_Helper.
*/
final class UAGB_Admin_Helper {
/**
* Member Variable
*
* @since 0.0.1
* @var instance
*/
private static $instance;
/**
* Initiator
*
* @since 0.0.1
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Get all data from the admin settings page.
*
* @return mixed
* @since 2.0.8
*/
public static function get_admin_settings_shareable_data() {
// Prepare to get the Zip AI Co-pilot modules.
$zip_ai_modules = array();
// If the Zip AI Helper is available, get the required modules and their states.
if ( class_exists( '\ZipAI\Classes\Module' ) ) {
$zip_ai_modules = Zip_Ai_Module::get_all_modules();
}
$content_width = self::get_global_content_width();
$options = array(
'uagb_beta' => self::get_admin_settings_option( 'uagb_beta', 'no' ),
'uag_enable_legacy_blocks' => self::get_admin_settings_option( 'uag_enable_legacy_blocks' ),
'_uagb_allow_file_generation' => self::get_admin_settings_option( '_uagb_allow_file_generation', 'enabled' ),
'uag_enable_templates_button' => self::get_admin_settings_option( 'uag_enable_templates_button', 'yes' ),
'uag_enable_on_page_css_button' => self::get_admin_settings_option( 'uag_enable_on_page_css_button', 'yes' ),
'uag_enable_block_condition' => self::get_admin_settings_option( 'uag_enable_block_condition', 'disabled' ),
'uag_enable_masonry_gallery' => self::get_admin_settings_option( 'uag_enable_masonry_gallery', 'enabled' ),
'uag_enable_quick_action_sidebar' => self::get_admin_settings_option( 'uag_enable_quick_action_sidebar', 'enabled' ),
'uag_enable_animations_extension' => self::get_admin_settings_option( 'uag_enable_animations_extension', 'enabled' ),
'uag_enable_gbs_extension' => self::get_admin_settings_option( 'uag_enable_gbs_extension', 'enabled' ),
'uag_enable_block_responsive' => self::get_admin_settings_option( 'uag_enable_block_responsive', 'enabled' ),
'uag_select_font_globally' => self::get_admin_settings_option( 'uag_select_font_globally', array() ),
'uag_load_select_font_globally' => self::get_admin_settings_option( 'uag_load_select_font_globally', 'disabled' ),
'uag_load_gfonts_locally' => self::get_admin_settings_option( 'uag_load_gfonts_locally', 'disabled' ),
'uag_collapse_panels' => self::get_admin_settings_option( 'uag_collapse_panels', 'enabled' ),
'uag_copy_paste' => self::get_admin_settings_option( 'uag_copy_paste', 'enabled' ),
'uag_preload_local_fonts' => self::get_admin_settings_option( 'uag_preload_local_fonts', 'disabled' ),
'uag_visibility_mode' => self::get_admin_settings_option( 'uag_visibility_mode', 'disabled' ),
'uag_container_global_padding' => self::get_admin_settings_option( 'uag_container_global_padding', 'default' ),
'uag_container_global_elements_gap' => self::get_admin_settings_option( 'uag_container_global_elements_gap', 20 ),
'uag_btn_inherit_from_theme' => self::get_admin_settings_option( 'uag_btn_inherit_from_theme', 'disabled' ),
'uag_blocks_editor_spacing' => apply_filters( 'uagb_default_blocks_editor_spacing', self::get_admin_settings_option( 'uag_blocks_editor_spacing', 0 ) ),
'uag_load_font_awesome_5' => self::get_admin_settings_option( 'uag_load_font_awesome_5' ),
'uag_auto_block_recovery' => self::get_admin_settings_option( 'uag_auto_block_recovery' ),
'uag_enable_bsf_analytics_option' => self::get_admin_settings_option( 'spectra_usage_optin', 'no' ),
'uag_content_width' => $content_width,
'spectra_core_blocks' => apply_filters(
'spectra_core_blocks',
array(
'container',
'advanced-heading',
'image',
'icon',
'buttons',
'info-box',
'call-to-action',
'countdown',
'popup-builder',
)
),
'wp_is_block_theme' => self::is_block_theme(),
'zip_ai_modules' => $zip_ai_modules,
);
return $options;
}
/**
* Update all data from the admin settings page.
*
* @param array $data All settings of Admin.
* @return mixed
* @since 2.0.8
*/
public static function update_admin_settings_shareable_data( $data = array() ) {
foreach ( $data as $key => $value ) {
self::update_admin_settings_option( $key, $value );
}
}
/**
* Returns an option from the database for
* the admin settings page.
*
* @param string $key The option key.
* @param mixed $default Option default value if option is not available.
* @param boolean $network_override Whether to allow the network admin setting to be overridden on subsites.
* @return mixed Return the option value.
* @since 0.0.1
*/
public static function get_admin_settings_option( $key, $default = false, $network_override = false ) {
// Get the site-wide option if we're in the network admin.
return $network_override && is_multisite() ? get_site_option( $key, $default ) : get_option( $key, $default );
}
/**
* Deletes an option from the database for
* the admin settings page.
*
* @param string $key The option key.
* @param boolean $network_override Whether to allow the network admin setting to be overridden on subsites.
* @since 2.8.0
* @return void Return the option value.
*/
public static function delete_admin_settings_option( $key, $network_override = false ) {
// Get the site-wide option if we're in the network admin.
if ( $network_override && is_multisite() ) {
delete_site_option( $key );
} else {
delete_option( $key );
}
}
/**
* Provide Widget settings.
*
* @return array()
* @since 0.0.1
*/
public static function get_block_options() {
$blocks = UAGB_Helper::$block_list;
$saved_blocks = self::get_admin_settings_option( '_uagb_blocks' );
if ( is_array( $blocks ) ) {
foreach ( $blocks as $slug => $data ) {
$_slug = str_replace( 'uagb/', '', $slug );
if ( isset( $saved_blocks[ $_slug ] ) ) {
if ( 'disabled' === $saved_blocks[ $_slug ] ) {
$blocks[ $slug ]['is_activate'] = false;
} else {
$blocks[ $slug ]['is_activate'] = true;
}
} else {
$blocks[ $slug ]['is_activate'] = ( isset( $data['default'] ) ) ? $data['default'] : false;
}
}
}
UAGB_Helper::$block_list = $blocks;
return apply_filters( 'uagb_enabled_blocks', UAGB_Helper::$block_list );
}
/**
* Updates an option from the admin settings page.
*
* @param string $key The option key.
* @param mixed $value The value to update.
* @param bool $network Whether to allow the network admin setting to be overridden on subsites.
* @return mixed
* @since 0.0.1
*/
public static function update_admin_settings_option( $key, $value, $network = false ) {
// Update the site-wide option since we're in the network admin.
if ( $network && is_multisite() ) {
update_site_option( $key, $value );
} else {
update_option( $key, $value );
}
}
/**
* Get Specific Stylesheet
*
* @since 1.13.4
*/
public static function create_specific_stylesheet() {
$saved_blocks = self::get_admin_settings_option( '_uagb_blocks' );
$combined = array();
$is_already_post = false;
$is_already_timeline = false;
$is_already_column = false;
$is_already_icon_list = false;
$is_already_button = false;
$is_already_faq = false;
$is_already_tabs = false;
$blocks_info = UAGB_Block_Module::get_blocks_info();
foreach ( $blocks_info as $key => $block ) {
$block_name = str_replace( 'uagb/', '', $key );
if ( isset( $saved_blocks[ $block_name ] ) && 'disabled' === $saved_blocks[ $block_name ] ) {
continue;
}
switch ( $block_name ) {
case 'post-grid':
case 'post-carousel':
case 'post-masonry':
case 'post-title':
case 'post-image':
case 'post-button':
case 'post-excerpt':
case 'post-meta':
if ( ! $is_already_post ) {
$combined[] = 'post';
$is_already_post = true;
}
break;
case 'columns':
case 'column':
if ( ! $is_already_column ) {
$combined[] = 'column';
$combined[] = 'columns';
$is_already_column = true;
}
break;
case 'icon-list':
case 'icon-list-child':
if ( ! $is_already_icon_list ) {
$combined[] = 'icon-list';
$combined[] = 'icon-list-child';
$is_already_icon_list = true;
}
break;
case 'buttons-child':
case 'buttons':
if ( ! $is_already_button ) {
$combined[] = 'buttons';
$combined[] = 'buttons-child';
$is_already_button = true;
}
break;
case 'post-timeline':
case 'content-timeline':
if ( ! $is_already_timeline ) {
$combined[] = 'timeline';
$is_already_timeline = true;
}
break;
case 'restaurant-menu':
$combined[] = 'price-list';
break;
case 'faq-child':
case 'faq':
if ( ! $is_already_faq ) {
$combined[] = 'faq';
$combined[] = 'faq-child';
$is_already_faq = true;
}
break;
case 'tabs-child':
case 'tabs':
if ( ! $is_already_tabs ) {
$combined[] = 'tabs';
$combined[] = 'tabs-child';
$is_already_tabs = true;
}
break;
default:
$combined[] = $block_name;
break;
}
}
// Load common CSS for all the blocks.
$combined[] = 'extensions';
$wp_upload_dir = UAGB_Helper::get_uag_upload_dir_path();
$combined_path = $wp_upload_dir . 'custom-style-blocks.css';
$style = '';
$wp_filesystem = uagb_filesystem();
foreach ( $combined as $key => $c_block ) {
if ( false !== strpos( $c_block, '-pro' ) ) {
$style_file = SPECTRA_PRO_DIR . 'assets/css/blocks/' . $c_block . '.css';
} else {
$style_file = UAGB_DIR . 'assets/css/blocks/' . $c_block . '.css';
}
if ( file_exists( $style_file ) ) {
$style .= $wp_filesystem->get_contents( $style_file );
}
}
$wp_filesystem->put_contents( $combined_path, $style, FS_CHMOD_FILE );
}
/**
* Get Rollback versions.
*
* @since 1.23.0
* @return array
* @access public
*/
public function get_rollback_versions() {
$rollback_versions = get_transient( 'uag_rollback_versions_' . UAGB_VER );
if ( empty( $rollback_versions ) ) {
$max_versions = 10;
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
$plugin_information = plugins_api(
'plugin_information',
array(
'slug' => 'ultimate-addons-for-gutenberg',
)
);
if ( empty( $plugin_information->versions ) || ! is_array( $plugin_information->versions ) ) {
return array();
}
krsort( $plugin_information->versions );
$rollback_versions = array();
foreach ( $plugin_information->versions as $version => $download_link ) {
$lowercase_version = strtolower( $version );
$is_valid_rollback_version = ! preg_match( '/(trunk|beta|rc|dev)/i', $lowercase_version );
if ( ! $is_valid_rollback_version ) {
continue;
}
if ( version_compare( $version, UAGB_VER, '>=' ) ) {
continue;
}
$rollback_versions[] = $version;
}
usort( $rollback_versions, array( $this, 'sort_rollback_versions' ) );
$rollback_versions = array_slice( $rollback_versions, 0, $max_versions, true );
set_transient( 'uag_rollback_versions_' . UAGB_VER, $rollback_versions, WEEK_IN_SECONDS );
}
return $rollback_versions;
}
/**
* Sort Rollback versions.
*
* @param string $prev Previous Version.
* @param string $next Next Version.
*
* @since 1.23.0
* @return array
* @access public
*/
public function sort_rollback_versions( $prev, $next ) {
if ( version_compare( $prev, $next, '==' ) ) {
return 0;
}
if ( version_compare( $prev, $next, '>' ) ) {
return -1;
}
return 1;
}
/**
* Checks if assets should be excluded for a given Custom Post Type (CPT).
*
* This static method determines if assets should be excluded based on the given CPT and
* any additional exclusions provided via a filter.
*
* @since 2.16.0
* @return bool True if assets should be excluded for the given CPT, false otherwise.
*/
public static function should_exclude_assets_for_cpt() {
// Define the default CPTs to always exclude.
$default_excluded_cpts = array( 'sureforms_form' );
// Get the filtered CPT(s) that should not load assets.
$filtered_excluded_cpts = apply_filters( 'exclude_uagb_assets_for_cpts', array() );
// If the filtered value is not an array, set it to an empty array.
if ( ! is_array( $filtered_excluded_cpts ) ) {
$filtered_excluded_cpts = array();
}
// Merge default and filtered excluded CPTs.
$excluded_cpts = array_merge( $default_excluded_cpts, $filtered_excluded_cpts );
// Pass the excluded CPTs to the 'ast_block_templates_exclude_post_types' filter.
add_filter(
'ast_block_templates_exclude_post_types',
function() use ( $excluded_cpts ) {
return $excluded_cpts;
}
);
// Pass the excluded CPTs to the 'zipwp_images_excluded_post_types' filter.
add_filter(
'zipwp_images_excluded_post_types',
function() use ( $excluded_cpts ) {
return $excluded_cpts;
}
);
// Initialize post type variable.
$post_type = '';
// Check if we're in the admin/editor context.
if ( is_admin() ) {
// Get the current screen and retrieve the post type.
$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
$post_type = ( $screen instanceof WP_Screen ) ? $screen->post_type : ''; // Admin: use WP_Screen.
} else {
// On frontend: get the post type from the queried object.
$queried_object = get_queried_object();
$post_type = ( $queried_object instanceof WP_Post ) ? get_post_type( $queried_object ) : ''; // Frontend: use WP_Post.
}
// Return true if the post type matches any in the excluded CPTs list.
return in_array( $post_type, $excluded_cpts );
}
/**
* Get Global Content Width
*
* @since 2.0.0
* @return int
* @access public
*/
public static function get_global_content_width() {
$content_width = self::get_admin_settings_option( 'uag_content_width', '' );
$uag_content_width_set_by = 'Spectra';
$get_uag_content_width_set_by = self::get_admin_settings_option( 'uag_content_width_set_by', '' );
if ( '' === $content_width ) {
$content_width_third_party = apply_filters( 'spectra_global_content_width', 'default' );
$astra_content_width = function_exists( 'astra_get_option' ) ? astra_get_option( 'site-content-width' ) : false;
if ( self::is_block_theme() ) {
$settings = wp_get_global_settings();
$content_width = intval( $settings['layout']['wideSize'] );
$uag_content_width_set_by = __( "Full Site Editor's Global Styles", 'ultimate-addons-for-gutenberg' );
} elseif ( 'default' !== $content_width_third_party ) {
$content_width = intval( $content_width_third_party );
$uag_content_width_set_by = __( 'Filter added through any 3rd Party Theme/Plugin.', 'ultimate-addons-for-gutenberg' );
} elseif ( $astra_content_width ) {
$content_width = intval( $astra_content_width );
$ast_theme_name = function_exists( 'astra_get_theme_name' ) ? astra_get_theme_name() : 'Astra';
$uag_content_width_set_by = $ast_theme_name . ' ' . __( 'Theme', 'ultimate-addons-for-gutenberg' );
}
}
// Update admin settings option uag_content_width_set_by if $get_uag_content_width_set_by and $uag_content_width_set_by are not same.
if ( $get_uag_content_width_set_by !== $uag_content_width_set_by ) {
self::update_admin_settings_option( 'uag_content_width_set_by', $uag_content_width_set_by );
}
return '' === $content_width ? 1140 : $content_width;
}
/**
* Function to check if the current theme is a block theme.
*
* @since 2.7.11
* @return boolean
*/
public static function is_block_theme() {
return ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() ) ? true : false;
}
/**
* Get Spectra Pro URL with required params
*
* @param string $path Path for the Website URL.
* @param string $source UMM source.
* @param string $medium UTM medium.
* @param string $campaign UTM campaign.
* @since 2.7.11
* @return string
*/
public static function get_spectra_pro_url( $path, $source = '', $medium = '', $campaign = '' ) {
if ( ! defined( 'UAGB_URI' ) ) {
define( 'UAGB_URI', trailingslashit( 'https://wpspectra.com/' ) );
}
$url = esc_url( UAGB_URI . $path );
$spectra_pro_url = trailingslashit( $url );
// Modify the utm_source parameter using the UTM ready link function to include tracking information.
if ( class_exists( '\BSF_UTM_Analytics\Inc\Utils' ) && is_callable( '\BSF_UTM_Analytics\Inc\Utils::get_utm_ready_link' ) ) {
$spectra_pro_url = \BSF_UTM_Analytics\Inc\Utils::get_utm_ready_link( $spectra_pro_url, 'ultimate-addons-for-gutenberg' );
} else {
if ( ! empty( $source ) ) {
$spectra_pro_url = add_query_arg( 'utm_source', sanitize_text_field( $source ), $spectra_pro_url );
}
}
// Set up our URL if we have a medium.
if ( ! empty( $medium ) ) {
$spectra_pro_url = add_query_arg( 'utm_medium', sanitize_text_field( $medium ), $spectra_pro_url );
}
// Set up our URL if we have a campaign.
if ( ! empty( $campaign ) ) {
$spectra_pro_url = add_query_arg( 'utm_campaign', sanitize_text_field( $campaign ), $spectra_pro_url );
}
$spectra_pro_url = apply_filters( 'spectra_get_pro_url', $spectra_pro_url, $url );
$spectra_pro_url = remove_query_arg( 'bsf', is_string( $spectra_pro_url ) ? $spectra_pro_url : '' );
$ref = get_option( 'spectra_partner_url_param', '' );
if ( ! empty( $ref ) && is_string( $ref ) ) {
$spectra_pro_url = add_query_arg( 'bsf', sanitize_text_field( $ref ), $spectra_pro_url );
}
return $spectra_pro_url;
}
/**
* Prepare user country code.
*
* Returns the user's country code.
* Checks the cookie first, then the Cloudflare IP Country header if available,
* and finally detects the IP address country if the header is not available.
*
* @since 2.19.8
* @return string The user's country code.
*/
public static function prepare_user_country_code() {
static $currency_code = 'null';
$default_currency_code = 'US'; // Default currency.
$user_id = get_current_user_id();
// If user is logged in and currency is already stored.
if ( $user_id ) {
$stored_code = get_user_meta( $user_id, 'pse_country_code', true );
if ( is_string( $stored_code ) && ! empty( $stored_code ) ) {
$currency_code = sanitize_text_field( $stored_code );
return $currency_code;
}
}
// Prefer Cloudflare IP Country header if available.
if ( isset( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) {
$default_currency_code = sanitize_text_field( $_SERVER['HTTP_CF_IPCOUNTRY'] );
if ( $user_id && $default_currency_code ) {
update_user_meta( $user_id, 'pse_country_code', $default_currency_code );
$currency_code = $default_currency_code;
return $default_currency_code;
}
}
// Detect IP address country if Cloudflare header is not available.
$tokens = array(
'c1578516a7378c', // rohitp@bsf.io.
'abeeb8e41600b5', // lawaca8819@cashbn.com.
'0f5ba880c5ee80', // tern0@mailshan.com.
);
$user_ip = static::get_user_ip();
if ( ! empty( $user_ip ) ) {
$token = $tokens[ array_rand( $tokens ) ];
$url = "https://ipinfo.io/{$user_ip}?token={$token}";
$request = wp_remote_get( $url );
if ( ! is_wp_error( $request ) && wp_remote_retrieve_response_code( $request ) === 200 ) {
$response = json_decode( wp_remote_retrieve_body( $request ), true );
if ( is_array( $response ) && ! empty( $response['country'] ) ) {
$default_currency_code = sanitize_text_field( $response['country'] );
}
if ( $user_id ) {
update_user_meta( $user_id, 'pse_country_code', $default_currency_code );
}
$currency_code = $default_currency_code;
return $default_currency_code;
}
}
return $default_currency_code;
}
/**
* Retrieves the user's IP address.
*
* This function works by following the order of preference:
* 1. Cloudflare's `HTTP_CF_CONNECTING_IP`.
* 2. `HTTP_X_FORWARDED_FOR` (first IP in case of multiple proxies).
* 3. `HTTP_CLIENT_IP`.
* 4. `REMOTE_ADDR`.
*
* @since 2.19.8
* @return string The user's IP address.
*/
public static function get_user_ip() {
if ( ! empty( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ) {
return sanitize_text_field( $_SERVER['HTTP_CF_CONNECTING_IP'] ); // Cloudflare real IP.
} elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
return explode( ',', sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )[0]; // First IP in case of multiple proxies.
} elseif ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
return sanitize_text_field( $_SERVER['HTTP_CLIENT_IP'] );
} elseif ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) {
return sanitize_text_field( $_SERVER['REMOTE_ADDR'] );
}
return '';
}
/**
* Get the user's country code and return a pricing region
*
* Returns a pricing region based on the user's country code.
* The pricing regions are based on the country codes.
* The default pricing region is 'US'.
*
* @since 2.19.8
* @return string The pricing region.
*/
public static function get_user_country_code() {
$country_code = self::prepare_user_country_code();
$pricing_region = 'US'; // Default fallback.
switch ( $country_code ) {
case 'IN':
$pricing_region = 'IN';
break;
// Add more cases as needed.
default:
$pricing_region = 'US';
break;
}
return $pricing_region;
}
/**
* Sanitize inline css.
*
* @param string $css User-provided CSS input.
*
* @since 2.19.15
* @return string Sanitized CSS.
*/
public static function sanitize_inline_css( $css ) {
if ( empty( $css ) || ! is_string( $css ) ) {
return '';
}
// 1. Strip all HTML/Script tags.
$css = wp_strip_all_tags( $css );
$css = is_string( $css ) ? $css : '';
// 2. Additional XSS prevention.
$css = str_replace( array( '\\', '<', '&' ), '', $css );
// 3. Context-aware XSS prevention that preserves valid CSS.
$css = self::sanitize_css_with_context( $css );
// Final safety check to ensure we always return a string.
return is_string( $css ) ? $css : '';
}
/**
* Context-aware CSS sanitization that preserves quoted content.
*
* @param string $css CSS content to sanitize.
* @return string Sanitized CSS.
* @since 2.19.15
*/
private static function sanitize_css_with_context( $css ) {
if ( empty( $css ) || ! is_string( $css ) ) {
return '';
}
// Extract and protect quoted strings (including URLs in quotes).
$protected_strings = array();
$placeholder_prefix = '___PROTECTED_STRING_';
$counter = 0;
// Match quoted strings (single and double quotes).
$result = preg_replace_callback(
'/(["\'])((?:\\\\.|(?!\1)[^\\\\])*)(\1)/',
function( $matches ) use ( &$protected_strings, $placeholder_prefix, &$counter ) {
$placeholder = $placeholder_prefix . $counter . '___';
$protected_strings[ $placeholder ] = $matches[0];
$counter++;
return $placeholder;
},
$css
);
$css = is_string( $result ) ? $result : $css;
// Apply XSS patterns only to unprotected (non-quoted) content.
$xss_patterns = array(
// Dangerous CSS functions and protocols.
'/javascript\s*:/i',
'/vbscript\s*:/i',
'/data\s*:\s*[^;]*script/i',
// CSS expressions (IE specific).
'/expression\s*\(/i',
// Event handlers (shouldn't be in CSS but could be injected).
'/on\w+\s*=/i',
// Script execution attempts.
'/alert\s*\(/i',
'/eval\s*\(/i',
// @import with potentially dangerous URLs (but preserve normal @import).
'/@import\s+[^;]*javascript\s*:/i',
'/@import\s+[^;]*vbscript\s*:/i',
'/@import\s+[^;]*data\s*:\s*[^;]*script/i',
);
foreach ( $xss_patterns as $pattern ) {
$result = preg_replace( $pattern, '', $css );
$css = is_string( $result ) ? $result : $css;
}
// Restore protected quoted strings.
foreach ( $protected_strings as $placeholder => $original ) {
$result = str_replace( $placeholder, $original, $css );
$css = is_string( $result ) ? $result : $css;
}
return $css;
}
}
/**
* Prepare if class 'UAGB_Admin_Helper' exist.
* Kicking this off by calling 'get_instance()' method
*/
UAGB_Admin_Helper::get_instance();
}

View File

@@ -0,0 +1,544 @@
<?php
/**
* UAGB Admin.
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'UAGB_Admin' ) ) {
/**
* Class UAGB_Admin.
*/
final class UAGB_Admin {
/**
* Member Variable
*
* @var instance
*/
private static $instance;
/**
* Initiator
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
public function __construct() {
if ( ! is_admin() ) {
return;
}
global $wp_customize;
/**
* Conditionally load the scripts in the customizer.
* If the customizer is not set, it means we are not in the customizer.
* In that case load the script that will reload the page after migration is complete.
*/
if ( empty( $wp_customize ) ) {
add_action( 'admin_enqueue_scripts', array( $this, 'reload_on_migration_complete' ) );
}
add_action( 'wp_ajax_uag_migrate', array( $this, 'handle_migration_action_ajax' ) );
add_action( 'admin_notices', array( $this, 'register_notices' ) );
add_filter( 'wp_kses_allowed_html', array( $this, 'add_data_attributes' ), 10, 2 );
add_action( 'admin_enqueue_scripts', array( $this, 'notice_styles_scripts' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'notice_styles_scripts_upgrade_pro' ) );
add_filter( 'rank_math/researches/toc_plugins', array( $this, 'toc_plugin' ) );
add_action( 'admin_init', array( $this, 'activation_redirect' ) );
add_action( 'admin_init', array( $this, 'update_old_user_option_by_url_params' ) );
add_action( 'admin_post_uag_rollback', array( $this, 'post_uagb_rollback' ) );
// Update get access url in Template Kits.
add_filter( 'ast_block_templates_pro_url', array( $this, 'update_gutenberg_templates_pro_url' ) );
add_action( 'admin_post_uag_download_log', array( $this, 'handle_log_download' ) );
}
/**
* Handle migration action AJAX.
*
* @since 2.13.9
* @return void
*/
public function handle_migration_action_ajax() {
check_ajax_referer( 'spectra-migration', 'security' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( array( 'message' => 'Permission Denied' ) );
}
// Trigger the migration.
Spectra_Migrate_Blocks::get_instance()->blocks_migration();
// Update the migration status to 'no' before starting.
update_option( 'uag_migration_status', 'yes' );
// Set a new option to know that the migration process has started.
update_option( 'uag_migration_progress_status', 'in-progress' );
// Prepare the response.
$response = array(
'success' => true,
'data' => array(
'message' => esc_html__( 'Migration started successfully.', 'ultimate-addons-for-gutenberg' ),
),
);
// Send JSON response.
wp_send_json_success( $response );
}
/**
* Callback function to display migration log page content.
*
* @since 2.13.9
* @return void
*/
public function handle_log_download() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'You do not have permission to access this page.', 'ultimate-addons-for-gutenberg' ) );
}
$log_file = ABSPATH . 'wp-content/uploads/migration-log.txt';
if ( file_exists( $log_file ) ) {
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/octet-stream' );
header( 'Content-Disposition: attachment; filename="' . basename( $log_file ) . '"' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate' );
header( 'Pragma: public' );
header( 'Content-Length: ' . filesize( $log_file ) );
flush(); // Flush system output buffer.
readfile( $log_file );
exit;
} else {
wp_die( esc_html__( 'Log file not found.', 'ultimate-addons-for-gutenberg' ) );
}
}
/**
* Updates the Gutenberg templates pro URL.
* This function returns the URL for the pro version of Gutenberg templates.
*
* @since 2.13.7
* @return string The URL for Spectra Webpage.
*/
public function update_gutenberg_templates_pro_url() {
return \UAGB_Admin_Helper::get_spectra_pro_url( '/pricing/', 'gutenberg-templates', 'dashboard', 'Starter-Template-Backend' );
}
/**
* Update Old user option using URL Param.
*
* If any user wants to set the site as old user then just add the URL param as true.
*
* @since 2.0.1
* @access public
*/
public function update_old_user_option_by_url_params() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$spectra_old_user = isset( $_GET['spectra_old_user'] ) ? sanitize_text_field( $_GET['spectra_old_user'] ) : false; //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- $_GET['spectra_old_user'] does not provide nonce.
if ( 'yes' === $spectra_old_user ) {
update_option( 'uagb-old-user-less-than-2', 'yes' );
} elseif ( 'no' === $spectra_old_user ) {
delete_option( 'uagb-old-user-less-than-2' );
}
}
/**
* UAG version rollback.
*
* Rollback to previous UAG version.
*
* Fired by `admin_post_uag_rollback` action.
*
* @since 1.23.0
* @access public
*/
public function post_uagb_rollback() {
if ( ! current_user_can( 'install_plugins' ) ) {
wp_die(
esc_html__( 'You do not have permission to access this page.', 'ultimate-addons-for-gutenberg' ),
esc_html__( 'Rollback to Previous Version', 'ultimate-addons-for-gutenberg' ),
array(
'response' => 200,
)
);
}
check_admin_referer( 'uag_rollback' );
$rollback_versions = UAGB_Admin_Helper::get_instance()->get_rollback_versions();
$update_version = isset( $_GET['version'] ) ? sanitize_text_field( $_GET['version'] ) : '';
if ( empty( $update_version ) || ! in_array( $update_version, $rollback_versions, true ) ) {
wp_die( esc_html__( 'Error occurred, The version selected is invalid. Try selecting different version.', 'ultimate-addons-for-gutenberg' ) );
}
$plugin_slug = basename( UAGB_FILE, '.php' );
$rollback = new UAGB_Rollback(
array(
'version' => $update_version,
'plugin_name' => UAGB_BASE,
'plugin_slug' => $plugin_slug,
'package_url' => sprintf( 'https://downloads.wordpress.org/plugin/%s.%s.zip', $plugin_slug, $update_version ),
)
);
$rollback->run();
wp_die(
'',
esc_html__( 'Rollback to Previous Version', 'ultimate-addons-for-gutenberg' ),
array(
'response' => 200,
)
);
}
/**
* Activation Reset
*/
public function activation_redirect() {
$do_redirect = apply_filters( 'uagb_enable_redirect_activation', get_option( '__uagb_do_redirect' ) );
if ( $do_redirect ) {
update_option( '__uagb_do_redirect', false );
if ( ! is_multisite() ) {
wp_safe_redirect(
add_query_arg(
array(
'page' => UAGB_SLUG,
'spectra-activation-redirect' => true,
),
admin_url( 'admin.php' )
)
);
exit();
}
}
}
/**
* Filters and Returns a list of allowed tags and attributes for a given context.
*
* @param Array $allowedposttags Array of allowed tags.
* @param String $context Context type (explicit).
* @since 1.8.0
* @return Array
*/
public function add_data_attributes( $allowedposttags, $context ) {
$allowedposttags['a']['data-repeat-notice-after'] = true;
return $allowedposttags;
}
/**
* Ask Plugin Rating
*
* @since 1.8.0
*/
public function register_notices() {
// Check if assets should be excluded for the current post type.
if ( UAGB_Admin_Helper::should_exclude_assets_for_cpt() ) {
return; // Early return to prevent loading assets.
}
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$image_path = UAGB_URL . 'admin-core/assets/images/uag-logo.svg';
if ( ! get_option( 'uag_migration_status', false ) && 'yes' === get_option( 'uagb-old-user-less-than-2' ) && 'in-progress' !== get_option( 'uag_migration_progress_status', '' ) ) {
Astra_Notices::add_notice(
array(
'id' => 'uagb-block-migration_status',
'type' => '',
'message' => sprintf(
// Translators: %1$s: Spectra logo, %2$s: migration note , %3$s: The closing tag, %4$s: migration description, %5$s: migration button placeholder, %6$s: Learn more button, %7$s: learn more placeholder.
'<div class="notice-image">
<img src="%1$s" class="custom-logo" alt="Spectra" itemprop="logo"></div>
<div class="notice-content">
<h4 style="margin: 0.5em 0" class="notice-heading">
%2$s
</h4>
%3$s<br /><br />
<strong>%4$s</strong>
<div style="margin-bottom: 0.5em" class="astra-review-notice-container">
<a style="margin-right: 0.5em" id="trigger_migration" class="uagb-review-notice button-primary">
%5$s
</a>
<a href="%6$s" class="uagb-review-notice button-primary">
%7$s
</a>
</div>
</div><br />',
$image_path,
__( 'Spectra database update required', 'ultimate-addons-for-gutenberg' ),
__( "We've detected that some of your pages were created with an older version of Spectra. To ensure your designs remain unaffected, we recommend updating the Spectra database now. Updating the Spectra database will not impact any other parts of your website.", 'ultimate-addons-for-gutenberg' ),
__( 'To be on the safer side, please be sure to back up your site before updating.', 'ultimate-addons-for-gutenberg' ),
__( 'Update Spectra Database', 'ultimate-addons-for-gutenberg' ),
esc_url( 'https://wpspectra.com/docs/spectra-database-update-instructions/' ),
__( 'Learn More About This', 'ultimate-addons-for-gutenberg' )
),
'priority' => 20,
'display-with-other-notices' => true,
)
);
} elseif ( 'yes' !== get_option( 'uag_migration_complete', 0 ) && 'yes' === get_option( 'uagb-old-user-less-than-2' ) ) {
Astra_Notices::add_notice(
array(
'id' => 'uag_migration_in_progress',
'type' => 'info',
'message' => sprintf(
// Translators: %1$s: Spectra logo, %2$s: in-progress note.
'<div class="notice-image">
<img src="%1$s" class="custom-logo" alt="Spectra" itemprop="logo"></div>
<div class="notice-content">
<h4 style="margin: 0.5em 0" class="notice-heading">
%2$s
</h4>
<div style="margin-bottom: 0.5em" class="astra-review-notice-container">
<span class="spinner is-active"></span>
%3$s
</div>
</div><br />',
$image_path,
__( 'Spectra database update in progress', 'ultimate-addons-for-gutenberg' ),
__( 'Great! This should only take a few minutes. Thanks for hanging in there.', 'ultimate-addons-for-gutenberg' )
),
'dismissible' => false,
'priority' => 20,
'display-with-other-notices' => true,
)
);
} elseif ( 'yes' === get_option( 'uag_migration_complete', 0 ) ) {
Astra_Notices::add_notice(
array(
'id' => 'uag_migration_success',
'type' => 'success',
'message' => sprintf(
// Translators: %1$s: Spectra logo, %2$s: success message, %3$s: additional note.
'<div class="notice-image">
<img src="%1$s" class="custom-logo" alt="Spectra" itemprop="logo"></div>
<div class="notice-content">
<h4 style="margin: 0.5em 0" class="notice-heading">
%2$s
</h4>
<div style="margin-bottom: 0.5em" class="astra-review-notice-container">
%3$s
</div>
</div><br />',
$image_path,
__( 'Update Successful!', 'ultimate-addons-for-gutenberg' ),
__( 'Your Spectra database is now up-to-date. Your website will continue to function as before.', 'ultimate-addons-for-gutenberg' ) . ' <a href="' . esc_url( admin_url( 'admin-post.php?action=uag_download_log' ) ) . '">' . __( 'View Log', 'ultimate-addons-for-gutenberg' ) . '</a>'
),
'dismissible' => true,
'priority' => 20,
'display-with-other-notices' => true,
)
);
}
if ( class_exists( 'Classic_Editor' ) ) {
$editor_option = get_option( 'classic-editor-replace' );
if ( 'block' !== $editor_option ) {
Astra_Notices::add_notice(
array(
'id' => 'uagb-classic-editor',
'type' => 'warning',
'message' => sprintf(
/* translators: %s: html tags */
__( 'Spectra requires&nbsp;%3$sBlock Editor%4$s. You can change your editor settings to Block Editor from&nbsp;%1$shere%2$s. Plugin is currently NOT RUNNING.', 'ultimate-addons-for-gutenberg' ),
'<a href="' . admin_url( 'options-writing.php' ) . '">',
'</a>',
'<strong>',
'</strong>'
),
'priority' => 20,
'display-with-other-notices' => true,
)
);
}
}
$image_path = UAGB_URL . 'admin-core/assets/images/uag-logo.svg';
$installed_plugins = get_plugins();
$status = isset( $installed_plugins['spectra-pro/spectra-pro.php'] )
? ( is_plugin_active( 'spectra-pro/spectra-pro.php' )
? 'active'
: 'inactive' )
: 'not-installed';
if ( 'not-installed' === $status && isset( $_GET['post_type'] ) && 'spectra-popup' === $_GET['post_type'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- $_GET['post_type'] does not provide nonce.
Astra_Notices::add_notice(
array(
'id' => 'uagb-spectra-pro-popup-note',
'type' => '',
'message' => sprintf(
'<div class="notice-image">
<img src="%1$s" class="custom-logo" style="max-width: 40px;" alt="Spectra" itemprop="logo"></div>
<div class="notice-content">
<div class="notice-heading">
<strong>
%2$s
</strong>
</div>
%3$s<br />
<div class="astra-review-notice-container">
<a href="%4$s" class="not-astra-notice-close uagb-review-notice button-primary" target="_blank">
%5$s
</a>
</div>
</div>',
$image_path,
__( 'Want to do more with Popup Builder?', 'ultimate-addons-for-gutenberg' ),
__( 'Maximize your popup potential with Spectra Pro. Unlock enhanced features, intuitive design options, and increased conversions!', 'ultimate-addons-for-gutenberg' ),
esc_url( \UAGB_Admin_Helper::get_spectra_pro_url( '/pricing/', 'free-plugin', 'popup-builder', 'popup-builder-banner' ) ),
__( 'Upgrade Now', 'ultimate-addons-for-gutenberg' )
),
'dismissible' => true,
'priority' => 20,
'display-with-other-notices' => true,
'class' => 'spectra-upsell',
)
);
}
}
/**
* Enqueue the needed CSS/JS for the builder's admin settings page.
*
* @since 1.8.0
*/
public function notice_styles_scripts() {
$screen = get_current_screen();
if ( $screen && 'admin_page_migration-log' === $screen->base ) {
wp_enqueue_style( 'uag-admin-css', UAGB_URL . 'admin/assets/admin-notice.css', array(), UAGB_VER );
// Add inline CSS to hide elements with the 'notice' class.
$custom_css = '.notice { display: none !important; }';
wp_add_inline_style( 'uag-admin-css', $custom_css );
}
}
/**
* Enqueue the needed CSS/JS for the plugin / popup page.
*
* @since 2.16.0
* @return void
*/
public function notice_styles_scripts_upgrade_pro() {
$screen = get_current_screen();
if ( $screen && ( 'plugins' === $screen->base || 'spectra-popup' === $screen->post_type ) ) {
wp_enqueue_style( 'uag-admin-spectra-pro-upgrade-pro-css', UAGB_URL . 'admin/assets/admin-notice-spectra-pro-upgrade-pro.css', array(), UAGB_VER );
}
// Redirect to Pro pricing page when click on Get Spectra Pro button.
if ( $screen && 'toplevel_page_spectra' === $screen->base ) {
?>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
let upgradeLink = document.querySelector('a[href$="&path=upgrade-now"]');
if (upgradeLink) {
upgradeLink.setAttribute('target', '_blank');
upgradeLink.setAttribute('rel', 'noreferrer');
upgradeLink.addEventListener('click', function(e) {
e.preventDefault();
window.open( <?php echo esc_url( \UAGB_Admin_Helper::get_spectra_pro_url( '/pricing/', 'free-plugin', 'dashboard', 'setting' ) ); ?>, '_blank', 'noopener,noreferrer' );
});
}
});
</script>
<?php
}
}
/**
* Enqueue script to reload the page on migration complete.
*
* @since 2.13.9
* @return void
*/
public function reload_on_migration_complete() {
?>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
var triggerButton = document.getElementById('trigger_migration');
if (triggerButton) {
triggerButton.addEventListener('click', function(e) {
e.preventDefault();
fetch('<?php echo esc_html( admin_url( 'admin-ajax.php' ) ); ?>', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'action=uag_migrate&security=' + encodeURIComponent('<?php echo esc_html( wp_create_nonce( 'spectra-migration' ) ); ?>'),
})
.then(function(response) {
return response.json();
})
.then(function(data) {
if (data.success) {
location.reload();
// Optionally, reload the page or perform additional actions.
} else {
return;
}
})
.catch(function(error) {
console.error('Error occurred during migration:', error);
});
});
}
});
</script>
<?php
}
/**
* Rank Math SEO filter to add kb-elementor to the TOC list.
*
* @param array $plugins TOC plugins.
*/
public function toc_plugin( $plugins ) {
$plugins['ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php'] = 'Spectra';
return $plugins;
}
}
UAGB_Admin::get_instance();
}

View File

@@ -0,0 +1,145 @@
<?php
/**
* UAGB Beta Updates.
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'UAGB_Beta_Updates' ) ) {
/**
* Class UAGB_Beta_Updates.
*/
final class UAGB_Beta_Updates {
/**
* Member Variable
*
* @var instance
*/
private static $instance;
/**
* Transient key.
*
* Holds the UAG beta updates transient key.
*
* @since 1.23.0
* @access private
* @static
*
* @var string Transient key.
*/
private $transient_key;
/**
* Initiator
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*
* @since 1.23.0
*/
public function __construct() {
if ( 'yes' !== get_option( 'uagb_beta', 'no' ) ) {
return;
}
$this->transient_key = md5( 'uagb_beta_testers_response_key' );
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_version' ) );
}
/**
* Get beta version.
*
* Retrieve UAG beta version from wp.org plugin repository.
*
* @since 1.23.0
* @access private
*
* @return string|false Beta version or false.
*/
private function get_beta_version() {
$beta_version = get_site_transient( $this->transient_key );
if ( false === $beta_version ) {
$beta_version = 'false';
$response = wp_remote_get( 'https://plugins.svn.wordpress.org/ultimate-addons-for-gutenberg/trunk/readme.txt' );
if ( ! is_wp_error( $response ) && ! empty( $response['body'] ) ) {
preg_match( '/Beta tag: (.*)/i', $response['body'], $matches );
if ( isset( $matches[1] ) ) {
$beta_version = $matches[1];
}
}
set_site_transient( $this->transient_key, $beta_version, 6 * HOUR_IN_SECONDS );
}
return $beta_version;
}
/**
* Check version.
*
* Checks whether a beta version exist, and retrieve the version data.
*
* Fired by `pre_set_site_transient_update_plugins` filter, before WordPress
* runs the plugin update checker.
*
* @since 1.23.0
* @access public
*
* @param object $transient Plugin version data.
*
* @return array Plugin version data.
*/
public function check_version( $transient ) {
if ( empty( $transient->checked ) ) {
return $transient;
}
delete_site_transient( $this->transient_key );
$plugin_slug = basename( UAGB_FILE, '.php' );
$beta_version = $this->get_beta_version();
if ( 'false' !== $beta_version && version_compare( $beta_version, UAGB_VER, '>' ) ) {
$response = new \stdClass();
$response->plugin = $plugin_slug;
$response->slug = $plugin_slug;
$response->new_version = $beta_version;
$response->url = 'https://wpspectra.com/';
$response->package = sprintf( 'https://downloads.wordpress.org/plugin/ultimate-addons-for-gutenberg.%s.zip', $beta_version );
$transient->response[ UAGB_BASE ] = $response;
}
return $transient;
}
}
/**
* Prepare if class 'UAGB_Beta_Updates' exist.
* Kicking this off by calling 'get_instance()' method
*/
UAGB_Beta_Updates::get_instance();
}

View File

@@ -0,0 +1,759 @@
<?php
/**
* UAGB Block Helper.
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'UAGB_Block_JS' ) ) {
/**
* Class UAGB_Block_JS.
*/
class UAGB_Block_JS {
/**
* Adds Google fonts for Advanced Heading block.
*
* @since 1.9.1
* @param array $attr the blocks attr.
*/
public static function blocks_advanced_heading_gfont( $attr ) {
$head_load_google_font = isset( $attr['headLoadGoogleFonts'] ) ? $attr['headLoadGoogleFonts'] : '';
$head_font_family = isset( $attr['headFontFamily'] ) ? $attr['headFontFamily'] : '';
$head_font_weight = isset( $attr['headFontWeight'] ) ? $attr['headFontWeight'] : '';
$subhead_load_google_font = isset( $attr['subHeadLoadGoogleFonts'] ) ? $attr['subHeadLoadGoogleFonts'] : '';
$subhead_font_family = isset( $attr['subHeadFontFamily'] ) ? $attr['subHeadFontFamily'] : '';
$subhead_font_weight = isset( $attr['subHeadFontWeight'] ) ? $attr['subHeadFontWeight'] : '';
$highlight_head_load_google_font = isset( $attr['highLightLoadGoogleFonts'] ) ? $attr['highLightLoadGoogleFonts'] : '';
$highlight_head_font_family = isset( $attr['highLightFontFamily'] ) ? $attr['highLightFontFamily'] : '';
$highlight_head_font_weight = isset( $attr['highLightFontWeight'] ) ? $attr['highLightFontWeight'] : '';
UAGB_Helper::blocks_google_font( $head_load_google_font, $head_font_family, $head_font_weight );
UAGB_Helper::blocks_google_font( $subhead_load_google_font, $subhead_font_family, $subhead_font_weight );
UAGB_Helper::blocks_google_font( $highlight_head_load_google_font, $highlight_head_font_family, $highlight_head_font_weight );
}
/**
* Adds Google fonts for How To block.
*
* @since 1.15.0
* @param array $attr the blocks attr.
*/
public static function blocks_how_to_gfont( $attr ) {
$head_load_google_font = isset( $attr['headLoadGoogleFonts'] ) ? $attr['headLoadGoogleFonts'] : '';
$head_font_family = isset( $attr['headFontFamily'] ) ? $attr['headFontFamily'] : '';
$head_font_weight = isset( $attr['headFontWeight'] ) ? $attr['headFontWeight'] : '';
$subhead_load_google_font = isset( $attr['subHeadLoadGoogleFonts'] ) ? $attr['subHeadLoadGoogleFonts'] : '';
$subhead_font_family = isset( $attr['subHeadFontFamily'] ) ? $attr['subHeadFontFamily'] : '';
$subhead_font_weight = isset( $attr['subHeadFontWeight'] ) ? $attr['subHeadFontWeight'] : '';
$price_load_google_font = isset( $attr['priceLoadGoogleFonts'] ) ? $attr['priceLoadGoogleFonts'] : '';
$price_font_family = isset( $attr['priceFontFamily'] ) ? $attr['priceFontFamily'] : '';
$price_font_weight = isset( $attr['priceFontWeight'] ) ? $attr['priceFontWeight'] : '';
UAGB_Helper::blocks_google_font( $head_load_google_font, $head_font_family, $head_font_weight );
UAGB_Helper::blocks_google_font( $subhead_load_google_font, $subhead_font_family, $subhead_font_weight );
UAGB_Helper::blocks_google_font( $price_load_google_font, $price_font_family, $price_font_weight );
}
/**
* Adds Google fonts for How To Step block.
*
* @since 2.0.0
* @param array $attr the blocks attr.
*/
public static function blocks_how_to_step_gfont( $attr ) {
$url_load_google_font = isset( $attr['urlLoadGoogleFonts'] ) ? $attr['urlLoadGoogleFonts'] : '';
$url_font_family = isset( $attr['urlFontFamily'] ) ? $attr['urlFontFamily'] : '';
$url_font_weight = isset( $attr['urlFontWeight'] ) ? $attr['urlFontWeight'] : '';
$title_load_google_font = isset( $attr['titleLoadGoogleFonts'] ) ? $attr['titleLoadGoogleFonts'] : '';
$title_font_family = isset( $attr['titleFontFamily'] ) ? $attr['titleFontFamily'] : '';
$title_font_weight = isset( $attr['titleFontWeight'] ) ? $attr['titleFontWeight'] : '';
$description_load_google_font = isset( $attr['descriptionLoadGoogleFonts'] ) ? $attr['descriptionLoadGoogleFonts'] : '';
$description_font_family = isset( $attr['descriptionFontFamily'] ) ? $attr['descriptionFontFamily'] : '';
$description_font_weight = isset( $attr['descriptionFontWeight'] ) ? $attr['descriptionFontWeight'] : '';
UAGB_Helper::blocks_google_font( $url_load_google_font, $url_font_family, $url_font_weight );
UAGB_Helper::blocks_google_font( $title_load_google_font, $title_font_family, $title_font_weight );
UAGB_Helper::blocks_google_font( $description_load_google_font, $description_font_family, $description_font_weight );
}
/**
* Adds Google fonts for review block.
*
* @since 1.19.0
* @param array $attr the blocks attr.
*/
public static function blocks_review_gfont( $attr ) {
$head_load_google_font = isset( $attr['headLoadGoogleFonts'] ) ? $attr['headLoadGoogleFonts'] : '';
$head_font_family = isset( $attr['headFontFamily'] ) ? $attr['headFontFamily'] : '';
$head_font_weight = isset( $attr['headFontWeight'] ) ? $attr['headFontWeight'] : '';
$subhead_load_google_font = isset( $attr['subHeadLoadGoogleFonts'] ) ? $attr['subHeadLoadGoogleFonts'] : '';
$subhead_font_family = isset( $attr['subHeadFontFamily'] ) ? $attr['subHeadFontFamily'] : '';
$subhead_font_weight = isset( $attr['subHeadFontWeight'] ) ? $attr['subHeadFontWeight'] : '';
$content_load_google_fonts = isset( $attr['contentLoadGoogleFonts'] ) ? $attr['contentLoadGoogleFonts'] : '';
$content_font_family = isset( $attr['contentFontFamily'] ) ? $attr['contentFontFamily'] : '';
$content_font_weight = isset( $attr['contentFontWeight'] ) ? $attr['contentFontWeight'] : '';
UAGB_Helper::blocks_google_font( $subhead_load_google_font, $subhead_font_family, $subhead_font_weight );
UAGB_Helper::blocks_google_font( $head_load_google_font, $head_font_family, $head_font_weight );
UAGB_Helper::blocks_google_font( $content_load_google_fonts, $content_font_family, $content_font_weight );
}
/**
* Adds Google fonts for Inline Notice block.
*
* @since 1.16.0
* @param array $attr the blocks attr.
*/
public static function blocks_inline_notice_gfont( $attr ) {
$title_load_google_font = isset( $attr['titleLoadGoogleFonts'] ) ? $attr['titleLoadGoogleFonts'] : '';
$title_font_family = isset( $attr['titleFontFamily'] ) ? $attr['titleFontFamily'] : '';
$title_font_weight = isset( $attr['titleFontWeight'] ) ? $attr['titleFontWeight'] : '';
$desc_load_google_font = isset( $attr['descLoadGoogleFonts'] ) ? $attr['descLoadGoogleFonts'] : '';
$desc_font_family = isset( $attr['descFontFamily'] ) ? $attr['descFontFamily'] : '';
$desc_font_weight = isset( $attr['descFontWeight'] ) ? $attr['descFontWeight'] : '';
UAGB_Helper::blocks_google_font( $title_load_google_font, $title_font_family, $title_font_weight );
UAGB_Helper::blocks_google_font( $desc_load_google_font, $desc_font_family, $desc_font_weight );
}
/**
* Adds Google fonts for CF7 Styler block.
*
* @since 1.10.0
* @param array $attr the blocks attr.
*/
public static function blocks_cf7_styler_gfont( $attr ) {
$label_load_google_font = isset( $attr['labelLoadGoogleFonts'] ) ? $attr['labelLoadGoogleFonts'] : '';
$label_font_family = isset( $attr['labelFontFamily'] ) ? $attr['labelFontFamily'] : '';
$label_font_weight = isset( $attr['labelFontWeight'] ) ? $attr['labelFontWeight'] : '';
$input_load_google_font = isset( $attr['inputLoadGoogleFonts'] ) ? $attr['inputLoadGoogleFonts'] : '';
$input_font_family = isset( $attr['inputFontFamily'] ) ? $attr['inputFontFamily'] : '';
$input_font_weight = isset( $attr['inputFontWeight'] ) ? $attr['inputFontWeight'] : '';
$radio_check_load_google_font = isset( $attr['radioCheckLoadGoogleFonts'] ) ? $attr['radioCheckLoadGoogleFonts'] : '';
$radio_check_font_family = isset( $attr['radioCheckFontFamily'] ) ? $attr['radioCheckFontFamily'] : '';
$radio_check_font_weight = isset( $attr['radioCheckFontWeight'] ) ? $attr['radioCheckFontWeight'] : '';
$button_load_google_font = isset( $attr['buttonLoadGoogleFonts'] ) ? $attr['buttonLoadGoogleFonts'] : '';
$button_font_family = isset( $attr['buttonFontFamily'] ) ? $attr['buttonFontFamily'] : '';
$button_font_weight = isset( $attr['buttonFontWeight'] ) ? $attr['buttonFontWeight'] : '';
$msg_font_load_google_font = isset( $attr['msgLoadGoogleFonts'] ) ? $attr['msgLoadGoogleFonts'] : '';
$msg_font_family = isset( $attr['msgFontFamily'] ) ? $attr['msgFontFamily'] : '';
$msg_font_weight = isset( $attr['msgFontWeight'] ) ? $attr['msgFontWeight'] : '';
$validation_msg_load_google_font = isset( $attr['validationMsgLoadGoogleFonts'] ) ? $attr['validationMsgLoadGoogleFonts'] : '';
$validation_msg_font_family = isset( $attr['validationMsgFontFamily'] ) ? $attr['validationMsgFontFamily'] : '';
$validation_msg_font_weight = isset( $attr['validationMsgFontWeight'] ) ? $attr['validationMsgFontWeight'] : '';
UAGB_Helper::blocks_google_font( $msg_font_load_google_font, $msg_font_family, $msg_font_weight );
UAGB_Helper::blocks_google_font( $validation_msg_load_google_font, $validation_msg_font_family, $validation_msg_font_weight );
UAGB_Helper::blocks_google_font( $radio_check_load_google_font, $radio_check_font_family, $radio_check_font_weight );
UAGB_Helper::blocks_google_font( $button_load_google_font, $button_font_family, $button_font_weight );
UAGB_Helper::blocks_google_font( $label_load_google_font, $label_font_family, $label_font_weight );
UAGB_Helper::blocks_google_font( $input_load_google_font, $input_font_family, $input_font_weight );
}
/**
* Adds Google fonts for Gravity Form Styler block.
*
* @since 1.12.0
* @param array $attr the blocks attr.
*/
public static function blocks_gf_styler_gfont( $attr ) {
$label_load_google_font = isset( $attr['labelLoadGoogleFonts'] ) ? $attr['labelLoadGoogleFonts'] : '';
$label_font_family = isset( $attr['labelFontFamily'] ) ? $attr['labelFontFamily'] : '';
$label_font_weight = isset( $attr['labelFontWeight'] ) ? $attr['labelFontWeight'] : '';
$input_load_google_font = isset( $attr['inputLoadGoogleFonts'] ) ? $attr['inputLoadGoogleFonts'] : '';
$input_font_family = isset( $attr['inputFontFamily'] ) ? $attr['inputFontFamily'] : '';
$input_font_weight = isset( $attr['inputFontWeight'] ) ? $attr['inputFontWeight'] : '';
$radio_check_load_google_font = isset( $attr['radioCheckLoadGoogleFonts'] ) ? $attr['radioCheckLoadGoogleFonts'] : '';
$radio_check_font_family = isset( $attr['radioCheckFontFamily'] ) ? $attr['radioCheckFontFamily'] : '';
$radio_check_font_weight = isset( $attr['radioCheckFontWeight'] ) ? $attr['radioCheckFontWeight'] : '';
$button_load_google_font = isset( $attr['buttonLoadGoogleFonts'] ) ? $attr['buttonLoadGoogleFonts'] : '';
$button_font_family = isset( $attr['buttonFontFamily'] ) ? $attr['buttonFontFamily'] : '';
$button_font_weight = isset( $attr['buttonFontWeight'] ) ? $attr['buttonFontWeight'] : '';
$msg_font_load_google_font = isset( $attr['msgLoadGoogleFonts'] ) ? $attr['msgLoadGoogleFonts'] : '';
$msg_font_family = isset( $attr['msgFontFamily'] ) ? $attr['msgFontFamily'] : '';
$msg_font_weight = isset( $attr['msgFontWeight'] ) ? $attr['msgFontWeight'] : '';
$validation_msg_load_google_font = isset( $attr['validationMsgLoadGoogleFonts'] ) ? $attr['validationMsgLoadGoogleFonts'] : '';
$validation_msg_font_family = isset( $attr['validationMsgFontFamily'] ) ? $attr['validationMsgFontFamily'] : '';
$validation_msg_font_weight = isset( $attr['validationMsgFontWeight'] ) ? $attr['validationMsgFontWeight'] : '';
UAGB_Helper::blocks_google_font( $msg_font_load_google_font, $msg_font_family, $msg_font_weight );
UAGB_Helper::blocks_google_font( $validation_msg_load_google_font, $validation_msg_font_family, $validation_msg_font_weight );
UAGB_Helper::blocks_google_font( $radio_check_load_google_font, $radio_check_font_family, $radio_check_font_weight );
UAGB_Helper::blocks_google_font( $button_load_google_font, $button_font_family, $button_font_weight );
UAGB_Helper::blocks_google_font( $label_load_google_font, $label_font_family, $label_font_weight );
UAGB_Helper::blocks_google_font( $input_load_google_font, $input_font_family, $input_font_weight );
}
/**
* Adds Google fonts for Marketing Button block.
*
* @since 1.11.0
* @param array $attr the blocks attr.
*/
public static function blocks_marketing_btn_gfont( $attr ) {
$title_load_google_font = isset( $attr['titleLoadGoogleFonts'] ) ? $attr['titleLoadGoogleFonts'] : '';
$title_font_family = isset( $attr['titleFontFamily'] ) ? $attr['titleFontFamily'] : '';
$title_font_weight = isset( $attr['titleFontWeight'] ) ? $attr['titleFontWeight'] : '';
$prefix_load_google_font = isset( $attr['prefixLoadGoogleFonts'] ) ? $attr['prefixLoadGoogleFonts'] : '';
$prefix_font_family = isset( $attr['prefixFontFamily'] ) ? $attr['prefixFontFamily'] : '';
$prefix_font_weight = isset( $attr['prefixFontWeight'] ) ? $attr['prefixFontWeight'] : '';
UAGB_Helper::blocks_google_font( $title_load_google_font, $title_font_family, $title_font_weight );
UAGB_Helper::blocks_google_font( $prefix_load_google_font, $prefix_font_family, $prefix_font_weight );
}
/**
* Adds Google fonts for Table Of Contents block.
*
* @since 1.13.0
* @param array $attr the blocks attr.
*/
public static function blocks_table_of_contents_gfont( $attr ) {
$load_google_font = isset( $attr['loadGoogleFonts'] ) ? $attr['loadGoogleFonts'] : '';
$font_family = isset( $attr['fontFamily'] ) ? $attr['fontFamily'] : '';
$font_weight = isset( $attr['fontWeight'] ) ? $attr['fontWeight'] : '';
$heading_load_google_font = isset( $attr['headingLoadGoogleFonts'] ) ? $attr['headingLoadGoogleFonts'] : '';
$heading_font_family = isset( $attr['headingFontFamily'] ) ? $attr['headingFontFamily'] : '';
$heading_font_weight = isset( $attr['headingFontWeight'] ) ? $attr['headingFontWeight'] : '';
UAGB_Helper::blocks_google_font( $load_google_font, $font_family, $font_weight );
UAGB_Helper::blocks_google_font( $heading_load_google_font, $heading_font_family, $heading_font_weight );
}
/**
* Adds Google fonts for Blockquote.
*
* @since 1.9.1
* @param array $attr the blocks attr.
*/
public static function blocks_blockquote_gfont( $attr ) {
$desc_load_google_font = isset( $attr['descLoadGoogleFonts'] ) ? $attr['descLoadGoogleFonts'] : '';
$desc_font_family = isset( $attr['descFontFamily'] ) ? $attr['descFontFamily'] : '';
$desc_font_weight = isset( $attr['descFontWeight'] ) ? $attr['descFontWeight'] : '';
$author_load_google_font = isset( $attr['authorLoadGoogleFonts'] ) ? $attr['authorLoadGoogleFonts'] : '';
$author_font_family = isset( $attr['authorFontFamily'] ) ? $attr['authorFontFamily'] : '';
$author_font_weight = isset( $attr['authorFontWeight'] ) ? $attr['authorFontWeight'] : '';
$tweet_btn_load_google_font = isset( $attr['tweetBtnLoadGoogleFonts'] ) ? $attr['tweetBtnLoadGoogleFonts'] : '';
$tweet_btn_font_family = isset( $attr['tweetBtnFontFamily'] ) ? $attr['tweetBtnFontFamily'] : '';
$tweet_btn_font_weight = isset( $attr['tweetBtnFontWeight'] ) ? $attr['tweetBtnFontWeight'] : '';
UAGB_Helper::blocks_google_font( $desc_load_google_font, $desc_font_family, $desc_font_weight );
UAGB_Helper::blocks_google_font( $author_load_google_font, $author_font_family, $author_font_weight );
UAGB_Helper::blocks_google_font( $tweet_btn_load_google_font, $tweet_btn_font_family, $tweet_btn_font_weight );
}
/**
* Adds Google fonts for Testimonials block.
*
* @since 1.9.1
* @param array $attr the blocks attr.
*/
public static function blocks_testimonial_gfont( $attr ) {
$desc_load_google_fonts = isset( $attr['descLoadGoogleFonts'] ) ? $attr['descLoadGoogleFonts'] : '';
$desc_font_family = isset( $attr['descFontFamily'] ) ? $attr['descFontFamily'] : '';
$desc_font_weight = isset( $attr['descFontWeight'] ) ? $attr['descFontWeight'] : '';
$name_load_google_fonts = isset( $attr['nameLoadGoogleFonts'] ) ? $attr['nameLoadGoogleFonts'] : '';
$name_font_family = isset( $attr['nameFontFamily'] ) ? $attr['nameFontFamily'] : '';
$name_font_weight = isset( $attr['nameFontWeight'] ) ? $attr['nameFontWeight'] : '';
$company_load_google_fonts = isset( $attr['companyLoadGoogleFonts'] ) ? $attr['companyLoadGoogleFonts'] : '';
$company_font_family = isset( $attr['companyFontFamily'] ) ? $attr['companyFontFamily'] : '';
$company_font_weight = isset( $attr['companyFontWeight'] ) ? $attr['companyFontWeight'] : '';
UAGB_Helper::blocks_google_font( $desc_load_google_fonts, $desc_font_family, $desc_font_weight );
UAGB_Helper::blocks_google_font( $name_load_google_fonts, $name_font_family, $name_font_weight );
UAGB_Helper::blocks_google_font( $company_load_google_fonts, $company_font_family, $company_font_weight );
}
/**
* Adds Google fonts for Advanced Heading block.
*
* @since 1.9.1
* @param array $attr the blocks attr.
*/
public static function blocks_team_gfont( $attr ) {
$title_load_google_font = isset( $attr['titleLoadGoogleFonts'] ) ? $attr['titleLoadGoogleFonts'] : '';
$title_font_family = isset( $attr['titleFontFamily'] ) ? $attr['titleFontFamily'] : '';
$title_font_weight = isset( $attr['titleFontWeight'] ) ? $attr['titleFontWeight'] : '';
$prefix_load_google_font = isset( $attr['prefixLoadGoogleFonts'] ) ? $attr['prefixLoadGoogleFonts'] : '';
$prefix_font_family = isset( $attr['prefixFontFamily'] ) ? $attr['prefixFontFamily'] : '';
$prefix_font_weight = isset( $attr['prefixFontWeight'] ) ? $attr['prefixFontWeight'] : '';
$desc_load_google_font = isset( $attr['descLoadGoogleFonts'] ) ? $attr['descLoadGoogleFonts'] : '';
$desc_font_family = isset( $attr['descFontFamily'] ) ? $attr['descFontFamily'] : '';
$desc_font_weight = isset( $attr['descFontWeight'] ) ? $attr['descFontWeight'] : '';
UAGB_Helper::blocks_google_font( $title_load_google_font, $title_font_family, $title_font_weight );
UAGB_Helper::blocks_google_font( $prefix_load_google_font, $prefix_font_family, $prefix_font_weight );
UAGB_Helper::blocks_google_font( $desc_load_google_font, $desc_font_family, $desc_font_weight );
}
/**
*
* Adds Google fonts for Restaurant Menu block.
*
* @since 1.9.1
* @param array $attr the blocks attr.
*/
public static function blocks_restaurant_menu_gfont( $attr ) {
$title_load_google_fonts = isset( $attr['titleLoadGoogleFonts'] ) ? $attr['titleLoadGoogleFonts'] : '';
$title_font_family = isset( $attr['titleFontFamily'] ) ? $attr['titleFontFamily'] : '';
$title_font_weight = isset( $attr['titleFontWeight'] ) ? $attr['titleFontWeight'] : '';
$price_load_google_fonts = isset( $attr['priceLoadGoogleFonts'] ) ? $attr['priceLoadGoogleFonts'] : '';
$price_font_family = isset( $attr['priceFontFamily'] ) ? $attr['priceFontFamily'] : '';
$price_font_weight = isset( $attr['priceFontWeight'] ) ? $attr['priceFontWeight'] : '';
$desc_load_google_fonts = isset( $attr['descLoadGoogleFonts'] ) ? $attr['descLoadGoogleFonts'] : '';
$desc_font_family = isset( $attr['descFontFamily'] ) ? $attr['descFontFamily'] : '';
$desc_font_weight = isset( $attr['descFontWeight'] ) ? $attr['descFontWeight'] : '';
UAGB_Helper::blocks_google_font( $title_load_google_fonts, $title_font_family, $title_font_weight );
UAGB_Helper::blocks_google_font( $price_load_google_fonts, $price_font_family, $price_font_weight );
UAGB_Helper::blocks_google_font( $desc_load_google_fonts, $desc_font_family, $desc_font_weight );
}
/**
* Adds Google fonts for Content Timeline block.
*
* @since 1.9.1
* @param array $attr the blocks attr.
*/
public static function blocks_content_timeline_gfont( $attr ) {
$head_load_google_fonts = isset( $attr['headLoadGoogleFonts'] ) ? $attr['headLoadGoogleFonts'] : '';
$head_font_family = isset( $attr['headFontFamily'] ) ? $attr['headFontFamily'] : '';
$head_font_weight = isset( $attr['headFontWeight'] ) ? $attr['headFontWeight'] : '';
$subheadload_google_fonts = isset( $attr['subHeadLoadGoogleFonts'] ) ? $attr['subHeadLoadGoogleFonts'] : '';
$subheadfont_family = isset( $attr['subHeadFontFamily'] ) ? $attr['subHeadFontFamily'] : '';
$subheadfont_weight = isset( $attr['subHeadFontWeight'] ) ? $attr['subHeadFontWeight'] : '';
$date_load_google_fonts = isset( $attr['dateLoadGoogleFonts'] ) ? $attr['dateLoadGoogleFonts'] : '';
$date_font_family = isset( $attr['dateFontFamily'] ) ? $attr['dateFontFamily'] : '';
$date_font_weight = isset( $attr['dateFontWeight'] ) ? $attr['dateFontWeight'] : '';
UAGB_Helper::blocks_google_font( $head_load_google_fonts, $head_font_family, $head_font_weight );
UAGB_Helper::blocks_google_font( $subheadload_google_fonts, $subheadfont_family, $subheadfont_weight );
UAGB_Helper::blocks_google_font( $date_load_google_fonts, $date_font_family, $date_font_weight );
}
/**
* Adds Google fonts for Post Timeline block.
*
* @since 1.9.1
* @param array $attr the blocks attr.
*/
public static function blocks_post_timeline_gfont( $attr ) {
self::blocks_content_timeline_gfont( $attr );
$author_load_google_fonts = isset( $attr['authorLoadGoogleFonts'] ) ? $attr['authorLoadGoogleFonts'] : '';
$author_font_family = isset( $attr['authorFontFamily'] ) ? $attr['authorFontFamily'] : '';
$author_font_weight = isset( $attr['authorFontWeight'] ) ? $attr['authorFontWeight'] : '';
$cta_load_google_fonts = isset( $attr['ctaLoadGoogleFonts'] ) ? $attr['ctaLoadGoogleFonts'] : '';
$cta_font_family = isset( $attr['ctaFontFamily'] ) ? $attr['ctaFontFamily'] : '';
$cta_font_weight = isset( $attr['ctaFontWeight'] ) ? $attr['ctaFontWeight'] : '';
UAGB_Helper::blocks_google_font( $author_load_google_fonts, $author_font_family, $author_font_weight );
UAGB_Helper::blocks_google_font( $cta_load_google_fonts, $cta_font_family, $cta_font_weight );
}
/**
* Adds Google fonts for Mulit Button's block.
*
* @since 1.9.1
* @param array $attr the blocks attr.
*/
public static function blocks_buttons_gfont( $attr ) {
$load_google_font = isset( $attr['loadGoogleFonts'] ) ? $attr['loadGoogleFonts'] : '';
$font_family = isset( $attr['fontFamily'] ) ? $attr['fontFamily'] : '';
$font_weight = isset( $attr['fontWeight'] ) ? $attr['fontWeight'] : '';
UAGB_Helper::blocks_google_font( $load_google_font, $font_family, $font_weight );
}
/**
* Adds Google fonts for Post block.
*
* @since 1.9.1
* @param array $attr the blocks attr.
*/
public static function blocks_post_gfont( $attr ) {
$title_load_google_font = isset( $attr['titleLoadGoogleFonts'] ) ? $attr['titleLoadGoogleFonts'] : '';
$title_font_family = isset( $attr['titleFontFamily'] ) ? $attr['titleFontFamily'] : '';
$title_font_weight = isset( $attr['titleFontWeight'] ) ? $attr['titleFontWeight'] : '';
$meta_load_google_font = isset( $attr['metaLoadGoogleFonts'] ) ? $attr['metaLoadGoogleFonts'] : '';
$meta_font_family = isset( $attr['metaFontFamily'] ) ? $attr['metaFontFamily'] : '';
$meta_font_weight = isset( $attr['metaFontWeight'] ) ? $attr['metaFontWeight'] : '';
$excerpt_load_google_font = isset( $attr['excerptLoadGoogleFonts'] ) ? $attr['excerptLoadGoogleFonts'] : '';
$excerpt_font_family = isset( $attr['excerptFontFamily'] ) ? $attr['excerptFontFamily'] : '';
$excerpt_font_weight = isset( $attr['excerptFontWeight'] ) ? $attr['excerptFontWeight'] : '';
$cta_load_google_font = isset( $attr['ctaLoadGoogleFonts'] ) ? $attr['ctaLoadGoogleFonts'] : '';
$cta_font_family = isset( $attr['ctaFontFamily'] ) ? $attr['ctaFontFamily'] : '';
$cta_font_weight = isset( $attr['ctaFontWeight'] ) ? $attr['ctaFontWeight'] : '';
UAGB_Helper::blocks_google_font( $title_load_google_font, $title_font_family, $title_font_weight );
UAGB_Helper::blocks_google_font( $meta_load_google_font, $meta_font_family, $meta_font_weight );
UAGB_Helper::blocks_google_font( $excerpt_load_google_font, $excerpt_font_family, $excerpt_font_weight );
UAGB_Helper::blocks_google_font( $cta_load_google_font, $cta_font_family, $cta_font_weight );
}
/**
* Adds Google fonts for Advanced Heading block.
*
* @since 1.9.1
* @param array $attr the blocks attr.
*/
public static function blocks_info_box_gfont( $attr ) {
$head_load_google_font = isset( $attr['headLoadGoogleFonts'] ) ? $attr['headLoadGoogleFonts'] : '';
$head_font_family = isset( $attr['headFontFamily'] ) ? $attr['headFontFamily'] : '';
$head_font_weight = isset( $attr['headFontWeight'] ) ? $attr['headFontWeight'] : '';
$prefix_load_google_font = isset( $attr['prefixLoadGoogleFonts'] ) ? $attr['prefixLoadGoogleFonts'] : '';
$prefix_font_family = isset( $attr['prefixFontFamily'] ) ? $attr['prefixFontFamily'] : '';
$prefix_font_weight = isset( $attr['prefixFontWeight'] ) ? $attr['prefixFontWeight'] : '';
$subhead_load_google_font = isset( $attr['subHeadLoadGoogleFonts'] ) ? $attr['subHeadLoadGoogleFonts'] : '';
$subhead_font_family = isset( $attr['subHeadFontFamily'] ) ? $attr['subHeadFontFamily'] : '';
$subhead_font_weight = isset( $attr['subHeadFontWeight'] ) ? $attr['subHeadFontWeight'] : '';
$cta_load_google_font = isset( $attr['ctaLoadGoogleFonts'] ) ? $attr['ctaLoadGoogleFonts'] : '';
$cta_font_family = isset( $attr['ctaFontFamily'] ) ? $attr['ctaFontFamily'] : '';
$cta_font_weight = isset( $attr['ctaFontWeight'] ) ? $attr['ctaFontWeight'] : '';
UAGB_Helper::blocks_google_font( $cta_load_google_font, $cta_font_family, $cta_font_weight );
UAGB_Helper::blocks_google_font( $head_load_google_font, $head_font_family, $head_font_weight );
UAGB_Helper::blocks_google_font( $prefix_load_google_font, $prefix_font_family, $prefix_font_weight );
UAGB_Helper::blocks_google_font( $subhead_load_google_font, $subhead_font_family, $subhead_font_weight );
}
/**
* Adds Google fonts for Call To Action block.
*
* @since 1.9.1
* @param array $attr the blocks attr.
*/
public static function blocks_call_to_action_gfont( $attr ) {
$title_load_google_font = isset( $attr['titleLoadGoogleFonts'] ) ? $attr['titleLoadGoogleFonts'] : '';
$title_font_family = isset( $attr['titleFontFamily'] ) ? $attr['titleFontFamily'] : '';
$title_font_weight = isset( $attr['titleFontWeight'] ) ? $attr['titleFontWeight'] : '';
$desc_load_google_font = isset( $attr['descLoadGoogleFonts'] ) ? $attr['descLoadGoogleFonts'] : '';
$desc_font_family = isset( $attr['descFontFamily'] ) ? $attr['descFontFamily'] : '';
$desc_font_weight = isset( $attr['descFontWeight'] ) ? $attr['descFontWeight'] : '';
$cta_load_google_font = isset( $attr['ctaLoadGoogleFonts'] ) ? $attr['ctaLoadGoogleFonts'] : '';
$cta_font_family = isset( $attr['ctaFontFamily'] ) ? $attr['ctaFontFamily'] : '';
$cta_font_weight = isset( $attr['ctaFontWeight'] ) ? $attr['ctaFontWeight'] : '';
$second_cta_load_google_font = isset( $attr['secondCtaLoadGoogleFonts'] ) ? $attr['secondCtaLoadGoogleFonts'] : '';
$second_cta_font_family = isset( $attr['secondCtaFontFamily'] ) ? $attr['secondCtaFontFamily'] : '';
$second_cta_font_weight = isset( $attr['secondCtaFontWeight'] ) ? $attr['secondCtaFontWeight'] : '';
UAGB_Helper::blocks_google_font( $cta_load_google_font, $cta_font_family, $cta_font_weight );
UAGB_Helper::blocks_google_font( $title_load_google_font, $title_font_family, $title_font_weight );
UAGB_Helper::blocks_google_font( $desc_load_google_font, $desc_font_family, $desc_font_weight );
UAGB_Helper::blocks_google_font( $second_cta_load_google_font, $second_cta_font_family, $second_cta_font_weight );
}
/**
* Adds Google fonts for FAQ block.
*
* @since 1.15.0
* @param array $attr the blocks attr.
*/
public static function blocks_faq_gfont( $attr ) {
$question_load_google_font = isset( $attr['questionloadGoogleFonts'] ) ? $attr['questionloadGoogleFonts'] : '';
$question_font_family = isset( $attr['questionFontFamily'] ) ? $attr['questionFontFamily'] : '';
$question_font_weight = isset( $attr['questionFontWeight'] ) ? $attr['questionFontWeight'] : '';
$answer_load_google_font = isset( $attr['answerloadGoogleFonts'] ) ? $attr['answerloadGoogleFonts'] : '';
$answer_font_family = isset( $attr['answerFontFamily'] ) ? $attr['answerFontFamily'] : '';
$answer_font_weight = isset( $attr['answerFontWeight'] ) ? $attr['answerFontWeight'] : '';
UAGB_Helper::blocks_google_font( $question_load_google_font, $question_font_family, $question_font_weight );
UAGB_Helper::blocks_google_font( $answer_load_google_font, $answer_font_family, $answer_font_weight );
}
/**
* Adds Google fonts for WP Search block.
*
* @since 1.16.0
* @param array $attr the blocks attr.
*/
public static function blocks_wp_search_gfont( $attr ) {
$input_load_google_font = isset( $attr['inputloadGoogleFonts'] ) ? $attr['inputloadGoogleFonts'] : '';
$input_font_family = isset( $attr['inputFontFamily'] ) ? $attr['inputFontFamily'] : '';
$input_font_weight = isset( $attr['inputFontWeight'] ) ? $attr['inputFontWeight'] : '';
$button_load_google_font = isset( $attr['buttonloadGoogleFonts'] ) ? $attr['buttonloadGoogleFonts'] : '';
$button_font_family = isset( $attr['buttonFontFamily'] ) ? $attr['buttonFontFamily'] : '';
$button_font_weight = isset( $attr['buttonFontWeight'] ) ? $attr['buttonFontWeight'] : '';
UAGB_Helper::blocks_google_font( $button_load_google_font, $button_font_family, $button_font_weight );
UAGB_Helper::blocks_google_font( $input_load_google_font, $input_font_family, $input_font_weight );
}
/**
*
* Adds Google fonts for Separator block.
*
* @since 2.6.0
* @param array $attr the blocks attr.
* @return void
*/
public static function blocks_separator_gfont( $attr ) {
$element_text_load_google_font = isset( $attr['elementTextLoadGoogleFonts'] ) ? $attr['elementTextLoadGoogleFonts'] : '';
$element_text_font_family = isset( $attr['elementTextFontFamily'] ) ? $attr['elementTextFontFamily'] : '';
$element_text_font_weight = isset( $attr['elementTextFontWeight'] ) ? $attr['elementTextFontWeight'] : '';
UAGB_Helper::blocks_google_font( $element_text_load_google_font, $element_text_font_family, $element_text_font_weight );
}
/**
* Adds Google fonts for Taxonomy List block.
*
* @since 1.18.0
* @param array $attr the blocks attr.
*/
public static function blocks_taxonomy_list_gfont( $attr ) {
$title_load_google_font = isset( $attr['titleLoadGoogleFonts'] ) ? $attr['titleLoadGoogleFonts'] : '';
$title_font_family = isset( $attr['titleFontFamily'] ) ? $attr['titleFontFamily'] : '';
$title_font_weight = isset( $attr['titleFontWeight'] ) ? $attr['titleFontWeight'] : '';
$count_load_google_font = isset( $attr['countLoadGoogleFonts'] ) ? $attr['countLoadGoogleFonts'] : '';
$count_font_family = isset( $attr['countFontFamily'] ) ? $attr['countFontFamily'] : '';
$count_font_weight = isset( $attr['countFontWeight'] ) ? $attr['countFontWeight'] : '';
$list_load_google_font = isset( $attr['listLoadGoogleFonts'] ) ? $attr['listLoadGoogleFonts'] : '';
$list_font_family = isset( $attr['listFontFamily'] ) ? $attr['listFontFamily'] : '';
$list_font_weight = isset( $attr['listFontWeight'] ) ? $attr['listFontWeight'] : '';
UAGB_Helper::blocks_google_font( $title_load_google_font, $title_font_family, $title_font_weight );
UAGB_Helper::blocks_google_font( $count_load_google_font, $count_font_family, $count_font_weight );
UAGB_Helper::blocks_google_font( $list_load_google_font, $list_font_family, $list_font_weight );
}
/**
* Adds Google fonts for Forms block.
*
* @since 1.22.0
* @param array $attr the blocks attr.
*/
public static function blocks_forms_gfont( $attr ) {
$submitText_load_google_font = isset( $attr['submitTextloadGoogleFonts'] ) ? $attr['submitTextloadGoogleFonts'] : '';
$submitText_font_family = isset( $attr['submitTextFontFamily'] ) ? $attr['submitTextFontFamily'] : '';
$submitText_font_weight = isset( $attr['submitTextFontWeight'] ) ? $attr['submitTextFontWeight'] : '';
$label_load_google_font = isset( $attr['labelloadGoogleFonts'] ) ? $attr['labelloadGoogleFonts'] : '';
$label_font_family = isset( $attr['labelFontFamily'] ) ? $attr['labelFontFamily'] : '';
$label_font_weight = isset( $attr['labelFontWeight'] ) ? $attr['labelFontWeight'] : '';
$input_load_google_font = isset( $attr['inputloadGoogleFonts'] ) ? $attr['inputloadGoogleFonts'] : '';
$input_font_family = isset( $attr['inputFontFamily'] ) ? $attr['inputFontFamily'] : '';
$input_font_weight = isset( $attr['inputFontWeight'] ) ? $attr['inputFontWeight'] : '';
UAGB_Helper::blocks_google_font( $submitText_load_google_font, $submitText_font_family, $submitText_font_weight );
UAGB_Helper::blocks_google_font( $label_load_google_font, $label_font_family, $label_font_weight );
UAGB_Helper::blocks_google_font( $input_load_google_font, $input_font_family, $input_font_weight );
}
/**
* Adds Google fonts for Star Rating block.
*
* @since 2.0.0
* @param array $attr the blocks attr.
*/
public static function blocks_star_rating_gfont( $attr ) {
$load_google_font = isset( $attr['loadGoogleFonts'] ) ? $attr['loadGoogleFonts'] : '';
$font_family = isset( $attr['fontFamily'] ) ? $attr['fontFamily'] : '';
$font_weight = isset( $attr['fontWeight'] ) ? $attr['fontWeight'] : '';
UAGB_Helper::blocks_google_font( $load_google_font, $font_family, $font_weight );
}
/**
* Adds Google fonts for Tabs block.
*
* @since 2.0.0
* @param array $attr the blocks attr.
*/
public static function blocks_tabs_gfont( $attr ) {
$load_google_font = isset( $attr['titleLoadGoogleFonts'] ) ? $attr['titleLoadGoogleFonts'] : '';
$font_family = isset( $attr['titleFontFamily'] ) ? $attr['titleFontFamily'] : '';
$font_weight = isset( $attr['titleFontWeight'] ) ? $attr['titleFontWeight'] : '';
UAGB_Helper::blocks_google_font( $load_google_font, $font_family, $font_weight );
}
/**
* Adds Google fonts for Advanced Image block.
*
* @since 2.0.0
* @param array $attr the blocks attr.
*/
public static function blocks_advanced_image_gfont( $attr ) {
$heading_load_google_font = isset( $attr['headingLoadGoogleFonts'] ) ? $attr['headingLoadGoogleFonts'] : '';
$heading_font_family = isset( $attr['headingFontFamily'] ) ? $attr['headingFontFamily'] : '';
$heading_font_weight = isset( $attr['headingFontWeight'] ) ? $attr['headingFontWeight'] : '';
$caption_load_google_font = isset( $attr['captionLoadGoogleFonts'] ) ? $attr['captionLoadGoogleFonts'] : '';
$caption_font_family = isset( $attr['captionFontFamily'] ) ? $attr['captionFontFamily'] : '';
$caption_font_weight = isset( $attr['captionFontWeight'] ) ? $attr['captionFontWeight'] : '';
UAGB_Helper::blocks_google_font( $heading_load_google_font, $heading_font_family, $heading_font_weight );
UAGB_Helper::blocks_google_font( $caption_load_google_font, $caption_font_family, $caption_font_weight );
}
/**
* Adds Google fonts for Counter block.
*
* @since 2.1.0
* @param array $attr the blocks attr.
*/
public static function blocks_counter_gfont( $attr ) {
$heading_load_google_font = isset( $attr['headingLoadGoogleFonts'] ) ? $attr['headingLoadGoogleFonts'] : '';
$heading_font_family = isset( $attr['headingFontFamily'] ) ? $attr['headingFontFamily'] : '';
$heading_font_weight = isset( $attr['headingFontWeight'] ) ? $attr['headingFontWeight'] : '';
$number_load_google_font = isset( $attr['numberLoadGoogleFonts'] ) ? $attr['numberLoadGoogleFonts'] : '';
$number_font_family = isset( $attr['numberFontFamily'] ) ? $attr['numberFontFamily'] : '';
$number_font_weight = isset( $attr['numberFontWeight'] ) ? $attr['numberFontWeight'] : '';
UAGB_Helper::blocks_google_font( $heading_load_google_font, $heading_font_family, $heading_font_weight );
UAGB_Helper::blocks_google_font( $number_load_google_font, $number_font_family, $number_font_weight );
}
/**
* Adds Google fonts for Image Gallery block.
*
* @since 2.1.0
* @param array $attr the blocks attr.
*/
public static function blocks_image_gallery_gfont( $attr ) {
$caption_load_google_font = isset( $attr['captionLoadGoogleFonts'] ) ? $attr['captionLoadGoogleFonts'] : '';
$caption_font_family = isset( $attr['captionFontFamily'] ) ? $attr['captionFontFamily'] : '';
$caption_font_weight = isset( $attr['captionFontWeight'] ) ? $attr['captionFontWeight'] : '';
$load_more_load_google_font = isset( $attr['loadMoreLoadGoogleFonts'] ) ? $attr['loadMoreLoadGoogleFonts'] : '';
$load_more_font_family = isset( $attr['loadMoreFontFamily'] ) ? $attr['loadMoreFontFamily'] : '';
$load_more_font_weight = isset( $attr['loadMoreFontWeight'] ) ? $attr['loadMoreFontWeight'] : '';
$lightbox_load_google_font = isset( $attr['lightboxLoadGoogleFonts'] ) ? $attr['lightboxLoadGoogleFonts'] : '';
$lightbox_font_family = isset( $attr['lightboxFontFamily'] ) ? $attr['lightboxFontFamily'] : '';
$lightbox_font_weight = isset( $attr['lightboxFontWeight'] ) ? $attr['lightboxFontWeight'] : '';
UAGB_Helper::blocks_google_font( $caption_load_google_font, $caption_font_family, $caption_font_weight );
UAGB_Helper::blocks_google_font( $load_more_load_google_font, $load_more_font_family, $load_more_font_weight );
UAGB_Helper::blocks_google_font( $lightbox_load_google_font, $lightbox_font_family, $lightbox_font_weight );
}
/**
* Adds Google fonts for Countdown block.
*
* @since 2.4.0
* @param array $attr the blocks attr.
* @return void
*/
public static function blocks_countdown_gfont( $attr ) {
$digit_load_google_font = isset( $attr['digitLoadGoogleFonts'] ) ? $attr['digitLoadGoogleFonts'] : '';
$digit_font_family = isset( $attr['digitFontFamily'] ) ? $attr['digitFontFamily'] : '';
$digit_font_weight = isset( $attr['digitFontWeight'] ) ? $attr['digitFontWeight'] : '';
$label_load_google_font = isset( $attr['labelLoadGoogleFonts'] ) ? $attr['labelLoadGoogleFonts'] : '';
$label_font_family = isset( $attr['labelFontFamily'] ) ? $attr['labelFontFamily'] : '';
$label_font_weight = isset( $attr['labelFontWeight'] ) ? $attr['labelFontWeight'] : '';
$separator_load_google_font = isset( $attr['separatorLoadGoogleFonts'] ) ? $attr['separatorLoadGoogleFonts'] : '';
$separator_font_family = isset( $attr['separatorFontFamily'] ) ? $attr['separatorFontFamily'] : '';
$separator_font_weight = isset( $attr['separatorFontWeight'] ) ? $attr['separatorFontWeight'] : '';
UAGB_Helper::blocks_google_font( $digit_load_google_font, $digit_font_family, $digit_font_weight );
UAGB_Helper::blocks_google_font( $label_load_google_font, $label_font_family, $label_font_weight );
UAGB_Helper::blocks_google_font( $separator_load_google_font, $separator_font_family, $separator_font_weight );
}
/**
* Adds Google fonts for Modal block.
*
* @since 2.2.0
* @param array $attr the blocks attr.
*/
public static function blocks_modal_gfont( $attr ) {
$text_load_google_font = isset( $attr['textLoadGoogleFonts'] ) ? $attr['textLoadGoogleFonts'] : '';
$text_font_family = isset( $attr['textFontFamily'] ) ? $attr['textFontFamily'] : '';
$text_font_weight = isset( $attr['textFontWeight'] ) ? $attr['textFontWeight'] : '';
$btn_load_google_font = isset( $attr['btnLoadGoogleFonts'] ) ? $attr['btnLoadGoogleFonts'] : '';
$btn_font_family = isset( $attr['btnFontFamily'] ) ? $attr['btnFontFamily'] : '';
$btn_font_weight = isset( $attr['btnFontWeight'] ) ? $attr['btnFontWeight'] : '';
UAGB_Helper::blocks_google_font( $text_load_google_font, $text_font_family, $text_font_weight );
UAGB_Helper::blocks_google_font( $btn_load_google_font, $btn_font_family, $btn_font_weight );
}
}
}

View File

@@ -0,0 +1,332 @@
<?php
/**
* UAGB Block Module.
*
* @since 2.0.0
*
* @package uagb
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'UAGB_Block_Module' ) ) {
/**
* Class doc
*/
class UAGB_Block_Module {
/**
* Member Variable
*
* @var instance
*/
private static $instance;
/**
* Block Attributes
*
* @var block_attributes
*/
public static $block_attributes = null;
/**
* Block Assets
*
* @var array<mixed> block_assets
*/
public static $block_assets = null;
/**
* Initiator
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
public function __construct() {
add_filter( 'uag_register_block_static_dependencies', array( __CLASS__, 'uag_register_block_static_dependencies' ) );
}
/**
* Add Blocks Static Assets.
*
* @since 2.0.0
*
* @param array $block_assets Block Assets.
* @return array
*/
public static function uag_register_block_static_dependencies( $block_assets ) {
$blocks = self::get_blocks_info();
foreach ( $blocks as $block ) {
if ( ! isset( $block['static_dependencies'] ) ) {
continue;
}
foreach ( $block['static_dependencies'] as $key => $static_dependencies ) {
if ( ! isset( $static_dependencies['src'] ) ) {
continue;
}
$block_assets[ $key ] = $static_dependencies;
}
}
return $block_assets;
}
/**
* Get frontend CSS.
*
* @since 2.0.0
*
* @param string $slug Block slug.
* @param array $attr Block attributes.
* @param string $id Block id.
* @param bool $is_gbs Is Global Block Style.
* @return array
*/
public static function get_frontend_css( $slug, $attr, $id, $is_gbs = false ) {
return self::get_frontend_assets( $slug, $attr, esc_attr( $id ), 'css', $is_gbs );
}
/**
* Get frontend JS.
*
* @since 2.0.0
*
* @param string $slug Block slug.
* @param array $attr Block attributes.
* @param string $id Block id.
* @return array
*/
public static function get_frontend_js( $slug, $attr, $id ) {
return self::get_frontend_assets( $slug, $attr, esc_attr( $id ), 'js' );
}
/**
* Filter GBS Placeholder Attributes.
*
* @param array $attributes Block attributes.
* @since 2.9.0
* @return array $attributes Block attributes by removing 0.001020304.
*/
public static function gbs_filter_placeholder_attributes( $attributes ) {
if ( ! empty( $attributes ) && is_array( $attributes ) ) {
foreach ( $attributes as $key => $attribute ) {
// Replace 0.001020304 with empty string.
if ( 0.001020304 === $attribute ) {
$attributes[ $key ] = '';
}
}
return $attributes;
}
return array();
}
/**
* Get frontend Assets.
*
* @since 2.0.0
*
* @param string $slug Block slug.
* @param array $attr Block attributes.
* @param string $id Block id.
* @param string $type Asset Type.
* @param bool $is_gbs Is Global Block Style.
* @return array
*/
public static function get_frontend_assets( $slug, $attr, $id, $type = 'css', $is_gbs = false ) {
$attr = self::gbs_filter_placeholder_attributes( $attr ); // Filter out GBS Placeholders if any added.
$assets = array();
if ( 'js' === $type ) {
$assets = '';
}
$blocks_info = self::get_blocks_info();
if ( ! isset( $blocks_info[ 'uagb/' . $slug ] ) || ! isset( $blocks_info[ 'uagb/' . $slug ]['dynamic_assets'] ) ) {
return $assets;
}
$blocks = array(
$slug => $blocks_info[ 'uagb/' . $slug ]['dynamic_assets'],
);
if ( isset( $blocks[ $slug ] ) ) {
$main_dir = UAGB_DIR;
if ( isset( $blocks[ $slug ]['plugin-dir'] ) ) {
$main_dir = $blocks[ $slug ]['plugin-dir'];
}
$block_dir = $main_dir . 'includes/blocks/' . $blocks[ $slug ]['dir'];
$assets_file = realpath( $block_dir . '/frontend.' . $type . '.php' );
if ( is_string( $assets_file ) && file_exists( $assets_file ) ) {
// Set default attributes.
$attr_file = realpath( $block_dir . '/attributes.php' );
if ( is_string( $attr_file ) && file_exists( $attr_file ) ) {
$default_attr = include $attr_file;
$attr = self::get_fallback_values( $default_attr, $attr );
if ( ! empty( $attr['globalBlockStyleId'] ) && $is_gbs ) {
$gbs_class = UAGB_Helper::get_gbs_selector( $attr['globalBlockStyleId'] );
}
}
// Get Assets.
$assets = include $assets_file;
}
}
return $assets;
}
/**
* Get Widget List.
*
* @since 2.0.0
*
* @return array The Widget List.
*/
public static function get_blocks_info() {
return uagb_block()->get_blocks();
}
/**
* Get Block Assets.
*
* @since 1.13.4
*
* @return array The Asset List.
*/
public static function get_block_dependencies() {
$blocks = UAGB_Admin_Helper::get_block_options();
if ( null === self::$block_assets && defined( 'UAGB_URL' ) ) {
self::$block_assets = array(
// Lib.
'uagb-imagesloaded' => array(
'src' => UAGB_URL . 'assets/js/imagesloaded.min.js',
'dep' => array( 'jquery' ),
'type' => 'js',
),
'uagb-slick-js' => array(
'src' => UAGB_URL . 'assets/js/slick.min.js',
'dep' => array( 'jquery' ),
'type' => 'js',
),
'uagb-slick-css' => array(
'src' => UAGB_URL . 'assets/css/slick.min.css',
'dep' => array(),
'type' => 'css',
),
'uagb-masonry' => array(
'src' => UAGB_URL . 'assets/js/isotope.min.js',
'dep' => array( 'jquery' ),
'type' => 'js',
),
'uagb-cookie-lib' => array(
'src' => UAGB_URL . 'assets/js/js_cookie.min.js',
'dep' => array( 'jquery' ),
'skipEditor' => true,
'type' => 'js',
),
'uagb-bodymovin-js' => array(
'src' => UAGB_URL . 'assets/js/uagb-bodymovin.min.js',
'dep' => array(),
'skipEditor' => true,
'type' => 'js',
),
'uagb-countUp-js' => array(
'src' => UAGB_URL . 'assets/js/countUp.min.js',
'dep' => array(),
'type' => 'js',
),
'uagb-swiper-js' => array(
'src' => UAGB_URL . 'assets/js/swiper-bundle.min.js',
'dep' => array(),
'skipEditor' => true,
'type' => 'js',
),
'uagb-swiper-css' => array(
'src' => UAGB_URL . 'assets/css/swiper-bundle.min.css',
'dep' => array(),
'type' => 'css',
),
'uagb-aos-js' => array(
'src' => UAGB_URL . 'assets/js/aos.min.js',
'dep' => array(),
'type' => 'js',
),
'uagb-aos-css' => array(
'src' => UAGB_URL . 'assets/css/aos.min.css',
'dep' => array(),
'type' => 'css',
),
'uagb-block-positioning-js' => array(
'src' => UAGB_URL . 'assets/js/spectra-block-positioning.min.js',
'dep' => array(),
'type' => 'js',
),
'uagb-block-positioning-css' => array(
'src' => UAGB_URL . 'assets/css/spectra-block-positioning.min.css',
'dep' => array(),
'type' => 'css',
),
);
}
return apply_filters( 'uag_register_block_static_dependencies', self::$block_assets );
}
/**
* Returns attributes array with default value wherever required.
*
* @param array $default_attr default attribute value array from attributes.php.
* @param array $attr saved attributes data from database.
* @return array
* @since 2.3.2
*/
public static function get_fallback_values( $default_attr, $attr ) {
foreach ( $default_attr as $key => $value ) {
// sets default value if key is not available in database.
if ( ! isset( $attr[ $key ] ) ) {
$attr[ $key ] = $value;
}
}
return $attr;
}
}
}
/**
* Prepare if class 'UAGB_Block_Module' exist.
* Kicking this off by calling 'get_instance()' method
*/
UAGB_Block_Module::get_instance();

View File

@@ -0,0 +1,108 @@
<?php
/**
* UAGB Block.
*
* @since 2.1.0
*
* @package uagb
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'UAGB_Block' ) ) {
/**
* Class doc
*/
class UAGB_Block {
/**
* Member Variable
*
* @var instance
*/
private static $instance;
/**
* Block Attributes
*
* @var block_attributes
*/
private static $blocks = null;
/**
* Initiator
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Register a Block.
*
* @since 2.1.0
* @param string $block_file Block File Path.
*/
public function register( $block_file ) {
$block_slug = '';
$block_data = array();
include $block_file;
if ( ! empty( $block_slug ) && ! empty( $block_data ) ) {
self::$blocks[ $block_slug ] = apply_filters( "spectra_{$block_slug}_blockdata", $block_data );
}
}
/**
* Register all UAG Lite Blocks.
*
* @since 2.1.0
*/
public function register_blocks() {
self::$blocks = array();
$block_files = glob( UAGB_DIR . 'includes/blocks/*/block.php' );
foreach ( $block_files as $block_file ) {
$this->register( $block_file );
}
do_action( 'uag_register_block', $this );
}
/**
* Gives all Blocks.
*
* @since 2.1.0
*/
public function get_blocks() {
if ( null === self::$blocks ) {
$this->register_blocks();
}
return self::$blocks;
}
}
/**
* Gives UAGB_Block object
*
* @since 2.1.0
*
* @return object
*/
function uagb_block() {
return UAGB_Block::get_instance();
}
}

View File

@@ -0,0 +1,108 @@
<?php
/**
* UAGB Caching.
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
use SiteGround_Optimizer\Options\Options;
use SiteGround_Optimizer\File_Cacher\File_Cacher;
/**
* Class UAGB_Caching.
*
* @since 2.10.1
*/
class UAGB_Caching {
/**
* Member Variable
*
* @since 2.10.1
* @var UAGB_Caching|null
*/
private static $instance;
/**
* Initiator
*
* @since 2.10.1
* @return UAGB_Caching
*/
public static function get_instance() {
if ( ! isset( self::$instance ) || null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*
* @since 2.10.1
*/
public function __construct() {
add_action( 'uagb_delete_uag_asset_dir', array( $this, 'clear_cache' ) );
add_action( 'uagb_delete_page_assets', array( $this, 'clear_cache' ) );
}
/**
* Clears the cache.
*
* @since 2.10.1
* @return void
*/
public function clear_cache() {
self::clear_siteground_cache();
self::clear_cloudways_cache();
}
/**
* Clears the SiteGround cache.
*
* @since 2.10.1
* @return void
*/
public static function clear_siteground_cache() {
if ( ! class_exists( 'SiteGround_Optimizer\Options\Options' ) || ! class_exists( 'SiteGround_Optimizer\File_Cacher\File_Cacher' ) ) {
return;
}
if ( Options::is_enabled( 'siteground_optimizer_file_caching' ) ) {
File_Cacher::get_instance()->purge_everything();
}
}
/**
* This function helps to purge all cache in clodways envirnoment.
* In presence of Breeze plugin (https://wordpress.org/plugins/breeze/)
*
* @since 2.11.0
* @return void
*/
public static function clear_cloudways_cache() {
if ( ! class_exists( 'Breeze_Configuration' ) || ! class_exists( 'Breeze_CloudFlare_Helper' ) || ! class_exists( 'Breeze_Admin' ) ) {
return;
}
// clear varnish cache.
$admin = new Breeze_Admin();
$admin->breeze_clear_varnish();
// clear static cache.
Breeze_Configuration::breeze_clean_cache();
Breeze_CloudFlare_Helper::reset_all_cache();
}
}
/**
* Prepare if class 'UAGB_Caching' exist.
* Kicking this off by calling 'get_instance()' method
*/
UAGB_Caching::get_instance();

View File

@@ -0,0 +1,108 @@
<?php
/**
* UAGB Filesystem
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Class UAGB_Filesystem.
*/
class UAGB_Filesystem {
/**
* Member Variable
*
* @var instance
*/
private static $instance;
/**
* Initiator
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Get an instance of WP_Filesystem.
*
* @since 1.23.0
*/
public function get_filesystem() {
global $wp_filesystem;
if ( ! $wp_filesystem || 'direct' !== $wp_filesystem->method ) {
require_once ABSPATH . '/wp-admin/includes/file.php';
/**
* Context for filesystem, default false.
*
* @see request_filesystem_credentials_context
*/
$context = apply_filters( 'request_filesystem_credentials_context', false );
add_filter( 'filesystem_method', array( $this, 'filesystem_method' ) );
add_filter( 'request_filesystem_credentials', array( $this, 'request_filesystem_credentials' ) );
$creds = request_filesystem_credentials( site_url(), '', true, $context, null );
WP_Filesystem( $creds, $context );
remove_filter( 'filesystem_method', array( $this, 'filesystem_method' ) );
remove_filter( 'request_filesystem_credentials', array( $this, 'request_filesystem_credentials' ) );
}
// Set the permission constants if not already set.
if ( ! defined( 'FS_CHMOD_DIR' ) ) {
define( 'FS_CHMOD_DIR', 0755 );
}
if ( ! defined( 'FS_CHMOD_FILE' ) ) {
define( 'FS_CHMOD_FILE', 0644 );
}
return $wp_filesystem;
}
/**
* Method to direct.
*
* @since 1.23.0
*/
public function filesystem_method() {
return 'direct';
}
/**
* Sets credentials to true.
*
* @since 1.23.0
*/
public function request_filesystem_credentials() {
return true;
}
}
/**
* Prepare if class 'UAGB_Filesystem' exist.
* Kicking this off by calling 'get_instance()' method
*/
UAGB_Filesystem::get_instance();
/**
* Filesystem class
*
* @since 1.23.0
*/
function uagb_filesystem() {
return UAGB_Filesystem::get_instance()->get_filesystem();
}

View File

@@ -0,0 +1,246 @@
<?php
/**
* UAGB Front Assets.
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Class UAGB_Front_Assets.
*/
class UAGB_Front_Assets {
/**
* Member Variable
*
* @since 0.0.1
* @var instance
*/
private static $instance;
/**
* Post ID
*
* @since 1.23.0
* @var array
*/
protected $post_id;
/**
* Assets Post Object
*
* @since 1.23.0
* @var object
*/
protected $post_assets;
/**
* Initiator
*
* @since 0.0.1
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
public function __construct() {
add_action( 'wp', array( $this, 'set_initial_variables' ), 99 );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_asset_files' ) );
add_action( 'spectra_regenerate_post_assets', array( $this, 'update_current_post_assets' ) );
add_action( 'wp_insert_post', array( $this, 'trigger_regeneration_event' ), 10, 3 );
}
/**
* Set initial variables.
*
* @since 1.23.0
*/
public function set_initial_variables() {
$this->post_id = false;
if ( is_single() || is_page() || is_404() ) {
$this->post_id = get_the_ID();
}
if ( ! $this->post_id ) {
return;
}
$this->post_assets = uagb_get_post_assets( $this->post_id );
if ( ! $this->post_assets->is_allowed_assets_generation ) {
return;
}
if ( is_single() || is_page() || is_404() ) {
$this_post = get_post( $this->post_id );
/**
* Filters the post to build stylesheet for.
*
* @param \WP_Post $this_post The global post.
*/
$this_post = apply_filters_deprecated( 'uagb_post_for_stylesheet', array( $this_post ), '1.23.0' );
if ( $this_post && $this->post_id !== $this_post->ID ) {
$this->post_assets->prepare_assets( $this_post );
}
}
}
/**
* Enqueue asset files.
*
* @since 1.23.0
*/
public function enqueue_asset_files() {
// Check if assets should be excluded for the current post type.
if ( UAGB_Admin_Helper::should_exclude_assets_for_cpt() ) {
return; // Early return to prevent loading assets.
}
if ( $this->post_assets ) {
$this->post_assets->enqueue_scripts();
}
/* Archive & 404 page compatibility */
if ( is_archive() || is_home() || is_search() || is_404() ) {
global $wp_query;
$current_object_id = $wp_query->get_queried_object_id();
$cached_wp_query = $wp_query->posts;
if ( 0 !== $current_object_id && null !== $current_object_id ) {
$current_post_assets = new UAGB_Post_Assets( $current_object_id );
$current_post_assets->enqueue_scripts();
} elseif ( ! ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() ) && ! empty( $cached_wp_query ) && is_array( $cached_wp_query ) ) {
foreach ( $cached_wp_query as $post ) {
$current_post_assets = new UAGB_Post_Assets( $post->ID );
$current_post_assets->enqueue_scripts();
}
} else {
/*
If no posts are present in the category/archive
or 404 page (which is an obvious case for 404), then get the current page ID and enqueue script.
*/
$current_object_id = is_int( $current_object_id ) ? $current_object_id : (int) $current_object_id;
$current_post_assets = new UAGB_Post_Assets( $current_object_id );
$current_post_assets->enqueue_scripts();
}
}
/* WooCommerce compatibility */
if ( class_exists( 'WooCommerce' ) ) {
if ( is_cart() ) {
$id = get_option( 'woocommerce_cart_page_id' );
} elseif ( is_account_page() ) {
$id = get_option( 'woocommerce_myaccount_page_id' );
} elseif ( is_checkout() ) {
if ( is_order_received_page() ) {
$id = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
} else {
$id = get_option( 'woocommerce_checkout_page_id' );
}
} elseif ( is_checkout_pay_page() ) {
$id = get_option( 'woocommerce_pay_page_id' );
} elseif ( is_shop() ) {
$id = get_option( 'woocommerce_shop_page_id' );
} elseif ( is_order_received_page() ) {
$id = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
}
if ( ! empty( $id ) ) {
$current_post_assets = new UAGB_Post_Assets( intval( $id ) );
$current_post_assets->enqueue_scripts();
}
}
}
/**
* Trigger post assets update.
*
* @param int $post_id Post ID.
* @param WP_Post $post Post object.
* @param bool $update Whether this is an existing post being updated.
* @since 2.13.4
* @return mixed void if not an update, otherwise null.
*/
public function trigger_regeneration_event( $post_id, $post, $update ) {
if ( ! $update ) {
return;
}
if ( ! wp_next_scheduled( 'spectra_regenerate_post_assets' ) && ! wp_installing() ) {
$post_assets_regeneration_buffer_time = apply_filters( 'spectra_post_assets_regeneration_buffer_time', 30 );
wp_schedule_single_event( time() + $post_assets_regeneration_buffer_time, 'spectra_regenerate_post_assets', array( $post_id ) ); // Schedule for 30 seconds later.
}
}
/**
* Update post assets.
*
* By passing everything and update assets once post is updated.
*
* @param int $post_id Post ID.
* @since 2.13.4
* @return void
*/
public function update_current_post_assets( $post_id ) {
/**
* Case: If previous asset version is same then we need to update the assets, resultant will reduce cache conflicts.
*/
$page_assets = (array) get_post_meta( $post_id, '_uag_page_assets', true );
if ( isset( $page_assets['uag_version'] ) && UAGB_ASSET_VER === $page_assets['uag_version'] ) {
$page_assets['uag_version'] = '';
update_post_meta( $post_id, '_uag_page_assets', $page_assets );
}
}
/**
* Get post_assets obj.
*
* @since 1.23.0
*/
public function get_post_assets_obj() {
return $this->post_assets;
}
}
/**
* Prepare if class 'UAGB_Front_Assets' exist.
* Kicking this off by calling 'get_instance()' method
*/
UAGB_Front_Assets::get_instance();
/**
* Get frontend post_assets obj.
*
* @since 1.23.0
*/
function uagb_get_front_post_assets() {
return UAGB_Front_Assets::get_instance()->get_post_assets_obj();
}

View File

@@ -0,0 +1,657 @@
<?php
/**
* UAGB FSE Fonts Compatibility.
*
* @since 2.5.1
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'UAGB_FSE_Fonts_Compatibility' ) ) {
/**
* Class UAGB_FSE_Fonts_Compatibility.
*
* @since 2.5.1
*/
final class UAGB_FSE_Fonts_Compatibility {
/**
* Member Variable
*
* @since 2.5.1
* @var instance
*/
private static $instance;
/**
* Base path.
*
* @access protected
* @since 2.5.1
* @var string
*/
protected $base_path;
/**
* Base URL.
*
* @access protected
* @since 2.5.1
* @var string
*/
protected $base_url;
/**
* The remote CSS.
*
* @access protected
* @since 2.5.1
* @var string
*/
protected $remote_styles;
/**
* The font-format.
*
* Use "woff" or "woff2".
* This will change the user-agent user to make the request.
*
* @access protected
* @since 2.5.1
* @var string
*/
protected $font_format = 'woff2';
/**
* Initiator
*
* @return object instance.
* @since 2.5.1
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*
* @return void
* @since 2.5.1
*/
public function __construct() {
$this->base_path = UAGB_UPLOAD_DIR . 'assets/';
$this->base_url = UAGB_UPLOAD_URL . 'assets/';
if ( empty( $_GET['page'] ) || 'spectra' !== $_GET['page'] || empty( $_GET['path'] ) || 'settings' !== $_GET['path'] || empty( $_GET['settings'] ) || 'fse-support' !== $_GET['settings'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- $_GET['settings'] does not provide nonce.
return;
}
$uagb_filesystem = uagb_filesystem();
$fonts_folder_path = get_stylesheet_directory() . '/assets/fonts/spectra';
if ( file_exists( $fonts_folder_path ) ) {
$uagb_filesystem->delete( $fonts_folder_path, true, 'd' );
}
self::delete_all_theme_font_family();
$load_fse_font_globally = UAGB_Admin_Helper::get_admin_settings_option( 'uag_load_fse_font_globally', 'disabled' );
if ( 'disabled' !== $load_fse_font_globally ) {
add_action( 'admin_init', array( $this, 'save_google_fonts_to_theme' ) );
}
}
/**
* Get, add and update font family in Spectra for ST.
*
* @param array $families font family.
* @since 2.7.0
* @return void
*/
public function get_font_family_for_starter_template( $families ) {
if ( UAGB_Admin_Helper::get_admin_settings_option( 'uag_load_fse_font_globally', 'disabled' ) ) { // if Load FSE Fonts Globaly is disabled then enabled it.
UAGB_Admin_Helper::update_admin_settings_option( 'uag_load_fse_font_globally', 'enabled' );
}
$new_font_families = array();
$new_font_faces = array();
if ( empty( $families ) || ! is_array( $families ) ) {
return;
}
foreach ( $families as $family ) {
$font_name = ! empty( $family ) ? $family : '';
$font_name_string = explode( ',', $font_name );
$font_family = trim( $font_name_string[0], "'" );
$font_slug = $this->get_font_slug( $font_family );
$font_weight = 'Default';
$font_style = 'normal';
$final_font_files = $this->get_fonts_file_url( $font_family, $font_weight, $font_style );
// Loop through each font file and create a font face for it.
foreach ( $final_font_files as $src ) {
$new_font_faces[] = array(
'fontFamily' => $font_family,
'fontStyle' => $font_style,
'fontWeight' => $font_weight,
'src' => array( $src ),
);
}
$this->add_or_update_theme_font_faces( $font_family, $font_slug, $new_font_faces );
}
$theme_json_raw = json_decode( file_get_contents( get_stylesheet_directory() . '/theme.json' ), true );
$all_font_families = $theme_json_raw['settings']['typography']['fontFamilies'];
if ( empty( $all_font_families ) || ! is_array( $all_font_families ) ) {
return;
}
foreach ( $all_font_families as $font_families_item ) {
$new_font_families_item = array(
'value' => $font_families_item['fontFamily'],
'label' => $font_families_item['fontFamily'],
'weights' => array(
array(
'value' => 'Default',
'label' => __( 'Default', 'ultimate-addons-for-gutenberg' ),
),
array(
'value' => '400',
'label' => __( '400', 'ultimate-addons-for-gutenberg' ),
),
),
'styles' => array(
array(
'value' => 'normal',
'label' => __( 'normal', 'ultimate-addons-for-gutenberg' ),
),
),
'weight' => array(
array(
'value' => '400',
'label' => __( '400', 'ultimate-addons-for-gutenberg' ),
),
),
'style' => array(
array(
'value' => 'normal',
'label' => __( 'normal', 'ultimate-addons-for-gutenberg' ),
),
),
);
$new_font_families[] = $new_font_families_item;
}
UAGB_Admin_Helper::update_admin_settings_option( 'spectra_global_fse_fonts', $new_font_families );
}
/**
* Save Google Fonts to the FSE Theme.
*
* @return void
* @since 2.5.1
*/
public function save_google_fonts_to_theme() {
$spectra_global_fse_fonts = \UAGB_Admin_Helper::get_admin_settings_option( 'spectra_global_fse_fonts', array() );
if ( empty( $spectra_global_fse_fonts ) || ! is_array( $spectra_global_fse_fonts ) ) {
return;
}
foreach ( $spectra_global_fse_fonts as $font ) {
$font_family = ! empty( $font['value'] ) ? $font['value'] : '';
$font_slug = $this->get_font_slug( $font_family );
$new_font_faces = array();
foreach ( $font['weight'] as $weight ) {
$font_weight = ! empty( $weight['value'] ) ? $weight['value'] : '';
foreach ( $font['style'] as $style ) {
$font_style = ! empty( $style['value'] ) ? $style['value'] : '';
$final_font_files = $this->get_fonts_file_url( $font_family, $font_weight, $font_style );
// Loop through each font file and create a font face for it.
foreach ( $final_font_files as $src ) {
$new_font_faces[] = array(
'fontFamily' => $font_family,
'fontStyle' => $font_style,
'fontWeight' => $font_weight,
'src' => array( $src ),
);
}
}
}
$this->add_or_update_theme_font_faces( $font_family, $font_slug, $new_font_faces );
}
}
/**
* Get Font Slug.
*
* @return string slug.
* @param string $name Font Family.
* @since 2.5.1
*/
public function get_font_slug( $name ) {
$slug = sanitize_title( $name );
$slug = preg_replace( '/\s+/', '', $slug ); // Remove spaces.
return $slug;
}
/**
* Get Font URl.
*
* @param string $font_family Font Family.
* @param string $font_weight Font Weight.
* @param string $font_style Font Style.
* @return array final font files.
* @since 2.5.1
*/
public function get_fonts_file_url( $font_family, $font_weight, $font_style ) {
$font_family_key = sanitize_key( strtolower( str_replace( ' ', '-', $font_family ) ) );
$fonts_attr = str_replace( ' ', '+', $font_family );
$fonts_file_name = $font_family_key;
if ( ! empty( $font_weight ) ) {
$fonts_attr .= ':' . $font_weight;
$fonts_file_name .= '-' . $font_weight;
if ( ! empty( $font_style ) ) {
$fonts_attr .= ',' . $font_weight . $font_style;
$fonts_file_name .= '-' . $font_style;
}
}
$fonts_link = 'https://fonts.googleapis.com/css?family=' . esc_attr( $fonts_attr );
// Get the remote URL contents.
$this->remote_styles = $this->get_remote_url_contents( $fonts_link );
$font_files = $this->get_remote_files_from_css();
$fonts_folder_path = get_stylesheet_directory() . '/assets/fonts/spectra/';
// If the fonts folder don't exist, create it.
if ( ! file_exists( $fonts_folder_path ) ) {
wp_mkdir_p( $fonts_folder_path );
if ( ! file_exists( $fonts_folder_path ) ) {
$this->get_filesystem()->mkdir( $fonts_folder_path, FS_CHMOD_DIR );
}
}
$final_font_files = array();
if ( ! is_array( $font_files ) && empty( $font_files ) && empty( $font_family_key ) ) {
return;
}
foreach ( $font_files[ $font_family_key ] as $key => $font_file ) {
// require file.php if the download_url function doesn't exist.
if ( ! function_exists( 'download_url' ) ) {
require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' );
}
// Download file to temporary location.
$tmp_path = download_url( $font_file );
// Make sure there were no errors.
if ( is_wp_error( $tmp_path ) ) {
return array();
}
$fonts_file_name_final = $fonts_file_name . $key . '.' . $this->font_format;
// Move font asset to theme assets folder.
rename( $tmp_path, get_stylesheet_directory() . '/assets/fonts/spectra/' . $fonts_file_name_final ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_rename
$final_font_files[] = 'file:./assets/fonts/spectra/' . $fonts_file_name_final;
}
return $final_font_files;
}
/**
* Get the filesystem.
*
* @access protected
* @since 2.5.1
* @return WP_Filesystem
*/
protected function get_filesystem() {
global $wp_filesystem;
// If the filesystem has not been instantiated yet, do it here.
if ( ! $wp_filesystem ) {
if ( ! function_exists( 'WP_Filesystem' ) ) {
require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' );
}
WP_Filesystem();
}
return $wp_filesystem;
}
/**
* Get remote file contents.
*
* @access public
* @param string $url URL.
* @since 2.5.1
* @return string Returns the remote URL contents.
*/
public function get_remote_url_contents( $url ) {
/**
* The user-agent we want to use.
*
* The default user-agent is the only one compatible with woff (not woff2)
* which also supports unicode ranges.
*/
$user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8';
// Switch to a user-agent supporting woff2 if we don't need to support IE.
if ( 'woff2' === $this->font_format ) {
$user_agent = 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0';
}
// Get the response.
$response = wp_remote_get( $url, array( 'user-agent' => $user_agent ) );
// Early exit if there was an error.
if ( is_wp_error( $response ) ) {
return '';
}
// Get the CSS from our response.
$contents = wp_remote_retrieve_body( $response );
// Early exit if there was an error.
if ( is_wp_error( $contents ) ) {
return '';
}
return $contents;
}
/**
* Get font files from the CSS.
*
* @access public
* @since 2.5.1
* @return array Returns an array of font-families and the font-files used.
*/
public function get_remote_files_from_css() {
// Return early if remote styles is not a string, or is empty.
if ( ! is_string( $this->remote_styles ) || empty( $this->remote_styles ) ) {
return array();
}
$font_faces = explode( '@font-face', $this->remote_styles );
// Return early if font faces is not an array, or is empty.
if ( ! is_array( $font_faces ) || empty( $font_faces ) ) {
return array();
}
$result = array();
// Loop all our font-face declarations.
foreach ( $font_faces as $font_face ) {
// Continue the loop if the current font face is not a string, or is empty.
if ( ! is_string( $font_face ) || empty( $font_face ) ) {
continue;
}
// Get the styles based on the font face.
$style_array = explode( '}', $font_face );
// Continue the loop if the current font face is not a string, or is empty.
if ( ! is_string( $style_array[0] ) || empty( $style_array[0] ) ) {
continue;
}
// Make sure we only process styles inside this declaration.
$style = $style_array[0];
// Sanity check.
if ( false === strpos( $style, 'font-family' ) ) {
continue;
}
// Get an array of our font-families.
preg_match_all( '/font-family.*?\;/', $style, $matched_font_families );
// Get an array of our font-files.
preg_match_all( '/url\(.*?\)/i', $style, $matched_font_files );
// Get the font-family name.
$font_family = 'unknown';
if ( isset( $matched_font_families[0] ) && isset( $matched_font_families[0][0] ) ) {
$font_family = rtrim( ltrim( $matched_font_families[0][0], 'font-family:' ), ';' );
$font_family = trim( str_replace( array( "'", ';' ), '', $font_family ) );
$font_family = sanitize_key( strtolower( str_replace( ' ', '-', $font_family ) ) );
}
// Make sure the font-family is set in our array.
if ( ! isset( $result[ $font_family ] ) ) {
$result[ $font_family ] = array();
}
// Get files for this font-family and add them to the array.
foreach ( $matched_font_files as $match ) {
// Sanity check.
if ( ! isset( $match[0] ) ) {
continue;
}
// Add the file URL.
$result[ $font_family ][] = rtrim( ltrim( $match[0], 'url(' ), ')' );
}
// Make sure we have unique items.
// We're using array_flip here instead of array_unique for improved performance.
$result[ $font_family ] = array_flip( array_flip( $result[ $font_family ] ) );
}
return $result;
}
/**
* Get font files from the CSS.
*
* @access public
* @param string $font_name Font Name.
* @param string $font_slug Font Slug.
* @param array $font_faces Font Faces.
* @return void
* @since 2.5.1
*/
public function add_or_update_theme_font_faces( $font_name, $font_slug, $font_faces ) {
// Get the current theme.json and fontFamilies defined (if any).
$theme_json_raw = json_decode( file_get_contents( get_stylesheet_directory() . '/theme.json' ), true );
$theme_font_families = isset( $theme_json_raw['settings']['typography']['fontFamilies'] ) ? $theme_json_raw['settings']['typography']['fontFamilies'] : null;
$existent_family = $theme_font_families ? array_values(
array_filter(
$theme_font_families,
function ( $font_family ) use ( $font_slug ) {
return $font_family['slug'] === $font_slug; }
)
) : null;
// Add the new font faces.
if ( empty( $existent_family ) ) { // If the new font family doesn't exist in the theme.json font families, add it to the exising font families.
$theme_font_families[] = array(
'fontFamily' => $font_name,
'slug' => $font_slug,
'fontFace' => $font_faces,
'isSpectra' => true,
);
} else { // If the new font family already exists in the theme.json font families, add the new font faces to the existing font family.
$theme_font_families = array_values(
array_filter(
$theme_font_families,
function ( $font_family ) use ( $font_slug ) {
return $font_family['slug'] !== $font_slug; }
)
);
$existent_family[0]['fontFace'] = $font_faces;
$theme_font_families = array_merge( $theme_font_families, $existent_family );
}
// Overwrite the previous fontFamilies with the new ones.
$theme_json_raw['settings']['typography']['fontFamilies'] = $theme_font_families;
$theme_json = wp_json_encode( $theme_json_raw, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
$theme_json_string = preg_replace( '~(?:^|\G)\h{4}~m', "\t", $theme_json );
// Write the new theme.json to the theme folder.
file_put_contents( // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions
get_stylesheet_directory() . '/theme.json',
$theme_json_string
);
}
/**
* Save setting - Sanitizes form inputs.
*
* @param array $input_settings setting data.
* @return array The sanitized form inputs.
*
* @since 2.5.1
*/
public static function sanitize_form_inputs( $input_settings = array() ) {
$new_settings = array();
if ( ! empty( $input_settings ) ) {
foreach ( $input_settings as $key => $value ) {
$new_key = sanitize_text_field( $key );
if ( is_array( $value ) ) {
$new_settings[ $new_key ] = self::sanitize_form_inputs( $value );
} else {
$new_settings[ $new_key ] = sanitize_text_field( $value );
}
}
}
return $new_settings;
}
/**
* Delete all Spectra font files from the theme JSON.
*
* @return void
* @since 2.5.1
*/
public static function delete_all_theme_font_family() {
// Construct updated theme.json.
$theme_json_raw = json_decode( file_get_contents( get_stylesheet_directory() . '/theme.json' ), true );
if ( empty( $theme_json_raw['settings']['typography']['fontFamilies'] ) ) { // Added condition to resolve an issue of PHP Notice: Undefined index: fontFamilies.
return;
}
// Overwrite the previous fontFamilies with the new ones.
$font_families = $theme_json_raw['settings']['typography']['fontFamilies'];
if ( ! empty( $font_families ) && is_array( $font_families ) ) {
$font_families = array_values(
array_filter(
$font_families,
function( $value ) {
if ( ! empty( $value['isSpectra'] ) ) {
return false;
}
return true;
}
)
);
}
$theme_json_raw['settings']['typography']['fontFamilies'] = $font_families;
$theme_json = wp_json_encode( $theme_json_raw, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
$theme_json_string = preg_replace( '~(?:^|\G)\h{4}~m', "\t", $theme_json );
// Write the new theme.json to the theme folder.
file_put_contents( // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions
get_stylesheet_directory() . '/theme.json',
$theme_json_string
);
}
/**
* Delete font files from the CSS.
*
* @return void
* @param array $font Font Data.
* @since 2.5.1
*/
public static function delete_theme_font_family( $font ) {
// Construct updated theme.json.
$theme_json_raw = json_decode( file_get_contents( get_stylesheet_directory() . '/theme.json' ), true );
// Overwrite the previous fontFamilies with the new ones.
$font_families = $theme_json_raw['settings']['typography']['fontFamilies'];
if ( ! empty( $font_families ) && is_array( $font_families ) ) {
foreach ( $font_families as $key => $value ) {
if ( $font['fontFamily'] === $value['fontFamily'] && ! empty( $value['fontFace'] ) && is_array( $value['fontFace'] ) ) {
unset( $font_families[ $key ] );
break;
}
}
}
$theme_json_raw['settings']['typography']['fontFamilies'] = $font_families;
$theme_json = wp_json_encode( $theme_json_raw, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
$theme_json_string = preg_replace( '~(?:^|\G)\h{4}~m', "\t", $theme_json );
// Write the new theme.json to the theme folder.
file_put_contents( // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions
get_stylesheet_directory() . '/theme.json',
$theme_json_string
);
$spectra_global_fse_fonts = \UAGB_Admin_Helper::get_admin_settings_option( 'spectra_global_fse_fonts', array() );
if ( ! is_array( $spectra_global_fse_fonts ) ) {
$response_data = array(
'messsage' => __( 'There was some error in deleting the font.', 'ultimate-addons-for-gutenberg' ),
);
wp_send_json_error( $response_data );
}
$spectra_global_fse_fonts = array_values(
array_filter(
$spectra_global_fse_fonts,
function( $value ) use ( $font ) {
if ( $font['fontFamily'] === $value['value'] ) {
return false;
}
return true;
}
)
);
foreach ( $spectra_global_fse_fonts as $key => $value ) {
if ( $font['fontFamily'] === $value['value'] ) {
array_splice( $spectra_global_fse_fonts, $key, $key );
}
}
$spectra_global_fse_fonts = self::sanitize_form_inputs( $spectra_global_fse_fonts );
UAGB_Admin_Helper::update_admin_settings_option( 'spectra_global_fse_fonts', $spectra_global_fse_fonts );
$response_data = array(
'messsage' => __( 'Successfully deleted font.', 'ultimate-addons-for-gutenberg' ),
);
wp_send_json_success( $response_data );
}
}
}
UAGB_FSE_Fonts_Compatibility::get_instance();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,102 @@
<?php
/**
* UAGB Filesystem
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Class UAGB_Install.
*/
class UAGB_Install {
/**
* Member Variable
*
* @var instance
*/
private static $instance;
/**
* Initiator
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Create files/directories.
*/
public function create_files() {
if ( ! defined( 'UAGB_UPLOAD_DIR_NAME' ) ) {
define( 'UAGB_UPLOAD_DIR_NAME', 'uag-plugin' );
}
if ( ! defined( 'UAGB_UPLOAD_DIR' ) ) {
$upload_dir = wp_upload_dir( null, false );
define( 'UAGB_UPLOAD_DIR', $upload_dir['basedir'] . '/' . UAGB_UPLOAD_DIR_NAME . '/' );
}
$files = array(
array(
'base' => UAGB_UPLOAD_DIR,
'file' => 'index.html',
'content' => '',
),
array(
'base' => UAGB_UPLOAD_DIR . 'assets',
'file' => 'index.html',
'content' => '',
),
array(
'base' => UAGB_UPLOAD_DIR . 'assets/fonts',
),
);
foreach ( $files as $file ) {
if ( wp_mkdir_p( $file['base'] ) && ! empty( $file['file'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
$file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ); // phpcs:ignore
if ( $file_handle ) {
fwrite( $file_handle, $file['content'] ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_fwrite
fclose( $file_handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose
}
}
}
}
}
/**
* Prepare if class 'UAGB_Install' exist.
* Kicking this off by calling 'get_instance()' method
*/
UAGB_Install::get_instance();
/**
* Filesystem class
*
* @since 1.23.0
*/
/**
* Install class
*
* @since 2.0.0
*
* @return object
*/
function uagb_install() {
return UAGB_Install::get_instance();
}

View File

@@ -0,0 +1,836 @@
<?php
/**
* UAGB Loader.
*
* @package UAGB
*/
use UAGB\Admin_Helper;
use \ZipAI\Classes\Module as Zip_Ai_Module;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'UAGB_Loader' ) ) {
/**
* Class UAGB_Loader.
*/
final class UAGB_Loader {
/**
* Member Variable
*
* @var instance
*/
private static $instance;
/**
* Post assets object cache
*
* @var array
*/
public $post_assets_objs = array();
/**
* Block analytics instance
*
* @var UAGB_Block_Analytics
*/
public $block_analytics;
/**
* Initiator
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
/**
* Spectra loaded.
*
* Fires when Spectra was fully loaded and instantiated.
*
* @since 2.1.0
*/
do_action( 'spectra_core_loaded' );
}
return self::$instance;
}
/**
* Constructor
*/
public function __construct() {
// Activation hook.
register_activation_hook( UAGB_FILE, array( $this, 'activation_reset' ) );
// deActivation hook.
register_deactivation_hook( UAGB_FILE, array( $this, 'deactivation_reset' ) );
$this->define_constants();
$this->loader();
add_action( 'after_setup_theme', array( $this, 'load_compatibility' ) );
add_action( 'plugins_loaded', array( $this, 'load_plugin' ) );
add_action( 'init', array( $this, 'init_actions' ) );
/*
* BSF Analytics.
*/
if ( ! class_exists( 'BSF_Analytics_Loader' ) ) {
require_once UAGB_DIR . 'lib/bsf-analytics/class-bsf-analytics-loader.php';
}
if ( class_exists( 'BSF_Analytics_Loader' ) && is_callable( 'BSF_Analytics_Loader::get_instance' ) ) {
$spectra_bsf_analytics = BSF_Analytics_Loader::get_instance();
$spectra_bsf_analytics->set_entity(
array(
'spectra' => array(
'product_name' => 'Spectra',
'path' => UAGB_DIR . 'lib/bsf-analytics',
'author' => 'Spectra by Brainstorm Force',
'time_to_display' => '+24 hours',
'deactivation_survey' => apply_filters(
'spectra_deactivation_survey_data',
array(
array(
'id' => 'deactivation-survey-ultimate-addons-for-gutenberg',
'popup_logo' => esc_url( plugin_dir_url( __DIR__ ) . 'assets/images/logos/spectra.svg' ),
'plugin_slug' => 'ultimate-addons-for-gutenberg',
'popup_title' => 'Quick Feedback',
'support_url' => 'https://wpspectra.com/contact/',
'popup_description' => 'If you have a moment, please share why you are deactivating Spectra:',
'show_on_screens' => array( 'plugins' ),
'plugin_version' => UAGB_VER,
),
)
),
'hide_optin_checkbox' => true,
),
)
);
}
add_filter( 'bsf_core_stats', array( $this, 'spectra_get_specific_stats' ) );
// Initialize block analytics after BSF analytics is set up.
$this->block_analytics = UAGB_Block_Analytics::get_instance();
}
/**
* Defines all constants
*
* @since 1.0.0
*/
public function define_constants() {
define( 'UAGB_BASE', plugin_basename( UAGB_FILE ) );
define( 'UAGB_DIR', plugin_dir_path( UAGB_FILE ) );
define( 'UAGB_URL', plugins_url( '/', UAGB_FILE ) );
define( 'UAGB_VER', '2.19.20' );
define( 'UAGB_MODULES_DIR', UAGB_DIR . 'modules/' );
define( 'UAGB_MODULES_URL', UAGB_URL . 'modules/' );
define( 'UAGB_SLUG', 'spectra' );
define( 'UAGB_URI', trailingslashit( 'https://wpspectra.com/' ) );
if ( ! defined( 'UAGB_TABLET_BREAKPOINT' ) ) {
define( 'UAGB_TABLET_BREAKPOINT', '976' );
}
if ( ! defined( 'UAGB_MOBILE_BREAKPOINT' ) ) {
define( 'UAGB_MOBILE_BREAKPOINT', '767' );
}
if ( ! defined( 'UAGB_UPLOAD_DIR_NAME' ) ) {
define( 'UAGB_UPLOAD_DIR_NAME', 'uag-plugin' );
}
$upload_dir = wp_upload_dir( null, false );
if ( ! defined( 'UAGB_UPLOAD_DIR' ) ) {
define( 'UAGB_UPLOAD_DIR', $upload_dir['basedir'] . '/' . UAGB_UPLOAD_DIR_NAME . '/' );
}
if ( ! defined( 'UAGB_UPLOAD_URL' ) ) {
define( 'UAGB_UPLOAD_URL', $upload_dir['baseurl'] . '/' . UAGB_UPLOAD_DIR_NAME . '/' );
}
define( 'UAGB_ASSET_VER', get_option( '__uagb_asset_version', UAGB_VER ) );
define( 'UAGB_CSS_EXT', defined( 'WP_DEBUG' ) && WP_DEBUG ? '.css' : '.min.css' );
define( 'UAGB_JS_EXT', defined( 'WP_DEBUG' ) && WP_DEBUG ? '.js' : '.min.js' );
}
/**
* Loads Other files.
*
* @since 1.0.0
*
* @return void
*/
public function loader() {
require_once UAGB_DIR . 'classes/utils.php';
require_once UAGB_DIR . 'classes/class-spectra-block-prioritization.php';
require_once UAGB_DIR . 'classes/class-uagb-install.php';
require_once UAGB_DIR . 'classes/class-uagb-filesystem.php';
require_once UAGB_DIR . 'classes/class-uagb-update.php';
require_once UAGB_DIR . 'classes/class-uagb-block.php';
require_once UAGB_DIR . 'classes/migration/class-spectra-migrate-blocks.php';
require_once UAGB_DIR . 'classes/migration/class-uagb-background-process.php';
require_once UAGB_DIR . 'classes/analytics/class-uagb-block-analytics.php';
/**
* Register Commands.
*/
if ( defined( 'WP_CLI' ) && WP_CLI ) {
require_once UAGB_DIR . 'classes/commands/class-spectra-regenerate-assets-command.php';
}
if ( is_admin() ) {
require_once UAGB_DIR . 'classes/class-uagb-beta-updates.php';
require_once UAGB_DIR . 'classes/class-uagb-rollback.php';
}
}
/**
* Loads plugin files.
*
* @since 1.0.0
*
* @return void
*/
public function load_plugin() {
require_once UAGB_DIR . 'classes/class-uagb-scripts-utils.php';
require_once UAGB_DIR . 'classes/class-uagb-block-module.php';
require_once UAGB_DIR . 'classes/class-uagb-admin-helper.php';
require_once UAGB_DIR . 'classes/class-uagb-helper.php';
require_once UAGB_DIR . 'blocks-config/blocks-config.php';
require_once UAGB_DIR . 'lib/astra-notices/class-astra-notices.php';
require_once UAGB_DIR . 'lib/class-uagb-zipwp-images.php';
require_once UAGB_DIR . 'lib/class-uagb-nps-survey.php';
/**
* UTM Analytics lib file.
*/
require_once UAGB_DIR . 'lib/class-uagb-utm-analytics.php';
if ( is_admin() ) {
require_once UAGB_DIR . 'classes/class-uagb-admin.php';
}
require_once UAGB_DIR . 'classes/class-uagb-post-assets.php';
require_once UAGB_DIR . 'classes/class-uagb-front-assets.php';
require_once UAGB_DIR . 'classes/class-uagb-init-blocks.php';
require_once UAGB_DIR . 'classes/class-uagb-rest-api.php';
require_once UAGB_DIR . 'classes/class-uagb-visibility.php';
require_once UAGB_DIR . 'classes/class-uagb-caching.php';
require_once UAGB_DIR . 'classes/class-uagb-nps-notice.php';
if ( 'twentyseventeen' === get_template() ) {
require_once UAGB_DIR . 'classes/class-uagb-twenty-seventeen-compatibility.php';
}
if ( 'twentysixteen' === get_template() ) {
require_once UAGB_DIR . 'compatibility/class-uagb-twenty-sixteen-compatibility.php';
}
require_once UAGB_DIR . 'admin-core/admin-loader.php';
add_filter( 'rest_pre_dispatch', array( $this, 'rest_pre_dispatch' ), 10, 3 );
$enable_templates_button = UAGB_Admin_Helper::get_admin_settings_option( 'uag_enable_templates_button', 'yes' );
// Sync the Zip AI Library textdomain with the Spectra textdomain.
add_filter( 'zip_ai_library_textdomain', array( $this, 'sync_library_textdomain' ) );
if ( 'yes' === $enable_templates_button ) {
require_once UAGB_DIR . 'lib/class-uagb-ast-block-templates.php';
} else {
add_filter( 'ast_block_templates_disable', '__return_true' );
}
// Add the filters for the Zip AI Library and include it.
add_filter( 'zip_ai_collab_product_details', array( $this, 'add_zip_ai_collab_product_details' ), 20, 1 );
add_filter( 'zip_ai_modules', array( $this, 'add_zip_ai_modules' ), 20, 1 );
add_filter( 'zip_ai_auth_redirection_flag', '__return_true', 20, 1 );
add_filter( 'zip_ai_auth_redirection_url', array( $this, 'add_zip_ai_redirection_url' ), 20, 1 );
add_filter( 'zip_ai_revoke_redirection_url', array( $this, 'add_zip_ai_redirection_url' ), 20, 1 );
require_once UAGB_DIR . 'lib/class-uagb-zip-ai.php';
}
/**
* Sync the Zip AI Library textdomain with the Spectra textdomain.
*
* @param string $textdomain The textdomain for the Zip AI Library.
* @since 2.13.9
* @return string The Spectra textdomain.
*/
public function sync_library_textdomain( $textdomain ) {
return 'ultimate-addons-for-gutenberg';
}
/**
* Loads theme compatibility files.
*
* @since 2.5.1
*
* @return void
*/
public function load_compatibility() {
require_once UAGB_DIR . 'classes/class-uagb-fse-fonts-compatibility.php';
}
/**
* Fix REST API issue with blocks registered via PHP register_block_type.
*
* @since 1.25.2
*
* @param mixed $result Response to replace the requested version with.
* @param object $server Server instance.
* @param object $request Request used to generate the response.
*
* @return array Returns updated results.
*/
public function rest_pre_dispatch( $result, $server, $request ) {
if ( strpos( $request->get_route(), '/wp/v2/block-renderer' ) !== false && isset( $request['attributes'] ) ) {
$attributes = $request['attributes'];
if ( isset( $attributes['UAGUserRole'] ) ) {
unset( $attributes['UAGUserRole'] );
}
if ( isset( $attributes['UAGBrowser'] ) ) {
unset( $attributes['UAGBrowser'] );
}
if ( isset( $attributes['UAGSystem'] ) ) {
unset( $attributes['UAGSystem'] );
}
if ( isset( $attributes['UAGDisplayConditions'] ) ) {
unset( $attributes['UAGDisplayConditions'] );
}
if ( isset( $attributes['UAGHideDesktop'] ) ) {
unset( $attributes['UAGHideDesktop'] );
}
if ( isset( $attributes['UAGHideMob'] ) ) {
unset( $attributes['UAGHideMob'] );
}
if ( isset( $attributes['UAGHideTab'] ) ) {
unset( $attributes['UAGHideTab'] );
}
if ( isset( $attributes['UAGLoggedIn'] ) ) {
unset( $attributes['UAGLoggedIn'] );
}
if ( isset( $attributes['UAGLoggedOut'] ) ) {
unset( $attributes['UAGLoggedOut'] );
}
if ( isset( $attributes['UAGDay'] ) ) {
unset( $attributes['UAGDay'] );
}
if ( isset( $attributes['zIndex'] ) ) {
unset( $attributes['zIndex'] );
}
if ( isset( $attributes['UAGResponsiveConditions'] ) ) {
unset( $attributes['UAGResponsiveConditions'] );
}
if ( isset( $attributes['UAGAnimationType'] ) ) {
unset( $attributes['UAGAnimationType'] );
}
if ( isset( $attributes['UAGAnimationTime'] ) ) {
unset( $attributes['UAGAnimationTime'] );
}
if ( isset( $attributes['UAGAnimationDelay'] ) ) {
unset( $attributes['UAGAnimationDelay'] );
}
if ( isset( $attributes['UAGAnimationEasing'] ) ) {
unset( $attributes['UAGAnimationEasing'] );
}
if ( isset( $attributes['UAGAnimationRepeat'] ) ) {
unset( $attributes['UAGAnimationRepeat'] );
}
if ( isset( $attributes['UAGAnimationDelayInterval'] ) ) {
unset( $attributes['UAGAnimationDelayInterval'] );
}
if ( isset( $attributes['UAGAnimationDoNotApplyToContainer'] ) ) {
unset( $attributes['UAGAnimationDoNotApplyToContainer'] );
}
if ( isset( $attributes['UAGStickyLocation'] ) ) {
unset( $attributes['UAGStickyLocation'] );
}
if ( isset( $attributes['UAGStickyRestricted'] ) ) {
unset( $attributes['UAGStickyRestricted'] );
}
if ( isset( $attributes['UAGStickyOffset'] ) ) {
unset( $attributes['UAGStickyOffset'] );
}
if ( isset( $attributes['UAGPosition'] ) ) {
unset( $attributes['UAGPosition'] );
}
$request['attributes'] = $attributes;
}
return $result;
}
/**
* Check if Gutenberg is active
*
* @since 1.1.0
*
* @return boolean
*/
public function is_gutenberg_active() {
return function_exists( 'register_block_type' );
}
/**
* Load Ultimate Gutenberg Text Domain.
* This will load the translation textdomain depending on the file priorities.
* 1. Global Languages /wp-content/languages/ultimate-addons-for-gutenberg/ folder
* 2. Local directory /wp-content/plugins/ultimate-addons-for-gutenberg/languages/ folder
*
* @since 1.0.0
* @return void
*/
public function load_textdomain() {
/**
* Filters the languages directory path to use for AffiliateWP.
*
* @param string $lang_dir The languages directory path.
*/
$lang_dir = apply_filters( 'uagb_languages_directory', UAGB_ROOT . '/languages/' );
load_plugin_textdomain( 'ultimate-addons-for-gutenberg', false, $lang_dir );
}
/**
* Fires admin notice when Gutenberg is not installed and activated.
*
* @since 1.0.0
*
* @return void
*/
public function uagb_fails_to_load() {
if ( ! current_user_can( 'install_plugins' ) ) {
return;
}
$class = 'notice notice-error';
/* translators: %s: html tags */
$message = sprintf( __( 'The %1$sSpectra%2$s plugin requires %1$sGutenberg%2$s plugin installed & activated.', 'ultimate-addons-for-gutenberg' ), '<strong>', '</strong>' );
$action_url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=gutenberg' ), 'install-plugin_gutenberg' );
$button_label = __( 'Install Gutenberg', 'ultimate-addons-for-gutenberg' );
$button = '<p><a href="' . $action_url . '" class="button-primary">' . $button_label . '</a></p><p></p>';
printf( '<div class="%1$s"><p>%2$s</p>%3$s</div>', esc_attr( $class ), wp_kses_post( $message ), wp_kses_post( $button ) );
}
/**
* Activation Reset
*/
public function activation_reset() {
$has_activated_before = get_option( '__uagb_activated_before', false );
if ( ! $has_activated_before ) {
uagb_install()->create_files();
update_option( '__uagb_do_redirect', true );
update_option( '__uagb_activated_before', true );
update_option( '__uagb_asset_version', time() );
} else {
update_option( '__uagb_do_redirect', false );
}
}
/**
* Deactivation Reset
*/
public function deactivation_reset() {
update_option( '__uagb_do_redirect', false );
}
/**
* Init actions
*
* @since 2.0.0
*
* @return void
*/
public function init_actions() {
// Check if Gutenberg is active, if not, don't load anything.
// TO DO: Add an admin notice to inform the user that Gutenberg is not active.
if ( ! $this->is_gutenberg_active() ) {
add_action( 'admin_notices', array( $this, 'uagb_fails_to_load' ) );
return;
}
// Load the text domain for translation.
$this->load_textdomain();
// Register all UAG Lite Blocks. This is done by calling the register_blocks method
// on the uagb_block() instance. This method is responsible for registering all the
// blocks in the plugin.
uagb_block()->register_blocks();
$theme_folder = get_template();
if ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() ) {
if ( 'twentytwentytwo' === $theme_folder ) {
require_once UAGB_DIR . 'compatibility/class-uagb-twenty-twenty-two-compatibility.php';
}
}
if ( 'astra' === $theme_folder ) {
require_once UAGB_DIR . 'compatibility/class-uagb-astra-compatibility.php';
}
register_meta(
'post',
'_uag_custom_page_level_css',
array(
'show_in_rest' => true,
'type' => 'string',
'single' => true,
'auth_callback' => function() {
return current_user_can( 'edit_posts' );
},
'sanitize_callback' => function( $meta_value ) {
return UAGB_Admin_Helper::sanitize_inline_css( $meta_value );
},
)
);
// This class is loaded from blocks config.
UAGB_Popup_Builder::generate_scripts();
UAGB_Update::migrate_visibility_mode();
// Adds filters to modify the blocks allowed in excerpts.
add_filter( 'excerpt_allowed_blocks', array( $this, 'add_blocks_to_excerpt' ), 20 );
add_filter( 'excerpt_allowed_wrapper_blocks', array( $this, 'add_wrapper_blocks_to_excerpt' ), 20 );
add_filter( 'uagb_blocks_allowed_in_excerpt', array( $this, 'add_uagb_blocks_to_excerpt' ), 20, 2 );
$this->get_regenerate_assets_on_migration();
}
/**
* Adds specified blocks to the list of allowed blocks in excerpts.
*
* @param array $allowed List of allowed blocks in excerpts.
* @since 2.6.0
* @return array Modified list of allowed blocks in excerpts.
*/
public function add_blocks_to_excerpt( $allowed ) {
return apply_filters( 'uagb_blocks_allowed_in_excerpt', $allowed, array( 'uagb/advanced-heading' ) );
}
/**
* Adds specified wrapper blocks to the list of allowed blocks in excerpts.
*
* @param array $allowed List of allowed blocks in excerpts.
* @since 2.6.0
* @return array Modified list of allowed blocks in excerpts.
*/
public function add_wrapper_blocks_to_excerpt( $allowed ) {
return apply_filters(
'uagb_blocks_allowed_in_excerpt',
$allowed,
array(
'uagb/container',
'uagb/columns',
'uagb/column',
)
);
}
/**
* Adds specified UAGB blocks to the list of allowed blocks in excerpts.
*
* @param array $excerpt_blocks List of allowed blocks in excerpts.
* @param array $blocks_to_add Blocks to add to the list of allowed blocks in excerpts.
* @since 2.6.0
* @return array The merged excerpt blocks array if both parameters are arrays, or the original excerpt blocks if either parameter is not an array.
*/
public function add_uagb_blocks_to_excerpt( $excerpt_blocks, $blocks_to_add ) {
if ( is_array( $excerpt_blocks ) && is_array( $blocks_to_add ) ) {
return array_merge( $excerpt_blocks, $blocks_to_add );
}
// If either parameter is not an array, return the original excerpt blocks.
return $excerpt_blocks;
}
/**
* Generate assets on migration.
*
* @since 2.7.10
* @return void
*/
public function get_regenerate_assets_on_migration() {
// Parse the host (domain/hostname) from the site URL.
$site_host = wp_parse_url( site_url(), PHP_URL_HOST );
// Check if $site_host is empty or not a string. If true, return and exit the function.
if ( empty( $site_host ) || ! is_string( $site_host ) ) {
return;
}
// Remove 'www.' from the domain.
$domain = str_replace( 'www.', '', $site_host );
// Replace dots (.) with dashes (-) in the domain to create $site_domain.
$site_domain = str_replace( '.', '-', $domain );
// Retrieve the stored domain from admin settings.
$stored_domain = \UAGB_Admin_Helper::get_admin_settings_option( 'uagb_site_url', '' );
// If the stored domain is empty, update the 'uagb_site_url' option in admin settings with the modified site domain and return.
if ( empty( $stored_domain ) ) {
\UAGB_Admin_Helper::update_admin_settings_option( 'uagb_site_url', $site_domain );
return;
}
// If the stored domain is different from the current site domain, update the '__uagb_asset_version' option with the current timestamp.
if ( $stored_domain !== $site_domain ) {
\UAGB_Admin_Helper::update_admin_settings_option( '__uagb_asset_version', time() );
}
}
/**
* Add the Zip AI Collab Product Details.
*
* @param mixed $product_details The previous product details, if any.
* @since 2.10.2
* @return array The Spectra product details.
*/
public function add_zip_ai_collab_product_details( $product_details ) {
// Overwrite the product details that were of a lower priority, if any.
$product_details = array(
'product_name' => 'Spectra',
'product_slug' => 'spectra',
'product_logo' => file_get_contents( UAGB_DIR . 'assets/images/logos/spectra.svg' ),
'product_primary_color' => '#5733ff',
'ai_assistant_learn_more_url' => admin_url( 'admin.php?page=spectra&path=ai-features' ),
'ai_assistant_authorized_disable_url' => admin_url( 'admin.php?page=spectra&path=ai-features&manage-features=yes' ),
'ai_assistant_unauthorized_disable_url' => admin_url( 'admin.php?page=spectra&path=ai-features&manage-features=yes' ),
);
// Return the Spectra product details.
return $product_details;
}
/**
* Add the Zip AI Modules that come with Spectra.
*
* @param mixed $modules The modules for Zip AI, if any.
* @since 2.10.2
* @return array The Spectra default modules.
*/
public function add_zip_ai_modules( $modules ) {
// If the filtered modules is not an array, make it one.
$modules = is_array( $modules ) ? $modules : array();
// List of module names to enable.
$modules_to_enable = array( 'ai_assistant', 'ai_design_copilot' );
// Ensure each module in the list is enabled.
foreach ( $modules_to_enable as $module_name ) {
// @phpcs:ignore WordPress.NamingConventions.ValidVariableName
if ( class_exists( '\ZipAI\Classes\Module' ) && method_exists( '\ZipAI\Classes\Module', 'force_enabled' ) ) {
\ZipAI\Classes\Module::force_enabled( $modules, $module_name );
}
}
// Return the Spectra default modules.
return $modules;
}
/**
* Add the Zip AI Authorization/Revoke URL.
*
* @param mixed $auth_url The previous authorization URL, if any.
* @since 2.10.2
* @return string The Spectra redirection URL.
*/
public function add_zip_ai_redirection_url( $auth_url ) {
return admin_url( 'admin.php?page=spectra&path=ai-features' );
}
/**
* Create an array of block status.
*
* @return array $block_status_data An associative array of block slug => status.
* The status can be either 'enabled' or 'disabled'.
*/
public function create_block_status_array() {
$saved_blocks = (array) \UAGB_Admin_Helper::get_admin_settings_option( '_uagb_blocks' );
$block_manager = uagb_block();
$blocks = ( method_exists( $block_manager, 'get_blocks' ) )
? (array) $block_manager->get_blocks()
: array();
$block_status_data = array();
if ( is_array( $blocks ) ) {
foreach ( $blocks as $slug => $data ) {
$_slug = str_replace( 'uagb/', '', $slug );
// Skip child blocks.
if ( isset( $blocks[ $slug ]['is_child'] ) ) {
continue;
}
// Initialize status array.
$block_status_data[ $_slug ] = array();
// Check saved status.
if ( isset( $saved_blocks[ $_slug ] ) ) {
$block_status_data[ $_slug ] =
'disabled' === $saved_blocks[ $_slug ] ? 'disabled' : 'enabled';
} else {
$block_status_data[ $_slug ] = 'enabled';
}
}
}
return $block_status_data;
}
/**
* Generates global setting data for analytics
*
* @since 1.4.0
* @return array
*/
public function global_settings_data() {
$global_data = array();
// Prepare to get the Zip AI Co-pilot modules.
$zip_ai_modules = array();
$bsf_internal_referrer = get_option( 'bsf_product_referers', array() );
$bsf_internal_referrer = (array) $bsf_internal_referrer;
$global_data['internal_referer'] = isset( $bsf_internal_referrer['ultimate-addons-for-gutenberg'] )
? $bsf_internal_referrer['ultimate-addons-for-gutenberg']
: '';
$global_data['beta'] = get_option( 'uagb_beta' );
$global_data['enable_legacy_blocks'] = get_option( 'uag_enable_legacy_blocks' );
$global_data['file_generation'] = get_option( '_uagb_allow_file_generation' );
$global_data['templates_button'] = get_option( 'uag_enable_templates_button' );
$global_data['on_page_css_button'] = get_option( 'uag_enable_on_page_css_button' );
$global_data['block_condition'] = get_option( 'uag_enable_block_condition' );
$global_data['quick_action_sidebar'] = get_option( 'uag_enable_quick_action_sidebar' );
$global_data['gbs_extension'] = get_option( 'uag_enable_gbs_extension' );
$global_data['block_responsive'] = get_option( 'uag_enable_block_responsive' );
$global_data['load_select_font_globally'] = get_option( 'uag_load_select_font_globally' );
$global_data['load_gfonts_locally'] = get_option( 'uag_load_gfonts_locally' );
$global_data['collapse_panels'] = get_option( 'uag_collapse_panels' );
$global_data['copy_paste'] = get_option( 'uag_copy_paste' );
$global_data['preload_local_fonts'] = get_option( 'uag_preload_local_fonts' );
$global_data['visibility_mode'] = get_option( 'uag_visibility_mode' );
$global_data['container_global_padding'] = get_option( 'uag_container_global_padding' );
$global_data['container_global_elements_gap'] = get_option( 'uag_container_global_elements_gap' );
$global_data['btn_inherit_from_theme'] = get_option( 'uag_btn_inherit_from_theme' );
$global_data['blocks_editor_spacing'] = get_option( 'uag_blocks_editor_spacing' );
$global_data['load_font_awesome_5'] = get_option( 'uag_load_font_awesome_5' );
$global_data['auto_block_recovery'] = get_option( 'uag_auto_block_recovery' );
$global_data['load_fse_font_globally'] = get_option( 'uag_load_fse_font_globally' );
// If the Zip AI Helper is available, get the required modules and their states.
if ( class_exists( '\ZipAI\Classes\Module' ) ) {
$zip_ai_modules = Zip_Ai_Module::get_all_modules();
// Restructure AI-related data.
if ( isset( $zip_ai_modules['ai_assistant'] ) ) {
$global_data['ai_assistant'] = $zip_ai_modules['ai_assistant']['status'];
}
if ( isset( $zip_ai_modules['ai_design_copilot'] ) ) {
$global_data['ai_design_copilot'] = $zip_ai_modules['ai_design_copilot']['status'];
}
// Merge the rest of the modules.
$global_data = array_merge_recursive(
$global_data,
array_filter(
$zip_ai_modules,
function( $key ) {
return ! in_array( $key, array( 'ai_assistant', 'ai_design_copilot' ) );
},
ARRAY_FILTER_USE_KEY
)
);
}
// Return the global data.
return $global_data;
}
/**
* Pass spectra specific stats to BSF analytics.
*
* @since 2.19.5
* @param array $default_stats Default stats array.
* @return array $default_stats Default stats with spectra specific stats array.
*/
public function spectra_get_specific_stats( $default_stats ) {
$default_stats['plugin_data']['spectra'] = array(
'version' => UAGB_VER,
'old_user_less_than_2' => get_option( 'uagb-old-user-less-than-2' ), // Retrieves current user is old user less than 2 or not.
'migration_status' => get_option( 'uag_migration_status' ), // Retrieves migration status.
);
$default_stats['plugin_data']['spectra'] = array_merge_recursive( $default_stats['plugin_data']['spectra'], $this->global_settings_data() );
$default_stats['plugin_data']['spectra'] = array_merge_recursive( $default_stats['plugin_data']['spectra'], $this->create_block_status_array() );
// Add advanced block usage statistics.
if ( is_object( $this->block_analytics ) ) {
$default_stats['plugin_data']['spectra'] = $this->block_analytics->get_block_stats_for_analytics( $default_stats['plugin_data']['spectra'] );
}
return $default_stats;
}
}
}
/**
* Prepare if class 'UAGB_Loader' exist.
* Kicking this off by calling 'get_instance()' method
*/
UAGB_Loader::get_instance();
/**
* Load main object
*
* @since 2.0.0
*
* @return object
*/
function uagb() {
return UAGB_Loader::get_instance();
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* UAGB NPS Notice.
*
* @since 2.18.0
*
* @package ultimate-addons-for-gutenberg
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'UAGB_NPS_Notice' ) ) :
/**
* Class UAGB_NPS_Notice
*/
class UAGB_NPS_Notice {
/**
* Instance
*
* @since 2.18.0
* @var (Object) UAGB_NPS_Notice
*/
private static $instance = null;
/**
* Get Instance
*
* @since 2.18.0
*
* @return object Class object.
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor.
*
* @since 2.18.0
*/
private function __construct() {
add_action( 'admin_footer', array( $this, 'show_nps_notice' ), 999 );
}
/**
* Render NPS Survey
*
* @since 2.18.0
* @return void
*/
public function show_nps_notice() {
// Ensure the Nps_Survey class exists before proceeding.
if ( ! class_exists( 'Nps_Survey' ) ) {
return;
}
/*
Check if the constant WEEK_IN_SECONDS is already defined.
This ensures that the constant is not redefined if it's already set by WordPress or other parts of the code.
*/
if ( ! defined( 'WEEK_IN_SECONDS' ) ) {
// Define the WEEK_IN_SECONDS constant with the value of 604800 seconds (equivalent to 7 days).
define( 'WEEK_IN_SECONDS', 604800 );
}
$allowed_screens = array( 'toplevel_page_spectra', 'edit-spectra-popup' );
$allowed_screens = array( 'toplevel_page_spectra', 'edit-spectra-popup' );
// Display the NPS survey.
Nps_Survey::show_nps_notice(
'nps-survey-ultimate-addons-for-gutenberg',
array(
'show_if' => true,
'dismiss_timespan' => 2 * WEEK_IN_SECONDS,
'display_after' => 2 * WEEK_IN_SECONDS,
'plugin_slug' => 'spectra',
'show_on_screens' => $allowed_screens,
'message' => array(
'logo' => esc_url( plugin_dir_url( __DIR__ ) . 'assets/images/logos/spectra.svg' ),
'plugin_name' => __( 'Spectra', 'ultimate-addons-for-gutenberg' ),
'nps_rating_message' => __( 'How likely are you to recommend Spectra to your friends or colleagues?', 'ultimate-addons-for-gutenberg' ),
'feedback_title' => __( 'Thanks a lot for your feedback! 😍', 'ultimate-addons-for-gutenberg' ),
'feedback_content' => __( 'Could you please do us a favor and give us a 5-star rating on WordPress? It would help others choose Spectra with confidence. Thank you!', 'ultimate-addons-for-gutenberg' ),
'plugin_rating_link' => esc_url( 'https://wordpress.org/support/plugin/ultimate-addons-for-gutenberg/reviews/#new-post' ),
'plugin_rating_title' => __( 'Thank you for your feedback', 'ultimate-addons-for-gutenberg' ),
'plugin_rating_content' => __( 'We value your input. How can we improve your experience?', 'ultimate-addons-for-gutenberg' ),
'plugin_rating_button_string' => __( 'Rate Spectra', 'ultimate-addons-for-gutenberg' ),
),
)
);
}
}
/**
* Initialize the class.
*/
UAGB_NPS_Notice::get_instance();
endif;

View File

@@ -0,0 +1,627 @@
<?php
/**
* UAGB Rest API.
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'UAGB_Rest_API' ) ) {
/**
* Class UAGB_Rest_API.
*/
final class UAGB_Rest_API {
/**
* Member Variable
*
* @var instance
*/
private static $instance;
/**
* Initiator
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
public function __construct() {
// Activation hook.
add_action( 'rest_api_init', array( $this, 'blocks_register_rest_fields' ) );
add_action( 'init', array( $this, 'register_rest_orderby_fields' ) );
add_filter( 'register_post_type_args', array( $this, 'add_cpts_to_api' ), 10, 2 );
// We have added this action here to support both the ways of post updations, Rest API & Normal.
add_action( 'save_post', array( 'UAGB_Helper', 'delete_page_assets' ), 10, 1 );
// Adding this action to delete post assets if the post is moved to trash.
add_action( 'wp_trash_post', array( $this, 'delete_page_assets_on_trash' ) );
global $wp_customize;
if ( $wp_customize ) { // Check whether the $wp_customize is set.
add_filter( 'render_block_data', array( $this, 'content_pre_render' ) ); // Add a inline style for block when it rendered in customizer.
add_action( 'customize_save', array( $this, 'after_widget_save_action' ) ); // Update the assets on customizer save/publish.
} else {
add_action( 'rest_after_save_widget', array( $this, 'after_widget_save_action' ) ); // Update the assets on widget save.
}
}
/**
* Function to delete post assets.
*
* @param int $post_id post_id of deleted post.
* @since 2.13.1
* @return void
*/
public function delete_page_assets_on_trash( $post_id ) {
$css_asset_info = UAGB_Scripts_Utils::get_asset_info( 'css', $post_id );
$js_asset_info = UAGB_Scripts_Utils::get_asset_info( 'js', $post_id );
$css_file_path = $css_asset_info['css'];
$js_file_path = $js_asset_info['js'];
if ( file_exists( $css_file_path ) ) {
wp_delete_file( $css_file_path );
}
if ( file_exists( $js_file_path ) ) {
wp_delete_file( $js_file_path );
}
}
/**
* Function to load assets for post/page in customizer before gutenberg rendering.
*
* @param array $block Block data.
*
* @since 2.0.13
*
* @return array New block data.
*/
public function content_pre_render( $block ) {
$tab_styling_css = '';
$mob_styling_css = '';
$UAGB_Post_Assets = new UAGB_Post_Assets( get_the_ID() );
$assets = $UAGB_Post_Assets->get_block_css_and_js( $block );
$desktop_css = isset( $assets['css']['desktop'] ) ? $assets['css']['desktop'] : '';
if ( ! empty( $assets['css']['tablet'] ) ) {
$tab_styling_css .= '@media only screen and (max-width: ' . UAGB_TABLET_BREAKPOINT . 'px) {';
$tab_styling_css .= $assets['css']['tablet'];
$tab_styling_css .= '}';
}
if ( ! empty( $assets['css']['mobile'] ) ) {
$mob_styling_css .= '@media only screen and (max-width: ' . UAGB_MOBILE_BREAKPOINT . 'px) {';
$mob_styling_css .= $assets['css']['mobile'];
$mob_styling_css .= '}';
}
$block_css_style = $desktop_css . $tab_styling_css . $mob_styling_css;
if ( empty( $block_css_style ) || empty( $block['attrs'] ) || ! is_array( $block['attrs'] ) ) {
return $block;
}
// This line of code creates a new array named $font_family_attrs by searching through the keys of an existing array.
$font_family_attrs = preg_grep( '/fontfamily/i', array_keys( $block['attrs'] ) );
$link_tag_list = '';
if ( ! empty( $font_family_attrs ) && is_array( $font_family_attrs ) ) {
foreach ( $font_family_attrs as $attr ) {
if ( ! empty( $block['attrs'][ $attr ] ) ) {
// Get the font family value and construct the Google Fonts URL.
$gfont_url = 'https://fonts.googleapis.com/css?family=' . urlencode( $block['attrs'][ $attr ] );
// Create a link tag for the stylesheet with the constructed URL.
$link_tag_list .= '<link rel="stylesheet" href="' . esc_url( $gfont_url ) . '" media="all">';
}
}
}
$style = '<style class="uagb-widgets-style-renderer">' . $block_css_style . '</style>';
$style = $style . $link_tag_list;
array_push( $block['innerContent'], $style );
return $block;
}
/**
* This function updates the __uagb_asset_version when Widgets Editor is Updated.
*
* @since 2.0.0
*/
public function after_widget_save_action() {
/* Update the asset version */
update_option( '__uagb_asset_version', time() );
}
/**
* Create API fields for additional info
*
* @since 0.0.1
*/
public function blocks_register_rest_fields() {
$post_type = UAGB_Helper::get_post_types();
foreach ( $post_type as $key => $value ) {
// Add featured image source.
register_rest_field(
$value['value'],
'uagb_featured_image_src',
array(
'get_callback' => array( $this, 'get_image_src' ),
'update_callback' => null,
'schema' => null,
)
);
// Add author info.
register_rest_field(
$value['value'],
'uagb_author_info',
array(
'get_callback' => array( $this, 'get_author_info' ),
'update_callback' => null,
'schema' => null,
)
);
// Add comment info.
register_rest_field(
$value['value'],
'uagb_comment_info',
array(
'get_callback' => array( $this, 'get_comment_info' ),
'update_callback' => null,
'schema' => null,
)
);
// Add excerpt info.
register_rest_field(
$value['value'],
'uagb_excerpt',
array(
'get_callback' => array( $this, 'get_excerpt' ),
'update_callback' => null,
'schema' => null,
)
);
}
register_rest_route(
'spectra/v1',
'all_taxonomy',
array(
array(
'methods' => 'GET',
'callback' => array( $this, 'get_related_taxonomy' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => array(),
),
)
);
register_rest_route(
'spectra/v1',
'editor',
array(
array(
'methods' => 'GET',
'callback' => array( $this, 'uagb_initial_states' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => array(),
),
)
);
register_rest_route(
'spectra/v1',
'check-custom-fields-support',
array(
array(
'methods' => 'GET',
'callback' => array( $this, 'check_custom_fields_support' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
),
)
);
}
/**
* Get Initial States.
*
* @since 2.12.0
* @return array
*/
public function uagb_initial_states() {
$response = array_merge(
// For GBS initial states.
$this->get_gbs_initial_states(),
// For quick action sidebar.
$this->get_quick_action_bar_initial_states()
);
return $response;
}
/**
* Get Quick Action Bar Initial States.
*
* @since 2.12.0
* @return array
*/
public function get_quick_action_bar_initial_states() {
// Get value from DB for Quick Action Bar.
$db_value = \UAGB_Admin_Helper::get_admin_settings_option( 'uag_enable_quick_action_sidebar' );
$show_enable = ( empty( $db_value ) ) ? 'enabled' : $db_value;
$spectra_enable_quick_action_sidebar = \UAGB_Admin_Helper::get_admin_settings_option( 'uag_enable_quick_action_sidebar', $show_enable );
$spectra_default_allowed_quick_sidebar_blocks = \UAGB_Admin_Helper::get_admin_settings_option(
'uagb_quick_sidebar_allowed_blocks',
array()
);
if ( empty( $spectra_default_allowed_quick_sidebar_blocks ) ) {
$spectra_default_allowed_quick_sidebar_blocks = array(
'uagb/container',
'uagb/advanced-heading',
'uagb/image',
'uagb/icon',
'uagb/buttons',
'uagb/info-box',
'uagb/call-to-action',
);
}
$initial_state = array(
'uag_enable_quick_action_sidebar' => $spectra_enable_quick_action_sidebar,
'uagb_quick_sidebar_allowed_blocks' => $spectra_default_allowed_quick_sidebar_blocks,
);
return $initial_state;
}
/**
* Get GBS Initial States.
*
* @since 2.9.0
* @return array
*/
public function get_gbs_initial_states() {
// check if GBS is enabled or not.
if ( 'enabled' !== \UAGB_Admin_Helper::get_admin_settings_option( 'uag_enable_gbs_extension', 'enabled' ) ) {
return array();
}
$spectra_global_block_styles = get_option(
'spectra_global_block_styles',
array(
array(
'value' => '',
'label' => __( 'None', 'ultimate-addons-for-gutenberg' ),
),
)
);
$spectra_gbs_google_fonts_editor = get_option(
'spectra_gbs_google_fonts_editor',
array()
);
if ( empty( $spectra_global_block_styles ) ) {
$spectra_global_block_styles = array(
array(
'value' => '',
'label' => __( 'None', 'ultimate-addons-for-gutenberg' ),
),
);
}
$initial_state = array(
'spectra_global_block_styles' => $spectra_global_block_styles,
'spectra_gbs_google_fonts_editor' => $spectra_gbs_google_fonts_editor,
);
return $initial_state;
}
/**
* Get all taxonomies.
*
* @since 1.11.0
* @access public
*/
public function get_related_taxonomy() {
$post_types = self::get_post_types();
$return_array = array();
foreach ( $post_types as $key => $value ) {
$post_type = $value['value'];
$taxonomies = get_object_taxonomies( $post_type, 'objects' );
$data = array();
foreach ( $taxonomies as $tax_slug => $tax ) {
if ( ! $tax->public || ! $tax->show_ui || ! $tax->show_in_rest ) {
continue;
}
$data[ $tax_slug ] = $tax;
$terms = get_terms( $tax_slug );
$related_tax = array();
if ( ! empty( $terms ) ) {
foreach ( $terms as $t_index => $t_obj ) {
$related_tax[] = array(
'id' => $t_obj->term_id,
'name' => $t_obj->name,
'child' => get_term_children( $t_obj->term_id, $tax_slug ),
);
}
$return_array[ $post_type ]['terms'][ $tax_slug ] = $related_tax;
}
}
$return_array[ $post_type ]['taxonomy'] = $data;
}
return apply_filters( 'uagb_post_loop_taxonomies', $return_array );
}
/**
* Get Post Types.
*
* @since 1.11.0
* @access public
*/
public static function get_post_types() {
$post_types = get_post_types(
array(
'public' => true,
'show_in_rest' => true,
),
'objects'
);
$options = array();
foreach ( $post_types as $post_type ) {
if ( 'attachment' === $post_type->name ) {
continue;
}
$options[] = array(
'value' => $post_type->name,
'label' => $post_type->label,
);
}
return apply_filters( 'uagb_loop_post_types', $options );
}
/**
* Check whether a given request has permission to read notes.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_Error|boolean
*/
public function get_items_permissions_check( $request ) {
if ( ! current_user_can( 'edit_posts' ) ) {
return new \WP_Error( 'uag_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'ultimate-addons-for-gutenberg' ), array( 'status' => rest_authorization_required_code() ) );
}
return true;
}
/**
* Get featured image source for the rest field as per size
*
* @param object $object Post Object.
* @param string $field_name Field name.
* @param object $request Request Object.
* @since 0.0.1
*/
public function get_image_src( $object, $field_name, $request ) {
$image_sizes = UAGB_Helper::get_image_sizes();
$featured_images = array();
if ( ! isset( $object['featured_media'] ) ) {
return $featured_images;
}
foreach ( $image_sizes as $key => $value ) {
$size = $value['value'];
$featured_images[ $size ] = wp_get_attachment_image_src(
$object['featured_media'],
$size,
false
);
}
return $featured_images;
}
/**
* Get author info for the rest field
*
* @param object $object Post Object.
* @param string $field_name Field name.
* @param object $request Request Object.
* @since 0.0.1
*/
public function get_author_info( $object, $field_name, $request ) {
$author = ( isset( $object['author'] ) ) ? $object['author'] : '';
// Get the author name.
$author_data['display_name'] = get_the_author_meta( 'display_name', $author );
// Get the author link.
$author_data['author_link'] = get_author_posts_url( $author );
// Return the author data.
return $author_data;
}
/**
* Get comment info for the rest field
*
* @param object $object Post Object.
* @param string $field_name Field name.
* @param object $request Request Object.
* @since 0.0.1
*/
public function get_comment_info( $object, $field_name, $request ) {
// Get the comments link.
$comments_count = wp_count_comments( $object['id'] );
return $comments_count->total_comments;
}
/**
* Get excerpt for the rest field
*
* @param object $object Post Object.
* @param string $field_name Field name.
* @param object $request Request Object.
* @since 0.0.1
*/
public function get_excerpt( $object, $field_name, $request ) {
$excerpt = wp_trim_words( get_the_excerpt( $object['id'] ) );
if ( ! $excerpt ) {
$excerpt = null;
}
return $excerpt;
}
/**
* Create API Order By Fields
*
* @since 1.12.0
*/
public function register_rest_orderby_fields() {
$post_type = UAGB_Helper::get_post_types();
foreach ( $post_type as $key => $type ) {
add_filter( "rest_{$type['value']}_collection_params", array( $this, 'add_orderby' ), 10, 1 );
}
}
/**
* Adds Order By values to Rest API
*
* @param object $params Parameters.
* @since 1.12.0
*/
public function add_orderby( $params ) {
$params['orderby']['enum'][] = 'rand';
$params['orderby']['enum'][] = 'menu_order';
return $params;
}
/**
* Adds the Contect Form 7 Custom Post Type to REST.
*
* @param array $args Array of arguments.
* @param string $post_type Post Type.
* @since 1.10.0
*/
public function add_cpts_to_api( $args, $post_type ) {
if ( 'wpcf7_contact_form' !== $post_type || ! is_admin() ) {
return $args; // Don't change anything for other post types.
}
// Modify args only for wpcf7_contact_form.
$args['show_in_rest'] = true;
return $args;
}
/**
* Supported arguments to check if the given post type supports custom fields.
*
* @since 2.13.1
* @return array The array of supported arguments.
*/
public function check_custom_fields_support_args() {
$args = array();
$args['post_type'] = array(
'type' => 'string',
'required' => false,
);
return $args;
}
/**
* Checks if the given post type supports custom fields.
*
* @param WP_REST_Request $request All the details about the request.
* @since 2.13.1
* @return WP_REST_Response The response.
*/
public function check_custom_fields_support( $request ) {
$post_type = $request->get_param( 'post_type' );
// If the post type was not passed, abandon ship.
if ( empty( $post_type ) || ! is_string( $post_type ) ) {
$response = new \WP_REST_Response(
array(
'success' => false,
)
);
$response->set_status( 400 );
return $response;
}
// Sanitize the post type, and check if the post type supports custom fields.
$post_type = sanitize_text_field( $post_type );
$supports_custom_fields = post_type_supports( $post_type, 'custom-fields' );
// Return the successful response, with whether or not custom fields is supported.
$response = new \WP_REST_Response(
array(
'success' => true,
'supports_custom_fields' => $supports_custom_fields,
)
);
$response->set_status( 200 );
return $response;
}
}
/**
* Prepare if class 'UAGB_Rest_API' exist.
* Kicking this off by calling 'get_instance()' method
*/
UAGB_Rest_API::get_instance();
}

View File

@@ -0,0 +1,186 @@
<?php
/**
* UAGB Rollback.
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* UAG Rollback.
*
* UAG Rollback. handler class is responsible for rolling back UAG to
* previous version.
*
* @since 1.23.0
*/
class UAGB_Rollback {
/**
* Package URL.
*
* Holds the package URL.
*
* @since 1.23.0
* @access protected
*
* @var string Package URL.
*/
protected $package_url;
/**
* Version.
*
* Holds the version.
*
* @since 1.23.0
* @access protected
*
* @var string Package URL.
*/
protected $version;
/**
* Plugin name.
*
* Holds the plugin name.
*
* @since 1.23.0
* @access protected
*
* @var string Plugin name.
*/
protected $plugin_name;
/**
* Plugin slug.
*
* Holds the plugin slug.
*
* @since 1.23.0
* @access protected
*
* @var string Plugin slug.
*/
protected $plugin_slug;
/**
* UAG Rollback constructor.
*
* Initializing UAG Rollback.
*
* @since 1.23.0
* @access public
*
* @param array $args Optional. UAGB Rollback arguments. Default is an empty array.
*/
public function __construct( $args = array() ) {
foreach ( $args as $key => $value ) {
$this->{$key} = $value;
}
}
/**
* Print inline style.
*
* Add an inline CSS to the UAG Rollback page.
*
* @since 1.23.0
* @access private
*/
private function print_inline_style() {
?>
<style>
.wrap {
overflow: hidden;
max-width: 850px;
margin: auto;
font-family: Courier, monospace;
}
h1 {
background: rgb(74, 0, 224);
text-align: center;
color: #fff !important;
padding: 70px !important;
text-transform: uppercase;
letter-spacing: 1px;
}
h1 img {
max-width: 300px;
display: block;
margin: auto auto 50px;
}
</style>
<?php
}
/**
* Apply package.
*
* Change the plugin data when WordPress checks for updates. This method
* modifies package data to update the plugin from a specific URL containing
* the version package.
*
* @since 1.23.0
* @access protected
*/
protected function apply_package() {
$update_plugins = get_site_transient( 'update_plugins' );
if ( ! is_object( $update_plugins ) ) {
$update_plugins = new \stdClass();
}
$plugin_info = new \stdClass();
$plugin_info->new_version = $this->version;
$plugin_info->slug = $this->plugin_slug;
$plugin_info->package = $this->package_url;
$plugin_info->url = 'https://wpspectra.com/';
$update_plugins->response[ $this->plugin_name ] = $plugin_info;
set_site_transient( 'update_plugins', $update_plugins );
}
/**
* Upgrade.
*
* Run WordPress upgrade to UAGB Rollback to previous version.
*
* @since 1.23.0
* @access protected
*/
protected function upgrade() {
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
$upgrader_args = array(
'url' => 'update.php?action=upgrade-plugin&plugin=' . rawurlencode( $this->plugin_name ),
'plugin' => $this->plugin_name,
'nonce' => 'upgrade-plugin_' . $this->plugin_name,
'title' => __( 'Spectra <p>Rollback to Previous Version</p>', 'ultimate-addons-for-gutenberg' ),
);
$this->print_inline_style();
$upgrader = new \Plugin_Upgrader( new \Plugin_Upgrader_Skin( $upgrader_args ) );
$upgrader->upgrade( $this->plugin_name );
}
/**
* Run.
*
* Rollback UAG to previous versions.
*
* @since 1.23.0
* @access public
*/
public function run() {
$this->apply_package();
$this->upgrade();
}
}

View File

@@ -0,0 +1,227 @@
<?php
/**
* UAGB Scripts Utils.
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Class UAGB_Scripts_Utils.
*/
final class UAGB_Scripts_Utils {
/**
* Enqueue Gutenberg block assets for both frontend + backend.
*
* @since 1.23.0
*/
public static function enqueue_blocks_dependency_both() {
$blocks = UAGB_Block_Module::get_blocks_info();
$saved_blocks = UAGB_Admin_Helper::get_admin_settings_option( '_uagb_blocks', array() );
$block_assets = UAGB_Block_Module::get_block_dependencies();
foreach ( $blocks as $slug => $value ) {
$_slug = str_replace( 'uagb/', '', $slug );
if ( ! ( isset( $saved_blocks[ $_slug ] ) && 'disabled' === $saved_blocks[ $_slug ] ) ) {
if ( 'cf7-styler' === $_slug ) {
if ( ! wp_script_is( 'contact-form-7', 'enqueued' ) ) {
wp_enqueue_script( 'contact-form-7' );
}
if ( ! wp_script_is( ' wpcf7-admin', 'enqueued' ) ) {
wp_enqueue_script( ' wpcf7-admin' );
}
}
foreach ( $block_assets as $handle => $asset ) {
if ( isset( $asset['type'] ) ) {
if ( 'js' === $asset['type'] ) {
// Scripts.
wp_register_script(
$handle, // Handle.
$asset['src'],
$asset['dep'],
UAGB_VER,
true
);
$skip_editor = isset( $asset['skipEditor'] ) ? $asset['skipEditor'] : false;
if ( is_admin() && false === $skip_editor ) {
wp_enqueue_script( $handle );
}
} elseif ( 'css' === $asset['type'] ) {
// Styles.
wp_register_style(
$handle, // Handle.
$asset['src'],
$asset['dep'],
UAGB_VER
);
if ( is_admin() ) {
wp_enqueue_style( $handle );
}
}
}
}
}
}
$uagb_masonry_ajax_nonce = wp_create_nonce( 'uagb_masonry_ajax_nonce' );
wp_localize_script(
'uagb-post-js',
'uagb_data',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'uagb_masonry_ajax_nonce' => $uagb_masonry_ajax_nonce,
)
);
$uagb_forms_ajax_nonce = wp_create_nonce( 'uagb_forms_ajax_nonce' );
wp_localize_script(
'uagb-forms-js',
'uagb_forms_data',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'uagb_forms_ajax_nonce' => $uagb_forms_ajax_nonce,
)
);
$uagb_image_gallery_masonry_ajax_nonce = wp_create_nonce( 'uagb_image_gallery_masonry_ajax_nonce' );
$uagb_image_gallery_grid_pagination_ajax_nonce = wp_create_nonce( 'uagb_image_gallery_grid_pagination_ajax_nonce' );
wp_localize_script(
'uagb-image-gallery-js',
'uagb_image_gallery',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'uagb_image_gallery_masonry_ajax_nonce' => $uagb_image_gallery_masonry_ajax_nonce,
'uagb_image_gallery_grid_pagination_ajax_nonce' => $uagb_image_gallery_grid_pagination_ajax_nonce,
)
);
wp_localize_script(
'uagb-countdown-js',
'uagb_countdown_data',
array(
'site_name_slug' => sanitize_title( get_bloginfo( 'name' ) ),
)
);
}
/**
* Enqueue block styles.
*
* @since 1.23.0
*/
public static function enqueue_blocks_styles() {
$wp_upload_dir = UAGB_Helper::get_uag_upload_dir_path();
if ( file_exists( $wp_upload_dir . 'custom-style-blocks.css' ) ) {
$wp_upload_url = UAGB_Helper::get_uag_upload_url_path();
wp_enqueue_style(
'uagb-block-css', // Handle.
$wp_upload_url . 'custom-style-blocks.css', // Block style CSS.
array(),
UAGB_VER
);
} else {
wp_enqueue_style(
'uagb-block-css', // Handle.
UAGB_URL . 'dist/style-blocks.css', // Block style CSS.
array(),
UAGB_VER
);
}
}
/**
* Enqueue block rtl styles.
*
* @since 1.23.0
*/
public static function enqueue_blocks_rtl_styles() {
if ( is_rtl() ) {
wp_enqueue_style(
'uagb-style-rtl', // Handle.
UAGB_URL . 'assets/css/style-blocks-rtl.min.css', // RTL style CSS.
array(),
UAGB_VER
);
}
}
/**
* Get folder name by post id.
*
* @param int $post_id post id.
* @since 2.0.0
*/
public static function get_asset_folder_name( $post_id ) {
$folder_name = 0;
if ( ! empty( $post_id ) ) {
$folder_name = absint( round( $post_id, -3 ) );
}
return $folder_name;
}
/**
* Returns an array of paths for the CSS and JS assets
* of the current post.
*
* @param string $type Gets the CSS\JS type.
* @param int $post_id Post ID.
* @since 1.14.0
* @return array
*/
public static function get_asset_info( $type, $post_id ) {
$uploads_dir = UAGB_Helper::get_upload_dir();
$folder_name = self::get_asset_folder_name( $post_id );
$file_name = get_post_meta( $post_id, '_uag_' . $type . '_file_name', true );
$path = $type;
$url = $type . '_url';
$info = array(
$path => '',
$url => '',
);
if ( ! empty( $file_name ) ) {
$info[ $path ] = $uploads_dir['path'] . 'assets/' . $folder_name . '/' . $file_name;
$info[ $url ] = $uploads_dir['url'] . 'assets/' . $folder_name . '/' . $file_name;
}
return $info;
}
/**
* Get JS url from to assets.
*
* @since 2.0.0
*
* @param string $file_name File name.
*
* @return string JS url.
*/
public static function get_js_url( $file_name ) {
return UAGB_URL . 'assets/js/' . $file_name . UAGB_JS_EXT;
}
}

View File

@@ -0,0 +1,82 @@
<?php
/**
* UAGB Twenty Seventeen Compatibility.
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'UAGB_Twenty_Seventeen_Compatibility' ) ) {
/**
* Class UAGB_Twenty_Seventeen_Compatibility.
*/
final class UAGB_Twenty_Seventeen_Compatibility {
/**
* Member Variable
*
* @var instance
*/
private static $instance;
/**
* Initiator
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
public function __construct() {
add_action( 'wp', array( $this, 'generate_stylesheet' ), 101 );
}
/**
* Generates stylesheet and appends in head tag.
*
* @since 1.18.1
*/
public function generate_stylesheet() {
if ( is_home() ) {
$post_id = get_the_ID();
$current_post_assets = new UAGB_Post_Assets( intval( $post_id ) );
if ( is_object( $current_post_assets ) ) {
$current_post_assets->enqueue_scripts();
}
}
if ( ! function_exists( 'twentyseventeen_panel_count' ) ) {
return;
}
$panel_count = twentyseventeen_panel_count();
$post_assets_obj = uagb_get_front_post_assets();
$all_posts = array();
for ( $i = 1; $i <= $panel_count; $i++ ) {
$mod_key = 'panel_' . $i;
$post_id = get_theme_mod( $mod_key );
$post = get_post( $post_id );
array_push( $all_posts, $post );
}
if ( ! is_object( $post_assets_obj ) ) {
return;
}
foreach ( $all_posts as $post ) {
$post_assets_obj->prepare_assets( $post );
}
}
}
}
UAGB_Twenty_Seventeen_Compatibility::get_instance();

View File

@@ -0,0 +1,273 @@
<?php
/**
* Update Compatibility
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'UAGB_Update' ) ) :
/**
* UAGB Update initial setup
*
* @since 1.13.4
*/
class UAGB_Update {
/**
* Class instance.
*
* @access private
* @var $instance Class instance.
*/
private static $instance;
/**
* Initiator
*/
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
public function __construct() {
add_action( 'admin_init', array( $this, 'init' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles' ) );
add_action( 'in_plugin_update_message-' . UAGB_BASE, array( $this, 'plugin_update_notification' ), 10 );
}
/**
* Init
*
* @since 1.13.4
* @return void
*/
public function init() {
// Get auto saved version number.
$saved_version = get_option( 'uagb-version', false );
// Update auto saved version number.
if ( ! $saved_version || ! is_string( $saved_version ) ) {
// Fresh install updation.
$this->fresh_install_update_asset_generation_option();
// Update current version.
update_option( 'uagb-version', UAGB_VER );
return;
}
do_action( 'uagb_update_before' );
// If equals then return.
if ( version_compare( $saved_version, UAGB_VER, '=' ) ) {
return;
}
// If user is older than 2.0.0 then set the option.
if ( version_compare( $saved_version, '2.0.0', '<' ) ) {
update_option( 'uagb-old-user-less-than-2', 'yes' );
}
// Enable Legacy Blocks for users older than 2.0.5.
if ( version_compare( $saved_version, '2.0.5', '<' ) ) {
UAGB_Admin_Helper::update_admin_settings_option( 'uag_enable_legacy_blocks', 'yes' );
}
// If user is older than equal to 2.12.1 then set the option.
if ( version_compare( $saved_version, '2.12.1', '<=' ) ) {
UAGB_Admin_Helper::update_admin_settings_option( 'uag_enable_quick_action_sidebar', 'disabled' );
}
// Delete any of the unused options that have been unsupported or no longer required.
// Delete the header titlebar option if it exists- which has been removed from version 2.14.1.
if ( UAGB_Admin_Helper::get_admin_settings_option( 'uag_enable_header_titlebar' ) ) {
UAGB_Admin_Helper::delete_admin_settings_option( 'uag_enable_header_titlebar' );
}
// Create a Core Block Array for all versions in which a Core Spectra Block was added.
$core_blocks = array();
$blocks_status = UAGB_Admin_Helper::get_admin_settings_option( '_uagb_blocks' );
// If Block Statuses exists and is not empty, enable the required Core Spectra Blocks.
if ( is_array( $blocks_status ) && ! empty( $blocks_status ) ) {
// If user is older than 2.0.16 then enable all the Core Spectra Blocks, as we have removed option to disable core blocks from 2.0.16.
if ( version_compare( $saved_version, '2.0.16', '<' ) ) {
array_push(
$core_blocks,
'container',
'advanced-heading',
'image',
'buttons',
'info-box',
'call-to-action'
);
}
// If user is older than 2.4.0 then enable the Icon Block that was added to the Core Blocks in this release.
if ( version_compare( $saved_version, '2.4.0', '<' ) ) {
array_push(
$core_blocks,
'icon'
);
}
// If user is older than 2.6.0 then enable the Countdown Block that was added to the Core Blocks in this release.
if ( version_compare( $saved_version, '2.6.0', '<' ) ) {
array_push(
$core_blocks,
'countdown'
);
}
// If user is older than 2.12.3 then enable the popup-builder Block that was added to the Core Blocks in this release.
if ( version_compare( $saved_version, '2.12.3', '<' ) ) {
array_push(
$core_blocks,
'popup-builder'
);
}
}
$inherit_from_theme = UAGB_Admin_Helper::get_admin_settings_option( 'uag_btn_inherit_from_theme' );
// If user is older than 2.13.4 and Inherit from theme is enabled update the fallback.
if ( version_compare( $saved_version, '2.13.4', '<' ) && 'enabled' === $inherit_from_theme ) {
UAGB_Admin_Helper::update_admin_settings_option( 'uag_btn_inherit_from_theme_fallback', 'disabled' );
}
// If the core block array is not empty, update the enabled blocks option.
if ( ! empty( $core_blocks ) ) {
foreach ( $core_blocks as $block ) {
$blocks_status[ $block ] = $block;
}
UAGB_Admin_Helper::update_admin_settings_option( '_uagb_blocks', $blocks_status );
}
// Create file if not present.
uagb_install()->create_files();
/* Create activated blocks stylesheet */
UAGB_Admin_Helper::create_specific_stylesheet();
// Update asset version number.
update_option( '__uagb_asset_version', time() );
// Update auto saved version number.
update_option( 'uagb-version', UAGB_VER );
do_action( 'uagb_update_after' );
}
/**
* Migrate_visibility_mode
*
* @since 2.8.0
* @return void
*/
public static function migrate_visibility_mode() {
$old_option = UAGB_Admin_Helper::get_admin_settings_option( 'uag_enable_coming_soon_mode' );
$old_option_page = UAGB_Admin_Helper::get_admin_settings_option( 'uag_coming_soon_page' );
if ( ! $old_option && ! $old_option_page ) {
return;
}
// Update the option.
UAGB_Admin_Helper::update_admin_settings_option( 'uag_visibility_mode', $old_option ? $old_option : 'disabled' );
UAGB_Admin_Helper::update_admin_settings_option( 'uag_visibility_page', $old_option_page ? $old_option_page : '' );
// Delete the old option.
UAGB_Admin_Helper::delete_admin_settings_option( 'uag_enable_coming_soon_mode' );
UAGB_Admin_Helper::delete_admin_settings_option( 'uag_coming_soon_page' );
}
/**
* Update asset generation option if it is not exist.
*
* @since 1.22.4
* @return void
*/
public function fresh_install_update_asset_generation_option() {
uagb_install()->create_files();
if ( UAGB_Helper::is_uag_dir_has_write_permissions() ) {
update_option( '_uagb_allow_file_generation', 'enabled' );
}
}
/**
* Plugin update notification.
*
* @param array $data Plugin update data.
* @since 2.7.2
* @return void
*/
public function plugin_update_notification( $data ) {
if ( ! empty( $data['upgrade_notice'] ) ) { ?>
<hr class="uagb-plugin-update-notification__separator" />
<div class="uagb-plugin-update-notification">
<div class="uagb-plugin-update-notification__icon">
<span class="dashicons dashicons-info"></span>
</div>
<div>
<div class="uagb-plugin-update-notification__title">
<?php echo esc_html__( 'Heads up!', 'ultimate-addons-for-gutenberg' ); ?>
</div>
<div class="uagb-plugin-update-notification__message">
<?php
printf(
wp_kses(
$data['upgrade_notice'],
array( 'a' => array( 'href' => array() ) )
)
);
?>
</div>
</div>
</div>
<?php
} //end if
}
/**
* Enqueue styles.
*
* @since 2.7.2
* @return void
*/
public function enqueue_styles() {
// Check if assets should be excluded for the current post type.
if ( UAGB_Admin_Helper::should_exclude_assets_for_cpt() ) {
return; // Early return to prevent loading assets.
}
$screen = get_current_screen();
if ( empty( $screen->id ) || 'plugins' !== $screen->id ) {
return;
}
wp_enqueue_style( 'uagb-update-notice', UAGB_URL . 'admin/assets/css/update-notice.css', array(), UAGB_VER );
}
}
/**
* Kicking this off by calling 'get_instance()' method
*/
UAGB_Update::get_instance();
endif;

View File

@@ -0,0 +1,120 @@
<?php
/**
* UAGB Visibility.
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* Class UAGB_Visibility.
*/
class UAGB_Visibility {
/**
* Member Variable
*
* @since 2.8.0
* @var UAGB_Visibility|null
*/
private static $instance;
/**
* Initiator
*
* @since 2.8.0
* @return UAGB_Visibility
*/
public static function get_instance() {
if ( ! isset( self::$instance ) || null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor
*/
public function __construct() {
$visibility = UAGB_Admin_Helper::get_admin_settings_option( 'uag_visibility_mode', 'disabled' );
$visibility_page_id = UAGB_Admin_Helper::get_admin_settings_option( 'uag_visibility_page', false );
if ( 'disabled' !== $visibility && ! is_user_logged_in() && false !== $visibility_page_id && isset( $visibility_page_id ) && ! empty( $visibility_page_id ) ) {
add_action( 'template_redirect', array( $this, 'set_visibility_page' ), 99 );
add_filter( 'template_include', array( $this, 'set_visibility_template' ), 99 );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_asset_files' ) );
}
}
/**
* Set Visibility Template.
*
* @since 2.8.0
*
* @return string Template file path.
*/
public function set_visibility_template() {
return UAGB_DIR . 'templates/visibility-template.php';
}
/**
* Set Visibility Page.
*
* @since 2.8.0
*
* @return void
*/
public function set_visibility_page() {
$visibility_page_id = intval( UAGB_Admin_Helper::get_admin_settings_option( 'uag_visibility_page', false ) );
$current_page_id = get_the_ID();
if ( $visibility_page_id !== $current_page_id && 'publish' === get_post_status( $visibility_page_id ) ) {
$maintenance = UAGB_Admin_Helper::get_admin_settings_option( 'uag_visibility_mode', 'disabled' );
if ( 'maintenance' === $maintenance ) {
status_header( 503 );
}
// Output JavaScript for redirection.
echo '<script type="text/javascript">window.location.href = "' . esc_url( get_page_link( $visibility_page_id ) ) . '";</script>';
// Exit to prevent further processing.
exit();
}
}
/**
* Enqueue asset files.
*
* @since 2.8.0
*/
public function enqueue_asset_files() {
// Check if assets should be excluded for the current post type.
if ( UAGB_Admin_Helper::should_exclude_assets_for_cpt() ) {
return; // Early return to prevent loading assets.
}
$current_page_id = get_the_ID();
$visibility_page_id = intval( UAGB_Admin_Helper::get_admin_settings_option( 'uag_visibility_page', false ) );
if ( $visibility_page_id === $current_page_id ) {
wp_enqueue_style(
'uagb-style-visibility', // Handle.
UAGB_URL . 'assets/css/visibility.min.css',
array(),
UAGB_VER
);
}
}
}
/**
* Prepare if class 'UAGB_Visibility' exist.
* Kicking this off by calling 'get_instance()' method
*/
UAGB_Visibility::get_instance();

View File

@@ -0,0 +1,52 @@
<?php
/**
* Spectra Regenerate Assets Command.
*
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'Spectra_Regenerate_Assets_Command' ) ) {
/**
* Class Spectra_Regenerate_Assets_Command
*/
class Spectra_Regenerate_Assets_Command {
/**
* Regenerates Spectra CSS files.
*
* EXAMPLES: wp spectra regenerate-css
*
* @since 2.19.9
*
* @param array $args Positional arguments.
* @param array $assoc_args Associative arguments.
* @return void
*/
public function regenerate_assets( $args, $assoc_args ) {
try {
/* Update the asset version */
\UAGB_Admin_Helper::create_specific_stylesheet();
\UAGB_Admin_Helper::update_admin_settings_option( '__uagb_asset_version', time() );
WP_CLI::success( 'Assets regenerated successfully!' );
} catch ( Exception $e ) {
WP_CLI::error( 'Error: ' . $e->getMessage() );
return;
}
}
}
// Register the command to regenerate assets.
WP_CLI::add_command( 'spectra regenerate-css', array( 'Spectra_Regenerate_Assets_Command', 'regenerate_assets' ) );
}

View File

@@ -0,0 +1,357 @@
<?php
/**
* Spectra block migrator.
*
* Class to execute cron event when the plugin is updated.
*
* @since 2.13.9
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'Uagb_Background_Process' ) ) {
require_once UAGB_DIR . 'classes/migration/class-uagb-background-process.php';
}
/**
* Spectra_Update_Features.
*
* @package UAGB
* @since 2.13.9
*/
class Spectra_Migrate_Blocks {
/**
* Member Variable
*
* @since 2.13.9
* @var Spectra_Migrate_Blocks
*/
private static $instance;
/**
* Info Box Mapping Array
*
* @var array<string,array<string,bool|int>> $info_box_mapping
*/
public static $info_box_mapping;
/**
* Advanced Heading Mapping Array
*
* @var array<string,array<string,bool|string>> $advanced_heading_mapping
*/
public static $advanced_heading_mapping;
/**
* Migration process instance.
*
* @var Uagb_Background_Process
*/
public $migration_process;
/**
* Initiator
*
* @since 2.13.9
* @return Spectra_Migrate_Blocks
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Constructor function.
*
* @since 2.13.9
*/
public function __construct() {
self::$info_box_mapping = array(
'imageWidth' => array(
'old' => 120,
),
);
self::$advanced_heading_mapping = array(
'headingAlign' => array(
'old' => 'center',
'new' => 'left',
),
'headingDescToggle' => array(
'old' => true,
'new' => false,
),
);
// Initialize the background process handler.
$this->migration_process = new Uagb_Background_Process();
add_action( 'spectra_blocks_migration_event', array( $this, 'blocks_migration' ) );
add_action( 'admin_init', array( $this, 'query_migrate_to_new' ) );
add_action( 'wp_ajax_check_migration_status', array( $this, 'check_migration_status' ) );
add_action( 'wp_ajax_nopriv_check_migration_status', array( $this, 'check_migration_status' ) );
if ( 'yes' === get_option( 'uag_migration_status', 'no' ) && 'yes' === get_option( 'uagb-old-user-less-than-2', false ) ) {
add_action( 'admin_footer', array( $this, 'add_migration_status_script' ) );
$this->migrate_blocks();
}
}
/**
* Trigger migration via query parameter.
*
* @since 2.13.9
* @return void
*/
public function query_migrate_to_new() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
// Sanitize and check if the nonce is valid.
$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( $_POST['nonce'] ) : '';
if ( ! wp_verify_nonce( $nonce, 'wp_spectra_blocks_migration' ) ) {
$migrate_to_new = isset( $_GET['migrate_to_new'] ) ? sanitize_text_field( $_GET['migrate_to_new'] ) : false;
if ( 'yes' === $migrate_to_new ) {
spectra_log( 'Migration triggered via query parameter by an authorized user.' );
$this->migrate_blocks();
}
}
}
/**
* Schedule and run blocks migration.
*
* @since 2.13.9
* @return void
*/
public function migrate_blocks() {
if ( 'yes' !== get_option( 'uagb-old-user-less-than-2', false ) ) {
return;
}
if ( ! wp_next_scheduled( 'spectra_blocks_migration_event' ) ) {
wp_schedule_single_event( time(), 'spectra_blocks_migration_event' );
}
update_option( 'uag_enable_legacy_blocks', 'yes' );
update_option( 'uag_load_font_awesome_5', 'enabled' );
}
/**
* Execute blocks migration process.
*
* @since 2.13.9
* @return void
*/
public function blocks_migration() {
$posts_per_page = 100;
$page = 1;
$post_types = get_post_types( array( 'public' => true ), 'names' );
do {
$query = new WP_Query(
array(
'post_type' => $post_types,
'post_status' => 'any',
'posts_per_page' => $posts_per_page,
'paged' => $page,
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Reason: Necessary for migration process.
'meta_query' => array(
array(
'key' => '_uag_migration_processed',
'compare' => 'NOT EXISTS',
),
),
)
);
foreach ( $query->posts as $post ) {
if ( ! $post instanceof WP_Post ) {
spectra_log( 'Skipped post ID: ' . ( is_object( $post ) ? $post->ID : 'Invalid post type' ) );
continue;
}
$this->migration_process->push_to_queue( $post->ID );
spectra_log( 'Queued post ID: ' . ( is_object( $post ) ? $post->ID : 'Invalid post type' ) );
}
$page++;
} while ( $query->max_num_pages >= $page );
$this->migration_process->save()->dispatch();
}
/**
* Check the status of the migration process.
*
* @since 2.13.9
* @return void
*/
public function check_migration_status() {
// Sanitize and check if the nonce is valid.
$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( $_POST['nonce'] ) : '';
if ( ! wp_verify_nonce( $nonce, 'check_migration_status_nonce' ) ) {
wp_send_json_error(
array(
'status' => 'fail',
'type' => 'error',
'msg' => 'Invalid nonce',
)
);
return;
}
$migration_complete = get_option( 'uag_migration_complete', 'no' );
$migration_needs_reload = get_transient( 'uag_migration_needs_reload' ) ? 'yes' : 'no';
// If migration is complete and reload is needed, delete the transient to avoid repeated reloads.
if ( 'yes' === $migration_complete && 'yes' === $migration_needs_reload ) {
delete_transient( 'uag_migration_needs_reload' );
}
// Check if the migration status retrieval failed.
if ( 'fail' === $migration_complete ) {
wp_send_json_error(
array(
'status' => 'fail',
'type' => 'error',
'msg' => "We couldn't catch current tasks, please try again",
)
);
} else {
wp_send_json_success(
array(
'complete' => $migration_complete,
'reload' => $migration_needs_reload,
)
);
}
}
/**
* Add migration status checking script to admin footer.
*
* @since 2.13.9
* @return void
*/
public function add_migration_status_script() {
$ajax_nonce = wp_create_nonce( 'check_migration_status_nonce' );
?>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
let reloadDone = false; // Flag to track if reload has been done.
function checkMigrationStatus() {
if (reloadDone) {
return; // Exit function if reloadDone is true.
}
fetch('<?php echo esc_html( admin_url( 'admin-ajax.php' ) ); ?>', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
action: 'check_migration_status',
nonce: '<?php echo esc_js( $ajax_nonce ); ?>',
}),
})
.then(response => response.json())
.then(data => {
if ( data.success ) {
if ( data.data.reload === 'yes' ) {
reloadDone = true; // Set reloadDone flag to true.
location.reload();
} else {
setTimeout(checkMigrationStatus, 10000); // Retry after 10 seconds.
}
} else {
console.error('Error:', data);
setTimeout(checkMigrationStatus, 10000); // Retry after 10 seconds.
}
})
.catch(error => {
console.error('Fetch error:', error);
setTimeout(checkMigrationStatus, 10000); // Retry after 10 seconds.
});
}
checkMigrationStatus(); // Initial call to start checking.
});
</script>
<?php
}
/**
* Update the content blocks.
*
* @since 2.13.9
* @param string $content Content to be updated.
* @return array<string|string> Array of whether migration is required, and the updated content.
*/
public function get_updated_content( $content ) {
$is_migration_needed = false;
$blocks = parse_blocks( $content );
$blocks = $this->get_updated_blocks( $blocks, $is_migration_needed );
return array(
'requires_migration' => $is_migration_needed,
'content' => serialize_blocks( $blocks ),
);
}
/**
* Update blocks with new attributes.
*
* @param array $blocks Blocks to be updated.
* @param boolean $is_migration_needed Whether the page needs migration or not.
* @since 2.13.9
* @return array Updated blocks.
*/
public function get_updated_blocks( array $blocks, &$is_migration_needed ) {
foreach ( $blocks as &$block ) {
if ( ! empty( $block['innerBlocks'] ) ) {
$block['innerBlocks'] = $this->get_updated_blocks( $block['innerBlocks'], $is_migration_needed );
} else {
if ( ! isset( $block['blockName'] ) ) {
continue;
}
if ( 'uagb/info-box' === $block['blockName'] ) {
$is_migration_needed = true;
$attributes = $block['attrs'];
foreach ( self::$info_box_mapping as $key => $value ) {
if ( ! isset( $attributes[ $key ] ) ) { // Meaning this is set to default, so no need to update.
$attributes[ $key ] = $value['old'];
}
}
$block['attrs'] = $attributes;
}
if ( 'uagb/advanced-heading' === $block['blockName'] ) {
$is_migration_needed = true;
$attributes = $block['attrs'];
foreach ( self::$advanced_heading_mapping as $key => $value ) {
if ( ! isset( $attributes[ $key ] ) ) { // Meaning this is set to default, so no need to update.
$attributes[ $key ] = $value['old'];
}
}
$block['attrs'] = $attributes;
}
}
}
return $blocks;
}
}
/**
* Prepare if class 'UAGB_Init_Blocks' exist.
* Kicking this off by calling 'get_instance()' method.
*
* @since 2.13.9
*/
Spectra_Migrate_Blocks::get_instance();
?>

View File

@@ -0,0 +1,162 @@
<?php
/**
* Spectra block migrator.
*
* Class to execute cron event when the plugin is updated.
*
* @since 2.13.9
* @package UAGB
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'WP_Async_Request' ) ) {
require_once UAGB_DIR . 'lib/batch-processing/class-wp-async-request.php';
}
if ( ! class_exists( 'WP_Background_Process' ) ) {
require_once UAGB_DIR . 'lib/batch-processing/class-wp-background-process.php';
}
/**
* Spectra migration log.
*
* @since 2.13.9
* @package UAGB
*
* @param string $message The message to log.
* @return void
*/
function spectra_log( $message ) {
$log_file = ABSPATH . 'wp-content/uploads/migration-log.txt';
$file = fopen( $log_file, 'a' ); //phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fopen
if ( $file ) {
fwrite( $file, gmdate( 'Y-m-d H:i:s' ) . ' - ' . $message . PHP_EOL ); //phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_fwrite
fclose( $file ); // Close the file after writing.
}
}
/**
* Prevents the modification of the post modified date.
*
* This function ensures that the post modified date is not updated.
*
* @param array $new The new post data.
* @param array $old The old post data.
* @since 2.14.1
* @return array The modified post data with the original modified date.
*/
function spectra_stop_modified_date_update( $new, $old ) {
$new['post_modified'] = $old['post_modified'];
$new['post_modified_gmt'] = $old['post_modified_gmt'];
return $new;
}
if ( ! class_exists( 'class_spectra_migrate_blocks' ) ) {
/**
* Class Uagb_Background_Process
*
* Handles background processing for block migrations.
*
* @since 2.13.9
* @package UAGB
*/
class Uagb_Background_Process extends WP_Background_Process {
/**
* Action name.
*
* @var string
*/
protected $action = 'spectra_blocks_migration';
/**
* Task to be performed for each post.
*
* @param int $post_id Post ID to be processed.
* @return bool|mixed False if the task is complete, or the post ID for further processing.
*/
protected function task( $post_id ) {
if ( get_post_meta( $post_id, '_uag_migration_processed', true ) ) {
spectra_log( 'Skipping already processed post ID: ' . $post_id );
return false;
}
$post = get_post( $post_id );
if ( ! is_object( $post ) || ! is_a( $post, 'WP_Post' ) ) {
return false;
}
$migration_details = Spectra_Migrate_Blocks::get_instance()->get_updated_content( $post->post_content );
// Only update when the post needs to be updated - if it has any blocks that needed to be migrated.
if ( ! empty( $migration_details['requires_migration'] ) && ! empty( $migration_details['content'] ) && is_string( $migration_details['content'] ) ) {
add_filter( 'wp_insert_post_data', 'spectra_stop_modified_date_update', 99999, 2 );
$updated_post_id = wp_update_post(
array(
'ID' => $post->ID,
'post_content' => wp_slash( $migration_details['content'] ),
)
);
remove_filter( 'wp_insert_post_data', 'spectra_stop_modified_date_update', 99999 );
// If the Post ID is correct ( which means the update was successful ) - Update the Post Meta and add to the log.
if ( ! empty( $updated_post_id ) ) {
update_post_meta( $post->ID, '_uag_migration_processed', '1' );
spectra_log( 'Migration processed post ID: ' . $updated_post_id );
} else {
spectra_log( 'Migration not processed for post ID: ' . $post_id );
}
} else {
update_post_meta( $post->ID, '_uag_migration_processed', '1' );
spectra_log( 'Migration not required for post ID: ' . $post_id );
}
return false;
}
/**
* Complete the migration process.
*
* @since 2.13.9
* @return void
*/
protected function complete() {
parent::complete();
$post_types = get_post_types( array( 'public' => true ), 'names' );
$query = new WP_Query(
array(
'post_type' => $post_types,
'post_status' => 'any',
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Reason: Necessary for migration process.
'meta_query' => array(
array(
'key' => '_uag_migration_processed',
'compare' => 'NOT EXISTS',
),
),
)
);
if ( ! $query->have_posts() ) {
// Delete the option once the migration progress is complete as it is not required.
delete_option( 'uag_migration_progress_status' );
update_option( 'uag_migration_complete', 'yes' );
delete_option( 'uagb-old-user-less-than-2' );
spectra_log( 'End of blocks migration' );
set_transient( 'uag_migration_needs_reload', true );
} else {
update_option( 'uag_migration_complete', 'no' );
}
}
}
}

File diff suppressed because it is too large Load Diff