PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 3.2.6
ShopBuilder – WooCommerce Builder For Elementor v3.2.6
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.6, at app/Controllers/Builder/BuilderCpt.php

435 lines 15.1 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 } else {
280 $option_name = BuilderFns::option_name( $template_type );
281 $is_set_default = TemplateSettings::instance()->get_option( $option_name );
282 $set_default = $is_set_default;
283 }
284 if ( ! $set_default && $is_set_default === $post_id ) {
285 $is_set_default = '';
286 }
287 }
288 ?>
289 <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' ); ?>">
290 <label class="rtsb-switch">
291 <?php do_action( 'rtsb/set/default/column/extra/field', $post_id, $template_type, $is_set_default, $is_published ); ?>
292 <div class="rtsb_template_type" data-template_type="<?php echo esc_attr( $template_type ); ?>" style='display:none;'></div>
293 <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' : '' ); ?> >
294 <span class="rtsb-slider rtsb-round ">
295 <span class="rtsb-loader"></span>
296 </span>
297 </label>
298 </span>
299 <?php
300 break;
301 }
302 }
303
304 /**
305 * Register sortable columns
306 *
307 * @param [type] $columns column list.
308 *
309 * @return array
310 */
311 public function register_sortable_columns( $columns ) {
312 $columns['type'] = 'type';
313
314 return $columns;
315 }
316
317 /**
318 * Meta sortable function.
319 *
320 * @param object $query query object.
321 *
322 * @return void
323 */
324 public function sortable_columns_query( $query ) {
325 if ( ! is_admin() || ! $this->is_current_screen() ) {
326 return;
327 }
328 $orderby = $query->get( 'orderby' );
329 if ( 'type' === $orderby ) {
330 $query->set( 'meta_key', BuilderFns::template_type_meta_key() );
331 $query->set( 'orderby', 'meta_value' );
332 }
333 }
334
335 /**
336 * Check template screen
337 *
338 * @return boolean
339 */
340 public function is_current_screen() {
341 global $pagenow, $typenow;
342
343 return 'edit.php' === $pagenow && BuilderFns::$post_type_tb === $typenow;
344 }
345
346 /**
347 * Manage Template filter by template type
348 *
349 * @param WP_Query $query WordPress main query.
350 *
351 * @return void
352 */
353 public function query_filter( WP_Query $query ) {
354
355 if ( ! is_admin() || ! $this->is_current_screen() || ! empty( $query->query_vars['meta_key'] ) ) {
356 return;
357 }
358 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
359 $type = isset( $_GET['template_type'] ) ? sanitize_key( $_GET['template_type'] ) : '';
360
361 if ( '' != $type && 'all' != $type ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
362 $query->query_vars['meta_key'] = BuilderFns::template_type_meta_key(); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
363 $query->query_vars['meta_value'] = $type; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
364 $query->query_vars['meta_compare'] = '=';
365 }
366 }
367
368 /**
369 * Load Template.
370 *
371 * @param string $template Template File.
372 *
373 * @return string
374 */
375 public function builder_template( $template ) {
376 $builder_page_id = BuilderFns::is_builder_preview() ? get_the_ID() : BuilderFns::builder_page_id_by_page();
377 if ( defined( 'ELEMENTOR_VERSION' ) && $builder_page_id ) { // Elementor Check.
378 $page_template = get_post_meta( $builder_page_id, '_wp_page_template', true );
379 $new_template = RTSB_ABSPATH . 'page-templates/builder-template.php';
380 if ( 'elementor_canvas' === $page_template ) {
381 $new_template = RTSB_ABSPATH . 'page-templates/elementor-canvas.php';
382 } elseif ( 'elementor_header_footer' === $page_template ) {
383 $new_template = RTSB_ABSPATH . 'page-templates/builder-template.php';
384 }
385 if ( file_exists( $new_template ) ) {
386 $template = $new_template;
387 }
388 }
389
390 return $template;
391 }
392
393 /**
394 * Restrict the preview access.
395 *
396 * @return void
397 */
398 public function restrict_preview_access() {
399 if ( ! apply_filters( 'rtsb/builder/preview/access', true ) ) {
400 return;
401 }
402
403 if ( is_singular( 'rtsb_builder' ) ) {
404 if ( ! is_user_logged_in() ) {
405 wp_safe_redirect( home_url() );
406 }
407 }
408 }
409
410 /**
411 * Add/Remove edit link in dashboard.
412 *
413 * Add or remove an edit link to the post/page action links on the post/pages list table.
414 *
415 * Fired by `post_row_actions` and `page_row_actions` filters.
416 *
417 * @access public
418 *
419 * @param array $actions An array of row action links.
420 *
421 * @return array An updated array of row action links.
422 */
423 public function filter_post_row_actions( $actions ) {
424 if ( $this->is_current_screen() ) {
425 unset( $actions['inline hide-if-no-js'] );
426
427 if ( isset( $actions['view'] ) ) {
428 $actions['view'] = str_replace( __( 'View', 'shopbuilder' ), __( 'Preview', 'shopbuilder' ), $actions['view'] );
429 }
430 }
431
432 return $actions;
433 }
434 }
435