PluginProbe
Ultimate Store Kit / 3.0.9
Ultimate Store Kit v3.0.9
3.0.8 3.0.9 3.1.0 3.1.2 3.1.3 3.0.7 3.0.5 3.0.4 3.0.3 3.0.2 trunk 1.5.0 1.5.1 1.5.2 1.6.1 1.6.2 1.6.3 1.6.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 92 releases
ultimate-store-kit / includes / builder / builder-cpt.php

builder-cpt.php in Ultimate Store Kit 3.0.9, at includes/builder/builder-cpt.php

483 lines 14.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace UltimateStoreKit\Includes\Builder;
4
5 use UltimateStoreKit\Base\Singleton;
6
7 if (! defined('ABSPATH')) {
8 exit;
9 }
10
11 class Builder_Cpt {
12
13 use Singleton;
14
15 public function init_hooks() {
16 $builderCpt = Meta::POST_TYPE;
17
18 add_action('init', [$this, 'registered_post_type']);
19 add_action('admin_footer', [$this, 'add_modal_html'], 1);
20 add_action('delete_post', [$this, 'trashed_or_delete_post'], 10, 2);
21 add_action('trashed_post', [$this, 'trashed_or_delete_post'], 10, 1);
22
23 add_action('wp_ajax_ultimate_store_kit_builder_create_template', [$this, 'create_builder_template']);
24 add_action('wp_ajax_ultimate_store_kit_builder_get_edit_template', [$this, 'get_builder_template_action']);
25 add_filter("manage_{$builderCpt}_posts_columns", [$this, 'set_post_columns']);
26 add_action("manage_{$builderCpt}_posts_custom_column", [$this, 'set_custom_column_value'], 10, 2);
27 add_filter('post_row_actions', [$this, 'post_row_actions_filter'], 20, 2);
28
29 // Simple WPML fix
30 if (function_exists('icl_object_id')) {
31 add_filter('elementor/editor/before_enqueue_scripts', [$this, 'fix_wpml_elementor_data'], 1);
32 }
33
34 if (is_admin()) {
35 add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts'], 1);
36 add_action('admin_menu', [$this, 'add_admin_menu'], 202);
37 add_action('restrict_manage_posts', [$this, 'add_filter']);
38 add_filter('parse_query', [$this, 'parse_query_filter']);
39 }
40
41 // $this->resetTemplateCache();
42 }
43
44 public function resetTemplateCache() {
45 global $wpdb;
46
47 $postType = Meta::POST_TYPE;
48
49 $query = $wpdb->get_results("SELECT {$wpdb->posts}.ID,{$wpdb->posts}.post_type, {$wpdb->posts}.post_status, {$wpdb->postmeta}.meta_value as template_type
50 FROM $wpdb->posts
51 LEFT JOIN $wpdb->postmeta
52 ON {$wpdb->postmeta}.post_id = {$wpdb->posts}.ID
53 WHERE 1=1
54 AND {$wpdb->posts}.post_type ='{$postType}'
55 AND {$wpdb->postmeta}.meta_key ='_ultimate_store_kit_template_type'
56 ORDER BY {$wpdb->posts}.post_date DESC");
57
58 foreach ($query as $q) {
59 if (! $q->template_type) {
60 continue;
61 }
62
63 $optionKey = Meta::TEMPLATE_ID . $q->template_type;
64
65 if ($q->post_status == 'publish') {
66 update_option($optionKey, $q->ID);
67 } else {
68 delete_option($optionKey, $q->ID);
69 }
70 }
71 }
72
73 public function trashed_or_delete_post($postId) {
74 if (get_post_type($postId) != Meta::POST_TYPE) {
75 return;
76 }
77
78 if ($template = get_post_meta($postId, Meta::TEMPLATE_TYPE, true)) {
79 delete_option(Meta::TEMPLATE_ID . $template);
80 }
81 }
82
83 public function post_row_actions_filter($actions, $post) {
84
85 global $typenow;
86
87 if ($typenow !== Meta::POST_TYPE) {
88 return $actions;
89 }
90
91 if (isset($actions['edit_with_elementor'])) {
92 unset($actions['edit_with_elementor']);
93 }
94
95 if (get_post_meta($post->ID, Meta::EDIT_WITH, true) == 'gutenberg') {
96 $actions['usk_edit_with_gutenberg'] = sprintf(
97 '<a href="%1$s">%2$s</a>',
98 add_query_arg(['post' => $post->ID, 'action' => 'edit'], admin_url('post.php')),
99 esc_html__('Edit with Gutenberg', 'ultimate-store-kit')
100 );
101 }
102
103 if (get_post_meta($post->ID, Meta::EDIT_WITH, true) == 'elementor') {
104 $actions['usk_edit_with_elementor'] = sprintf(
105 '<a href="%1$s">%2$s</a>',
106 add_query_arg(
107 [
108 'post' => $post->ID,
109 'action' => 'elementor',
110 'usk-template' => 1
111 ],
112 admin_url('post.php')
113 ),
114 esc_html__('Edit with Elementor', 'ultimate-store-kit')
115 );
116 } else {
117 // Always offer Elementor edit option regardless of stored preference
118 $actions['usk_edit_with_elementor'] = sprintf(
119 '<a href="%1$s">%2$s</a>',
120 add_query_arg(
121 [
122 'post' => $post->ID,
123 'action' => 'elementor',
124 'usk-template' => 1
125 ],
126 admin_url('post.php')
127 ),
128 esc_html__('Edit with Elementor', 'ultimate-store-kit')
129 );
130 }
131
132 $editActionLink = sprintf(
133 '<a href="%1$s" data-id="%2$s" >%3$s</a>',
134 'javascript:void(0)',
135 $post->ID,
136 esc_html__('Edit', 'ultimate-store-kit')
137 );
138
139 if (isset($actions['edit']) && apply_filters('ultimate_store_kit_remove_action_edit_link', __return_true())) {
140 unset($actions['edit']);
141 }
142
143 return array_slice($actions, 0, 1, true) + ['usk-edit-action' => $editActionLink] + array_slice($actions, 1, null, true);
144 }
145
146 public function set_post_columns($columns) {
147 return array_slice($columns, 0, 2, true) + ['template_type' => 'Type', 'is_enabled' => 'Status'] + array_slice($columns, 2, null, true);
148 }
149
150 public function set_custom_column_value($column, $post_id) {
151 $templateType = get_post_meta(
152 $post_id,
153 Meta::TEMPLATE_TYPE,
154 true
155 );
156
157 switch ($column) {
158 case 'template_type':
159 $postType = Builder_Template_Helper::getTemplatePostTypeByIndex($templateType);
160 $postTypeLabel = isset($postType->name) ? ' <strong>-- ' . ucwords($postType->name) . '</strong>' : '';
161 echo Builder_Template_Helper::getTemplateByIndex($templateType) . $postTypeLabel;
162 break;
163 case 'is_enabled':
164 echo (Builder_Template_Helper::getTemplateId($templateType) == $post_id ? 'Active' : 'Inactive');
165 break;
166 }
167 }
168
169 public function add_filter() {
170 global $typenow;
171
172 if ($typenow !== Meta::POST_TYPE) {
173 return;
174 }
175
176 $selected = isset($_GET['type']) ? sanitize_key($_GET['type']) : '';
177 ?>
178 <select name="type" id="type">
179 <option value="all" <?php
180 selected('all', $selected); ?>><?php
181 esc_html_e(
182 'Template Type ',
183 'ultimate-store-kit'
184 ); ?></option>
185 <?php
186 $templates = Builder_Template_Helper::templateForSelectDropdown();
187 // It is single
188 if (count($templates) == 1) {
189 $templateKey = array_key_last($templates);
190 $template = $templates[$templateKey];
191 foreach ($template as $key => $item) :
192 $selectValue = "{$templateKey}_$key";
193 ?>
194 <option value="<?php
195 echo esc_attr($selectValue) ?>"><?php
196 echo wp_kses_post($item) ?></option>
197 <?php
198 endforeach;
199 }
200
201 if (count($templates) > 1) {
202 foreach ($templates as $keys => $items) :
203 $label = ucwords(str_replace(
204 ['-', '_'],
205 [' '],
206 $keys
207 ));
208 if (is_array($items)) {
209 ?>
210 <optgroup label="<?php
211 echo esc_attr($label) ?>"><?php
212 foreach ($items as $key => $item) :
213 $itemValue = "{$keys}_$key"
214 ?>
215 <option value="<?php
216 echo esc_attr($itemValue) ?>" <?php
217 selected($key, $selected); ?>><?php
218 echo wp_kses_post($item) ?></option>
219 <?php
220 endforeach;
221 ?>
222 </optgroup>
223 <?php
224 }
225 endforeach;
226 }
227 ?>
228 </select>
229 <?php
230 }
231
232 public function parse_query_filter($query) {
233 global $pagenow, $typenow;
234
235 if ($typenow !== Meta::POST_TYPE) {
236 return;
237 }
238
239 if (
240 'edit.php' == $pagenow
241 && isset($_GET['type'])
242 && $_GET['type'] != ''
243 && $_GET['type'] != 'all'
244 ) {
245 $query->query_vars['meta_key'] = Meta::TEMPLATE_TYPE;
246 $query->query_vars['meta_value'] = sanitize_key($_GET['type']);
247 $query->query_vars['meta_compare'] = '=';
248 }
249 }
250
251
252 public function create_builder_template() {
253
254 if (! current_user_can('manage_options')) {
255 wp_send_json_error(['success' => false, 'errors_arr' => ['permission' => 'Permission denied']], 403);
256 }
257
258 parse_str($_POST['data'], $data);
259
260 if (! wp_verify_nonce($data['nonce'], 'usk-builder')) {
261 wp_send_json_error(['success' => false, 'errors_arr' => ['nonce' => 'Invalid nonce']], 403);
262 }
263
264 $templateId = isset($data['template_id']) ? trim($data['template_id']) : '';
265 $name = isset($data['template_name']) ? trim($data['template_name']) : '';
266 $type = isset($data['template_type']) ? trim($data['template_type']) : '';
267 $editWith = isset($data['edit_with']) ? trim($data['edit_with']) : 'elementor'; //gutenberg
268 $isEnabled = (isset($data['template_status']) && $data['template_status']) == 1 ? 1 : 0;
269
270 $errors = [];
271
272 if (empty($name)) {
273 $errors['template_name'] = 'Field is required';
274 }
275
276 if (empty($type)) {
277 $errors['template_type'] = 'Field is required';
278 } else {
279 if (! Builder_Template_Helper::getTemplateByIndex($type)) {
280 $errors['template_type'] = 'Invalid section';
281 }
282 }
283
284
285 if (count($errors) > 0) {
286 wp_send_json_error(['success' => false, 'errors_arr' => $errors], 422);
287 }
288
289 $page_data = [
290 'post_status' => 'publish',
291 'post_type' => Meta::POST_TYPE,
292 'post_author' => get_current_user_id(),
293 'post_title' => $name,
294 'comment_status' => 'closed',
295 'meta_input' => [
296 Meta::EDIT_WITH => $editWith,
297 Meta::TEMPLATE_TYPE => $type,
298 ],
299 ];
300
301 global $wp_rewrite;
302 $wp_rewrite->flush_rules();
303 $wp_rewrite->init();
304
305 if ($templateId) {
306 $page_data['ID'] = $templateId;
307 }
308
309 $post_id = wp_insert_post($page_data);
310
311 $enabledTemplate = strtolower(Meta::TEMPLATE_ID . $type);
312 if ($isEnabled == 1) {
313 update_option($enabledTemplate, $post_id);
314 } else {
315 if (get_option($enabledTemplate) == $post_id) {
316 delete_option($enabledTemplate);
317 }
318 }
319
320
321 if ($editWith == 'elementor') {
322 if (! get_post_meta($post_id, '_elementor_data')) {
323 update_post_meta($post_id, '_elementor_data', []);
324 }
325
326 if (! $templateId) {
327 update_post_meta($post_id, '_elementor_data', []);
328 }
329 update_post_meta($post_id, '_wp_page_template', 'elementor_header_footer');
330 update_post_meta($post_id, '_elementor_edit_mode', 'builder');
331 update_post_meta($post_id, '_elementor_version', '3.7.1');
332 }
333
334 if ($templateId) {
335 $url = add_query_arg(
336 ['post_type' => Meta::POST_TYPE],
337 admin_url('edit.php')
338 );
339 } else {
340 $url = add_query_arg([
341 'post' => $post_id,
342 'action' => $editWith,
343 ], admin_url('post.php'));
344 }
345
346 wp_send_json_success(['success' => true, 'redirect' => $url]);
347 }
348
349 public function get_builder_template_action() {
350
351 if (! current_user_can('manage_options')) {
352 wp_send_json_error(['success' => false, 'errors_arr' => ['permission' => 'Permission denied']], 403);
353 }
354
355 if (! wp_verify_nonce($_REQUEST['nonce'], 'ultimate_store_kit_builder_nonce')) {
356 wp_send_json_error(['success' => false, 'errors_arr' => ['nonce' => 'Invalid nonce']], 403);
357 }
358
359 if (isset($_REQUEST['template_id']) && ! empty($_REQUEST['template_id'])) {
360 $templateId = absint($_REQUEST['template_id']);
361 $templateData = get_post($templateId);
362
363 if ($templateData && $templateData->post_type === Meta::POST_TYPE) {
364 $meta = get_post_meta($templateData->ID);
365
366
367 $templateType = isset($meta[Meta::TEMPLATE_TYPE][0]) ? $meta[Meta::TEMPLATE_TYPE][0] : '';
368 $enabledTemplate = strtolower(Meta::TEMPLATE_ID . $templateType);
369 $enabledTemplate = get_option($enabledTemplate);
370
371 wp_send_json_success([
372 'id' => $templateData->ID,
373 'name' => $templateData->post_title,
374 'type' => $templateType,
375 'status' => is_numeric($enabledTemplate) ? 1 : 0,
376 ]);
377 }
378 }
379
380 wp_send_json_error(['success' => false, 'errors_arr' => ['template' => 'Template not found']], 404);
381 }
382
383 public function add_modal_html($hook_suffix) {
384 require_once 'modal/modal.php';
385 }
386
387 public function enqueue_scripts($hook_suffix) {
388 if (in_array($hook_suffix, ['edit.php', 'post-new.php'])) {
389 $screen = get_current_screen();
390
391 if (is_object($screen) && Meta::POST_TYPE == $screen->post_type) {
392 wp_enqueue_style('ultimate-store-kit-builder', BDTUSK_ASSETS_URL . 'admin/others/css/ultimate-builder.css', [], BDTUSK_VER);
393 wp_enqueue_script('ultimate-store-kit-builder', BDTUSK_ASSETS_URL . 'admin/others/js/ultimate-builder.js', ['jquery', 'wp-i18n'], BDTUSK_VER);
394 wp_set_script_translations('ultimate-store-kit-builder', 'ultimate-store-kit');
395
396 wp_localize_script('ultimate-store-kit-builder', 'UltimateStoreKitConfigBuilder', [
397 'ajaxurl' => admin_url('admin-ajax.php'),
398 'nonce' => wp_create_nonce('ultimate_store_kit_builder_nonce'),
399 'resturl' => rest_url('usk/v1/'),
400 ]);
401 }
402 }
403 }
404
405
406 public function add_admin_menu() {
407 add_submenu_page(
408 'ultimate-store-kit',
409 esc_html__('Template Builder', 'ultimate-store-kit'),
410 esc_html__('Template Builder', 'ultimate-store-kit'),
411 'manage_options',
412 'edit.php?post_type=' . Meta::POST_TYPE
413 );
414 }
415
416 public function registered_post_type() {
417 $labels = [
418 'name' => _x('Template Items', 'post type general name', 'ultimate-store-kit'),
419 'singular_name' => _x('Template Item', 'post type singular name', 'ultimate-store-kit'),
420 'menu_name' => _x('Template Manager', 'admin menu', 'ultimate-store-kit'),
421 'name_admin_bar' => _x('Template Manager', 'add new on admin bar', 'ultimate-store-kit'),
422 'add_new' => _x('Add New', 'template_manager', 'ultimate-store-kit'),
423 'add_new_item' => __('Add New Template', 'ultimate-store-kit'),
424 'new_item' => __('New Template', 'ultimate-store-kit'),
425 'edit_item' => __('Edit Template', 'ultimate-store-kit'),
426 'view_item' => __('View Template', 'ultimate-store-kit'),
427 'all_items' => __('All Templates', 'ultimate-store-kit'),
428 'search_items' => __('Search Templates', 'ultimate-store-kit'),
429 'parent_item_colon' => __('Parent Template:', 'ultimate-store-kit'),
430 'not_found' => __('No Template found.', 'ultimate-store-kit'),
431 'not_found_in_trash' => __('No Template found in Trash.', 'ultimate-store-kit'),
432 ];
433
434 $args = [
435 'labels' => $labels,
436 'description' => __('Description.', 'ultimate-store-kit'),
437 'taxonomies' => [],
438 'hierarchical' => false,
439 'public' => true,
440 'show_in_menu' => false,
441 'show_ui' => true,
442 'show_in_admin_bar' => true,
443 'menu_position' => null,
444 'menu_icon' => null,
445 'publicly_queryable' => true,
446 'supports' => ['title', 'editor', 'elementor'],
447 'exclude_from_search' => true,
448 'has_archive' => false,
449 'query_var' => true,
450 'can_export' => true,
451 'rewrite' => false,
452 'show_in_nav_menus' => false,
453 'capability_type' => 'post',
454 // 'rest_base' => $this->getPostType(),
455 // 'register_meta_box_cb' => [ $this, 'register_meta_box_cb' ],
456 ];
457
458 register_post_type(Meta::POST_TYPE, $args);
459
460 // Fix WPML integration with Elementor
461 if (function_exists('icl_object_id')) {
462 add_filter('wpml_pb_elementor_get_data', [$this, 'fix_wpml_elementor_data'], 10, 2);
463 }
464 }
465
466 /**
467 * Simple fix for WPML and Elementor integration
468 */
469 public function fix_wpml_elementor_data() {
470 if (isset($_REQUEST['post']) && get_post_type($_REQUEST['post']) === Meta::POST_TYPE) {
471 $post_id = (int) $_REQUEST['post'];
472 $meta_data = get_post_meta($post_id, '_elementor_data', true);
473
474 // If metadata exists but is in array format, convert it to JSON string
475 if (is_array($meta_data)) {
476 update_post_meta($post_id, '_elementor_data', wp_json_encode($meta_data));
477 }
478 }
479 }
480 }
481
482 Builder_Cpt::instance()->init_hooks();
483