PluginProbe ʕ •ᴥ•ʔ
YITH WooCommerce Wishlist / 3.0.17
YITH WooCommerce Wishlist v3.0.17
4.16.0 trunk 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.10 2.2.11 2.2.12 2.2.13 2.2.14 2.2.15 2.2.16 2.2.17 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 3.0.0 3.0.1 3.0.10 3.0.11 3.0.12 3.0.13 3.0.14 3.0.15 3.0.16 3.0.17 3.0.18 3.0.19 3.0.2 3.0.20 3.0.21 3.0.22 3.0.23 3.0.25 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.10.0 3.11.0 3.12.0 3.13.0 3.14.0 3.15.0 3.16.0 3.17.0 3.18.0 3.19.0 3.2.0 3.20.0 3.21.0 3.22.0 3.23.0 3.24.0 3.25.0 3.26.0 3.27.0 3.28.0 3.29.0 3.3.0 3.30.0 3.31.0 3.32.0 3.33.0 3.34.0 3.35.0 3.36.0 3.37.0 3.38.0 3.4.0 3.5.0 3.6.0 3.7.0 3.8.0 3.9.0 4.0.0 4.0.1 4.1.0 4.10.0 4.10.1 4.10.2 4.11.0 4.12.0 4.13.0 4.14.0 4.15.0 4.2.0 4.3.0 4.4.0 4.5.0 4.6.0 4.7.0 4.8.0 4.9.0
yith-woocommerce-wishlist / plugin-fw / lib / yit-cpt-unlimited.php
yith-woocommerce-wishlist / plugin-fw / lib Last commit date
privacy 5 years ago promo 6 years ago yit-ajax.php 7 years ago yit-assets.php 5 years ago yit-cpt-unlimited.php 6 years ago yit-debug.php 7 years ago yit-icons.php 7 years ago yit-metabox.php 6 years ago yit-plugin-common.php 8 years ago yit-plugin-gradients.php 6 years ago yit-plugin-licence.php 5 years ago yit-plugin-panel-wc.php 5 years ago yit-plugin-panel.php 5 years ago yit-plugin-subpanel.php 6 years ago yit-pointers.php 6 years ago yit-theme-licence.php 7 years ago yit-upgrade.php 7 years ago yit-video.php 7 years ago yith-dashboard.php 7 years ago yith-gutenberg.php 7 years ago yith-system-status.php 5 years ago
yit-cpt-unlimited.php
1783 lines
1 <?php
2 /*
3 * This file belongs to the YIT Framework.
4 *
5 * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6 * that is bundled with this package in the file LICENSE.txt.
7 * It is also available through the world-wide-web at this URL:
8 * http://www.gnu.org/licenses/gpl-3.0.txt
9 */
10 if (!defined('ABSPATH')) {exit('Direct access forbidden.');
11 }
12
13 /**
14 * Manage the custom post types as Portfolio, Contact Forms and similar (called CPTU)
15 *
16 * @class YIT_CPT_Unlimited
17 * @package YITH
18 * @since 2.0.0
19 * @author Your Inspiration Themes
20 *
21 */
22
23 class YIT_CPT_Unlimited {
24
25 /**
26 * @var string The name of main post type of CPTU
27 * @since 1.0
28 */
29 protected $_name = '';
30
31 /**
32 * @var string The prefix of each post type created by the post of main CPTU
33 * @since 1.0
34 */
35 protected $_prefix_cpt = '';
36
37 /**
38 * @var string The labels defined for the main CPTU
39 * @since 1.0
40 */
41 protected $_labels = '';
42
43 /**
44 * @var string The configuration arguments of post type
45 * @since 1.0
46 */
47 protected $_args = '';
48
49 /**
50 * @var array All post types created by the post of main CPTU
51 * @since 1.0
52 */
53 public $post_types = array();
54
55 /**
56 * @var array $layouts Array with all portfolio layouts available for this site
57 * @since 1.0
58 */
59 public $layouts = array();
60
61 /**
62 * @var string $template_path The pathname of template folder
63 * @since 1.0
64 */
65 protected $template_path = '';
66
67 /**
68 * @var string $template_url The URL of template folder
69 * @since 1.0
70 */
71 protected $template_url = '';
72
73 /**
74 * @var int $_index Unique sequential ID to differentiate same shortcodes in the same page
75 */
76 public $index = 0;
77
78 /**
79 * @var string $_layout Temporary attribute to load automatically the settings for each layout
80 * @since 1.0
81 */
82 private $_layout = '';
83
84
85 /**
86 * Constructor
87 *
88 * Accept an array of arguments to define the characteristics of CPTU to register.
89 *
90 * @since 1.0
91 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
92 */
93 public function __construct( $args = array() ) {
94
95 $defaults = array(
96 'name' => '',
97 'post_type_prefix' => '',
98 'labels' => array(
99 'main_name' => '',
100 'singular' => '',
101 'plural' => '',
102 'menu' => ''
103 ),
104 'manage_layouts' => false,
105 'add_multiuploader' => false,
106 'sortable' => false,
107 'has_single' => false,
108 'has_taxonomy' => false,
109 'label_item_sing' => '',
110 'label_item_plur' => '',
111 'shortcode_name' => '',
112 'shortcode_icon' => '', // URL or icon name from http://melchoyce.github.io/dashicons/
113 'layout_option' => '_type' // the option ID of layout metabox
114 );
115 $this->_args = wp_parse_args( $args, $defaults );
116
117 // fix labels
118 if ( empty( $this->_args['labels']['main_name'] ) ) {
119 $this->_args['labels']['main_name'] = $this->_args['labels']['singular'];
120 }
121 if ( empty( $this->_args['labels']['menu'] ) ) {
122 $this->_args['labels']['menu'] = $this->_args['labels']['singular'];
123 }
124
125 /* populate */
126 $this->_name = $this->_args['name'];
127 $this->_prefix_cpt = $this->_args['post_type_prefix'];
128 $this->_labels = $this->_args['labels'];
129
130 add_action( 'init', array( $this, 'register_post_type' ) );
131 add_action( 'init', array( $this, 'register_cptu_post_types' ) );
132
133 add_action( 'save_post', array( $this, 'rewrite_flush') );
134
135 // admin interface
136 add_action( 'admin_head', array( $this, 'add_cptu_menu_item' ) );
137 add_action( 'admin_init', array( $this, 'add_quick_links_metaboxes' ) );
138 add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) );
139
140 // metaboxes
141 if ( is_admin() ) {
142 add_action( 'init', array( $this, 'add_metabox_cptu' ) );
143 add_action( 'init', array( $this, 'add_metabox_item_fields' ) );
144 }
145
146 // multiuploader
147 if ( $this->_args['add_multiuploader'] ) {
148 add_action( 'admin_footer', array( $this, 'add_button_multiuploader' ) );
149 add_action( 'wp_ajax_yit_cptu_multiuploader', array( $this, 'post_multiuploader' ) );
150 }
151
152 // layouts
153 if ( $this->_args['manage_layouts'] ) {
154 // get all layouts available
155 $this->get_layouts();
156 }
157
158 // single layout
159 if ( $this->_args['has_single'] ) {
160 add_action( 'yit_loop', array( $this, 'single_template' ) );
161 add_action( 'wp', array( $this, 'single_template_config' ) );
162
163 if ( defined('DOING_AJAX') && DOING_AJAX ) {
164 add_action( 'init', array( $this, 'single_template_config' ) );
165 }
166 }
167
168 // archive template
169 add_action( 'wp', array( $this, 'archive_template' ) );
170
171 // enqueue the assets of each layout
172 add_action( 'wp_enqueue_scripts', array( $this, 'frontend_assets' ) );
173
174 // add the shortcode, used to show the frontend
175 if ( ! empty( $this->_args['shortcode_name'] ) ) {
176 add_shortcode( $this->_args['shortcode_name'], array( &$this, 'add_shortcode' ) );
177 add_filter( 'yit_shortcode_' . $this->_args['shortcode_name'] . '_icon', array( $this, 'shortcode_icon') );
178 add_filter( 'yit-shortcode-plugin-init', array( $this, 'add_shortcode_to_box' ) );
179 }
180
181 // add sortable feature
182 if ( $this->_args['sortable'] ) {
183 add_action( 'admin_enqueue_scripts', array( $this, 'admin_sortable_assets' ) );
184 add_action( 'wp_ajax_cpt_sort_posts', array( $this, 'sort_posts' ) );
185 add_action( 'admin_init', array( $this, 'init_menu_order' ) );
186 add_filter( 'pre_get_posts', array( $this, 'filter_active' ) );
187 add_filter( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
188 add_filter( 'get_next_post_where', array( $this, 'sorted_next_post_where' ) );
189 add_filter( 'get_previous_post_where', array( $this, 'sorted_prev_post_where' ) );
190 add_filter( 'get_next_post_sort', array( $this, 'sorted_next_post_sort' ) );
191 add_filter( 'get_previous_post_sort', array( $this, 'sorted_prev_post_sort' ) );
192 }
193
194 // add default columns to post type table list
195 add_filter( 'manage_edit-' . $this->_name . '_columns', array( $this, 'cptu_define_columns' ) );
196 add_action( 'manage_' . $this->_name . '_posts_custom_column' , array( $this, 'cptu_change_columns' ), 10, 2 );
197
198 // add required post type for wordpress importer
199 add_filter( 'wp_import_post_data_raw', array( $this, 'add_importer_required_post_type' ) );
200 add_filter( 'wp_import_terms', array( $this, 'add_importer_required_taxonomy' ) );
201 add_action( 'wp_import_set_post_terms', array( $this, 'recount_terms_post' ), 10, 3 );
202
203 }
204
205 /**
206 * Enqueue the assets for the sortable feature
207 *
208 * @return void
209 * @since 1.0
210 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
211 */
212 public function admin_sortable_assets() {
213 global $post;
214
215 if ( ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
216 return;
217 }
218
219 wp_enqueue_script( 'yit-cptu-sortable-posts', YIT_CORE_PLUGIN_URL . '/assets/js/yit-cptu-sortable-posts.js', array( 'jquery', 'jquery-ui-sortable' ), '1.0', true );
220 }
221
222 public function init_menu_order( $post_types = array() ) {
223 global $wpdb;
224
225 if ( empty( $post_types ) ) {
226 $post_types = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT post_type FROM $wpdb->posts WHERE post_type LIKE %s", str_replace( '_', '\_', $this->_prefix_cpt ) . '%' ) );
227 } elseif ( ! is_array( $post_types ) ) {
228 $post_types = array( $post_types );
229 }
230
231 foreach ( $post_types as $post_type ) {
232 $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = '{$post_type}' AND post_status IN ('publish', 'pending', 'draft', 'private', 'future') AND menu_order = 0" );
233
234 if ( empty( $count ) ) {
235 continue;
236 }
237
238 $sql = "SELECT ID
239 FROM $wpdb->posts
240 WHERE post_type = '" . $post_type . "'
241 AND post_status IN ('publish', 'pending', 'draft', 'private', 'future')
242 ORDER BY post_date DESC
243 ";
244
245 $results = $wpdb->get_results( $sql );
246
247 foreach ( $results as $key => $result ) {
248 $wpdb->update( $wpdb->posts, array( 'menu_order' => $key + 1 ), array( 'ID' => $result->ID ) );
249 }
250 }
251 }
252
253 /**
254 * Save the order of posts from sortable feature
255 *
256 * @return void
257 * @since 1.0
258 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
259 */
260 public function sort_posts() {
261 global $wpdb;
262
263 parse_str( $_REQUEST['order'], $data );
264
265 if ( is_array( $data ) ) {
266 //$this->init_menu_order( $_REQUEST['post_type'] );
267
268 $id_arr = array( );
269 foreach ( $data as $key => $values ) {
270 foreach ( $values as $position => $id ) {
271 $id_arr[] = $id;
272 }
273 }
274
275
276 $menu_order_arr = array( );
277 foreach ( $id_arr as $key => $id ) {
278 $results = $wpdb->get_results( "SELECT menu_order FROM $wpdb->posts WHERE ID = " . $id );
279 foreach ( $results as $result ) {
280 $menu_order_arr[] = $result->menu_order;
281 }
282 }
283
284 sort( $menu_order_arr );
285
286 foreach ( $data as $key => $values ) {
287 foreach ( $values as $position => $id ) {
288 $wpdb->update( $wpdb->posts, array( 'menu_order' => $menu_order_arr[$position] ), array( 'ID' => $id ) );
289 }
290 }
291 }
292
293 die();
294 }
295
296 public function filter_active( $wp_query ) {
297 if ( is_admin() && isset( $wp_query->query['suppress_filters'] ) )
298 $wp_query->query['suppress_filters'] = false;
299 if ( is_admin() && isset( $wp_query->query_vars['suppress_filters'] ) )
300 $wp_query->query_vars['suppress_filters'] = false;
301 return $wp_query;
302 }
303
304 public function pre_get_posts( $wp_query ) {
305 if ( is_admin() && !defined( 'DOING_AJAX' ) ) {
306 if ( isset( $wp_query->query['post_type'] ) ) {
307 $post_types = (array) $wp_query->query['post_type'];
308 foreach ( $post_types as $post_type ) {
309 if ( $this->_is_valid( $post_type ) ) {
310 $wp_query->set( 'orderby', 'menu_order' );
311 $wp_query->set( 'order', 'ASC' );
312 }
313 }
314 }
315
316 } else {
317
318 $active = false;
319
320 if ( isset( $wp_query->query['suppress_filters'] ) || isset( $wp_query->query['post_type'] ) ) {
321 $post_types = (array) $wp_query->query['post_type'];
322 foreach ( $post_types as $post_type ) {
323 if ( $this->_is_valid( $post_type ) ) {
324 $active = true;
325 }
326 }
327 }
328
329 if ( $active ) {
330 if ( !isset( $wp_query->query['orderby'] ) || $wp_query->query['orderby'] == 'post_date' )
331 $wp_query->set( 'orderby', 'menu_order' );
332 if ( !isset( $wp_query->query['order'] ) || $wp_query->query['order'] == 'DESC' )
333 $wp_query->set( 'order', 'ASC' );
334 }
335 }
336 }
337
338 /**
339 * Filters where clause for get next post
340 *
341 * @param $where
342 *
343 * @return string
344 * @since 1.0
345 * @author Antonio La Rocca <antonio.larocca@yithemes.com>
346 */
347 public function sorted_next_post_where( $where ){
348 global $post;
349 if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
350 $post = get_post( intval( $_REQUEST['post_id'] ) );
351 }
352 else{
353 $post = get_post();
354 }
355
356 if( ! $post || ! $this->_is_valid( $post->post_type ) ){
357 return $where;
358 }
359
360 $result = str_replace( "'" . $post->post_date . "'", $post->menu_order, $where );
361 $result = str_replace( 'p.post_date', 'p.menu_order', $result );
362
363 return $result;
364 }
365
366 /**
367 * Filters where clause for get prev post
368 *
369 * @param $where
370 *
371 * @return string
372 * @since 1.0
373 * @author Antonio La Rocca <antonio.larocca@yithemes.com>
374 */
375 public function sorted_prev_post_where( $where ){
376 global $post;
377
378 if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
379 $post = get_post( intval( $_REQUEST['post_id'] ) );
380 }
381 else{
382 $post = get_post();
383 }
384
385 if( ! $post || ! $this->_is_valid( $post->post_type ) ){
386 return $where;
387 }
388
389 $result = str_replace( "'" . $post->post_date . "'", $post->menu_order, $where );
390 $result = str_replace( 'p.post_date', 'p.menu_order', $result );
391
392 return $result;
393 }
394
395 /**
396 * Filters sort clause for get next post
397 *
398 * @param $sort
399 *
400 * @return string
401 * @since 1.0
402 * @author Antonio La Rocca <antonio.larocca@yithemes.com>
403 */
404 public function sorted_next_post_sort( $sort ){
405 global $post;
406
407 if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
408 $post = get_post( intval( $_REQUEST['post_id'] ) );
409 }
410 else{
411 $post = get_post();
412 }
413
414 if( ! $post || ! $this->_is_valid( $post->post_type ) ){
415 return $sort;
416 }
417
418 $result = str_replace( 'p.post_date', 'p.menu_order', $sort );
419 return $result;
420 }
421
422 /**
423 * Filters sort clause for get prev post
424 *
425 * @param $sort
426 *
427 * @return string
428 * @since 1.0
429 * @author Antonio La Rocca <antonio.larocca@yithemes.com>
430 */
431 public function sorted_prev_post_sort( $sort ){
432 global $post;
433
434 if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
435 $post = get_post( intval( $_REQUEST['post_id'] ) );
436 }
437 else{
438 $post = get_post();
439 }
440
441 if( ! $post || ! $this->_is_valid( $post->post_type ) ){
442 return $sort;
443 }
444
445 $result = str_replace( 'p.post_date', 'p.menu_order', $sort );
446 return $result;
447 }
448
449 /**
450 * Register post type
451 *
452 * Register the post type for the creation of portfolios
453 *
454 * @return void
455 * @since 1.0
456 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
457 */
458 public function register_post_type() {
459 $labels = array(
460 'name' => ucfirst( $this->_labels['main_name'] ),
461 'singular_name' => ucfirst( $this->_labels['singular'] ),
462 'add_new' => sprintf( __( 'Add %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['singular'] ) ),
463 'add_new_item' => sprintf( __( 'Add New %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['singular'] ) ),
464 'edit_item' => sprintf( __( 'Edit %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['singular'] ) ),
465 'new_item' => sprintf( __( 'New %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['singular'] ) ),
466 'all_items' => sprintf( __( 'All %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['plural'] ) ),
467 'view_item' => sprintf( __( 'View %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['singular'] ) ),
468 'search_items' => sprintf( __( 'Search %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['plural'] ) ),
469 'not_found' => sprintf( __( 'No %s found', 'yith-plugin-fw' ), ucfirst( $this->_labels['plural'] ) ),
470 'not_found_in_trash' => sprintf( __( 'No %s found in Trash', 'yith-plugin-fw' ), ucfirst( $this->_labels['plural'] ) ),
471 'parent_item_colon' => '',
472 'menu_name' => ucfirst( $this->_labels['menu'] )
473 );
474
475 $args = array(
476 'labels' => apply_filters( 'yit_' . $this->_name . '_labels', $labels ),
477 'public' => false,
478 'publicly_queryable' => false,
479 'show_ui' => true,
480 'show_in_menu' => true,
481 'query_var' => false,
482 'capability_type' => 'post',
483 'hierarchical' => false,
484 'menu_position' => null,
485 'supports' => array( 'title' )
486 );
487
488 if ( ! empty( $this->_args['menu_icon'] ) ) {
489 $args['menu_icon'] = $this->_args['menu_icon'];
490 }
491
492 register_post_type( $this->_name, apply_filters( 'yit_' . $this->_name . '_args', $args ) );
493 }
494
495 /**
496 * Retrieve the values configured inside the custom post type
497 *
498 * @param $post /WP_Query The post where get the arguments configured in the cpt
499 *
500 * @return array
501 * @since 1.0
502 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
503 */
504 protected function _cpt_args( $post ) {
505 if ( ! isset( $post->ID ) ) {
506 return;
507 }
508
509 $args = apply_filters( 'yit_cptu_register_post_type_args', array(
510 'layout' => get_post_meta( $post->ID, $this->_args['layout_option'], true ),
511 'rewrite' => get_post_meta( $post->ID, '_rewrite', true ),
512 'label_singular' => ! empty( $this->_args['label_item_sing'] ) ? $this->_args['label_item_sing'] : get_post_meta( $post->ID, '_label_singular', true ),
513 'label_plural' => ! empty( $this->_args['label_item_plur'] ) ? $this->_args['label_item_plur'] : get_post_meta( $post->ID, '_label_plural', true ),
514 'taxonomy' => get_post_meta( $post->ID, '_taxonomy', true ),
515 'taxonomy_rewrite' => get_post_meta( $post->ID, '_taxonomy_rewrite', true ),
516 ), $this->_name, $post );
517
518 $title = $post->post_title;
519
520 if ( empty( $args['label_singular'] ) ) {
521 $args['label_singular'] = $title;
522 }
523
524 if ( empty( $args['label_plural'] ) ) {
525 $args['label_plural'] = $title;
526 }
527
528 return $args;
529 }
530
531 /**
532 * Retrieve the post types created for this CPTU
533 *
534 * @return array The link changed
535 * @since 1.0
536 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
537 */
538 public function get_post_types() {
539 if ( ! empty( $this->post_types ) ) {
540 return $this->post_types;
541 }
542
543 $args = array(
544 'post_type' => $this->_name,
545 'posts_per_page' => -1,
546 'post_status' => 'publish'
547 );
548 $this->post_types = get_posts( $args );
549
550 return $this->post_types;
551 }
552
553 /**
554 * Register portfolio post types
555 *
556 * Register the post types for each portfolio created by admin
557 *
558 * @return void
559 * @since 1.0
560 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
561 */
562 public function register_cptu_post_types() {
563 $post_types = $this->get_post_types();
564 $pts = array();
565
566 foreach ( $post_types as $pt ) {
567
568 extract( $this->_cpt_args( $pt ) );
569
570 $name = $pt->post_name;
571 $title = $pt->post_title;
572
573 $labels = array(
574 'name' => $title,
575 'singular_name' => $label_singular,
576 'add_new' => sprintf( __( 'Add %s', 'yith-plugin-fw' ), $label_singular ),
577 'add_new_item' => sprintf( __( 'Add New %s', 'yith-plugin-fw' ), $label_singular ),
578 'edit_item' => sprintf( __( 'Edit %s', 'yith-plugin-fw' ), $label_singular ),
579 'new_item' => sprintf( __( 'New %s', 'yith-plugin-fw' ), $label_singular ),
580 'all_items' => sprintf( __( 'All %s', 'yith-plugin-fw' ), $label_plural ),
581 'view_item' => sprintf( __( 'View %s', 'yith-plugin-fw' ), $label_singular ),
582 'search_items' => sprintf( __( 'Search %s', 'yith-plugin-fw' ), $label_plural ),
583 'not_found' => sprintf( __( 'No %s found', 'yith-plugin-fw' ), $label_plural ),
584 'not_found_in_trash' => sprintf( __( 'No %s found in Trash', 'yith-plugin-fw' ), $label_plural ),
585 'parent_item_colon' => '',
586 'menu_name' => $title
587 );
588
589 $args = array(
590 'labels' => apply_filters( 'yit_' . $this->_prefix_cpt . $name . '_labels', $labels ),
591 'public' => true,
592 'publicly_queryable' => true,
593 'show_ui' => true,
594 'show_in_menu' => false,
595 'query_var' => true,
596 'capability_type' => 'post',
597 'hierarchical' => false,
598 'menu_position' => null,
599 'supports' => array( 'title', 'editor', 'thumbnail' )
600 );
601
602 if ( ! $this->_args['has_single'] ) {
603 $args['public'] = false;
604 $args['publicly_queryable'] = false;
605 $args['query_var'] = false;
606 }
607
608 if ( $this->_args['manage_layouts'] && isset($this->layouts[ $layout ]) && ! $this->layouts[ $layout ]['support']['description'] ) {
609 unset( $args['supports'][1] ); // remove 'editor'
610 }
611
612 if ( ! empty( $rewrite ) ) {
613 $args['rewrite'] = array( 'slug' => $rewrite );
614 }
615
616 // register post type
617 $post_type = yit_avoid_duplicate( str_replace( '-', '_', substr( $this->_prefix_cpt . $name, 0, 16) ), $post_types );
618 register_post_type( $post_type, apply_filters( 'yit_' . $this->_prefix_cpt . $name . '_args', $args, $pt ) ); // save the post type in post meta
619
620 update_post_meta( $pt->ID, '_post_type', $post_type );
621 $pts[] = $post_type;
622
623 // register taxonomy
624 if ( $this->_args['has_taxonomy'] && ! empty( $taxonomy ) ) {
625
626 $labels = array(
627 'name' => sprintf( _x( '%s Categories', 'taxonomy general name', 'yith-plugin-fw' ), $label_singular ),
628 'singular_name' => _x( 'Category', 'taxonomy singular name', 'yith-plugin-fw' ),
629 'search_items' => __( 'Search Categories', 'yith-plugin-fw' ),
630 'all_items' => __( 'All Categories', 'yith-plugin-fw' ),
631 'parent_item' => __( 'Parent Category', 'yith-plugin-fw' ),
632 'parent_item_colon' => __( 'Parent Category:', 'yith-plugin-fw' ),
633 'edit_item' => __( 'Edit Category', 'yith-plugin-fw' ),
634 'update_item' => __( 'Update Category', 'yith-plugin-fw' ),
635 'add_new_item' => __( 'Add New Category', 'yith-plugin-fw' ),
636 'new_item_name' => __( 'New Category Name', 'yith-plugin-fw' ),
637 'menu_name' => __( 'Category', 'yith-plugin-fw' ),
638 );
639
640 $args = array(
641 'hierarchical' => true,
642 'labels' => $labels,
643 'show_ui' => true,
644 'show_admin_column' => true,
645 'query_var' => true,
646 );
647
648 if ( ! empty( $taxonomy_rewrite ) ) {
649 $args['rewrite'] = array( 'slug' => $taxonomy_rewrite );
650 }
651
652 register_taxonomy( substr( $taxonomy, 0, 32 ), $post_type, $args );
653
654 }
655
656 }
657
658 wp_cache_set( 'yit_cptu_post_types', $post_types );
659 }
660
661 /**
662 * Flush Rewrite Rules
663 *
664 * rewrite rules when a cpt unlimited is saved
665 *
666 * @return void
667 * @since 1.0
668 * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
669 */
670
671 public function rewrite_flush( $post ){
672
673 if ( isset( $post ) && $this->_is_valid( get_post_type( intval( $post ) ) ) ) {
674 flush_rewrite_rules();
675 }
676
677 }
678
679 /**
680 * Add the item for each portfolio under "Portfolios"
681 *
682 * @return void
683 * @since 1.0
684 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
685 */
686 public function add_cptu_menu_item() {
687 global $submenu, $post, $parent_file, $pagenow;
688
689 // get current post type
690 if ( isset( $post->post_type ) ) {
691 $post_type = $post->post_type;
692 } else if ( isset( $_REQUEST['post_type'] ) ) {
693 $post_type = $_REQUEST['post_type'];
694 } else {
695 return;
696 }
697
698 $item = 'edit.php?post_type=' . $this->_name;
699
700 // add new items
701 if ( strpos( $post_type, $this->_prefix_cpt ) !== false ) {
702 global $wpdb;
703 $portfolio = $wpdb->get_row( $wpdb->prepare( "SELECT p.* FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $post_type, $this->_name ) );
704
705 if ( ! isset( $portfolio->ID ) ) {
706 return;
707 }
708
709 $label_singular = ! empty( $this->_args['label_item_sing'] ) ? $this->_args['label_item_sing'] : get_post_meta( $portfolio->ID, '_label_singular', true );
710 $label_plural = ! empty( $this->_args['label_item_plur'] ) ? $this->_args['label_item_plur'] : get_post_meta( $portfolio->ID, '_label_plural', true );
711
712 if ( empty( $label_plural ) ) {
713 $label_plural = $portfolio->post_title;
714 }
715
716 if ( empty( $label_singular ) ) {
717 $label_singular = $portfolio->post_title;
718 }
719
720 $submenu[ $item ][15] = array( ucfirst( $label_plural ), 'edit_posts', 'edit.php?post_type=' . $post_type );
721 $submenu[ $item ][20] = array( sprintf( __('Add %s', 'yith-plugin-fw'), ucfirst( $label_singular ) ), 'edit_posts', 'post-new.php?post_type=' . $post_type );
722
723 global $wp_taxonomies;
724 $taxonomy = get_post_meta( $portfolio->ID, '_taxonomy', true );
725 if ( isset( $wp_taxonomies[ $taxonomy ] ) ) {
726 $submenu[ $item ][25] = array( __('Categories', 'yith-plugin-fw'), 'edit_posts', 'edit-tags.php?taxonomy=' . $taxonomy . '&post_type=' . $post_type );
727 }
728 }
729
730 // set the parent item inside the single of each post type
731 if ( $pagenow == 'post.php' && isset( $_GET['post'] ) && $this->_is_valid( get_post_type( intval( $_GET['post'] ) ) ) ) {
732 $parent_file = 'edit.php?post_type=' . $this->_name;
733 }
734 }
735
736 /**
737 * Locate folder of CPTU templates, if there isn't a layouts management
738 *
739 * @return string
740 * @since 1.0
741 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
742 */
743 public function template_path() {
744 if ( ! empty( $this->template_path ) ) {
745 return $this->template_path;
746 }
747
748 // paths
749 $stylesheet_path_1 = get_stylesheet_directory() . '/theme/templates/' . $this->_name . '/';
750 $stylesheet_path_2 = get_template_directory() . '/theme/templates/' . $this->_name . '/';
751 $template_path_1 = get_stylesheet_directory() . '/' . $this->_name . '/';
752 $template_path_2 = get_template_directory() . '/' . $this->_name . '/';
753 $plugin_path = $this->_args['plugin_path'] . '/templates/';
754
755 foreach ( array( 'stylesheet_path_1', 'stylesheet_path_2', 'template_path_1', 'template_path_2', 'plugin_path' ) as $var ) {
756 $path = ${$var};
757
758 if ( file_exists( $path ) ) {
759 $this->template_path = $path;
760 }
761 }
762
763 return $this->template_path;
764 }
765
766 /**
767 * Locate folder of CPTU templates, if there isn't a layouts management
768 *
769 * @return string
770 * @since 1.0
771 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
772 */
773 public function template_url() {
774 if ( ! empty( $this->template_url ) ) {
775 return $this->template_path;
776 }
777
778 $this->template_url = str_replace( array(
779 get_stylesheet_directory(),
780 get_template_directory(),
781 $this->_args['plugin_path']
782 ), array(
783 get_stylesheet_directory_uri(),
784 get_template_directory_uri(),
785 $this->_args['plugin_url']
786 ), $this->template_path() );
787
788 return $this->template_url;
789 }
790
791 /**
792 * Retrieve all layouts to manage by custom post type added in the site in this order:
793 * 1. Child theme (if exists)
794 * 2. Theme
795 * 3. Plugin
796 *
797 * It also load the config.php file of each layout
798 *
799 * @return void
800 * @since 1.0
801 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
802 */
803 public function get_layouts() {
804
805 // paths
806 $stylesheet_path_1 = get_stylesheet_directory() . '/theme/templates/' . $this->_name . '/';
807 $stylesheet_path_2 = get_template_directory() . '/theme/templates/' . $this->_name . '/';
808 $template_path_1 = get_stylesheet_directory() . '/' . $this->_name . '/';
809 $template_path_2 = get_template_directory() . '/' . $this->_name . '/';
810 $plugin_path = $this->_args['plugin_path'] . '/templates/';
811
812 foreach ( array( 'stylesheet_path_1', 'stylesheet_path_2', 'template_path_1', 'template_path_2', 'plugin_path' ) as $var ) {
813 $path = ${$var};
814
815 if ( file_exists( $path ) ) {
816 foreach ( scandir( $path ) as $scan ) {
817 if ( ! isset( $this->layouts[$scan] ) && is_dir( $path . $scan ) && ! in_array( $scan, array( '.', '..', '.svn' ) ) && $scan[0] != '_' ) {
818 $this->layouts[$scan] = array(
819 'name' => ucfirst( str_replace( '-', ' ', $scan ) ),
820 'path' => $path . $scan,
821 'url' => str_replace( array(
822 get_stylesheet_directory(),
823 get_template_directory(),
824 $this->_args['plugin_path']
825 ), array(
826 get_stylesheet_directory_uri(),
827 get_template_directory_uri(),
828 $this->_args['plugin_url']
829 ), $path . $scan ),
830 'css' => array(),
831 'js' => array(),
832 'support' => array(
833 'description' => true
834 ),
835 'columns' => array()
836 );
837
838 // set the vars for config.php
839 $layout = $scan;
840 $this->_layout = $layout; // temporary attribute to load automatically the configuration inside the config.php, for this layout
841
842 // TODO Fare in modo di caricare il file config.php soltanto quando realmente serve
843 if ( ! in_array( $scan, array( 'single' ) ) && file_exists( $path . $scan . '/config.php' ) ) {
844 include_once( $path . $scan . '/config.php' );
845 }
846 }
847 }
848 }
849
850 }
851 }
852
853 /**
854 * Say if you want to set description for the current layout or not. This method must be used only inside the
855 * config.php file of layout
856 *
857 * @param $v string 'yes' or 'no'
858 *
859 * @return void
860 * @since 1.0
861 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
862 */
863 public function add_description_field( $v ) {
864 $this->layouts[ $this->_layout ]['support']['description'] = $v == 'yes' ? true : false;
865 }
866
867 /**
868 * Add the extra fields for the specific layout type of portfolio
869 *
870 * @param array $fields The fields to add
871 *
872 * @return void
873 * @since 1.0
874 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
875 */
876 public function add_layout_fields( $fields = array() ) {
877 // change the ID
878 foreach ( $fields as $id => $val ) {
879 unset( $fields[ $id ] );
880 $id = $this->_layout . '_' . $id;
881 $fields[ $id ] = $val;
882 }
883
884 $this->layouts[ $this->_layout ]['fields'] = $fields;
885 }
886
887 /**
888 * Add fields to add to the metabox of each item of each post type created
889 *
890 * @param array $fields The fields to add
891 *
892 * @return void
893 * @since 1.0
894 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
895 */
896 public function add_item_fields( $fields = array() ) {
897 // change the ID
898 foreach ( $fields as $id => $val ) {
899 unset( $fields[ $id ] );
900 //$id = $this->_layout . '_' . $id;
901 $fields[ $id ] = $val;
902 }
903 $this->layouts[ $this->_layout ]['item_fields'] = $fields;
904 }
905
906 /**
907 * Add columns to the table list
908 *
909 * @param array $columns The columns to add in the table list
910 *
911 * @return void
912 * @since 1.0
913 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
914 */
915 public function add_table_columns( $columns ) {
916 $this->layouts[ $this->_layout ]['columns'] = $columns;
917 }
918
919 /**
920 * Enqueue the css files of layout
921 *
922 * @param string $handle Name of the stylesheet.
923 * @param string|bool $src Path to the stylesheet from the root directory of WordPress. Example: '/css/mystyle.css'.
924 * @param array $deps An array of registered style handles this stylesheet depends on. Default empty array.
925 * @param string|bool $ver String specifying the stylesheet version number, if it has one. This parameter is used
926 * to ensure that the correct version is sent to the client regardless of caching, and so
927 * should be included if a version number is available and makes sense for the stylesheet.
928 * @param string $media Optional. The media for which this stylesheet has been defined.
929 * Default 'all'. Accepts 'all', 'aural', 'braille', 'handheld', 'projection', 'print',
930 * 'screen', 'tty', or 'tv'.
931 *
932 * @return void
933 * @since 1.0
934 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
935 */
936 public function enqueue_style( $handle, $src = false, $deps = array(), $ver = false, $media = 'all' ) {
937 $this->layouts[ $this->_layout ]['css'][] = compact( 'handle', 'src', 'deps', 'ver', 'media' );
938 }
939
940 /**
941 * Enqueue the js files of layout
942 *
943 * @param string $handle Name of the script.
944 * @param string|bool $src Path to the script from the root directory of WordPress. Example: '/js/myscript.js'.
945 * @param array $deps An array of registered handles this script depends on. Default empty array.
946 * @param string|bool $ver Optional. String specifying the script version number, if it has one. This parameter
947 * is used to ensure that the correct version is sent to the client regardless of caching,
948 * and so should be included if a version number is available and makes sense for the script.
949 * @param bool $in_footer Optional. Whether to enqueue the script before </head> or before </body>.
950 * Default 'false'. Accepts 'false' or 'true'.
951 *
952 * @return void
953 * @since 1.0
954 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
955 */
956 public function enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false ) {
957 $this->layouts[ $this->_layout ]['js'][] = compact( 'handle', 'src', 'deps', 'ver', 'in_footer' );
958 }
959
960 /**
961 * Enqueue the assets for the frontend
962 *
963 * @return void
964 * @since 1.0
965 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
966 */
967 public function frontend_assets() {
968 global $post;
969
970 // not single
971 if ( ! is_single() || ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
972 $posts = get_posts(array(
973 'post_type' => $this->_name,
974 'posts_per_page' => -1,
975 'post_status' => 'publish',
976 'fields' => 'ids'
977 ));
978
979 $enqueued = array();
980
981 foreach ( $posts as $post_id ) {
982 $layout = get_post_meta( $post_id, $this->_args['layout_option'], true );
983
984 if ( in_array( $layout, array( $enqueued ) ) || ! isset( $this->layouts[ $layout ]['css'] ) ) {
985 continue;
986 }
987
988 foreach ( $this->layouts[ $layout ]['css'] as $asset ) {
989 if ( empty( $asset ) ) {
990 continue;
991 }
992 yit_enqueue_style( $asset['handle'], empty( $asset['src'] ) ? false : $this->locate_url( $layout ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['media'] );
993 }
994
995 $enqueued[] = $layout;
996 }
997 }
998
999 // load assets of single template
1000 else {
1001 $layout = 'single';
1002
1003 if ( ! isset( $this->layouts[ $layout ]['css'] ) ) {
1004 return;
1005 }
1006
1007 foreach ( $this->layouts[ $layout ]['css'] as $asset ) {
1008 if ( empty( $asset ) ) {
1009 continue;
1010 }
1011 yit_enqueue_style( $asset['handle'], $this->locate_url( $layout ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['media'] );
1012 }
1013 }
1014
1015 }
1016
1017 /**
1018 * Register Metaboxes options
1019 *
1020 * Add the metabox for the portfolio settings
1021 *
1022 * @return void
1023 * @since 1.0
1024 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1025 */
1026 public function add_metabox_cptu() {
1027
1028 // Reorganize layouts
1029 if ( $this->_args['manage_layouts'] ) {
1030 $layouts = array();
1031 foreach ( $this->layouts as $layout_id => $layout ) {
1032 if ( 'single' == $layout_id ) {
1033 continue;
1034 }
1035 $layouts[ $layout_id ] = $layout['name'];
1036 }
1037
1038 $layouts = apply_filters( 'yit_cptu_' . $this->_name . '_layout_values', $layouts );
1039 }
1040
1041 $single_layouts = apply_filters( 'yit_cptu_' . $this->_name . '_single_layout_values', array() );
1042
1043 $metabox_args = array(
1044 'label' => sprintf( __( '%s Settings', 'yith-plugin-fw' ), $this->_labels['singular'] ),
1045 'pages' => $this->_name, //or array( 'post-type1', 'post-type2')
1046 'context' => 'normal', //('normal', 'advanced', or 'side')
1047 'priority' => 'default',
1048 'tabs' => array(
1049 'settings' => array(
1050 'label' => __( 'Settings', 'yith-plugin-fw' ),
1051 'fields' => apply_filters( 'yit_cptu_fields', array(
1052 'type' => array(
1053 'label' => __( 'Type', 'yith-plugin-fw' ),
1054 'desc' => sprintf( __( 'Layout for this %s' , 'yith-plugin-fw' ), strtolower( $this->_labels['singular'] ) ),
1055 'type' => 'select',
1056 'options' => isset( $layouts ) ? $layouts : array(),
1057 'std' => '' ),
1058
1059 'rewrite' => array(
1060 'label' => __( 'Rewrite', 'yith-plugin-fw' ),
1061 'desc' => __( 'Univocal identification name in the URL for each product (slug from post if empty)', 'yith-plugin-fw' ),
1062 'type' => 'text',
1063 'std' => '' ),
1064
1065 'label_singular' => array(
1066 'label' => __( 'Label in Singular', 'yith-plugin-fw' ),
1067 'desc' => __( 'Set a label in singular (title of portfolio if empty)', 'yith-plugin-fw' ),
1068 'type' => 'text',
1069 'std' => '' ),
1070
1071 'label_plural' => array(
1072 'label' => __( 'Label in Plural', 'yith-plugin-fw' ),
1073 'desc' => __( 'Set a label in plural (title of portfolio if empty)', 'yith-plugin-fw' ),
1074 'type' => 'text',
1075 'std' => '' ),
1076
1077 'taxonomy' => array(
1078 'label' => __( 'Taxonomy', 'yith-plugin-fw' ),
1079 'desc' => __( 'If you want to use categories in the portfolio, set a name for taxonomy. Name should be a slug (must not contain capital letters nor spaces) and must not be more than 32 characters long (database structure restriction).', 'yith-plugin-fw' ),
1080 'type' => 'text',
1081 'std' => '' ),
1082
1083 'taxonomy_rewrite' => array(
1084 'label' => __( 'Taxonomy Rewrite', 'yith-plugin-fw' ),
1085 'desc' => __( 'Set univocal name for each category page URL.', 'yith-plugin-fw' ),
1086 'type' => 'text',
1087 'std' => '' ),
1088
1089 'single_layout' => array(
1090 'label' => __( 'Single layout', 'yith-plugin-fw' ),
1091 'desc' => __( 'Layout for single page of this portfolio', 'yith-plugin-fw' ),
1092 'type' => 'select',
1093 'options' => $single_layouts,
1094 'std' => '' ),
1095 ) )
1096 )
1097 )
1098
1099 );
1100
1101 if ( ! $this->_args['has_single'] ) {
1102 unset( $metabox_args['tabs']['settings']['fields']['rewrite'] );
1103 }
1104
1105 if ( ! $this->_args['has_taxonomy'] ) {
1106 unset( $metabox_args['tabs']['settings']['fields']['taxonomy'] );
1107 unset( $metabox_args['tabs']['settings']['fields']['taxonomy_rewrite'] );
1108 }
1109
1110 if ( ! empty( $this->_args['label_item_sing'] ) ) {
1111 unset( $metabox_args['tabs']['settings']['fields']['label_singular'] );
1112 }
1113
1114 if ( ! empty( $this->_args['label_item_plur'] ) ) {
1115 unset( $metabox_args['tabs']['settings']['fields']['label_plural'] );
1116 }
1117
1118 if ( $this->_args['manage_layouts'] ) {
1119
1120 if ( count( $layouts ) < 1 ) {
1121 unset( $metabox_args['tabs']['settings']['fields']['type'] );
1122 }
1123
1124 // Layouts options
1125 foreach ( $this->layouts as $layout => $args ) {
1126 if ( ! isset( $args['fields'] ) ) {
1127 continue;
1128 }
1129
1130 // Section title
1131 $metabox_args['tabs']['settings']['fields'][ $layout . '_title' ] = array(
1132 'desc' => $args['name'] . ' ' . __( 'layout settings', 'yith-plugin-fw' ),
1133 'type' => 'title',
1134 'deps' => array(
1135 'ids' => '_type',
1136 'values' => $layout
1137 )
1138 );
1139
1140 // Options
1141 foreach( $args['fields'] as $field_id => $field ) {
1142 $metabox_args['tabs']['settings']['fields'][ $field_id ] = $field;
1143 $metabox_args['tabs']['settings']['fields'][ $field_id ]['deps'] = array(
1144 'ids' => '_type',
1145 'values' => $layout
1146 );
1147 }
1148 }
1149 }else {
1150 unset( $metabox_args['tabs']['settings']['fields']['type'] );
1151 }
1152
1153 if( count( $single_layouts ) < 1 ){
1154 unset( $metabox_args['tabs']['settings']['fields']['single_layout'] );
1155 }
1156
1157 // undo if tab empty
1158 if ( empty( $metabox_args['tabs']['settings']['fields'] ) ) {
1159 return;
1160 }
1161
1162 $metabox = YIT_Metabox( $this->_name . '_cptu_settings' );
1163 $metabox->init( $metabox_args );
1164 }
1165
1166 /**
1167 * Register Metaboxes options
1168 *
1169 * Add the metabox for the portfolio settings
1170 *
1171 * @return void
1172 * @since 1.0
1173 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1174 */
1175 public function add_metabox_item_fields() {
1176 global $pagenow, $post_type;
1177
1178 // get the actual post type, to add the metabox only if necessary
1179 if ( $pagenow == 'post.php' && isset( $_REQUEST['post'] ) ) {
1180 $post_type = get_post_type( intval( $_REQUEST['post'] ) );
1181 }
1182 elseif( $pagenow == 'post.php' && isset( $_REQUEST['post_ID'] ) ){
1183 $post_type = get_post_type( intval( $_REQUEST['post_ID'] ) );
1184 }
1185 elseif ( $pagenow == 'post-new.php' && isset( $_REQUEST['post_type'] ) ) {
1186 $post_type = $_REQUEST['post_type'];
1187 } else {
1188 return;
1189 }
1190
1191 $layout = get_post_meta( $this->_get_id_by_name( $post_type ), $this->_args['layout_option'], true );
1192
1193 if ( empty( $this->layouts[ $layout ]['item_fields'] ) ) {
1194 return;
1195 }
1196
1197 $metabox_args = array(
1198 'label' => __( 'Settings', 'yith-plugin-fw' ),
1199 'pages' => $post_type, //or array( 'post-type1', 'post-type2')
1200 'context' => 'normal', //('normal', 'advanced', or 'side')
1201 'priority' => 'default',
1202 'tabs' => array(
1203 'settings' => array(
1204 'label' => __( 'Settings', 'yith-plugin-fw' ),
1205 'fields' => $this->layouts[ $layout ]['item_fields']
1206 )
1207 )
1208 );
1209
1210 $metabox = YIT_Metabox( $post_type . '_item_fields' );
1211 $metabox->init( $metabox_args );
1212
1213 }
1214
1215 /**
1216 * Add quick links inside the editing page of CPTU and Custom Post Types
1217 *
1218 * @return void
1219 * @since 1.0
1220 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1221 */
1222 public function add_quick_links_metaboxes() {
1223 // CPTU
1224 add_meta_box( $this->_name . '_quick_links', __( 'Quick links', 'yith-plugin-fw' ), array( $this, 'quick_links_cptu_inner' ), $this->_name, 'side', 'high' );
1225
1226 // CPTs
1227 $args = array(
1228 'post_type' => $this->_name,
1229 'posts_per_page' => -1,
1230 'post_status' => 'publish'
1231 );
1232 $post_types = get_posts( $args );
1233
1234 foreach ( $post_types as $post ) {
1235 $post_type = get_post_meta( $post->ID, '_post_type', true );
1236 extract( $this->_cpt_args( $post ) );
1237 add_meta_box( $post->post_type . '_quick_links', __( 'Quick links', 'yith-plugin-fw' ), array( $this, 'quick_links_cpt_inner' ), $post_type, 'side', 'high' );
1238 }
1239 }
1240
1241 /**
1242 * Link to: "View Items", inside the CPTU
1243 *
1244 * @param $post
1245 *
1246 * @return void
1247 * @since 1.0
1248 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1249 */
1250 public function quick_links_cptu_inner( $post ) {
1251 extract( $this->_cpt_args( $post ) );
1252 ?>
1253 <a href="<?php echo admin_url( 'edit.php?post_type=' . get_post_meta( $post->ID, '_post_type', true ) ) ?>"><?php printf( __( 'View %s', 'yith-plugin-fw' ), $label_plural ) ?></a>
1254 <?php
1255 }
1256
1257 /**
1258 * Link to: "Edit %s", inside the CPTU
1259 *
1260 * @param $post
1261 *
1262 * @return void
1263 * @since 1.0
1264 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1265 */
1266 public function quick_links_cpt_inner( $post ) {
1267 $post = get_post( $this->_get_id_by_name( $post->post_type ) );
1268 ?>
1269 <a href="<?php echo admin_url( "post.php?post={$post->ID}&action=edit" ) ?>"><?php printf( __( 'Edit %s', 'yith-plugin-fw' ), $post->post_title ) ?></a>
1270 <?php
1271 }
1272
1273 /**
1274 * Define the columns to use in the list table of main sliders post type
1275 *
1276 * @param $columns array The columns used in the list table
1277 *
1278 * @return array
1279 * @since 1.0
1280 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1281 */
1282 public function cptu_define_columns( $columns ) {
1283 unset( $columns['date'] );
1284
1285 $columns['actions'] = '';
1286
1287 return $columns;
1288 }
1289
1290 /**
1291 * Change the content of each column of the table list
1292 *
1293 * @param $column string The current column
1294 * @param $post_id int The current post ID
1295 *
1296 * @return void
1297 * @since 1.0
1298 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1299 */
1300 public function cptu_change_columns( $column, $post_id ) {
1301 $post = get_post( $post_id );
1302 extract( $this->_cpt_args( $post ) );
1303
1304 switch ( $column ) {
1305 case 'actions' :
1306 echo '<a href="' . admin_url( "post.php?post={$post_id}&action=edit" ) . '" class="button-secondary">' . sprintf( __( 'Edit %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['singular'] ) ) . '</a> ';
1307 echo '<a href="' . admin_url( 'edit.php?post_type=' . get_post_meta( $post_id, '_post_type', true ) ) . '" class="button-secondary">' . sprintf( __( 'View %s', 'yith-plugin-fw' ), $label_plural ) . '</a> ';
1308 break;
1309 }
1310 }
1311
1312 /**
1313 * Retrieve the path of layout specified in parameter
1314 *
1315 * @param $layout
1316 * @param $file string The file to find
1317 *
1318 * @return bool|string
1319 * @since 1.0
1320 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1321 */
1322 public function locate_file( $layout, $file = '' ) {
1323 if ( ! $this->_args['manage_layouts'] ) {
1324 return $this->template_path(). '/' . ( ! empty( $file ) ? $file . '.php' : '' );
1325 }
1326
1327 if ( ! isset( $this->layouts[ $layout ] ) ) {
1328 $layout = 'default';
1329 }
1330
1331 return $this->layouts[ $layout ]['path'] . '/' . ( ! empty( $file ) ? $file . '.php' : '' );
1332 }
1333
1334 /**
1335 * Retrieve the URL of layout specified in parameter
1336 *
1337 * @param $layout
1338 * @param $file string The file to find
1339 *
1340 * @return bool|string
1341 * @since 1.0
1342 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1343 */
1344 public function locate_url( $layout, $file = '' ) {
1345 if ( ! $this->_args['manage_layouts'] ) {
1346 return $this->template_url();
1347
1348 }
1349
1350 if ( ! isset( $this->layouts[ $layout ] ) ) {
1351 $layout = 'default';
1352 }
1353
1354 return $this->layouts[ $layout ]['url'] . '/' . ( ! empty( $file ) ? $file . '.php' : '' );
1355 }
1356
1357 /**
1358 * Retrieve the post ID relative to the post of post type
1359 *
1360 * @param $name string
1361 *
1362 * @return mixed
1363 * @since 1.0
1364 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1365 */
1366 protected function _get_id_by_name( $name ) {
1367 global $wpdb;
1368 return $wpdb->get_var( $wpdb->prepare( "SELECT pm.post_id FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $name, $this->_name ) );
1369 }
1370
1371 /**
1372 * Retrieve the post_type of portfolio by portfolio name
1373 *
1374 * @param $name string
1375 *
1376 * @return mixed
1377 * @since 1.0
1378 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1379 */
1380 protected function _get_post_type_by_name( $name ) {
1381 global $wpdb;
1382 return $wpdb->get_var( $wpdb->prepare( "SELECT pm.meta_value FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND p.post_name = %s AND p.post_type = %s", '_post_type', $name, $this->_name ) );
1383 }
1384
1385 /**
1386 * The shortcode used to show the frontend
1387 *
1388 * @param array $atts
1389 * @param null $content
1390 *
1391 * @return string|null
1392 * @since 1.0
1393 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1394 */
1395 public function add_shortcode( $atts, $content = null ) {
1396 $atts = wp_parse_args( $atts, array(
1397 'name' => null,
1398 'cat' => array(),
1399 'posts_per_page' => false,
1400 'style' => null,
1401 ) );
1402
1403 // don't show the slider if 'name' is empty or is 'none'
1404 if ( empty( $atts['name'] ) || 'none' == $atts['name'] ) return null;
1405
1406 // compatibility fix: remove prefix if exists in portfolio object
1407 if( function_exists( 'YIT_Portfolio' ) && method_exists( YIT_Portfolio(), 'is' ) && YIT_Portfolio()->is( $atts['name'] ) ){
1408 $atts['name'] = str_replace( YIT_Portfolio()->post_type_prefix, '', $atts['name'] );
1409 }
1410
1411 // pass vars to template
1412 $atts['post_type'] = $this->_get_post_type_by_name( $atts['name'] );
1413 $atts['layout'] = $this->_args['manage_layouts'] ? get_post_meta( $this->_get_id_by_name( $atts['post_type'] ), $this->_args['layout_option'], true ) : '';
1414 extract( apply_filters( 'yit_cptu_frontend_vars', $atts, $this->_name ) );
1415
1416 // add the javascript assets
1417 if ( $this->_args['manage_layouts'] && isset( $this->layouts[ $layout ]['js'] ) && ! empty( $this->layouts[ $layout ]['js'] ) ) {
1418 foreach ( $this->layouts[ $layout ]['js'] as $asset ) {
1419 if ( empty( $asset ) ) continue;
1420
1421 if ( empty( $asset['src'] ) ) {
1422 wp_enqueue_script( $asset['handle'] );
1423 continue;
1424 }
1425
1426 yit_enqueue_script( $asset['handle'], $this->locate_url( $layout ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['in_footer'] );
1427 }
1428 }
1429
1430 // Unique sequential index to differentiate more cpt in the same page
1431 ++$this->index;
1432
1433 ob_start();
1434
1435 include( $this->locate_file( $layout, 'markup' ) );
1436
1437 return ob_get_clean();
1438
1439 }
1440
1441 /**
1442 * Shortcode icon
1443 *
1444 * Return the shortcode icone to display on shortcode panel
1445 *
1446 * @param $icon_url string Icone url found by yit_shortcode plugin
1447 *
1448 * @return string
1449 * @since 1.0.0
1450 * @author Antonino Scarfi' <antonio.scarfi@yithemes.it>
1451 */
1452 public function shortcode_icon( $icon_url ) {
1453 return ! empty( $this->_args['shortcode_icon'] ) ? $this->_args['shortcode_icon'] : $icon_url;
1454 }
1455
1456 /**
1457 * Return an array with cptu options to shortcode panel
1458 *
1459 * All definition settings to add cptu shortcode to Yit Shortcode Panel
1460 *
1461 * @param array $shortcodes
1462 *
1463 * @return array
1464 * @since 1.0
1465 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1466 */
1467 public function add_shortcode_to_box( $shortcodes ) {
1468 $post_types = array();
1469
1470 foreach ( $this->get_post_types() as $post ) {
1471 $post_types[ $post->post_name ] = $post->post_title;
1472 }
1473
1474 $args = array(
1475 $this->_args['shortcode_name'] => array(
1476 'title' => $this->_labels['singular'],
1477 'description' => sprintf( __( 'Show frontend of the %s', 'yith-plugin-fw' ), $this->_labels['main_name'] ),
1478 'tab' => 'cpt',
1479 'create' => false,
1480 'has_content' => false,
1481 'in_visual_composer' => true,
1482 'attributes' => array(
1483 'name' => array(
1484 'title' => __( 'Name', 'yith-plugin-fw' ),
1485 'type' => 'select',
1486 'options' => $post_types,
1487 'std' => ''
1488 ),
1489 )
1490 )
1491 );
1492
1493 return array_merge( $shortcodes, $args );
1494 }
1495
1496 /**
1497 * Check the post type passed in parameter, if is generated by this CPTU
1498 *
1499 * @param $post_type string The post type to check
1500 *
1501 * @return bool
1502 * @since 1.0
1503 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1504 */
1505 protected function _is_valid( $post_type ) {
1506 return (bool)( strpos( $post_type, $this->_args['post_type_prefix'] ) !== false );
1507 }
1508
1509 /**
1510 * Add as a valid post type all cptu when importing dummy data
1511 *
1512 * @param $post array The post object
1513 *
1514 * @return array
1515 * @since 1.0
1516 * @author Antonio La Rocca <antonio.larocca@yithemes.com>
1517 */
1518 public function add_importer_required_post_type( $post ){
1519 global $wp_post_types, $wp_taxonomies;
1520
1521 if( strpos( $post['post_type'], $this->_prefix_cpt ) === FALSE ){
1522 return $post;
1523 }
1524
1525 if( ! isset( $wp_post_types[ $post['post_type'] ] ) ){
1526 $wp_post_types[ $post['post_type'] ] = array(
1527 'name' => ''
1528 );
1529 }
1530
1531 if( ! empty( $post['terms'] ) ){
1532 foreach( $post['terms'] as $term ){
1533 if( ! isset( $wp_taxonomies[ $term['domain'] ] ) ){
1534 $wp_taxonomies[ $term['domain'] ] = array(
1535 'name' => ''
1536 );
1537 }
1538 }
1539 }
1540
1541
1542 return $post;
1543 }
1544
1545 /**
1546 * Add taxonomy when importing dummy data
1547 *
1548 * @param $terms array Array of terms
1549 *
1550 * @return array
1551 * @since 1.0
1552 * @author Antonio La Rocca <antonio.larocca@yithemes.com>
1553 */
1554 public function add_importer_required_taxonomy( $terms ){
1555 global $wp_taxonomies;
1556
1557 if( ! empty( $terms ) ){
1558 foreach ( $terms as $term ) {
1559 if( isset( $term['domain'] ) && ! isset( $wp_taxonomies[ $term['domain'] ] ) ){
1560 $wp_taxonomies[ $term['domain'] ] = array(
1561 'name' => ''
1562 );
1563 }
1564 }
1565 }
1566
1567 return $terms;
1568 }
1569
1570 /**
1571 * Force terms recount for imported taxonomy
1572 *
1573 * @param $tt_ids array Terms ids
1574 * @param $ids array Post ids
1575 * @param $tax string Taxonomy name
1576 *
1577 * @return void
1578 * @since 1.0
1579 * @author Antonio La Rocca <antonio.larocca@yithemes.com>
1580 */
1581 public function recount_terms_post( $tt_ids, $ids, $tax ){
1582 wp_update_term_count( $tt_ids, $tax );
1583 }
1584
1585 // ### ASSETS ###
1586
1587 /**
1588 * Enqueue the assets for the admin
1589 *
1590 * @return void
1591 * @since 1.0
1592 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1593 */
1594 public function admin_assets() {
1595 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
1596 wp_enqueue_media();
1597 wp_enqueue_script( 'yit-cptu', YIT_CORE_PLUGIN_URL . '/assets/js/yit-cpt-unlimited' . $suffix . '.js', array('jquery'), '', true );
1598 }
1599
1600 /**
1601 * Add the button to the top of the list table page of CPTU
1602 *
1603 * @return void
1604 * @since 1.0
1605 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1606 */
1607 public function add_button_multiuploader() {
1608 global $pagenow, $post_type, $wpdb;
1609
1610 if( $pagenow != 'edit.php' ){
1611 return;
1612 }
1613
1614 $cptu = $wpdb->get_var( $wpdb->prepare( "SELECT p.post_type FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s", '_post_type', $post_type ) );
1615
1616 $post = get_post( $this->_get_id_by_name( $post_type ) );
1617 if ( empty( $post ) ) {
1618 return;
1619 }
1620 extract( $this->_cpt_args( $post ) );
1621
1622 if ( $cptu != $this->_name || ! $this->_is_valid( $post_type ) ) {
1623 return;
1624 }
1625
1626 ?>
1627 <script>
1628 (function($) {
1629 "use strict";
1630 // Author code here
1631
1632 var button = $('<a />', {
1633 href: '#',
1634 class: 'multi-uploader add-new-h2',
1635 'data-uploader_title': '<?php printf( __( 'Add %s from images', 'yith-plugin-fw' ), $label_plural ) ?>',
1636 'data-uploader_button_text': '<?php printf( __( 'Add %s', 'yith-plugin-fw' ), $label_plural ) ?>',
1637 'data-nonce': '<?php echo wp_create_nonce( 'cpt-unlimited-multiuploader' ); ?>'
1638 }).text('<?php _e( 'Upload multiple files', 'yith-plugin-fw' ) ?>');
1639
1640 var spinner = $('<span />', {
1641 class: 'spinner',
1642 style: 'float: none;'
1643 });
1644
1645 button.appendTo('.wrap h2, .wrap h1').after(spinner);
1646
1647 })(jQuery);
1648 </script>
1649 <?php
1650 }
1651
1652 /**
1653 * Add more posts by multiupload
1654 *
1655 * @return void
1656 * @since 1.0
1657 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1658 */
1659 public function post_multiuploader() {
1660
1661 check_ajax_referer( 'cpt-unlimited-multiuploader' );
1662
1663 if ( ! isset( $_REQUEST['images'] ) || ! isset( $_REQUEST['post_type'] ) && $this->_is_valid( $_REQUEST['post_type'] ) ) {
1664 return;
1665 }
1666
1667 foreach ( $_REQUEST['images'] as $the ) {
1668
1669 // Create post object
1670 $arg = array(
1671 'post_title' => $the['title'],
1672 'post_type' => $_REQUEST['post_type']
1673 );
1674 $post_id = wp_insert_post( $arg );
1675
1676 set_post_thumbnail( $post_id, $the['id'] );
1677
1678 }
1679
1680 die();
1681 }
1682
1683
1684 // ###### SINGLE TEMPLATE ######
1685
1686 /**
1687 * Load the single template file
1688 *
1689 * @return void
1690 * @since 1.0
1691 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1692 */
1693 public function single_template() {
1694 global $post, $wpdb;
1695
1696 // if ( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ) {
1697 // $post = get_post( $_REQUEST['post_id'] );
1698 // }
1699
1700 if ( ( ( ! defined('DOING_AJAX') || ! DOING_AJAX ) && ! is_single() ) || ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
1701 return;
1702 }
1703
1704 // add the javascript assets
1705 if ( $this->_args['manage_layouts'] ) {
1706 foreach ( $this->layouts[ 'single' ]['js'] as $asset ) {
1707 yit_enqueue_script( $asset['handle'], $this->locate_url( 'single' ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['in_footer'] );
1708 }
1709 }
1710
1711 $post_name = $wpdb->get_var( $wpdb->prepare( "SELECT p.post_name FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $post->post_type, $this->_name ) );
1712 extract( apply_filters( 'yit_cptu_frontend_vars', array( 'name' => $post_name ), $this->_name ) );
1713
1714 include( $this->locate_file( 'single', 'markup' ) );
1715 }
1716
1717 /**
1718 * Load a file for the configuration of single template page of portfolio
1719 *
1720 * @return void
1721 * @since 1.0
1722 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1723 */
1724 public function single_template_config() {
1725 global $post, $wpdb;
1726
1727 if ( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ) {
1728 $post = get_post( $_REQUEST['post_id'] );
1729 }
1730
1731 if ( ( ( ! defined('DOING_AJAX') || ! DOING_AJAX ) && ! is_single() ) || ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
1732 return;
1733 }
1734
1735 $this->_layout = 'single';
1736 $path = $this->locate_file( 'single', 'config' );
1737
1738 if ( file_exists( $path ) ) {
1739 $post_name = $wpdb->get_var( $wpdb->prepare( "SELECT p.post_name FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $post->post_type, $this->_name ) );
1740 extract( apply_filters( 'yit_cptu_frontend_vars', array( 'name' => $post_name ), $this->_name ) );
1741
1742 include( $path );
1743 }
1744 }
1745
1746
1747 // ########################## ARCHIVE TEMPLATE ###############################
1748
1749
1750 /**
1751 * Load the template for archive page
1752 *
1753 * @return void
1754 * @since 1.0
1755 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1756 */
1757 public function archive_template() {
1758 global $wp_query;
1759
1760
1761 // check if we are in archive template
1762 if ( !( ! is_admin() && is_archive() && isset($wp_query->post) && $this->_is_valid( $wp_query->post->post_type ) ) ) {
1763 return;
1764 }
1765
1766 // remove the action from loop of theme
1767 remove_action( 'yit_content_loop', 'yit_content_loop', 10 );
1768 add_action( 'yit_content_loop', array( $this, 'archive_template_loop' ), 10 );
1769
1770 }
1771
1772 /**
1773 * Load loop for the archive template
1774 *
1775 * @return void
1776 * @since 1.0
1777 * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1778 */
1779 public function archive_template_loop() {
1780 echo $this->add_shortcode( array( 'name' => $GLOBALS['wp_query']->post->post_type ) );
1781 }
1782
1783 }