YIT_CPT_Unlimited

Manage the custom post types as Portfolio, Contact Forms and similar (called CPTU).

Defined (1)

The class is defined in the following location(s).

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