<?php // functions.php

function dbmo_unautop_slides($content) {
    $content = preg_replace('%<p>\s*(<div class="et_pb_slide .*?</div> <!-- .et_pb_slide -->\s*)</p>%s', '\\1', $content);
    $content = preg_replace('%<p>\s*(<div class="et_pb_slide .*?</div>\s*)</p>%s', '\\1', $content);
    return $content;
}

// === Builder detection === //

// Try to detect if in context of a divi builder
// - $builder_type is one of:
// -- any
// -- visual (= frontend or backend), 
// -- classic
// -- frontend (= original visual builder)
// -- backend (= "New Divi Experience" builder)

function db_is_divi_builder($builder_type = 'any') {

    // Either visual builder (frontend or backend)
    if (isset($_GET['et_fb']) && $_GET['et_fb'] && in_array($builder_type, array('any', 'visual'))) {
        return true;
    }

    // Backend builder
    if (isset($_GET['et_bfb']) && $_GET['et_bfb'] && in_array($builder_type, array('any', 'backend'))) {
        return true;
    }

    return false; // Unable to determine builder use
}

// Get Divi Booster setting 
if (!function_exists('dbdb_option')) {
    function dbdb_option($feature, $setting, $default = false) {
        $option = get_option(BOOSTER_SLUG_OLD, $default);
        $val = $default;

        // Some sites can end up with a corrupted option value (e.g. an object like
        // __PHP_Incomplete_Class) which would fatal if accessed as an array.
        // Treat anything other than an array as "no saved settings".
        if (is_array($option) && isset($option['fixes'][$feature][$setting])) {
            $val = $option['fixes'][$feature][$setting];
        }

        $val = apply_filters("divibooster_setting_{$feature}_{$setting}", $val);
        return $val;
    }
}

if (!function_exists('dbdb_enabled')) {
    function dbdb_enabled($feature_slug) {
        $enabled = dbdb_option($feature_slug, 'enabled', false);
        return apply_filters('dbdb_enabled', $enabled, $feature_slug);
    }
}

if (!function_exists('dbdb_is_pagebuilder_used')) {
    function dbdb_is_pagebuilder_used($post_id = 0) {
        return (function_exists('et_pb_is_pagebuilder_used') && et_pb_is_pagebuilder_used($post_id));
    }
}

if (!function_exists('dbdb_get_current_post_id')) {
    function dbdb_get_current_post_id() {
        global $post;
        if (isset($post) && is_object($post) && property_exists($post, 'ID')) {
            return $post->ID;
        }
        return false;
    }
}

// Get the order class from a list of module classes
// Return false if no order class found
function divibooster_get_order_class_from_content($module_slug, $content) {
    $classes = divibooster_get_classes_from_content($content);
    foreach ($classes as $class) {
        if (preg_match("#^{$module_slug}_\d+$#", $class)) {
            return $class;
        }
        if (preg_match("#^{$module_slug}_\d_tb_header$#", $class)) {
            return $class;
        }
        if (preg_match("#^{$module_slug}_\d_tb_footer$#", $class)) {
            return $class;
        }
    }
    return false;
}

// get the classes assigned to the module
function divibooster_get_classes_from_content($content) {
    preg_match('#<div [^>]*class="([^"]*?et_pb_module [^"]*?)">#', $content, $m);
    $classes = empty($m[1]) ? array() : explode(' ', $m[1]);
    return $classes;
}

function dbdb_setting_group_classes($is_subheading) {
    return "wtf-setting-group " . ($is_subheading ? 'wtf-subheading-group' : '');
}


if (!function_exists('dbdb_admin_menu_slug')) {
    function dbdb_admin_menu_slug() {
        if (dbdb_is_divi_2_4_up()) { // Recent Divis
            $result = 'et_divi_options';
        } elseif (dbdb_is_divi()) { // Early Divis
            $result = 'themes.php';
        } elseif (dbdb_is_extra()) { // Extra
            $result = 'et_extra_options';
        } else { // Assume Divi Builder
            $result = 'et_divi_options';
        }
        return $result;
    }
}

if (!function_exists('dbdb_settings_page_url')) {
    function dbdb_settings_page_url() {
        $page = (dbdb_admin_menu_slug() == 'themes.php' ? 'themes.php' : 'admin.php');
        return admin_url($page . '?page=wtfdivi_settings');
    }
}

if (!function_exists('dbdb_is_divi5_visual_builder_context')) {
    function dbdb_is_divi5_visual_builder_context() {
        $is_d5 = function_exists('et_builder_d5_enabled') && et_builder_d5_enabled();
        $is_fb = function_exists('et_core_is_fb_enabled') && et_core_is_fb_enabled();
        return $is_d5 && $is_fb;
    }
}

if (!function_exists('dbdb_resolve_registered_script_dependencies')) {
    /**
     * Resolve script dependencies from a list containing either:
     * - a script handle string, or
     * - an array of alternative handles (first registered one wins).
     */
    function dbdb_resolve_registered_script_dependencies($deps) {
        $resolved = array();
        $missing  = array();

        if (!is_array($deps) || !function_exists('wp_script_is')) {
            return array('resolved' => $resolved, 'missing' => $missing);
        }

        foreach ($deps as $dep) {
            if (is_array($dep)) {
                $chosen = '';
                foreach ($dep as $candidate) {
                    if (is_string($candidate) && $candidate !== '' && wp_script_is($candidate, 'registered')) {
                        $chosen = $candidate;
                        break;
                    }
                }
                if ($chosen !== '') {
                    $resolved[] = $chosen;
                } else {
                    $missing[] = implode('|', array_map('strval', $dep));
                }
                continue;
            }

            if (!is_string($dep) || $dep === '') {
                continue;
            }

            if (wp_script_is($dep, 'registered')) {
                $resolved[] = $dep;
            } else {
                $missing[] = $dep;
            }
        }

        return array(
            'resolved' => array_values(array_unique($resolved)),
            'missing'  => array_values(array_unique($missing)),
        );
    }
}

if (!function_exists('dbdb_enqueue_inline_script_if_dependencies_available')) {
    /**
     * Enqueue a handle-less inline script only when all dependencies can be resolved.
     * If called before Divi has enqueued app window scripts, defer once to that hook.
     * Use $load_before to attach the code before a Divi package initializes.
     */
    function dbdb_enqueue_inline_script_if_dependencies_available($handle, $inline_script, $deps = array(array('divi-vendor-wp-hooks', 'wp-hooks')), $position = 'after', $load_before = array()) {
        if (!is_string($handle) || $handle === '') {
            return false;
        }

        if (!function_exists('wp_register_script') || !function_exists('wp_enqueue_script') || !function_exists('wp_add_inline_script')) {
            return false;
        }

        if (!dbdb_is_divi5_visual_builder_context()) {
            return false;
        }

        $app_window_hook = 'divi_visual_builder_assets_before_enqueue_app_window_scripts';

        if (function_exists('did_action') && !did_action($app_window_hook) && function_exists('add_action')) {
            static $deferred = array();
            $encoded_deps = function_exists('wp_json_encode') ? wp_json_encode($deps) : serialize($deps);
            $encoded_load_before = function_exists('wp_json_encode') ? wp_json_encode($load_before) : serialize($load_before);
            $defer_key = md5($handle . '|' . $encoded_deps . '|' . md5((string) $inline_script) . '|' . (string) $position . '|' . $encoded_load_before);

            if (empty($deferred[$defer_key])) {
                $deferred[$defer_key] = true;

                add_action(
                    $app_window_hook,
                    static function () use ($handle, $inline_script, $deps, $position, $load_before) {
                        dbdb_enqueue_inline_script_if_dependencies_available($handle, $inline_script, $deps, $position, $load_before);
                    },
                    1000
                );
            }

            return false;
        }

        // Attach filters which must run before a Divi package directly to that
        // package. PackageBuildManager registers its script handles between the
        // before/after enqueue hooks, so wait for the latter when necessary.
        if (!empty($load_before) && is_array($load_before)) {
            foreach ($load_before as $later_handle) {
                if (is_string($later_handle) && wp_script_is($later_handle, 'registered')) {
                    return wp_add_inline_script($later_handle, (string) $inline_script, 'before');
                }
            }

            $after_app_window_hook = 'divi_visual_builder_assets_after_enqueue_app_window_scripts';
            if (function_exists('did_action') && !did_action($after_app_window_hook) && function_exists('add_action')) {
                static $load_before_deferred = array();
                $encoded_load_before = function_exists('wp_json_encode') ? wp_json_encode($load_before) : serialize($load_before);
                $defer_key = md5($handle . '|' . md5((string) $inline_script) . '|' . $encoded_load_before);

                if (empty($load_before_deferred[$defer_key])) {
                    $load_before_deferred[$defer_key] = true;
                    add_action(
                        $after_app_window_hook,
                        static function () use ($handle, $inline_script, $deps, $position, $load_before) {
                            dbdb_enqueue_inline_script_if_dependencies_available($handle, $inline_script, $deps, $position, $load_before);
                        },
                        1000
                    );
                }

                return false;
            }
        }

        $dependency_status = dbdb_resolve_registered_script_dependencies($deps);
        $resolved_deps     = $dependency_status['resolved'];
        $missing_deps      = $dependency_status['missing'];

        if (!empty($missing_deps)) {
            return false;
        }

        if (!wp_script_is($handle, 'registered')) {
            wp_register_script($handle, '', $resolved_deps, null, true);
        }

        if (!wp_script_is($handle, 'enqueued')) {
            wp_enqueue_script($handle);
        }

        $position = ($position === 'before') ? 'before' : 'after';
        wp_add_inline_script($handle, (string) $inline_script, $position);

        return true;
    }
}
