<?php namespace Give\ThirdPartySupport\Elementor\Actions; use Give\Campaigns\Models\Campaign; use Give\Campaigns\Models\CampaignPage; use Give\ThirdPartySupport\Elementor\Widgets\V2\ElementorCampaignDonationsWidget\ElementorCampaignDonationsWidget; use Give\ThirdPartySupport\Elementor\Widgets\V2\ElementorCampaignDonorsWidget\ElementorCampaignDonorsWidget; use Give\ThirdPartySupport\Elementor\Widgets\V2\ElementorCampaignGoalWidget\ElementorCampaignGoalWidget; use Give\ThirdPartySupport\Elementor\Widgets\V2\ElementorDonationFormWidget\ElementorDonationFormWidget; use Give\ThirdPartySupport\Elementor\Widgets\V2\ElementorCampaignStatsWidget\ElementorCampaignStatsWidget; /** * Automatically setup Elementor template data for campaign pages * * This class automatically populates campaign pages with our custom Elementor * template layout when Elementor is active, providing a seamless experience * for users creating campaign pages. * * @since 4.7.0 */ class SetupElementorCampaignTemplate { /** * Setup Elementor template data for campaign page * * @since 4.7.0 */ public function __invoke(CampaignPage $campaignPage): void { // Allow users to disable auto-setup via filter if (!apply_filters('givewp_auto_setup_elementor_campaign_template', true)) { return; } // Only proceed if Elementor is active if (!$this->isElementorActive()) { return; } // Only setup for new campaign pages that don't already have Elementor data if ($this->campaignPageHasElementorData($campaignPage->id)) { return; } $campaign = $campaignPage->campaign(); if (!$campaign) { return; } $this->setupElementorData($campaignPage->id, $campaign->id, $campaign->shortDescription); } /** * Check if Elementor is active and available * * @since 4.7.0 */ private function isElementorActive(): bool { return class_exists('\Elementor\Plugin') && defined('ELEMENTOR_VERSION'); } /** * Check if campaign page already has Elementor data * * @since 4.7.0 */ private function campaignPageHasElementorData(int $pageId): bool { $elementorData = get_post_meta($pageId, '_elementor_data', true); return !empty($elementorData) && $elementorData !== '[]'; } /** * Setup Elementor data and meta keys for the campaign page * * @since 4.7.0 */ private function setupElementorData(int $pageId, int $campaignId, string $shortDescription): void { // Get the template data structure $templateData = $this->getElementorTemplateData($campaignId, $shortDescription); // Convert to JSON and add proper slashing for WordPress $jsonData = wp_slash(wp_json_encode($templateData)); // Set the main Elementor data update_post_meta($pageId, '_elementor_data', $jsonData); // Set Elementor edit mode to enable editing update_post_meta($pageId, '_elementor_edit_mode', 'builder'); // Set template type update_post_meta($pageId, '_elementor_template_type', 'page'); // Set Elementor version if (defined('ELEMENTOR_VERSION')) { update_post_meta($pageId, '_elementor_version', ELEMENTOR_VERSION); } // Add our custom meta to track this as an auto-generated template update_post_meta($pageId, '_givewp_elementor_auto_template', true); update_post_meta($pageId, '_givewp_elementor_template_version', '1.0.0'); } /** * Get Elementor template data structure * * @since 4.7.0 * @return array */ private function getElementorTemplateData(int $campaignId, string $shortDescription): array { $campaign = Campaign::find($campaignId); if (!$campaign) { return []; } $campaignDefaultFormId = $campaign->defaultFormId; $campaignImageUrl = $campaign->image; $campaignImageId = null; if ($campaign->image && $imageId = attachment_url_to_postid($campaign->image)) { $campaignImageId = $imageId; } return [ [ 'id' => $this->generateElementorId(), 'elType' => 'section', 'settings' => [ 'layout' => 'boxed', 'gap' => 'default', 'content_width' => [ 'unit' => '%', 'size' => 100 ], 'margin' => [ 'unit' => 'px', 'top' => '0', 'right' => '0', 'bottom' => '40', 'left' => '0' ] ], 'elements' => [ // Left Column (60% - Post Featured Image) [ 'id' => $this->generateElementorId(), 'elType' => 'column', 'settings' => [ '_column_size' => 60, 'space_between_widgets' => '0' ], 'elements' => [ [ 'id' => $this->generateElementorId(), 'elType' => 'widget', 'widgetType' => 'image', 'settings' => [ 'image' => [ 'id' => $campaignImageId, 'url' => $campaignImageUrl ], 'image_size' => 'full', 'width' => [ 'unit' => '%', 'size' => 100 ], 'height' => [ 'unit' => '%', 'size' => 100 ], 'object-fit' => 'cover', 'image_border_border' => 'default', 'image_border_radius' => [ 'unit' => 'px', 'top' => 8, 'right' => 8, 'bottom' => 8, 'left' => 8, 'isLinked' => true ], 'height_inner' => [ 'unit' => 'px', 'size' => 0 ], 'aspect_ratio' => '16:9' ] ] ] ], // Right Column (40% - Goal, Stats, Donate Button) [ 'id' => $this->generateElementorId(), 'elType' => 'column', 'settings' => [ '_column_size' => 40, 'space_between_widgets' => '20' ], 'elements' => [ // Campaign Goal [ 'id' => $this->generateElementorId(), 'elType' => 'widget', 'widgetType' => give(ElementorCampaignGoalWidget::class)->get_name(), 'settings' => [ 'campaign_id' => $campaignId ] ], // Campaign Stats [ 'id' => $this->generateElementorId(), 'elType' => 'widget', 'widgetType' => give(ElementorCampaignStatsWidget::class)->get_name(), 'settings' => [ 'campaign_id' => $campaignId, 'statistic' => 'top-donation' ] ], [ 'id' => $this->generateElementorId(), 'elType' => 'widget', 'widgetType' => give(ElementorCampaignStatsWidget::class)->get_name(), 'settings' => [ 'campaign_id' => $campaignId, 'statistic' => 'average-donation' ] ], // Donate Button [ 'id' => $this->generateElementorId(), 'elType' => 'widget', 'widgetType' => give(ElementorDonationFormWidget::class)->get_name(), 'settings' => [ 'form_id' => $campaignDefaultFormId, 'display_style' => 'modal' ] ] ] ] ] ], // Description Section [ 'id' => $this->generateElementorId(), 'elType' => 'section', 'settings' => [ 'layout' => 'boxed', 'margin' => [ 'unit' => 'px', 'top' => '40', 'bottom' => '40' ] ], 'elements' => [ [ 'id' => $this->generateElementorId(), 'elType' => 'column', 'settings' => [ '_column_size' => 100 ], 'elements' => [ [ 'id' => $this->generateElementorId(), 'elType' => 'widget', 'widgetType' => 'text-editor', 'settings' => [ 'editor' => $shortDescription ?: '' ] ] ] ] ] ], // Donations Section [ 'id' => $this->generateElementorId(), 'elType' => 'section', 'settings' => [ 'layout' => 'boxed', 'margin' => [ 'unit' => 'px', 'bottom' => '40' ] ], 'elements' => [ [ 'id' => $this->generateElementorId(), 'elType' => 'column', 'settings' => [ '_column_size' => 100 ], 'elements' => [ [ 'id' => $this->generateElementorId(), 'elType' => 'widget', 'widgetType' => give(ElementorCampaignDonationsWidget::class)->get_name(), 'settings' => [ 'campaign_id' => $campaignId, 'show_anonymous' => 'yes', 'show_icon' => 'yes', 'show_button' => 'yes', 'donate_button_text' => 'Donate', 'sort_by' => 'recent-donations', 'donations_per_page' => 5, 'load_more_button_text' => 'Load more' ] ] ] ] ] ], // Donors Section [ 'id' => $this->generateElementorId(), 'elType' => 'section', 'settings' => [ 'layout' => 'boxed' ], 'elements' => [ [ 'id' => $this->generateElementorId(), 'elType' => 'column', 'settings' => [ '_column_size' => 100 ], 'elements' => [ [ 'id' => $this->generateElementorId(), 'elType' => 'widget', 'widgetType' => give(ElementorCampaignDonorsWidget::class)->get_name(), 'settings' => [ 'campaign_id' => $campaignId, 'show_anonymous' => 'yes', 'show_company_name' => 'yes', 'show_avatar' => 'yes', 'show_button' => 'yes', 'donate_button_text' => 'Join the list', 'sort_by' => 'top-donors', 'donors_per_page' => 5, 'load_more_button_text' => 'Load more' ] ] ] ] ] ] ]; } /** * Generate a random Elementor-style ID * * @since 4.7.0 */ private function generateElementorId(): string { return substr(md5(uniqid('', true)), 0, 7); } }