HEX
Server: Apache
System: Linux p102.lithium.hosting 4.18.0-553.141.1.el8_10.x86_64 #1 SMP Fri Jul 10 17:48:02 UTC 2026 x86_64
User: bvzmoamr (9955)
PHP: 8.1.34
Disabled: syslog
Upload Files
File: /var/www/html/wp-content/plugins/widget-options/includes/snippets/class-snippets-api.php
<?php
/**
 * Display Logic Snippets - API
 *
 * Provides AJAX endpoints and helper functions for accessing snippets
 * from various editors (widgets, Gutenberg, Elementor, etc.)
 *
 * @copyright   Copyright (c) 2024, Widget Options Team
 * @since       5.1
 */

// Exit if accessed directly
if (!defined('ABSPATH')) exit;

/**
 * Class WidgetOpts_Snippets_API
 * 
 * Handles API endpoints and data retrieval for snippets
 */
class WidgetOpts_Snippets_API {

    /**
     * Initialize the API
     */
    public static function init() {
        // AJAX endpoints
        add_action('wp_ajax_widgetopts_get_snippets', array(__CLASS__, 'ajax_get_snippets'));
        
        // Localize script data
        add_action('admin_enqueue_scripts', array(__CLASS__, 'localize_snippets_data'));
    }

    /**
     * AJAX handler to get all snippets
     */
    public static function ajax_get_snippets() {
        // Check if user can edit widgets
        if (!current_user_can('edit_theme_options')) {
            wp_send_json_error(array('message' => __('Permission denied.', 'widget-options')));
        }

        $snippets = WidgetOpts_Snippets_CPT::get_all_snippets();
        
        // Format for Select2 / dropdown
        $formatted = array(
            array(
                'id'    => '',
                'text'  => __('— No Logic —', 'widget-options'),
            )
        );

        foreach ($snippets as $snippet) {
            $formatted[] = array(
                'id'          => $snippet['id'],
                'text'        => $snippet['title'],
                'description' => $snippet['description'],
            );
        }

        wp_send_json_success($formatted);
    }

    /**
     * Localize snippets data for JavaScript
     */
    public static function localize_snippets_data($hook) {
        // Only on widgets page and customizer
        if (!in_array($hook, array('widgets.php', 'customize.php', 'post.php', 'post-new.php'))) {
            return;
        }

        $snippets = WidgetOpts_Snippets_CPT::get_all_snippets();
        
        $formatted = array(
            array(
                'id'          => '',
                'title'       => __('— No Logic —', 'widget-options'),
                'description' => '',
            )
        );

        foreach ($snippets as $snippet) {
            $formatted[] = array(
                'id'          => $snippet['id'],
                'title'       => $snippet['title'],
                'description' => $snippet['description'],
            );
        }

        wp_localize_script('jquery', 'widgetoptsSnippets', array(
            'snippets' => $formatted,
            'nonce'    => wp_create_nonce('widgetopts_snippets'),
            'strings'  => array(
                'selectSnippet' => __('Select Logic Snippet', 'widget-options'),
                'noLogic'       => __('— No Logic —', 'widget-options'),
                'search'        => __('Search snippets...', 'widget-options'),
            ),
        ));
    }

    /**
     * Get snippets for dropdown (non-AJAX)
     * 
     * @return array Array of snippets formatted for dropdown
     */
    public static function get_snippets_for_dropdown() {
        $snippets = WidgetOpts_Snippets_CPT::get_all_snippets();
        
        $options = array(
            '' => __('— No Logic —', 'widget-options'),
        );

        foreach ($snippets as $snippet) {
            $options[$snippet['id']] = $snippet['title'];
        }

        return $options;
    }

    /**
     * Execute snippet logic by ID
     * 
     * @param int $snippet_id Snippet post ID
     * @return bool|null True to show, false to hide, null if snippet not found
     */
    public static function execute_snippet($snippet_id) {
        if (empty($snippet_id)) {
            return null;
        }

        $code = WidgetOpts_Snippets_CPT::get_snippet_code($snippet_id);
        
        if ($code === false) {
            return null;
        }

        // Apply legacy filters for backward compatibility
        $code = apply_filters('widget_options_logic_override', $code);
        $code = apply_filters('extended_widget_options_logic_override', $code);

        // Handle filter returns
        if ($code === false) {
            return false;
        }
        if ($code === true) {
            return true;
        }

        // Decode and execute
        $code = htmlspecialchars_decode($code, ENT_QUOTES);

        if (function_exists('widgetopts_safe_eval_trusted')) {
            return widgetopts_safe_eval_trusted($code);
        }
        if (function_exists('widgetopts_safe_eval')) {
            return widgetopts_safe_eval($code);
        }

        return null;
    }

    /**
     * Get snippet ID from widget options (with backward compatibility)
     * 
     * Checks for new snippet_id field, falls back to legacy logic field
     * 
     * @param array $opts Widget options array
     * @param string $editor Editor type (classic, elementor, beaver, siteorigin)
     * @return int|string|null Snippet ID, legacy code, or null
     */
    public static function get_logic_from_opts($opts, $editor = 'classic') {
        switch ($editor) {
            case 'elementor':
                // New format
                if (isset($opts['widgetopts_logic_snippet_id']) && !empty($opts['widgetopts_logic_snippet_id'])) {
                    return array('type' => 'snippet', 'value' => $opts['widgetopts_logic_snippet_id']);
                }
                // Legacy format (should not exist after migration, but keep for safety)
                if (isset($opts['widgetopts_logic']) && !empty($opts['widgetopts_logic'])) {
                    return array('type' => 'legacy', 'value' => $opts['widgetopts_logic']);
                }
                break;

            case 'beaver':
                // New format
                if (isset($opts->widgetopts_logic_snippet_id) && !empty($opts->widgetopts_logic_snippet_id)) {
                    return array('type' => 'snippet', 'value' => $opts->widgetopts_logic_snippet_id);
                }
                // Legacy format
                if (isset($opts->widgetopts_settings_logic) && !empty($opts->widgetopts_settings_logic)) {
                    return array('type' => 'legacy', 'value' => $opts->widgetopts_settings_logic);
                }
                break;

            case 'siteorigin':
            case 'classic':
            default:
                // New format
                if (isset($opts['class']['logic_snippet_id']) && !empty($opts['class']['logic_snippet_id'])) {
                    return array('type' => 'snippet', 'value' => $opts['class']['logic_snippet_id']);
                }
                // Legacy format
                if (isset($opts['class']['logic']) && !empty($opts['class']['logic'])) {
                    return array('type' => 'legacy', 'value' => $opts['class']['logic']);
                }
                break;
        }

        return null;
    }

    /**
     * Process display logic and return visibility
     * 
     * @param array|object $opts Widget options
     * @param string $editor Editor type
     * @return bool|null True to show, false to hide, null if no logic
     */
    public static function process_display_logic($opts, $editor = 'classic') {
        $logic = self::get_logic_from_opts($opts, $editor);

        if ($logic === null) {
            return null; // No logic defined
        }

        if ($logic['type'] === 'snippet') {
            return self::execute_snippet($logic['value']);
        }

        // Legacy code execution (for backward compatibility during transition)
        if ($logic['type'] === 'legacy') {
            $code = stripslashes(trim($logic['value']));
            $code = apply_filters('widget_options_logic_override', $code);
            $code = apply_filters('extended_widget_options_logic_override', $code);

            if ($code === false) {
                return false;
            }
            if ($code === true) {
                return true;
            }

            $code = htmlspecialchars_decode($code, ENT_QUOTES);

            if (function_exists('widgetopts_safe_eval_trusted')) {
                return widgetopts_safe_eval_trusted($code);
            }
            if (function_exists('widgetopts_safe_eval')) {
                return widgetopts_safe_eval($code);
            }
        }

        return null;
    }
}

// Initialize
WidgetOpts_Snippets_API::init();