PageRenderTime 24ms CodeModel.GetById 2ms app.highlight 16ms RepoModel.GetById 2ms app.codeStats 0ms

/wp-content/themes/Builder/lib/classes/it-post-type.php

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