PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/wp-content/plugins/builder-seo-plugin/lib/classes/it-post-type.php

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