PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.5.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.5.0
4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / app / src / Integrations / Elementor / ElementorBlockAdapterService.php
surecart / app / src / Integrations / Elementor Last commit date
Conditions 1 year ago Documents 1 year ago DynamicTags 4 months ago Widgets 2 months ago assets 4 months ago ElementorBlockAdapterService.php 4 months ago ElementorCoreBlockStylesService.php 1 year ago ElementorDocumentsService.php 1 year ago ElementorDynamicTagsService.php 1 year ago ElementorEditorService.php 1 year ago ElementorFseScriptLoaderService.php 1 year ago ElementorServiceProvider.php 8 months ago ElementorShortcodeService.php 1 year ago ElementorTemplatesService.php 4 months ago ElementorWidgetsService.php 8 months ago
ElementorBlockAdapterService.php
213 lines
1 <?php
2
3 namespace SureCart\Integrations\Elementor;
4
5 use SureCart\Migration\ProductPageWrapperService;
6
7 /**
8 * Elementor block adapter service.
9 */
10 class ElementorBlockAdapterService {
11 /**
12 * Bootstrap the service.
13 *
14 * @return void
15 */
16 public function bootstrap() {
17 add_action( 'elementor/frontend/container/before_render', [ $this, 'addProductWrapperStart' ] );
18 add_action( 'elementor/frontend/container/after_render', [ $this, 'addProductWrapperEnd' ] );
19 add_action( 'elementor/frontend/before_get_builder_content', [ $this, 'preReturnSerializedBlock' ] );
20 add_action( 'elementor/frontend/the_content', [ $this, 'doBlocksAtEnd' ], 10 );
21 add_action( 'elementor/element/container/section_layout_container/after_section_start', [ $this, 'injectProductFormControls' ], 10 );
22 add_filter( 'elementor/frontend/the_content', [ $this, 'showAlertIfNotUsingProductWrapper' ], 11 );
23 add_filter( 'surecart/product/replace_content_with_product_info_part', [ $this, 'doNotReplaceContentIfRenderingWithElementor' ] );
24 }
25
26 /**
27 * Add product wrapper start.
28 *
29 * @param \Elementor\Widget_Base $element The element.
30 *
31 * @return void
32 */
33 public function addProductWrapperStart( $element ) {
34 $settings = $element->get_settings_for_display();
35 if ( 'surecart_form' === $settings['surecart_container_type'] ) {
36 echo '<!-- wp:surecart/product-page {"align":"wide"} -->';
37 }
38 }
39
40 /**
41 * Add product wrapper end.
42 *
43 * @param \Elementor\Widget_Base $element The element.
44 *
45 * @return void
46 */
47 public function addProductWrapperEnd( $element ) {
48 $settings = $element->get_settings_for_display();
49 if ( 'surecart_form' === $settings['surecart_container_type'] ) {
50 echo '<!-- /wp:surecart/product-page -->';
51 }
52 }
53
54 /**
55 * Adds the block serialization filter before Elementor content is processed.
56 *
57 * @return void
58 */
59 public function preReturnSerializedBlock(): void {
60 add_filter( 'pre_render_block', [ $this, 'serializeBlock' ], 10, 2 );
61 }
62
63 /**
64 * Disable Elementor render block.
65 *
66 * @param array $rendered The rendered block.
67 * @param array $parsed_block The parsed block.
68 *
69 * @return array
70 */
71 public function serializeBlock( $rendered, $parsed_block ) {
72 // don't serialize if it includes the surecart/ prefix.
73 if ( strpos( $parsed_block['blockName'] ?? '', 'surecart/' ) !== false ) {
74 return $rendered;
75 }
76
77 return $rendered;
78 }
79
80 /**
81 * Process Elementor content and remove the serialization filter.
82 *
83 * @param string $content The content to process.
84 *
85 * @return string The processed content
86 */
87 public function doBlocksAtEnd( string $content ): string {
88 remove_filter( 'pre_render_block', [ $this, 'serializeBlock' ], 10, 2 );
89 return do_blocks( $content );
90 }
91
92 /**
93 * Inject product form controls.
94 *
95 * @param \Elementor\Widget_Base $element The element.
96 *
97 * @return void
98 */
99 public function injectProductFormControls( $element ) {
100 $element->add_control(
101 'surecart_container_type',
102 [
103 'type' => \Elementor\Controls_Manager::SELECT,
104 'label' => esc_html__( 'Container Type', 'surecart' ),
105 'default' => 'default',
106 'options' => [
107 'default' => esc_html__( 'Default', 'surecart' ),
108 'surecart_form' => esc_html__( 'Product Form', 'surecart' ),
109 ],
110 ]
111 );
112 }
113
114 /**
115 * Show alert if not using product wrapper.
116 *
117 * @param string $content The content.
118 *
119 * @return string
120 */
121 public function showAlertIfNotUsingProductWrapper( $content ) {
122 // Show only to the users who has the permissions to edit the post
123 // and if the current post is a product.
124 if (
125 ! current_user_can( 'edit_posts', get_the_ID() ) ||
126 ! sc_get_product()
127 ) {
128 return $content;
129 }
130
131 $orphaned_blocks = $this->findOrphanedSurecartBlocks( $content );
132 if ( empty( $orphaned_blocks ) ) {
133 return $content;
134 }
135
136 $alert = '<div class="sc-alert sc-alert-warning" style="margin:1em 0;padding:1em;border:1px solid #ffc107;background:#fff3cd;color:#856404;">';
137 $alert .= sprintf(
138 /* translators: %s: URL to the SureCart Elementor documentation page. */
139 esc_html__( '⚠️ Warning: SureCart widgets must be placed inside a "Product Form" container to function properly. &nbsp; %s', 'surecart' ),
140 '<a href="https://surecart.com/docs/product-page-in-elementor" target="_blank" rel="noopener noreferrer">' . esc_html__( 'Learn more', 'surecart' ) . '</a>'
141 );
142 $alert .= '</div>';
143
144 return $alert . $content;
145 }
146
147 /**
148 * Do not replace content if rendering with and elementor template.
149 *
150 * @param bool $replace_content The replace content.
151 *
152 * @return bool
153 */
154 public function doNotReplaceContentIfRenderingWithElementor( $replace_content ) {
155 $document = \Elementor\Plugin::$instance->documents->get_current();
156 if ( ! empty( $document ) ) {
157 return false;
158 }
159
160 return $replace_content;
161 }
162
163 /**
164 * Find orphaned surecart blocks.
165 *
166 * @param string $content The content.
167 *
168 * @return array
169 */
170 public function findOrphanedSurecartBlocks( $content ) {
171 $processor = new \WP_HTML_Tag_Processor( $content );
172 $inside_form = false;
173 $orphaned_blocks = [];
174
175 // Set a bookmark at the start to return to it later if needed.
176 $processor->next_tag();
177 $processor->set_bookmark( 'start' );
178
179 while ( $processor->next_tag( array( 'tag_closers' => 'visit' ) ) ) {
180 $tag_name = strtolower( $processor->get_tag() );
181
182 // Track when we enter/exit form tags.
183 if ( 'form' === $tag_name && ! $processor->is_tag_closer() ) {
184 $inside_form = true;
185 continue;
186 }
187 if ( 'form' === $tag_name && $processor->is_tag_closer() ) {
188 $inside_form = false;
189 continue;
190 }
191
192 // If we're not inside a form, check for the class.
193 if ( ! $inside_form ) {
194 $class = $processor->get_attribute( 'class' ) ?? '';
195
196 // Skip for product-review blocks.
197 if ( preg_match( '/wp-block-surecart-product-review-/', $class ) ) {
198 continue;
199 }
200
201 if ( preg_match( '/wp-block-surecart-(?:product|price)-/', $class ) ) {
202 $orphaned_blocks[] = [
203 'tag' => $processor->get_tag(),
204 'class' => $class,
205 ];
206 }
207 }
208 }
209
210 return $orphaned_blocks;
211 }
212 }
213