PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.3.26
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.3.26
1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 All 49 releases
fluent-cart / app / Modules / Templating / BlockTemplates / TemplateParts / ProductModalTemplatePart.php

ProductModalTemplatePart.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.3.26, at app/Modules/Templating/BlockTemplates/TemplateParts/ProductModalTemplatePart.php

375 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Modules\Templating\BlockTemplates\TemplateParts;
4
5 class ProductModalTemplatePart
6 {
7 /**
8 * The slug of the template part.
9 *
10 * @var string
11 */
12 const SLUG = 'product-modal';
13
14 /**
15 * The area of the template part.
16 *
17 * @var string
18 */
19 const AREA = 'uncategorized';
20
21 /**
22 * Plugin namespace for template parts.
23 *
24 * @var string
25 */
26 const PLUGIN_NAMESPACE = 'fluent-cart';
27
28 /**
29 * Initialization method.
30 */
31 public function init()
32 {
33 add_action('init', [$this, 'register']);
34 }
35
36 /**
37 * Register the template part.
38 */
39 public function register()
40 {
41
42
43
44 add_filter('get_block_templates', [$this, 'addTemplatePart'], 10, 3);
45 add_filter('pre_get_block_file_template', [$this, 'getTemplatePart'], 10, 3);
46 }
47
48 /**
49 * Add the template part to the list of available template parts.
50 *
51 * @param array $query_result Array of found block templates.
52 * @param array $query Arguments to retrieve templates.
53 * @param string $template_type wp_template or wp_template_part.
54 * @return array Modified array of block templates.
55 */
56 public function addTemplatePart($query_result, $query, $template_type)
57 {
58 if ('wp_template_part' !== $template_type) {
59 return $query_result;
60 }
61
62 // dd($query_result);
63
64 // Check if our template part is already in the results
65 $template_id = $this->getTemplatePartId();
66 foreach ($query_result as $template) {
67 if ($template->id === $template_id) {
68 return $query_result;
69 }
70 }
71
72 // Create the template part object
73 $template_part = $this->buildTemplatePartObject();
74
75 $query_result[] = $template_part;
76
77 return $query_result;
78 }
79
80 /**
81 * Get template part when requested.
82 *
83 * @param \WP_Block_Template|null $template Block template object.
84 * @param string $id Template unique identifier.
85 * @param string $template_type Template type.
86 * @return \WP_Block_Template|null
87 */
88 public function getTemplatePart($template, $id, $template_type)
89 {
90 if ('wp_template_part' !== $template_type) {
91 return $template;
92 }
93
94 if ($this->getTemplatePartId() !== $id) {
95 return $template;
96 }
97
98 return $this->buildTemplatePartObject();
99 }
100
101 /**
102 * Build the template part object.
103 *
104 * @return \WP_Block_Template
105 */
106 private function buildTemplatePartObject()
107 {
108 $template_part = new \WP_Block_Template();
109 $template_part->type = 'wp_template_part';
110 $template_part->theme = get_stylesheet(); // Use current theme
111 $template_part->slug = self::SLUG;
112 $template_part->id = $this->getTemplatePartId();
113 $template_part->title = $this->getTitle();
114 $template_part->description = $this->getDescription();
115 $template_part->content = $this->getDefaultTemplate();
116 $template_part->source = 'plugin';
117 $template_part->origin = 'plugin';
118 $template_part->status = 'publish';
119 $template_part->has_theme_file = false;
120 $template_part->is_custom = true;
121 $template_part->area = self::AREA;
122 $template_part->post_types = [];
123 $template_part->plugin = self::PLUGIN_NAMESPACE;
124
125 return $template_part;
126 }
127
128 /**
129 * Returns the title of the template part.
130 *
131 * @return string
132 */
133 public function getTitle()
134 {
135 return _x('Product Modal', 'Template part name', 'fluent-cart');
136 }
137
138 /**
139 * Returns the description of the template part.
140 *
141 * @return string
142 */
143 public function getDescription()
144 {
145 return __('Editable template part for Single Product Modal.', 'fluent-cart');
146 }
147
148 /**
149 * Returns the default template content.
150 *
151 * @return string
152 */
153 public function getDefaultTemplate()
154 {
155 ob_start();
156 ?>
157 <!-- wp:group {"templateLock":"contentOnly","tagName":"main","className":"alignfull is-style-default","layout":{"type":"default"}} -->
158 <main class="wp-block-group alignfull is-style-default">
159 <!-- wp:group {"lock":{"move":true,"remove":true},"align":"wide","layout":{"type":"default"}} -->
160 <div class="wp-block-group alignwide">
161 <!-- wp:shortcode {"lock":{"move":true,"remove":true}} -->
162 [fluent_cart_product_header]
163 <!-- /wp:shortcode -->
164 </div>
165 <!-- /wp:group -->
166
167 <!-- wp:paragraph {"placeholder":"Add your content here..."} -->
168 <p></p>
169 <!-- /wp:paragraph -->
170 </main>
171 <!-- /wp:group -->
172 <?php
173 return ob_get_clean();
174 }
175
176 /**
177 * Get the current content of the template part (including user modifications).
178 *
179 * @return string|null
180 */
181 public function getTemplateContent()
182 {
183 // First, try to get the user-customized version from the database
184 $template_part_post = $this->getTemplatePartPost();
185
186 if ($template_part_post && !empty($template_part_post->post_content)) {
187 return $template_part_post->post_content;
188 }
189
190 // Fall back to default template
191 return $this->getDefaultTemplate();
192 }
193
194 /**
195 * Get the template part post from the database.
196 *
197 * @return \WP_Post|null
198 */
199 private function getTemplatePartPost()
200 {
201 $args = [
202 'post_type' => 'wp_template_part',
203 'post_status' => ['publish', 'auto-draft'],
204 'title' => $this->getTitle(),
205 'posts_per_page' => 1,
206 'no_found_rows' => true,
207 'update_post_meta_cache' => false,
208 'update_post_term_cache' => false,
209 ];
210
211 // Try to find by slug first
212 $args['name'] = self::SLUG;
213 $query = new \WP_Query($args);
214
215 if ($query->have_posts()) {
216 return $query->posts[0];
217 }
218
219 // Also check with theme-specific slug
220 $args['name'] = get_stylesheet() . '//' . self::SLUG;
221 $query = new \WP_Query($args);
222
223 if ($query->have_posts()) {
224 return $query->posts[0];
225 }
226
227 return null;
228 }
229
230 /**
231 * Render the template part with current content (including user customizations).
232 *
233 * @param array $args Optional arguments to pass to the template part.
234 * @return string Rendered HTML output.
235 */
236 public function render($args = [])
237 {
238 $content = $this->getTemplateContent();
239
240 if (empty($content)) {
241 return '';
242 }
243
244 // Apply filters before rendering (allows other plugins to modify)
245 $content = apply_filters_deprecated('fluent_cart_template_part_content', [$content, self::SLUG, $args], '1.3.16', 'fluent_cart/template_part_content', 'Use fluent_cart/template_part_content instead of fluent_cart_template_part_content.');
246 $content = apply_filters_deprecated('fluent_cart_template_part_content_' . self::SLUG, [$content, $args], '1.3.16', 'fluent_cart/template_part_content_' . self::SLUG, 'Use fluent_cart/template_part_content_' . self::SLUG . ' instead of fluent_cart_template_part_content_' . self::SLUG . '.');
247 $content = apply_filters('fluent_cart/template_part_content', $content, self::SLUG, $args);
248 $content = apply_filters('fluent_cart/template_part_content_' . self::SLUG, $content, $args);
249
250 // Parse and render blocks
251 $output = do_blocks($content);
252
253 // Apply filters after rendering
254 $output = apply_filters_deprecated('fluent_cart_template_part_output', [$output, self::SLUG, $args], '1.3.16', 'fluent_cart/template_part_output', 'Use fluent_cart/template_part_output instead of fluent_cart_template_part_output.');
255 $output = apply_filters_deprecated('fluent_cart_template_part_output_' . self::SLUG, [$output, $args], '1.3.16', 'fluent_cart/template_part_output_' . self::SLUG, 'Use fluent_cart/template_part_output_' . self::SLUG . ' instead of fluent_cart_template_part_output_' . self::SLUG . '.');
256 $output = apply_filters('fluent_cart/template_part_output', $output, self::SLUG, $args);
257 $output = apply_filters('fluent_cart/template_part_output_' . self::SLUG, $output, $args);
258
259 return $output;
260 }
261
262 /**
263 * Render the template part and echo it.
264 *
265 * @param array $args Optional arguments to pass to the template part.
266 */
267 public function display($args = [])
268 {
269 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped in render method
270 echo $this->render($args);
271 }
272
273 /**
274 * Get the template part ID.
275 *
276 * @return string
277 */
278 public function getTemplatePartId()
279 {
280 return get_stylesheet() . '//' . self::SLUG;
281 }
282
283 /**
284 * Check if the template part has been customized by the user.
285 *
286 * @return bool
287 */
288 public function isCustomized()
289 {
290 $template_part_post = $this->getTemplatePartPost();
291 return !is_null($template_part_post);
292 }
293
294 /**
295 * Reset the template part to default (remove customizations).
296 *
297 * @return bool True on success, false on failure.
298 */
299 public function resetToDefault()
300 {
301 $template_part_post = $this->getTemplatePartPost();
302
303 if ($template_part_post) {
304 $result = wp_delete_post($template_part_post->ID, true);
305
306 if ($result) {
307 // Clear any caches
308 wp_cache_delete('get_block_templates', 'block_templates');
309 return true;
310 }
311
312 return false;
313 }
314
315 return true; // Already at default
316 }
317
318 /**
319 * Export the template part content (for backup or migration).
320 *
321 * @return array
322 */
323 public function export()
324 {
325 return [
326 'slug' => self::SLUG,
327 'title' => $this->getTitle(),
328 'description' => $this->getDescription(),
329 'content' => $this->getTemplateContent(),
330 'is_custom' => $this->isCustomized(),
331 'plugin' => self::PLUGIN_NAMESPACE,
332 ];
333 }
334
335 /**
336 * Import template part content.
337 *
338 * @param string $content The template content to import.
339 * @return bool|\WP_Error True on success, WP_Error on failure.
340 */
341 public function import($content)
342 {
343 if (empty($content)) {
344 return new \WP_Error('empty_content', __('Template content cannot be empty.', 'fluent-cart'));
345 }
346
347 // Delete existing customization
348 $this->resetToDefault();
349
350 // Create new template part post
351 $post_data = [
352 'post_type' => 'wp_template_part',
353 'post_status' => 'publish',
354 'post_title' => $this->getTitle(),
355 'post_name' => self::SLUG,
356 'post_content' => $content,
357 'tax_input' => [
358 'wp_theme' => [get_stylesheet()],
359 'wp_template_part_area' => [self::AREA],
360 ],
361 ];
362
363 $post_id = wp_insert_post($post_data, true);
364
365 if (is_wp_error($post_id)) {
366 return $post_id;
367 }
368
369 // Clear caches
370 wp_cache_delete('get_block_templates', 'block_templates');
371
372 return true;
373 }
374 }
375