self::getCurrentLanguage() ]; // Add Buttonizer page data if (Settings::getSetting("include_page_data", false)) { // Get page categories $pageCategories = array_map(function ($category) { return $category->cat_ID; }, get_the_category()); // Collect page data $pageData = array_merge([ "page_id" => get_the_ID(), "categories" => $pageCategories, "is_frontpage" => is_front_page(), "is_404" => is_404(), "user_roles" => PermissionCheck::getUserRoles() ], $pageData); } // Define page data $buttonizerData = "if(!window._buttonizer) { window._buttonizer = {}; };var _buttonizer_page_data = " . wp_json_encode($pageData) . ";window._buttonizer.data = { ..._buttonizer_page_data, ...window._buttonizer.data };"; echo ''; } /** * Inject the Buttonizer CDN embed script into wp_footer. * * Respects the `wait_until_consent` GDPR setting. */ public static function injectEmbedScript(): void { if (!Settings::getSetting("site_id")) return; // Buttonizer integration script $buttonizerSnippet = "(function(n,t,c,d){if(t.getElementById(d)){return}var o=t.createElement('script');o.id=d;(o.async=!0),(o.src='https://cdn.buttonizer.io/embed.js'),(o.onload=function(){window.Buttonizer?window.Buttonizer.init(c):window.addEventListener('buttonizer_script_loaded',()=>window.Buttonizer.init(c))}),t.head.appendChild(o)})(window,document,'" . Settings::getSetting("site_id") . "','buttonizer_script')"; // GDPR Compliance check if (Settings::getSetting("wait_until_consent", false)) { $buttonizerSnippet = "// Buttonizer snippet container function enableButtonizer() {" . $buttonizerSnippet . "}; // Buttonizer consent given, load content if(window.buttonizer_consent_given){ enableButtonizer(); }"; } echo ''; } /** * Validate a UUID v4 string. * * @param string $uuid The string to validate. * * @return bool True if valid UUID v4. */ public static function isValidUUID(string $uuid): bool { $regex = '/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/'; return (bool) preg_match($regex, $uuid); } /** * Buttonizer inline widget shortcode handler. * * Usage: [buttonizer id="uuid-here"] * * @param array $atts Shortcode attributes. * * @return string Widget HTML or empty string. */ public static function widgetShortcode($atts): string { // Get attributes $atts = shortcode_atts( array( 'id' => '', ), $atts ); // Make sure the ID exists and is a valid UUID if (!isset($atts['id']) || !is_string($atts['id']) || !self::isValidUUID($atts['id'])) return ""; return '
'; } /** * Boot all shared WordPress hooks for the plugin. * * Call this from the plugin's init.php after the legacy check (if any). * * @param string $adminClass Fully qualified class name for the plugin's Admin class. * @param string $apiClass Fully qualified class name for the plugin's Api class. */ public static function boot(string $adminClass, string $apiClass): void { // Admin dashboard if (is_admin()) { new $adminClass(); } // Redirect to page in correct language add_action('template_redirect', [self::class, 'redirectToPage'], 0); // Page data injection (wp_head) add_action('wp_head', [self::class, 'injectPageData'], 10); // Embed script injection (wp_footer) add_action('wp_footer', [self::class, 'injectEmbedScript'], 11); // Widget shortcode add_action('init', function () { if (!shortcode_exists("buttonizer")) { add_shortcode('buttonizer', [self::class, 'widgetShortcode']); } }); // Admin bar add_action('admin_bar_menu', function ($bar) use ($adminClass) { $adminClass::wordpressAdminBar($bar); }, 100); // REST API endpoints add_action('rest_api_init', function () use ($apiClass) { new $apiClass(); }); } }