PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 3.2.2
ShopBuilder – WooCommerce Builder For Elementor v3.2.2
3.4.2 3.4.1 3.4.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 All 63 releases
shopbuilder / app / Controllers / Builder / BuilderCpt.php

BuilderCpt.php in ShopBuilder – WooCommerce Builder For Elementor 3.2.2, at app/Controllers/Builder/BuilderCpt.php

431 lines 14.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Builder Custom post type
4 *
5 * @package RadiusTheme\SB
6 */
7
8 namespace RadiusTheme\SB\Controllers\Builder;
9
10 defined( 'ABSPATH' ) || exit();
11
12 use RadiusTheme\SB\Models\TemplateSettings;
13 use WP_Query;
14 use RadiusTheme\SB\Helpers\Fns;
15 use RadiusTheme\SB\Helpers\BuilderFns;
16 use RadiusTheme\SB\Traits\SingletonTrait;
17
18 /**
19 * Builder Custom post type
20 */
21 class BuilderCpt {
22 /**
23 * Singleton
24 */
25 use SingletonTrait;
26
27 /**
28 * Final constructor.
29 */
30 private function __construct() {
31 add_action( 'init', [ $this, 'template_builder_post_type' ] );
32 add_filter( 'post_row_actions', [ $this, 'filter_post_row_actions' ], 11, 1 );
33 // Admin column.
34 add_filter( 'manage_edit-' . BuilderFns::$post_type_tb . '_columns', [ $this, 'add_new_columns' ] );
35 add_action( 'manage_' . BuilderFns::$post_type_tb . '_posts_custom_column', [ $this, 'custom_columns' ], 10, 2 );
36 add_filter( 'manage_edit-' . BuilderFns::$post_type_tb . '_sortable_columns', [ $this, 'register_sortable_columns' ] );
37 add_action( 'pre_get_posts', [ $this, 'sortable_columns_query' ] );
38 add_filter( 'template_include', [ $this, 'builder_template' ], 99 );
39 add_filter( 'template_redirect', [ $this, 'restrict_preview_access' ], 99 );
40
41 add_filter( 'parse_query', [ $this, 'query_filter' ] );
42 // Add filter for search.
43 add_action( 'restrict_manage_posts', [ $this, 'add_filter' ] );
44 // Post Content Remove For Elementor Builder.
45 add_action( 'save_post_' . BuilderFns::$post_type_tb, [ $this, 'on_save_post' ], 10, 2 );
46 }
47
48 /**
49 * Hook into post save to clear post content for specific post type and editor.
50 *
51 * This method checks if the post is being updated (not newly created),
52 * and if the post type matches the target type defined in BuilderFns::$post_type_tb.
53 * If the post is edited with Elementor, it clears the post_content directly
54 * from the database and clears the post cache.
55 *
56 * @param int $post_ID ID of the post being saved.
57 * @param WP_Post $post Post object.
58 *
59 * @return void
60 */
61 public function on_save_post( $post_ID, $post ) {
62 // Only proceed on update and specific post type.
63 if ( BuilderFns::$post_type_tb !== $post->post_type ) {
64 return;
65 }
66 if ( 'elementor' !== Fns::page_edit_with( $post_ID ) ) {
67 return;
68 }
69 global $wpdb;
70 // Directly update the post_content to empty.
71 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
72 $wpdb->update(
73 $wpdb->posts,
74 [ 'post_content' => '' ],
75 [ 'ID' => $post_ID ]
76 );
77 // Clear cache so changes reflect properly.
78 clean_post_cache( $post_ID );
79 }
80
81 /**
82 * Public function add_filter.
83 * Added search filter for type of template
84 *
85 * @since 1.0.0
86 */
87 public function add_filter() {
88
89 global $typenow;
90
91 if ( BuilderFns::$post_type_tb != $typenow ) {
92 return;
93 }
94 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
95 $selected = isset( $_GET['type'] ) ? sanitize_key( $_GET['type'] ) : '';
96 $builder_page_types = BuilderFns::builder_page_types();
97 ?>
98 <select name="template_type" id="type">
99 <option value="all" <?php selected( 'all', $selected ); ?>><?php esc_html_e( 'Template Type ', 'shopbuilder' ); ?></option>
100 <?php foreach ( $builder_page_types as $key => $value ) { ?>
101 <option value="<?php echo esc_attr( $key ); ?>" <?php selected( $key, $selected ); ?>><?php echo esc_html( $value ); ?></option>
102 <?php } ?>
103 </select>
104 <?php
105 }
106
107 /**
108 * Post type function
109 *
110 * @return void
111 */
112 public function template_builder_post_type() {
113 /**
114 * Template Builder Post type
115 */
116 $tb_labels = [
117 'name' => esc_html_x( 'WooCommerce Page Builder', 'Post Type General Name', 'shopbuilder' ),
118 'singular_name' => esc_html_x( 'Templates Builder', 'Post Type Singular Name', 'shopbuilder' ),
119 'menu_name' => esc_html__( 'Templates Builder', 'shopbuilder' ),
120 'name_admin_bar' => esc_html__( 'Templates Builder', 'shopbuilder' ),
121 'archives' => esc_html__( 'WC Page Archives', 'shopbuilder' ),
122 'attributes' => esc_html__( 'Page Attributes', 'shopbuilder' ),
123 'parent_item_colon' => esc_html__( 'Parent Item:', 'shopbuilder' ),
124 'all_items' => esc_html__( 'Templates Builder', 'shopbuilder' ),
125 'add_new_item' => esc_html__( 'Add New Page', 'shopbuilder' ),
126 'add_new' => esc_html__( 'Add New', 'shopbuilder' ),
127 'new_item' => esc_html__( 'New Page', 'shopbuilder' ),
128 'edit_item' => esc_html__( 'Edit Page', 'shopbuilder' ),
129 'update_item' => esc_html__( 'Update Page', 'shopbuilder' ),
130 'view_item' => esc_html__( 'View Page', 'shopbuilder' ),
131 'view_items' => esc_html__( 'View Pages', 'shopbuilder' ),
132 'search_items' => esc_html__( 'Search Pages', 'shopbuilder' ),
133 'not_found' => esc_html__( 'Not found', 'shopbuilder' ),
134 'not_found_in_trash' => esc_html__( 'Not found in Trash', 'shopbuilder' ),
135 'featured_image' => esc_html__( 'Featured Image', 'shopbuilder' ),
136 'set_featured_image' => esc_html__( 'Set featured image', 'shopbuilder' ),
137 'remove_featured_image' => esc_html__( 'Remove featured image', 'shopbuilder' ),
138 'use_featured_image' => esc_html__( 'Use as featured image', 'shopbuilder' ),
139 'insert_into_item' => esc_html__( 'Insert into page', 'shopbuilder' ),
140 'uploaded_to_this_item' => esc_html__( 'Uploaded to this page', 'shopbuilder' ),
141 'items_list' => esc_html__( 'Pages list', 'shopbuilder' ),
142 'items_list_navigation' => esc_html__( 'Pages list navigation', 'shopbuilder' ),
143 'filter_items_list' => esc_html__( 'Filter from list', 'shopbuilder' ),
144 ];
145
146 $tb_args = [
147 'label' => esc_html__( 'Templates Builder', 'shopbuilder' ),
148 'description' => esc_html__( 'Shopbuilder Template', 'shopbuilder' ),
149 'labels' => $tb_labels,
150 'supports' => [ 'title', 'editor', 'elementor', 'author', 'permalink', 'comments' ],
151 'hierarchical' => false,
152 'public' => true,
153 'show_ui' => true,
154 'show_in_menu' => 'rtsb',
155 'show_in_admin_bar' => false,
156 'show_in_nav_menus' => true,
157 'can_export' => true,
158 'has_archive' => false,
159 'rewrite' => [
160 'slug' => 'rtsb-template',
161 'pages' => false,
162 'with_front' => true,
163 'feeds' => false,
164 ],
165 'query_var' => true,
166 'publicly_queryable' => true,
167 // 'capability_type' => 'product', Will Remove this line in the future.
168 'show_in_rest' => true,
169 'rest_base' => BuilderFns::$post_type_tb,
170 ];
171
172 $tb_args = apply_filters( 'rtsb/builder/template_args', $tb_args );
173
174 register_post_type( BuilderFns::$post_type_tb, $tb_args );
175
176 // Flash rewrite rules.
177 $this->flush_rewrite_rules();
178 }
179
180 /**
181 * Flush rewrite
182 *
183 * @return void
184 */
185 public function flush_rewrite_rules() {
186 if ( get_option( 'shopbuilder_permalinks_flushed', 'no' ) !== 'yes' ) {
187 flush_rewrite_rules();
188 update_option( 'shopbuilder_permalinks_flushed', 'yes' );
189 }
190 }
191
192 /**
193 * Add new columns to the post table
194 *
195 * @param array $columns - Current columns on the list post.
196 */
197 public function add_new_columns( $columns ) {
198 $column_meta = [
199 'type' => esc_html__( 'Template Type', 'shopbuilder' ),
200 'edit_with' => esc_html__( 'Editor Type', 'shopbuilder' ),
201 'set_default' => esc_html__( 'Set as Active', 'shopbuilder' ),
202 ];
203
204 unset( $columns['comments'] );
205
206 $columns = array_merge(
207 array_slice( $columns, 0, 2 ),
208 $column_meta,
209 array_slice( $columns, 2 )
210 );
211
212 return $columns;
213 }
214
215 /**
216 * Display data in new columns
217 *
218 * @param string $column table column.
219 * @param string $post_id Post id.
220 *
221 * @return void
222 */
223 public function custom_columns( $column, $post_id ) { // phpcs:ignore Generic.Metrics.NestingLevel.TooHigh
224 $post_id = absint( $post_id );
225 $types = BuilderFns::builder_page_types();
226 $template_type = BuilderFns::builder_type( $post_id ) ? BuilderFns::builder_type( $post_id ) : array_key_first( $types );
227
228 switch ( $column ) {
229 case 'type':
230 $the_type = ! empty( $types[ $template_type ] ) ? '<b>' . esc_html( ucwords( $types[ $template_type ] ) ) . '</b>' : '';
231 Fns::print_html( apply_filters( 'rtsb/columns/template/types/text', $the_type, $template_type, $post_id ) );
232 break;
233 case 'edit_with':
234 $edit_by = Fns::page_edit_with( $post_id );
235 echo esc_html( ucfirst( $edit_by ) );
236 break;
237 case 'set_default':
238 $is_set_default = absint( BuilderFns::builder_page_id_by_type( $template_type ) );
239 $is_published = 'publish' === get_post_status( $post_id );
240 $page_type_for = $template_type;
241 if ( 'product' === $template_type ) {
242 $product_page_for = get_post_meta( $post_id, '_is_product_page_template_for', true );
243 switch ( $product_page_for ) {
244 case 'specific_products':
245 $page_type_for = 'template-' . $post_id . '-specific-products';
246 $set_default = BuilderFns::get_specific_product_as_default( $post_id );
247 if ( $set_default ) {
248 $is_set_default = $post_id;
249 }
250 if ( ! $set_default && $is_set_default === $post_id ) {
251 $is_set_default = '';
252 }
253 break;
254 case 'product_cats':
255 $page_type_for = 'product-page-template-' . $post_id . '-specific-category';
256 $set_default_option_name = BuilderFns::option_name_product_page_specific_cat_set_default( $post_id );
257 $pp_cat_set_default = TemplateSettings::instance()->get_option( $set_default_option_name );
258 if ( $pp_cat_set_default ) {
259 $is_set_default = $post_id;
260 }
261 break;
262 case 'product_tags':
263 $page_type_for = 'product-page-template-' . $post_id . '-specific-tag';
264 $set_default_option_name = BuilderFns::option_name_product_page_specific_tag_set_default( $post_id );
265 $pp_tag_set_default = TemplateSettings::instance()->get_option( $set_default_option_name );
266 if ( $pp_tag_set_default ) {
267 $is_set_default = $post_id;
268 }
269 break;
270 default:
271 break;
272 }
273 } elseif ( 'archive' === $template_type ) {
274 $categories_name = apply_filters( 'rtsb/template/builder/selected/categories', [], $post_id, $template_type );
275 $set_default = BuilderFns::get_specific_category_as_default( $post_id );
276 if ( ! empty( $categories_name ) && $set_default ) {
277 $is_set_default = $post_id;
278 $page_type_for = 'template-' . $post_id . '-specific-category';
279 }
280 if ( ! $set_default && $is_set_default === $post_id ) {
281 $is_set_default = '';
282 }
283 }
284 ?>
285 <span class="rtsb-switch-wrapper page-type-<?php echo esc_attr( $page_type_for ); ?>" <?php echo ! $is_published ? 'style="pointer-events: none;"' : null; ?> title="<?php esc_html_e( 'Only publish post can set default ', 'shopbuilder' ); ?>">
286 <label class="rtsb-switch">
287 <?php do_action( 'rtsb/set/default/column/extra/field', $post_id, $template_type, $is_set_default, $is_published ); ?>
288 <div class="rtsb_template_type" data-template_type="<?php echo esc_attr( $template_type ); ?>" style='display:none;'></div>
289 <input disabled="disabled" value="<?php echo absint( $post_id ); ?>" class="rtsb_set_default" name="set_default" type="checkbox" <?php echo esc_attr( $post_id === $is_set_default ? 'checked' : '' ); ?> >
290 <span class="rtsb-slider rtsb-round ">
291 <span class="rtsb-loader"></span>
292 </span>
293 </label>
294 </span>
295 <?php
296 break;
297 }
298 }
299
300 /**
301 * Register sortable columns
302 *
303 * @param [type] $columns column list.
304 *
305 * @return array
306 */
307 public function register_sortable_columns( $columns ) {
308 $columns['type'] = 'type';
309
310 return $columns;
311 }
312
313 /**
314 * Meta sortable function.
315 *
316 * @param object $query query object.
317 *
318 * @return void
319 */
320 public function sortable_columns_query( $query ) {
321 if ( ! is_admin() || ! $this->is_current_screen() ) {
322 return;
323 }
324 $orderby = $query->get( 'orderby' );
325 if ( 'type' === $orderby ) {
326 $query->set( 'meta_key', BuilderFns::template_type_meta_key() );
327 $query->set( 'orderby', 'meta_value' );
328 }
329 }
330
331 /**
332 * Check template screen
333 *
334 * @return boolean
335 */
336 public function is_current_screen() {
337 global $pagenow, $typenow;
338
339 return 'edit.php' === $pagenow && BuilderFns::$post_type_tb === $typenow;
340 }
341
342 /**
343 * Manage Template filter by template type
344 *
345 * @param WP_Query $query WordPress main query.
346 *
347 * @return void
348 */
349 public function query_filter( WP_Query $query ) {
350
351 if ( ! is_admin() || ! $this->is_current_screen() || ! empty( $query->query_vars['meta_key'] ) ) {
352 return;
353 }
354 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
355 $type = isset( $_GET['template_type'] ) ? sanitize_key( $_GET['template_type'] ) : '';
356
357 if ( '' != $type && 'all' != $type ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
358 $query->query_vars['meta_key'] = BuilderFns::template_type_meta_key(); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
359 $query->query_vars['meta_value'] = $type; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
360 $query->query_vars['meta_compare'] = '=';
361 }
362 }
363
364 /**
365 * Load Template.
366 *
367 * @param string $template Template File.
368 *
369 * @return string
370 */
371 public function builder_template( $template ) {
372 $builder_page_id = BuilderFns::is_builder_preview() ? get_the_ID() : BuilderFns::builder_page_id_by_page();
373 if ( defined( 'ELEMENTOR_VERSION' ) && $builder_page_id ) { // Elementor Check.
374 $page_template = get_post_meta( $builder_page_id, '_wp_page_template', true );
375 $new_template = RTSB_ABSPATH . 'page-templates/builder-template.php';
376 if ( 'elementor_canvas' === $page_template ) {
377 $new_template = RTSB_ABSPATH . 'page-templates/elementor-canvas.php';
378 } elseif ( 'elementor_header_footer' === $page_template ) {
379 $new_template = RTSB_ABSPATH . 'page-templates/builder-template.php';
380 }
381 if ( file_exists( $new_template ) ) {
382 $template = $new_template;
383 }
384 }
385
386 return $template;
387 }
388
389 /**
390 * Restrict the preview access.
391 *
392 * @return void
393 */
394 public function restrict_preview_access() {
395 if ( ! apply_filters( 'rtsb/builder/preview/access', true ) ) {
396 return;
397 }
398
399 if ( is_singular( 'rtsb_builder' ) ) {
400 if ( ! is_user_logged_in() ) {
401 wp_safe_redirect( home_url() );
402 }
403 }
404 }
405
406 /**
407 * Add/Remove edit link in dashboard.
408 *
409 * Add or remove an edit link to the post/page action links on the post/pages list table.
410 *
411 * Fired by `post_row_actions` and `page_row_actions` filters.
412 *
413 * @access public
414 *
415 * @param array $actions An array of row action links.
416 *
417 * @return array An updated array of row action links.
418 */
419 public function filter_post_row_actions( $actions ) {
420 if ( $this->is_current_screen() ) {
421 unset( $actions['inline hide-if-no-js'] );
422
423 if ( isset( $actions['view'] ) ) {
424 $actions['view'] = str_replace( __( 'View', 'shopbuilder' ), __( 'Preview', 'shopbuilder' ), $actions['view'] );
425 }
426 }
427
428 return $actions;
429 }
430 }
431