PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/www/wp-content/plugins/ithemes-exchange/lib/classes/it-post-type.php

https://github.com/ArzuA/gitwordpress
PHP | 563 lines | 367 code | 150 blank | 46 comment | 90 complexity | a5ac72eeae00917902f777c6bff0d3f8 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /*
  3. Written by Chris Jean for iThemes.com
  4. Version 2.0.2
  5. Version History
  6. 1.0.0 - 2010-07-27
  7. Initial release version
  8. 1.0.1 - 2010-10-05
  9. Added check for function get_post_type_object to force 3.0-only use
  10. 1.0.2 - 2010-10-06 - Chris Jean
  11. Removed "public" from function definition for PHP 4 compatibility
  12. 1.0.3 - 2011-05-03 - Chris Jean
  13. Added the ability for plugins to supply templates
  14. 1.0.4 - 2011-05-16 - Chris Jean
  15. Added $post_id arg to validate_meta_box_options call
  16. 1.1.0 - 2011-10-06 - Chris Jean
  17. Added it_custom_post_type_{$this->_var}_filter_settings filter
  18. 2.0.0 - 2011-12-09 - Chris Jean
  19. Big structural rewrite to update code to work better with the updated
  20. WordPress post type API
  21. 2.0.1 - 2011-12-12 - Chris Jean
  22. Changed wp_print_scripts hook to wp_enqueue_scripts
  23. Changed wp_print_styles hook to wp_enqueue_scripts
  24. 2.0.2 - 2013-05-21 - Chris Jean
  25. Removed assign by reference.
  26. */
  27. if ( ! class_exists( 'ITPostType' ) ) {
  28. it_classes_load( 'it-filterable-templates.php' );
  29. class ITPostType {
  30. var $_file = '';
  31. var $_template_path = null;
  32. var $_var = '';
  33. var $_slug = null;
  34. var $_name = '';
  35. var $_name_plural = '';
  36. var $_use_storage = false;
  37. var $_storage_version = '0';
  38. var $_settings = array();
  39. var $_meta_boxes = array();
  40. var $_menu_pages = array();
  41. var $_editor_load_jquery = false;
  42. var $_editor_load_thickbox = false;
  43. var $_public_load_jquery = false;
  44. var $_public_load_thickbox = false;
  45. var $_has_custom_screen_icon = false;
  46. var $_page_refs = array();
  47. var $_template = '';
  48. var $_storage = false;
  49. var $_options = false;
  50. var $_class;
  51. var $_is_singular = false;
  52. var $_is_archive = false;
  53. var $_is_editor = false;
  54. var $_is_admin_post_listing = false;
  55. function ITPostType() {
  56. $this->_class = get_class( $this );
  57. if ( ! $this->__validate_config() )
  58. return;
  59. if ( true == $this->_use_storage ) {
  60. it_classes_load( 'it-storage.php' );
  61. $this->_storage = new ITStorage2( $this->_var, $this->_storage_version );
  62. add_action( "it_storage_do_upgrade_{$this->_var}", array( &$this, '__load_storage_upgrade_handler' ) );
  63. if ( is_callable( array( &$this, 'set_defaults' ) ) )
  64. add_filter( "it_storage_get_defaults_{$this->_var}", array( &$this, 'set_defaults' ) );
  65. }
  66. add_action( 'deactivated_plugin', array( &$this, '__deactivate_plugin' ) );
  67. add_action( 'init', array( &$this, '__init' ) );
  68. add_action( 'admin_init', array( &$this, '__admin_init' ) );
  69. add_action( 'admin_menu', array( &$this, '__admin_menu' ) );
  70. add_action( 'pre_get_posts', array( &$this, '__identify_post_type' ) );
  71. add_action( 'load-post-new.php', array( &$this, '__identify_editor' ) );
  72. add_action( 'load-post.php', array( &$this, '__identify_editor' ) );
  73. add_action( 'load-edit.php', array( &$this, '__identify_editor' ) );
  74. add_action( 'admin_print_styles', array( &$this, '__admin_print_styles' ) );
  75. }
  76. // Initialize the Post Type ////////////////////////////
  77. function __init() {
  78. $this->_load();
  79. $this->__setup_default_settings();
  80. $this->_registered_args = register_post_type( $this->_var, $this->_settings );
  81. if ( empty( $this->_template_path ) ) {
  82. if ( is_callable( array( &$this, 'set_template_path' ) ) )
  83. $this->_template_path = $this->set_template_path();
  84. else
  85. $this->_template_path = dirname( $this->_file ) . '/templates';
  86. }
  87. if ( ! empty( $this->_template_path ) )
  88. add_filter( 'it_filter_possible_template_paths', array( &$this, '__filter_possible_template_paths' ) );
  89. if ( method_exists( $this, 'init' ) )
  90. $this->init();
  91. if ( ! is_admin() )
  92. $this->__public_init();
  93. }
  94. function __filter_possible_template_paths( $paths ) {
  95. $paths[] = $this->_template_path;
  96. return $paths;
  97. }
  98. function __admin_init() {
  99. if ( false === get_option( $this->_var . '_activated' ) )
  100. $this->__activate();
  101. }
  102. function __identify_editor() {
  103. $typenow = $GLOBALS['typenow'];
  104. if ( version_compare( $GLOBALS['wp_version'], '3.2.10', '<' ) && ( 'post' == $typenow ) ) {
  105. if ( isset( $_REQUEST['post'] ) )
  106. $typenow = get_post_type( $_REQUEST['post'] );
  107. else if ( isset( $_REQUEST['post_ID'] ) )
  108. $typenow = get_post_type( $_REQUEST['post_ID'] );
  109. }
  110. if ( $this->_var == $typenow )
  111. $this->__prepare_editor();
  112. }
  113. function __public_init() {
  114. if ( method_exists( $this, 'public_init' ) )
  115. $this->public_init();
  116. }
  117. // Add Custom Menu Pages ////////////////////////////
  118. function __admin_menu() {
  119. if ( empty( $this->_menu_pages ) )
  120. return;
  121. foreach ( (array) $this->_menu_pages as $var => $args ) {
  122. $this->_page_refs[$var] = add_submenu_page( "edit.php?post_type={$this->_var}", $args['page_title'], $args['menu_title'], $args['capability'], $var, array( &$this, $args['callback'] ) );
  123. add_action( "load-{$this->_page_refs[$var]}", array( &$this, '__prepare_editor' ) );
  124. }
  125. }
  126. // Setup/Run Editor-specific Handlers ////////////////////////////
  127. function __prepare_editor() {
  128. $this->_is_editor = true;
  129. add_filter( "views_edit-{$this->_var}", array( &$this, '__add_list_table_views' ) );
  130. add_action( 'save_post', array( &$this, 'save_meta_box_options' ) );
  131. add_action( 'admin_print_scripts', array( &$this, '__admin_print_editor_scripts' ) );
  132. add_action( 'admin_print_styles', array( &$this, '__admin_print_editor_styles' ) );
  133. if ( true === $this->_has_custom_screen_icon )
  134. add_action( 'admin_notices', array( &$this, '__modify_current_screen' ) );
  135. $this->__add_contextual_help();
  136. }
  137. function __add_list_table_views( $views ) {
  138. return $views;
  139. }
  140. // Load Custom Templates if in This Custom Post Type's views ////////////////////////////
  141. function __identify_post_type( $wp_query ) {
  142. if ( $wp_query->get( 'post_type' ) != $this->_var )
  143. return;
  144. remove_action( 'pre_get_posts', array( &$this, '__identify_post_type' ) );
  145. if ( is_archive() ) {
  146. if ( is_admin() ) {
  147. if ( ! isset( $_REQUEST['orderby'] ) )
  148. add_filter( 'posts_orderby', array( &$this, '__filter_posts_orderby' ), 10, 2 );
  149. $this->_is_admin_post_listing = true;
  150. }
  151. else {
  152. add_filter( 'posts_orderby', array( &$this, '__filter_posts_orderby' ), 10, 2 );
  153. add_filter( 'pre_option_posts_per_page', array( &$this, '__filter_posts_per_page' ) );
  154. $this->_template = 'archive';
  155. $this->_is_archive = true;
  156. }
  157. }
  158. else if ( is_singular() ) {
  159. $this->_template = 'single';
  160. $this->_is_singular = true;
  161. }
  162. else {
  163. return;
  164. }
  165. add_action( 'wp_enqueue_scripts', array( &$this, '__print_scripts' ) );
  166. add_action( 'wp_enqueue_scripts', array( &$this, '__print_styles' ) );
  167. add_action( 'template_redirect', array( &$this, '__template_redirect' ), 100 );
  168. }
  169. function __template_redirect() {
  170. $paths = array( get_stylesheet_directory(), get_template_directory() );
  171. if ( ! empty( $this->_template_path ) )
  172. $paths[] = $this->_template_path;
  173. $paths = apply_filters( 'it_post_type_filter_template_paths', array_unique( $paths ) );
  174. foreach ( (array) $paths as $path )
  175. $this->__load_template( $path );
  176. }
  177. function __load_template( $path ) {
  178. if ( ! is_dir( $path ) )
  179. return;
  180. $var_directory = str_replace( '_', '-', $this->_var );
  181. $file = '';
  182. if ( is_dir( "$path/$var_directory" ) && is_file( "$path/$var_directory/{$this->_template}.php" ) )
  183. $file = "$path/$var_directory/{$this->_template}.php";
  184. if ( is_file( "$path/{$this->_template}-{$this->_var}.php" ) )
  185. $file = "$path/{$this->_template}-{$this->_var}.php";
  186. if ( empty( $file ) )
  187. return;
  188. include( $file );
  189. exit;
  190. }
  191. // Help Handlers ////////////////////////////
  192. function __add_contextual_help() {
  193. if ( empty( $this->_menu_pages ) )
  194. return;
  195. foreach ( (array) $this->_menu_pages as $var => $args ) {
  196. if ( method_exists( $this, "{$var}_get_contextual_help" ) )
  197. add_contextual_help( $this->_page_refs[$var], call_user_func( array( $this, "{$var}_get_contextual_help" ) ) );
  198. }
  199. }
  200. // Ensure Proper Flushing of Rewrite Rules ////////////////////////////
  201. function __activate() {
  202. $this->__flush_rewrite_rules();
  203. }
  204. function __flush_rewrite_rules() {
  205. global $wp_rewrite;
  206. $wp_rewrite->flush_rules();
  207. update_option( $this->_var . '_activated', true );
  208. }
  209. function __deactivate_plugin() {
  210. delete_option( $this->_var . '_activated' );
  211. }
  212. // Options Storage ////////////////////////////
  213. function _save() {
  214. if ( false == $this->_use_storage )
  215. return;
  216. $this->_storage->save( $this->_options );
  217. }
  218. function _load() {
  219. if ( false == $this->_use_storage )
  220. return;
  221. if ( ! isset( $this->_storage ) || ! is_callable( array( $this->_storage, 'load' ) ) )
  222. ITError::fatal( "empty_var:class_var:{$this->_class}->_storage", "The $this->_class class did not set the \$this->_storage variable. This should be set by the ITPostType class, ensure that the ITPostType::ITPostType() method is called." );
  223. $this->_options = $this->_storage->load();
  224. }
  225. function __load_storage_upgrade_handler() {
  226. if ( ! empty( $this->_upgrade_handler_file ) && file_exists( $this->_upgrade_handler_file ) )
  227. require_once( $this->_upgrade_handler_file );
  228. else if ( file_exists( dirname( $this->_file ) . '/upgrade-storage.php' ) )
  229. require_once( dirname( $this->_file ) . '/upgrade-storage.php' );
  230. }
  231. // Style and Script Handlers ////////////////////////////
  232. function __load_style( $file, $name = null ) {
  233. if ( empty( $name ) )
  234. $name = "$file-style";
  235. if ( file_exists( dirname( $this->_file ) . "/css/$file-{$this->_var}.css" ) ) {
  236. it_classes_load( 'it-file-utility.php' );
  237. $css_url = ITFileUtility::get_url_from_file( dirname( $this->_file ) . "/css/$file-{$this->_var}.css" );
  238. wp_enqueue_style( "{$this->_var}-$name", $css_url );
  239. }
  240. }
  241. function __load_script( $file, $name = null ) {
  242. if ( empty( $name ) )
  243. $name = "$file-script";
  244. $dependencies = array();
  245. if ( is_admin() ) {
  246. if ( true === $this->_editor_load_jquery )
  247. $dependencies[] = 'jquery';
  248. if ( true === $this->_editor_load_thickbox )
  249. $dependencies[] = 'thickbox';
  250. }
  251. else {
  252. if ( true === $this->_public_load_jquery )
  253. $dependencies[] = 'jquery';
  254. if ( true === $this->_public_load_thickbox )
  255. $dependencies[] = 'thickbox';
  256. }
  257. if ( file_exists( dirname( $this->_file ) . "/js/$file-{$this->_var}.js" ) ) {
  258. it_classes_load( 'it-file-utility.php' );
  259. $js_url = ITFileUtility::get_url_from_file( dirname( $this->_file ) . "/js/$file-{$this->_var}.js" );
  260. wp_enqueue_script( "{$this->_var}-$name-script", $js_url, $dependencies );
  261. }
  262. }
  263. function __admin_print_styles() {
  264. $this->__load_style( 'admin' );
  265. if ( method_exists( $this, 'admin_print_styles' ) )
  266. $this->admin_print_styles();
  267. }
  268. function __admin_print_editor_scripts() {
  269. $this->__load_script( 'editor' );
  270. if ( method_exists( $this, 'admin_print_editor_scripts' ) )
  271. $this->admin_print_editor_scripts();
  272. else if ( method_exists( $this, 'admin_print_scripts' ) )
  273. $this->admin_print_scripts();
  274. }
  275. function __admin_print_editor_styles() {
  276. $this->__load_style( 'editor' );
  277. if ( method_exists( $this, 'admin_print_editor_styles' ) )
  278. $this->admin_print_editor_styles();
  279. else if ( method_exists( $this, 'admin_print_styles' ) )
  280. $this->admin_print_styles();
  281. }
  282. function __print_scripts() {
  283. $this->__load_script( 'public', 'script' );
  284. if ( method_exists( $this, 'print_scripts' ) )
  285. $this->print_scripts();
  286. }
  287. function __print_styles() {
  288. $this->__load_style( 'public', 'style' );
  289. if ( method_exists( $this, 'print_styles' ) )
  290. $this->print_styles();
  291. }
  292. // Ensure That the Custom Post Type's Icon is Used ////////////////////////////
  293. function __modify_current_screen() {
  294. global $current_screen;
  295. if ( empty( $current_screen->parent_file ) || ( "edit.php?post_type={$this->_var}" !== $current_screen->parent_file ) )
  296. return $current_screen;
  297. $current_screen->parent_base = $this->_var;
  298. }
  299. // Modify Post Query ////////////////////////////
  300. function __filter_posts_orderby( $orderby, $wp_query ) {
  301. if ( is_callable( array( &$this, 'filter_posts_orderby' ) ) ) {
  302. global $wpdb;
  303. $orderby = $this->filter_posts_orderby( $orderby, $wp_query );
  304. while ( preg_match( '/%WPDB-([^%]+)%/', $orderby, $match ) )
  305. $orderby = str_replace( "%WPDB-{$match[1]}%", $wpdb->{$match[1]}, $orderby );
  306. }
  307. return $orderby;
  308. }
  309. function __filter_posts_per_page( $posts_per_page ) {
  310. if ( is_callable( array( &$this, 'filter_posts_per_page' ) ) )
  311. return $this->filter_posts_per_page( $posts_per_page );
  312. return $posts_per_page;
  313. }
  314. // Adjust Custom Post Type Settings Based on Configuration ////////////////////////////
  315. function __setup_default_settings() {
  316. // For full list of available settings, see the register_post_type() function in wp-includes/post.php
  317. // Common settings: can_export, description, exclude_from_search, has_archive, hierarchical, menu_icon,
  318. // public, register_meta_box_cb, rewrite, show_in_nav_menus, show_ui, supports
  319. $default_settings = array(
  320. 'public' => true,
  321. 'has_archive' => true,
  322. 'supports' => array( // Shorthand for calling add_post_type_support()
  323. 'title',
  324. 'editor',
  325. ),
  326. 'register_meta_box_cb' => array( &$this, '__register_meta_boxes' ),
  327. );
  328. $default_settings['labels'] = $this->__get_default_labels();
  329. if ( ! empty( $this->_slug ) )
  330. $default_settings['rewrite'] = array( 'slug' => $this->_slug );
  331. $this->_settings = array_merge( $default_settings, $this->_settings );
  332. if ( ! empty( $this->_settings['menu_icon'] ) && ! preg_match( '/^http/', $this->_settings['menu_icon'] ) ) {
  333. if ( ! isset( $this->_url_base ) ) {
  334. it_classes_load( 'it-file-utility.php' );
  335. $this->_url_base = ITFileUtility::get_url_from_file( dirname( $this->_file ) );
  336. }
  337. $this->_settings['menu_icon'] = $this->_url_base . '/' . $this->_settings['menu_icon'];
  338. }
  339. $slug = apply_filters( "it_custom_post_type_{$this->_var}_filter_slug", '' );
  340. if ( ! empty( $slug ) )
  341. $this->_settings['rewrite'] = array( 'slug' => $slug );
  342. $this->_settings = apply_filters( "it_custom_post_type_{$this->_var}_filter_settings", $this->_settings );
  343. }
  344. function __get_default_labels() {
  345. $labels = array(
  346. 'name' => $this->_name_plural,
  347. 'singular_name' => $this->_name,
  348. 'add_new' => _x( 'Add New', 'post', 'it-l10n-ithemes-exchange' ),
  349. 'add_new_item' => sprintf( _x( 'Add New %s', 'post', 'it-l10n-ithemes-exchange' ), $this->_name ),
  350. 'edit_item' => sprintf( _x( 'Edit %s', 'post', 'it-l10n-ithemes-exchange' ), $this->_name ),
  351. 'new_item' => sprintf( _x( 'New %s', 'post', 'it-l10n-ithemes-exchange' ), $this->_name ),
  352. 'view_item' => sprintf( _x( 'View %s', 'post', 'it-l10n-ithemes-exchange' ), $this->_name ),
  353. 'search_items' => sprintf( _x( 'Search %s', 'post', 'it-l10n-ithemes-exchange' ), $this->_name_plural ),
  354. 'not_found' => sprintf( _x( 'No %s found', 'post', 'it-l10n-ithemes-exchange' ), strtolower( $this->_name ) ),
  355. 'not_found_in_trash' => sprintf( _x( 'No %s found in trash', 'post', 'it-l10n-ithemes-exchange' ), strtolower( $this->_name_plural ) ),
  356. 'parent_item_colon' => sprintf( _x( 'Parent %s:', 'post', 'it-l10n-ithemes-exchange' ), $this->_name ),
  357. 'all_items' => sprintf( _x( 'All %s', 'post', 'it-l10n-ithemes-exchange' ), $this->_name_plural ),
  358. );
  359. return $labels;
  360. }
  361. // Verify Class Configuration ////////////////////////////
  362. function __validate_config() {
  363. if ( ! function_exists( 'get_post_type_object' ) )
  364. return false;
  365. if ( empty( $this->_var ) ) {
  366. it_classes_load( 'it-error.php' );
  367. ITError::admin_warn( 'it-post-type-missing-var', "Unable to load {$this->_class} due to missing _var.", 'edit_plugins' );
  368. return false;
  369. }
  370. if ( empty( $this->_file ) ) {
  371. it_classes_load( 'it-error.php' );
  372. ITError::admin_warn( 'it-post-type-missing-file', "Unable to load {$this->_class} due to missing _file.", 'edit_plugins' );
  373. return false;
  374. }
  375. return true;
  376. }
  377. // Meta Box Handlers ////////////////////////////
  378. function __register_meta_boxes() {
  379. do_action( "register_post_type_meta_boxes-{$this->_var}" );
  380. foreach ( (array) $this->_meta_boxes as $var => $args )
  381. add_meta_box( $var, $args['title'], array( &$this, 'render_meta_box' ), $this->_var, $args['context'], $args['priority'], $args );
  382. }
  383. function render_meta_box( $post, $object ) {
  384. if ( ! isset( $this->_meta_box_options ) )
  385. $this->_meta_box_options = get_post_meta( $post->ID, '_it_options', true );
  386. if ( ! isset( $this->_meta_box_form ) )
  387. $this->_meta_box_form = new ITForm( $this->_meta_box_options, array( 'prefix' => $this->_var ) );
  388. call_user_func( array( &$this, $object['args']['callback'] ), $post, $this->_meta_box_form, $this->_meta_box_options, $object );
  389. if ( ! isset( $this->_meta_box_nonce_added ) ) {
  390. $this->_meta_box_form->add_hidden( 'nonce', wp_create_nonce( $this->_var ) );
  391. $this->_meta_box_nonce_added = true;
  392. }
  393. }
  394. function save_meta_box_options( $post_id ) {
  395. // Skip if the nonce check fails
  396. if ( ! isset( $_POST["{$this->_var}-nonce"] ) || ! wp_verify_nonce( $_POST["{$this->_var}-nonce"], $this->_var ) )
  397. return;
  398. // Don't save or update on autosave
  399. if ( defined( 'DOING_AUTOSAVE' ) && ( true === DOING_AUTOSAVE ) )
  400. return;
  401. // Only allow those with permissions to modify the type to save/update a layout
  402. if ( ! current_user_can( 'edit_post', $post_id ) )
  403. return;
  404. // Save/update options
  405. $options = ITForm::parse_values( $_POST, array( 'prefix' => $this->_var ) );
  406. unset( $options['nonce'] );
  407. if ( method_exists( $this, 'validate_meta_box_options' ) )
  408. $options = $this->validate_meta_box_options( $options, $post_id );
  409. update_post_meta( $post_id, '_it_options', $options );
  410. }
  411. }
  412. }