setup_error_handling(); $this->load_includes(); add_action('after_setup_theme', [$this, 'setup_theme']); add_action('wp_enqueue_scripts', [$this, 'enqueue_theme_styles']); // Temporarily disable complex features to test basic functionality // add_action('init', [$this, 'register_block_bindings']); // add_action('init', [$this, 'register_pattern_categories']); // add_action('after_setup_theme', [$this, 'enable_image_block_supports']); // Add debugging for admin pages add_action('admin_init', [$this, 'debug_admin_loading']); // Add simple test action to verify theme is loading add_action('init', function() { error_log("Caliph Theme: Theme is loading successfully"); }); // Register layout supports for blocks add_action('init', [$this, 'register_layout_supports']); } /** * Set up error handling to prevent fatal errors. */ private function setup_error_handling() { // Only set up error handling in admin area if (!is_admin()) { return; } // Set up error handler to catch fatal errors set_error_handler(function($errno, $errstr, $errfile, $errline) { // Log the error error_log("Caliph Error: $errstr in $errfile on line $errline"); // Only suppress specific REST API errors if (strpos($errstr, 'get_data()') !== false && strpos($errfile, 'rest-api') !== false) { return true; // Don't execute PHP internal error handler } return false; // Let PHP handle other errors normally }); // Set up exception handler set_exception_handler(function($exception) { error_log("Caliph Exception: " . $exception->getMessage()); // Only suppress specific REST API exceptions if (strpos($exception->getMessage(), 'get_data()') !== false && strpos($exception->getFile(), 'rest-api') !== false) { return; // Don't show the error } // Re-throw other exceptions throw $exception; }); } /** * Debug admin page loading. */ public function debug_admin_loading() { error_log("Caliph Debug: Admin page loading - " . $_SERVER['REQUEST_URI']); // Check if we're on a post edit page if (isset($_GET['post']) && isset($_GET['action']) && $_GET['action'] === 'edit') { error_log("Caliph Debug: Post edit page detected - Post ID: " . $_GET['post']); } } /** * Load necessary files for the theme. * * Includes all required PHP files from the includes directory. */ private function load_includes() { $files = [ 'class-attributes.php', // Handles custom block attributes 'block-styles.php', // Registers custom block styles 'class-enqueue.php', // Handles asset loading 'features/scroll-top.php',// Scroll-to-top feature 'theme-settings.php', // Theme settings ]; foreach ($files as $file) { $path = get_template_directory() . '/includes/' . $file; if (file_exists($path)) { require_once $path; } } } /** * Set up theme features and support. * * Registers theme support for various WordPress features. */ public function setup_theme() { // Load theme text domain for translations load_theme_textdomain('caliph', get_template_directory() . '/languages'); // Add support for post formats add_theme_support( 'post-formats', ['aside', 'audio', 'chat', 'gallery', 'image', 'link', 'quote', 'status', 'video'] ); // Add support for block templates and layout controls add_theme_support('block-templates'); add_theme_support('align-wide'); add_theme_support('wp-block-styles'); add_theme_support('responsive-embeds'); // Add support for layout controls (required for justification) add_theme_support('layout'); add_theme_support('custom-spacing'); } /** * Register layout supports for blocks. * * Adds layout support for columns blocks to enable justification controls. */ public function register_layout_supports() { // Register layout supports for columns blocks add_filter('block_type_metadata', function($metadata) { if (!is_array($metadata) || !isset($metadata['name'])) { return $metadata; } // Add layout support for columns and column blocks if (in_array($metadata['name'], ['core/columns', 'core/column'])) { if (!isset($metadata['supports'])) { $metadata['supports'] = []; } if (!isset($metadata['supports']['layout'])) { $metadata['supports']['layout'] = []; } $metadata['supports']['layout']['allowJustification'] = true; $metadata['supports']['layout']['allowVerticalAlignment'] = true; } return $metadata; }); } /** * Enqueue theme styles. * * Loads the main stylesheet for the theme. */ public function enqueue_theme_styles() { wp_enqueue_style( 'caliph-style', get_parent_theme_file_uri('style.css'), [], wp_get_theme()->get('Version') ); } /** * Register block bindings for dynamic content. * * Sets up custom block bindings for the theme. */ public function register_block_bindings() { register_block_bindings_source( 'caliph/format', [ 'label' => _x('Post format name', 'Label for the block binding placeholder in the editor', 'caliph'), 'get_value_callback' => [$this, 'format_binding_callback'], ] ); } /** * Callback for the post format binding. * * Returns the formatted post format name. * * @return string|null The post format name or null if standard format. */ public function format_binding_callback() { $post_format_slug = get_post_format(); if ($post_format_slug && 'standard' !== $post_format_slug) { return get_post_format_string($post_format_slug); } } /** * Register block pattern categories. * * Creates custom pattern categories for the theme. */ public function register_pattern_categories() { register_block_pattern_category( 'caliph_page', [ 'label' => __('Pages', 'caliph'), 'description' => __('A collection of full page layouts.', 'caliph'), ] ); register_block_pattern_category( 'caliph_post-format', [ 'label' => __('Post formats', 'caliph'), 'description' => __('A collection of post format patterns.', 'caliph'), ] ); } /** * Enable additional block supports for image blocks. * * Adds padding and background color support to image blocks. */ public function enable_image_block_supports() { // Enable padding and background for image blocks add_theme_support('custom-spacing'); add_theme_support('padding'); add_theme_support('margin'); // Register support for background colors on image blocks add_filter('block_type_metadata', function($metadata) { // Ensure metadata is valid if (!is_array($metadata) || !isset($metadata['name']) || $metadata['name'] !== 'core/image') { return $metadata; } // Ensure supports array exists if (!isset($metadata['supports']) || !is_array($metadata['supports'])) { $metadata['supports'] = []; } // Ensure spacing support exists if (!isset($metadata['supports']['spacing']) || !is_array($metadata['supports']['spacing'])) { $metadata['supports']['spacing'] = []; } // Ensure color support exists if (!isset($metadata['supports']['color']) || !is_array($metadata['supports']['color'])) { $metadata['supports']['color'] = []; } $metadata['supports']['spacing']['padding'] = true; $metadata['supports']['spacing']['margin'] = true; $metadata['supports']['color']['background'] = true; return $metadata; }); // Enable the render_block filter for proper image block handling add_filter('render_block', [$this, 'modify_image_block_output'], 10, 2); // Add filter to modify block attributes before rendering add_filter('block_type_metadata', [$this, 'modify_image_block_metadata'], 10, 1); // Add filter to modify block attributes in editor add_filter('block_editor_settings_all', [$this, 'modify_editor_settings'], 10, 2); // Add debugging to identify the source of warnings add_action('init', [$this, 'debug_block_registration'], 999); // Add filter to prevent REST API warnings add_filter('rest_pre_dispatch', [$this, 'prevent_rest_api_warnings'], 10, 3); // Add filter to handle REST API responses and prevent null errors add_filter('rest_post_dispatch', [$this, 'handle_rest_api_response'], 10, 3); // Add filter to handle block editor preload errors add_filter('block_editor_rest_api_preload', [$this, 'handle_block_editor_preload'], 10, 2); // Add filter to handle rest_preload_api_request errors add_filter('rest_preload_api_request', [$this, 'handle_preload_api_request'], 10, 2); // Add filter to handle REST API server errors // Temporarily disabled to prevent conflicts // add_filter('rest_pre_dispatch', [$this, 'handle_rest_server_errors'], 5, 3); // Add filter to handle response_to_data errors // Temporarily disabled to prevent conflicts // add_filter('rest_response_to_data', [$this, 'handle_response_to_data'], 10, 3); // Add filter to ensure all block metadata is properly structured add_filter('block_type_metadata', [$this, 'ensure_block_metadata_structure'], 5, 1); // Add filter to handle block editor settings add_filter('block_editor_settings_all', [$this, 'ensure_block_editor_settings'], 10, 2); // Add filter to ensure block editor loads properly add_filter('block_editor_rest_api_preload', [$this, 'ensure_block_editor_preload'], 5, 2); // Add custom CSS to apply styles to img tag instead of figure add_action('wp_enqueue_scripts', [$this, 'enqueue_image_block_styles']); add_action('enqueue_block_editor_assets', [$this, 'enqueue_image_block_styles']); // Add JavaScript to force border styles on figure elements add_action('wp_enqueue_scripts', [$this, 'enqueue_image_block_script']); add_action('enqueue_block_editor_assets', [$this, 'enqueue_image_block_script']); // Add editor-specific script add_action('enqueue_block_editor_assets', [$this, 'enqueue_editor_specific_script']); // Register custom block variation for image blocks // Temporarily disabled due to JSX syntax error in regular JS file // add_action('init', [$this, 'register_image_block_variation']); } /** * Enqueue custom styles for image blocks. * * Applies padding, background, border, and radius styles properly to image blocks. */ public function enqueue_image_block_styles() { $custom_css = ' /* Fix for image blocks with padding - ensure proper display */ .wp-block-image { display: block; overflow: visible; } /* Ensure img elements within padded blocks are visible */ .wp-block-image img { display: block; max-width: 100%; height: auto; border: none; border-radius: 0; } /* Handle padding on image blocks properly */ .wp-block-image[style*="padding"] { display: block; overflow: visible; } .wp-block-image[style*="padding"] figure { margin: 0; padding: 0; } .wp-block-image[style*="padding"] img { display: block; max-width: 100%; height: auto; } /* Handle background colors on image blocks */ .wp-block-image[style*="background"] { display: block; } .wp-block-image[style*="background"] figure { margin: 0; } /* Force border and radius to be on figure, not img */ .wp-block-image figure { border: inherit !important; border-radius: inherit !important; } .wp-block-image img { border: none !important; border-radius: 0 !important; } /* Target WordPress-generated border classes */ .wp-block-image.has-border-color figure { border-color: inherit !important; } .wp-block-image.has-border-color img { border-color: transparent !important; } .wp-block-image.has-border-width figure { border-width: inherit !important; } .wp-block-image.has-border-width img { border-width: 0 !important; } .wp-block-image.has-border-style figure { border-style: inherit !important; } .wp-block-image.has-border-style img { border-style: none !important; } /* Specific overrides for inline styles */ .wp-block-image figure[style*="border"] { border: inherit !important; } .wp-block-image figure[style*="border-radius"] { border-radius: inherit !important; overflow: hidden !important; } .wp-block-image img[style*="border"] { border: none !important; } .wp-block-image img[style*="border-radius"] { border-radius: 0 !important; } /* Additional specificity for WordPress border classes */ .wp-block-image[class*="has-border"] figure { border: inherit !important; border-radius: inherit !important; } .wp-block-image[class*="has-border"] img { border: none !important; border-radius: 0 !important; } /* Maximum specificity overrides for inline styles */ .wp-block-image img[style*="border"] { border: none !important; border-radius: 0 !important; border-width: 0 !important; border-color: transparent !important; border-style: none !important; } .wp-block-image img[style*="border-radius"] { border-radius: 0 !important; } .wp-block-image img[style*="border-width"] { border-width: 0 !important; } .wp-block-image img[style*="border-color"] { border-color: transparent !important; } .wp-block-image img[style*="border-style"] { border-style: none !important; } /* Force figure to inherit border styles */ .wp-block-image figure { border: inherit !important; border-radius: inherit !important; border-width: inherit !important; border-color: inherit !important; border-style: inherit !important; } /* Ensure proper spacing for image blocks with both padding and background */ .wp-block-image[style*="padding"][style*="background"] { display: block; overflow: visible; } /* Fix for editor preview mode */ .editor-styles-wrapper .wp-block-image[style*="padding"] { display: block !important; overflow: visible !important; } .editor-styles-wrapper .wp-block-image[style*="padding"] img { display: block !important; max-width: 100% !important; height: auto !important; } /* Editor-specific border fixes */ .editor-styles-wrapper .wp-block-image img[style*="border"] { border: none !important; border-radius: 0 !important; border-width: 0 !important; border-color: transparent !important; border-style: none !important; } .editor-styles-wrapper .wp-block-image img[style*="border-radius"] { border-radius: 0 !important; } .editor-styles-wrapper .wp-block-image figure { border: inherit !important; border-radius: inherit !important; border-width: inherit !important; border-color: inherit !important; border-style: inherit !important; } /* Force editor to apply borders to figure */ .editor-styles-wrapper .wp-block-image.has-border-color figure { border-color: inherit !important; } .editor-styles-wrapper .wp-block-image.has-border-width figure { border-width: inherit !important; } .editor-styles-wrapper .wp-block-image.has-border-style figure { border-style: inherit !important; } /* Maximum specificity for editor - override everything */ .editor-styles-wrapper .wp-block-image img, .editor-styles-wrapper .wp-block-image img[style*="border"], .editor-styles-wrapper .wp-block-image img[style*="border-radius"], .editor-styles-wrapper .wp-block-image img[style*="border-width"], .editor-styles-wrapper .wp-block-image img[style*="border-color"], .editor-styles-wrapper .wp-block-image img[style*="border-style"] { border: none !important; border-radius: 0 !important; border-width: 0 !important; border-color: transparent !important; border-style: none !important; } /* Force figure to inherit all border styles in editor */ .editor-styles-wrapper .wp-block-image figure, .editor-styles-wrapper .wp-block-image figure[style*="border"], .editor-styles-wrapper .wp-block-image figure[style*="border-radius"] { border: inherit !important; border-radius: inherit !important; border-width: inherit !important; border-color: inherit !important; border-style: inherit !important; } /* Target WordPress border classes in editor */ .editor-styles-wrapper .wp-block-image.has-border-color img, .editor-styles-wrapper .wp-block-image.has-border-width img, .editor-styles-wrapper .wp-block-image.has-border-style img, .editor-styles-wrapper .wp-block-image.has-border-radius img { border: none !important; border-radius: 0 !important; border-width: 0 !important; border-color: transparent !important; border-style: none !important; } .editor-styles-wrapper .wp-block-image.has-border-color figure, .editor-styles-wrapper .wp-block-image.has-border-width figure, .editor-styles-wrapper .wp-block-image.has-border-style figure, .editor-styles-wrapper .wp-block-image.has-border-radius figure { border: inherit !important; border-radius: inherit !important; border-width: inherit !important; border-color: inherit !important; border-style: inherit !important; overflow: hidden !important; } /* Additional fixes for preview mode */ .wp-block-image[style*="padding"] { position: relative; z-index: 1; } .wp-block-image[style*="padding"] figure { position: relative; z-index: 1; } /* Ensure images are always visible in preview */ .wp-block-image img { opacity: 1 !important; visibility: visible !important; } '; wp_add_inline_style('caliph-style', $custom_css); } /** * Modify image block output to move border/radius from img to figure. * * @param string $block_content The block content. * @param array $block The full block, including name and attributes. * @return string Modified block content. */ public function modify_image_block_output($block_content, $block) { // Only process image blocks if ($block['blockName'] !== 'core/image') { return $block_content; } // More aggressive approach - directly manipulate the HTML if (strpos($block_content, ']*style="([^"]*)"[^>]*>/', $block_content, $figure_matches); preg_match('/]*style="([^"]*)"[^>]*>/', $block_content, $img_matches); $figure_style = !empty($figure_matches[1]) ? $figure_matches[1] : ''; $img_style = !empty($img_matches[1]) ? $img_matches[1] : ''; // Extract border properties from img style $border_properties = []; $other_properties = []; if (!empty($img_style)) { $style_parts = explode(';', $img_style); foreach ($style_parts as $part) { $part = trim($part); if (empty($part)) continue; // Check if this is a border-related property if (preg_match('/border(-radius)?/', $part)) { $border_properties[] = $part; } else { $other_properties[] = $part; } } } // If we found border properties, move them to figure if (!empty($border_properties)) { // Add border properties to figure style $new_figure_style = $figure_style; foreach ($border_properties as $prop) { $new_figure_style .= '; ' . $prop; } // Add overflow hidden if we have border-radius if (array_filter($border_properties, function($p) { return strpos($p, 'border-radius') !== false; })) { $new_figure_style .= '; overflow: hidden'; } // Update figure style if (!empty($figure_matches[0])) { $block_content = str_replace($figure_matches[0], str_replace('style="' . $figure_style . '"', 'style="' . $new_figure_style . '"', $figure_matches[0]), $block_content ); } else { // No existing style, add one $block_content = preg_replace( '/(]*)(>)/', '$1 style="' . $new_figure_style . '"$2', $block_content ); } // Remove border properties from img and add border: none $new_img_style = implode('; ', $other_properties); if (!empty($new_img_style)) { $new_img_style .= '; border: none; border-radius: 0;'; } else { $new_img_style = 'border: none; border-radius: 0;'; } // Update img style if (!empty($img_matches[0])) { $block_content = str_replace($img_matches[0], str_replace('style="' . $img_style . '"', 'style="' . $new_img_style . '"', $img_matches[0]), $block_content ); } } } return $block_content; } /** * Modify image block metadata to ensure proper border handling. * * @param array $metadata The block metadata. * @return array Modified metadata. */ public function modify_image_block_metadata($metadata) { // Add error handling to prevent warnings try { // Ensure metadata is an array if (!is_array($metadata)) { return $metadata; } // Check if name exists and is core/image if (!isset($metadata['name']) || $metadata['name'] !== 'core/image') { return $metadata; } // Ensure supports array exists if (!isset($metadata['supports']) || !is_array($metadata['supports'])) { $metadata['supports'] = []; } // Ensure border support exists if (!isset($metadata['supports']['border']) || !is_array($metadata['supports']['border'])) { $metadata['supports']['border'] = []; } // Force border to be applied to the block wrapper, not the img $metadata['supports']['border']['__experimentalDefaultControls'] = [ 'color' => true, 'radius' => true, 'style' => true, 'width' => true, ]; // Ensure attributes array exists if (!isset($metadata['attributes']) || !is_array($metadata['attributes'])) { $metadata['attributes'] = []; } // Ensure className attribute exists if (!isset($metadata['attributes']['className']) || !is_array($metadata['attributes']['className'])) { $metadata['attributes']['className'] = []; } // Add custom CSS class to help with styling $metadata['attributes']['className']['default'] = 'caliph-image-block'; // Ensure all required properties have proper structure to prevent REST API warnings if (!isset($metadata['attributes']['className']['type'])) { $metadata['attributes']['className']['type'] = 'string'; } // Ensure other common attributes have proper structure $common_attributes = ['align', 'sizeSlug', 'linkTarget', 'rel', 'title']; foreach ($common_attributes as $attr) { if (!isset($metadata['attributes'][$attr])) { $metadata['attributes'][$attr] = [ 'type' => 'string', 'default' => '' ]; } elseif (!isset($metadata['attributes'][$attr]['type'])) { $metadata['attributes'][$attr]['type'] = 'string'; } } return $metadata; } catch (Exception $e) { // Log error but don't break the site error_log('Caliph: Error in modify_image_block_metadata: ' . $e->getMessage()); return $metadata; } } /** * Modify editor settings to ensure proper border handling. * * @param array $settings The editor settings. * @param array $context The editor context. * @return array Modified settings. */ public function modify_editor_settings($settings, $context) { // Add error handling to prevent warnings try { // Ensure settings is an array if (!is_array($settings)) { $settings = []; } // Add custom CSS to editor if (!isset($settings['styles']) || !is_array($settings['styles'])) { $settings['styles'] = []; } $settings['styles'][] = [ 'css' => ' /* Force borders to be on figure, not img in editor */ .wp-block-image { --caliph-border: inherit; --caliph-border-radius: inherit; --caliph-border-width: inherit; --caliph-border-color: inherit; --caliph-border-style: inherit; } .wp-block-image img { border: none !important; border-radius: 0 !important; border-width: 0 !important; border-color: transparent !important; border-style: none !important; } .wp-block-image figure { border: var(--caliph-border) !important; border-radius: var(--caliph-border-radius) !important; border-width: var(--caliph-border-width) !important; border-color: var(--caliph-border-color) !important; border-style: var(--caliph-border-style) !important; overflow: hidden; } /* Override any inline styles */ .wp-block-image img[style*="border"] { border: none !important; border-radius: 0 !important; border-width: 0 !important; border-color: transparent !important; border-style: none !important; } .wp-block-image figure[style*="border"] { border: inherit !important; border-radius: inherit !important; border-width: inherit !important; border-color: inherit !important; border-style: inherit !important; } /* Target WordPress border classes */ .wp-block-image.has-border-color figure { border-color: inherit !important; } .wp-block-image.has-border-width figure { border-width: inherit !important; } .wp-block-image.has-border-style figure { border-style: inherit !important; } .wp-block-image.has-border-radius figure { border-radius: inherit !important; overflow: hidden !important; } ' ]; return $settings; } catch (Exception $e) { // Log error but don't break the site error_log('Caliph: Error in modify_editor_settings: ' . $e->getMessage()); return $settings; } } /** * Enqueue JavaScript to force border styles on figure elements. */ public function enqueue_image_block_script() { $script = " function fixImageBlockBorders() { // Target both main document and editor iframe const contexts = [document]; // Add editor iframe if available const editorFrame = document.querySelector('iframe[name=\"editor-canvas\"]'); if (editorFrame && editorFrame.contentDocument) { contexts.push(editorFrame.contentDocument); } // Also check for any other iframes that might contain editor content const allIframes = document.querySelectorAll('iframe'); allIframes.forEach(function(iframe) { if (iframe.contentDocument && iframe.contentDocument.body) { contexts.push(iframe.contentDocument); } }); contexts.forEach(function(doc) { const imageBlocks = doc.querySelectorAll('.wp-block-image'); imageBlocks.forEach(function(block) { const img = block.querySelector('img'); const figure = block.querySelector('figure'); if (img && figure) { // Get computed styles const computedStyle = doc.defaultView ? doc.defaultView.getComputedStyle(img) : window.getComputedStyle(img); // Check for any border properties const hasBorder = computedStyle.border !== 'none' || computedStyle.borderWidth !== '0px' || computedStyle.borderRadius !== '0px' || computedStyle.borderColor !== 'rgba(0, 0, 0, 0)'; if (hasBorder) { console.log('Found border on img, moving to figure'); // Move all border properties to figure figure.style.border = computedStyle.border; figure.style.borderWidth = computedStyle.borderWidth; figure.style.borderColor = computedStyle.borderColor; figure.style.borderStyle = computedStyle.borderStyle; figure.style.borderRadius = computedStyle.borderRadius; // Add overflow hidden for border-radius if (computedStyle.borderRadius !== '0px') { figure.style.overflow = 'hidden'; } // Remove all border properties from img img.style.setProperty('border', 'none', 'important'); img.style.setProperty('border-radius', '0', 'important'); img.style.setProperty('border-width', '0', 'important'); img.style.setProperty('border-color', 'transparent', 'important'); img.style.setProperty('border-style', 'none', 'important'); } } }); }); } // Run immediately fixImageBlockBorders(); // Run on DOM ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', fixImageBlockBorders); } else { setTimeout(fixImageBlockBorders, 100); } // Run on window load window.addEventListener('load', fixImageBlockBorders); // Editor-specific handling if (typeof wp !== 'undefined' && wp.data) { console.log('WordPress editor detected, setting up listeners'); // Run on any editor change wp.data.subscribe(function() { setTimeout(fixImageBlockBorders, 50); }); // Run when image blocks are selected wp.data.subscribe(function() { const selectedBlock = wp.data.select('core/block-editor').getSelectedBlock(); if (selectedBlock && selectedBlock.name === 'core/image') { setTimeout(fixImageBlockBorders, 25); } }); } // Run very frequently in editor if (document.body.classList.contains('wp-admin') || document.body.classList.contains('editor-styles-wrapper') || document.body.classList.contains('block-editor-page')) { console.log('Editor detected, setting up frequent monitoring'); setInterval(fixImageBlockBorders, 100); // Also run on any DOM changes const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.type === 'childList' || mutation.type === 'attributes') { setTimeout(fixImageBlockBorders, 50); } }); }); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); } // Additional iframe monitoring function setupIframeMonitoring() { const iframes = document.querySelectorAll('iframe'); iframes.forEach(function(iframe) { if (iframe.contentDocument) { iframe.addEventListener('load', function() { setTimeout(fixImageBlockBorders, 100); // Inject CSS directly into iframe const style = iframe.contentDocument.createElement('style'); style.textContent = ` .wp-block-image figure { border: inherit !important; border-radius: inherit !important; border-width: inherit !important; border-color: inherit !important; border-style: inherit !important; } .wp-block-image img { border: none !important; border-radius: 0 !important; border-width: 0 !important; border-color: transparent !important; border-style: none !important; } .wp-block-image.has-border-color figure, .wp-block-image.has-border-width figure, .wp-block-image.has-border-style figure, .wp-block-image.has-border-radius figure { border: inherit !important; border-radius: inherit !important; border-width: inherit !important; border-color: inherit !important; border-style: inherit !important; overflow: hidden !important; } .wp-block-image.has-border-color img, .wp-block-image.has-border-width img, .wp-block-image.has-border-style img, .wp-block-image.has-border-radius img { border: none !important; border-radius: 0 !important; border-width: 0 !important; border-color: transparent !important; border-style: none !important; } `; iframe.contentDocument.head.appendChild(style); }); } }); } setupIframeMonitoring(); setInterval(setupIframeMonitoring, 1000); "; wp_add_inline_script('caliph-style', $script); } /** * Enqueue editor-specific script for image block borders. */ public function enqueue_editor_specific_script() { $script = " // Editor-specific border fix function editorFixImageBorders() { console.log('Editor border fix running...'); // Wait for editor to be ready if (typeof wp === 'undefined' || !wp.data) { setTimeout(editorFixImageBorders, 500); return; } // Get all image blocks in editor const blocks = wp.data.select('core/block-editor').getBlocks(); const imageBlocks = blocks.filter(block => block.name === 'core/image'); imageBlocks.forEach(function(block) { if (block.attributes.style && block.attributes.style.border) { console.log('Found image block with border:', block); // Force the block to re-render wp.data.dispatch('core/block-editor').updateBlockAttributes(block.clientId, { style: block.attributes.style }); } }); // Also check DOM elements const domImageBlocks = document.querySelectorAll('.wp-block-image'); domImageBlocks.forEach(function(block) { const img = block.querySelector('img'); const figure = block.querySelector('figure'); if (img && figure) { const computedStyle = window.getComputedStyle(img); if (computedStyle.border !== 'none' || computedStyle.borderRadius !== '0px') { console.log('Moving border from img to figure in editor'); // Move border to figure figure.style.border = computedStyle.border; figure.style.borderRadius = computedStyle.borderRadius; figure.style.overflow = 'hidden'; // Remove from img img.style.setProperty('border', 'none', 'important'); img.style.setProperty('border-radius', '0', 'important'); } } }); } // Run when editor is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', editorFixImageBorders); } else { editorFixImageBorders(); } // Run on editor changes if (typeof wp !== 'undefined' && wp.data) { wp.data.subscribe(function() { setTimeout(editorFixImageBorders, 100); }); } // Run frequently in editor setInterval(editorFixImageBorders, 300); "; wp_add_inline_script('caliph-style', $script); } /** * Register custom block variation for image blocks. */ public function register_image_block_variation() { // Check if the script file exists before enqueuing $script_path = get_template_directory() . '/assets/js/image-block-variation.js'; if (file_exists($script_path)) { wp_enqueue_script( 'caliph-image-block-variation', get_template_directory_uri() . '/assets/js/image-block-variation.js', ['wp-blocks', 'wp-dom-ready', 'wp-edit-post'], wp_get_theme()->get('Version'), true ); } } /** * Debug function to identify block registration issues. */ public function debug_block_registration() { // Only run in admin and when debugging is enabled if (!is_admin() || !defined('WP_DEBUG') || !WP_DEBUG) { return; } // Check if there are any block registration issues try { $blocks = WP_Block_Type_Registry::get_instance()->get_all_registered(); foreach ($blocks as $block_name => $block) { if ($block_name === 'core/image') { // Log the block structure for debugging error_log('Caliph Debug: Image block structure - ' . print_r($block, true)); // Check for missing properties if (!isset($block->attributes)) { error_log('Caliph Debug: Image block missing attributes'); } if (!isset($block->supports)) { error_log('Caliph Debug: Image block missing supports'); } } } } catch (Exception $e) { error_log('Caliph Debug: Error in debug_block_registration: ' . $e->getMessage()); } } /** * Prevent REST API warnings by ensuring array keys exist. */ public function prevent_rest_api_warnings($result, $server, $request) { // Only run if we're in debug mode if (!defined('WP_DEBUG') || !WP_DEBUG) { return $result; } // Suppress warnings for specific REST API endpoints that might cause issues if (strpos($request->get_route(), '/wp/v2/blocks') !== false || strpos($request->get_route(), '/wp/v2/block-types') !== false) { // Temporarily suppress warnings for this request $old_error_reporting = error_reporting(); error_reporting(E_ALL & ~E_WARNING); // Restore error reporting after a short delay add_action('rest_post_dispatch', function() use ($old_error_reporting) { error_reporting($old_error_reporting); }, 999); } return $result; } /** * Handle REST API response to prevent null get_data() errors. */ public function handle_rest_api_response($response, $handler, $request) { // Check if response is null and handle gracefully if ($response === null) { // Return an empty response object instead of null return new WP_REST_Response([], 200); } // If response is a WP_REST_Response but has null data, fix it if ($response instanceof WP_REST_Response && $response->get_data() === null) { $response->set_data([]); } return $response; } /** * Handle block editor preload to prevent REST API errors. */ public function handle_block_editor_preload($preload_data, $context) { // Filter out any null responses from preload data if (is_array($preload_data)) { foreach ($preload_data as $key => $value) { if ($value === null) { $preload_data[$key] = []; } } } return $preload_data; } /** * Handle rest_preload_api_request to prevent null get_data() errors. */ public function handle_preload_api_request($response, $path) { // If response is null, return empty array to prevent errors if ($response === null) { return []; } // If response is a WP_REST_Response but has null data, fix it if ($response instanceof WP_REST_Response) { try { $data = $response->get_data(); if ($data === null) { $response->set_data([]); } } catch (Exception $e) { // If get_data() throws an error, return empty array error_log("Caliph: Error in get_data(): " . $e->getMessage()); return []; } } return $response; } /** * Handle REST API server errors to prevent fatal errors. */ public function handle_rest_server_errors($result, $server, $request) { // Check if we're dealing with blocks endpoint if (strpos($request->get_route(), '/wp/v2/blocks') !== false) { // Set error handling to prevent fatal errors set_error_handler(function($errno, $errstr, $errfile, $errline) { // Log the error but don't throw fatal error error_log("Caliph REST API Error: $errstr in $errfile on line $errline"); return true; // Don't execute PHP internal error handler }); // Restore error handler after request add_action('rest_post_dispatch', function() { restore_error_handler(); }, 999); } return $result; } /** * Handle response_to_data to prevent null get_data() errors. */ public function handle_response_to_data($data, $response, $request) { // If response is null, return empty array if ($response === null) { return []; } // If data is null, return empty array if ($data === null) { return []; } return $data; } /** * Ensure all block metadata has proper structure to prevent REST API warnings. */ public function ensure_block_metadata_structure($metadata) { try { // Validate input if (!is_array($metadata)) { return $metadata; } // Ensure basic structure exists if (!isset($metadata['attributes']) || !is_array($metadata['attributes'])) { $metadata['attributes'] = []; } // Ensure all attributes have proper type definitions foreach ($metadata['attributes'] as $attr_name => $attr_config) { if (is_array($attr_config) && !isset($attr_config['type'])) { // Set default type based on attribute name or default value if (isset($attr_config['default'])) { if (is_bool($attr_config['default'])) { $metadata['attributes'][$attr_name]['type'] = 'boolean'; } elseif (is_int($attr_config['default'])) { $metadata['attributes'][$attr_name]['type'] = 'number'; } else { $metadata['attributes'][$attr_name]['type'] = 'string'; } } else { $metadata['attributes'][$attr_name]['type'] = 'string'; } } } // Ensure supports structure exists if (!isset($metadata['supports']) || !is_array($metadata['supports'])) { $metadata['supports'] = []; } return $metadata; } catch (Exception $e) { error_log('Caliph: Error in ensure_block_metadata_structure: ' . $e->getMessage()); return $metadata; } } /** * Ensure block editor settings are properly configured. */ public function ensure_block_editor_settings($settings, $context) { try { // Ensure settings is an array if (!is_array($settings)) { $settings = []; } // Ensure required settings exist if (!isset($settings['hasFixedToolbar'])) { $settings['hasFixedToolbar'] = false; } if (!isset($settings['hasReducedUI'])) { $settings['hasReducedUI'] = false; } if (!isset($settings['canUserUseUnfilteredHTML'])) { $settings['canUserUseUnfilteredHTML'] = false; } // Ensure blockTypes exists if (!isset($settings['blockTypes']) || !is_array($settings['blockTypes'])) { $settings['blockTypes'] = []; } // Ensure allowedBlockTypes exists if (!isset($settings['allowedBlockTypes'])) { $settings['allowedBlockTypes'] = true; } return $settings; } catch (Exception $e) { error_log('Caliph: Error in ensure_block_editor_settings: ' . $e->getMessage()); return $settings; } } /** * Ensure block editor preload works properly. */ public function ensure_block_editor_preload($preload_data, $context) { try { // Log preload attempt error_log("Caliph Debug: Block editor preload called"); // Ensure preload_data is an array if (!is_array($preload_data)) { $preload_data = []; } // Filter out any problematic data foreach ($preload_data as $key => $value) { if ($value === null) { unset($preload_data[$key]); } } return $preload_data; } catch (Exception $e) { error_log('Caliph: Error in ensure_block_editor_preload: ' . $e->getMessage()); return []; } } }