Created
November 13, 2012 17:29
-
-
Save esgy/4067163 to your computer and use it in GitHub Desktop.
JW_Post_Type.php for Wordpress
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// include this JW_Post_Type.php into function.php | |
session_start(); | |
/** | |
* JW Post Types | |
* @author Jeffrey Way | |
* @link http://jeffrey-way.com | |
*/ | |
class JW_Post_Type | |
{ | |
/** | |
* The name of the post type. | |
* @var string | |
*/ | |
public $post_type_name; | |
/** | |
* A list of user-specific options for the post type. | |
* @var array | |
*/ | |
public $post_type_args; | |
/** | |
* Sets default values, registers the passed post type, and | |
* listens for when the post is saved. | |
* | |
* @param string $name The name of the desired post type. | |
* @param array @post_type_args Override the options. | |
*/ | |
function __construct($name, $post_type_args = array()) | |
{ | |
if (!isset($_SESSION["taxonomy_data"])) { | |
$_SESSION['taxonomy_data'] = array(); | |
} | |
$this->post_type_name = strtolower($name); | |
$this->post_type_args = (array)$post_type_args; | |
// First step, register that new post type | |
$this->init(array(&$this, "register_post_type")); | |
$this->save_post(); | |
} | |
/** | |
* Helper method, that attaches a passed function to the 'init' WP action | |
* @param function $cb Passed callback function. | |
*/ | |
function init($cb) | |
{ | |
add_action("init", $cb); | |
} | |
/** | |
* Helper method, that attaches a passed function to the 'admin_init' WP action | |
* @param function $cb Passed callback function. | |
*/ | |
function admin_init($cb) | |
{ | |
add_action("admin_init", $cb); | |
} | |
/** | |
* Registers a new post type in the WP db. | |
*/ | |
function register_post_type() | |
{ | |
// do no exceed 20 characters | |
$n = ucwords( str_replace( '_', ' ', $this->post_type_name ) ); | |
$args = array( | |
"label" => $n, | |
'singular_name' => $n, | |
"public" => true, | |
"publicly_queryable" => true, | |
"query_var" => true, | |
#"menu_icon" => get_stylesheet_directory_uri() . "/article16.png", | |
"rewrite" => true, | |
"capability_type" => "post", | |
"hierarchical" => false, | |
"menu_position" => null, | |
"supports" => array("title", "editor", "thumbnail"), | |
'has_archive' => true | |
); | |
// Take user provided options, and override the defaults. | |
$args = array_merge($args, $this->post_type_args); | |
register_post_type(substr($this->post_type_name,0,20), $args); | |
} | |
/** | |
* Registers a new taxonomy, associated with the instantiated post type. | |
* | |
* @param string $taxonomy_name The name of the desired taxonomy | |
* @param string $prefix Unique indentifier to stop naming collision | |
* @param string $plural The plural form of the taxonomy name. (Optional) | |
* @param array $options A list of overrides | |
*/ | |
function add_taxonomy($taxonomy_name, $prefix, $plural = '', $options = array()) | |
{ | |
// Create local reference so we can pass it to the init cb. | |
$post_type_name = $this->post_type_name; | |
// If no plural form of the taxonomy was provided, do a crappy fix. :) | |
if ($plural==='') { | |
$plural = $taxonomy_name . 's'; | |
} | |
// Taxonomies need to be lowercase, but displaying them will look better this way... | |
$taxonomy_name = ucwords($taxonomy_name); | |
// At WordPress' init, register the taxonomy | |
$this->init( | |
function() use($taxonomy_name, $prefix, $plural, $post_type_name, $options) | |
{ | |
// Override defaults with user provided options | |
$options = array_merge( | |
array( | |
"hierarchical" => false, | |
"label" => $taxonomy_name, | |
"singular_label" => $plural, | |
"show_ui" => true, | |
"query_var" => true, | |
"rewrite" => array("slug" => strtolower($taxonomy_name)) | |
), | |
$options | |
); | |
// name of taxonomy, associated post type, options | |
register_taxonomy($prefix.strtolower($taxonomy_name), substr($post_type_name,0,20), $options); | |
}); | |
} | |
/** | |
* Creates a new custom meta box in the New 'post_type' page. | |
* | |
* @param string $title | |
* @param array $form_fields Associated array that contains the label of the input, and the desired input type. 'Title' => 'text' | |
*/ | |
function add_meta_box($title, $form_fields = array()) | |
{ | |
$post_type_name = $this->post_type_name; | |
// end update_edit_form | |
add_action('post_edit_form_tag', function() | |
{ | |
echo ' enctype="multipart/form-data"'; | |
}); | |
// At WordPress' admin_init action, add any applicable metaboxes. | |
$this->admin_init(function() use($title, $form_fields, $post_type_name) | |
{ | |
add_meta_box( | |
strtolower(str_replace(' ', '_', $title)), // id | |
$title, // title | |
function($post, $data) | |
{ // function that displays the form fields | |
global $post; | |
wp_nonce_field(plugin_basename(__FILE__), 'jw_nonce'); | |
// List of all the specified form fields | |
$inputs = $data['args'][0]; | |
// Get the saved field values | |
$meta = get_post_custom($post->ID); | |
// For each form field specified, we need to create the necessary markup | |
// $name = Label, $type = the type of input to create | |
foreach ($inputs as $name => $type) { | |
#'Happiness Info' in 'Snippet Info' box becomes | |
# snippet_info_happiness_level | |
$id_name = $data['id'] . '_' . strtolower(str_replace(' ', '_', $name)); | |
if (is_array($inputs[$name])) { | |
// then it must be a select or file upload | |
// $inputs[$name][0] = type of input | |
if (strtolower($inputs[$name][0]) === 'select') { | |
// filter through them, and create options | |
$select = "<select name='$id_name' class='widefat'>"; | |
foreach ($inputs[$name][1] as $option) { | |
// if what's stored in the db is equal to the | |
// current value in the foreach, that should | |
// be the selected one | |
if (isset($meta[$id_name]) && $meta[$id_name][0] == $option) { | |
$set_selected = "selected='selected'"; | |
} else $set_selected = ''; | |
$select .= "<option value='$option' $set_selected> $option </option>"; | |
} | |
$select .= "</select>"; | |
array_push($_SESSION['taxonomy_data'], $id_name); | |
} | |
} | |
// Attempt to set the value of the input, based on what's saved in the db. | |
$value = isset($meta[$id_name][0]) ? $meta[$id_name][0] : ''; | |
$checked = ($type == 'checkbox' && !empty($value) ? 'checked' : ''); | |
// Sorta sloppy. I need a way to access all these form fields later on. | |
// I had trouble finding an easy way to pass these values around, so I'm | |
// storing it in a session. Fix eventually. | |
array_push($_SESSION['taxonomy_data'], $id_name); | |
// TODO - Add the other input types. | |
$lookup = array( | |
"text" => "<input type='text' name='$id_name' value='$value' class='widefat' />", | |
"textarea" => "<textarea name='$id_name' class='widefat' rows='10'>$value</textarea>", | |
"checkbox" => "<input type='checkbox' name='$id_name' value='$name' $checked />", | |
"select" => isset($select) ? $select : '', | |
"file" => "<input type='file' name='$id_name' id='$id_name' />" | |
); | |
?> | |
<p> | |
<label><?php echo ucwords($name) . ':'; ?></label> | |
<?php echo $lookup[is_array($type) ? $type[0] : $type]; ?> | |
</p> | |
<p> | |
<?php | |
// If a file was uploaded, display it below the input. | |
$file = get_post_meta($post->ID, $id_name, true); | |
if ( $type === 'file' ) { | |
// display the image | |
$file = get_post_meta($post->ID, $id_name, true); | |
$file_type = wp_check_filetype($file); | |
$image_types = array('jpeg', 'jpg', 'bmp', 'gif', 'png'); | |
if ( isset($file) ) { | |
if ( in_array($file_type['ext'], $image_types) ) { | |
echo "<img src='$file' alt='' style='max-width: 400px;' />"; | |
} else { | |
echo "<a href='$file'>$file</a>"; | |
} | |
} | |
} | |
?> | |
</p> | |
<?php | |
} | |
}, | |
$post_type_name, // associated post type | |
'normal', // location/context. normal, side, etc. | |
'default', // priority level | |
array($form_fields) // optional passed arguments. | |
); // end add_meta_box | |
}); | |
} | |
/** | |
* When a post saved/updated in the database, this methods updates the meta box params in the db as well. | |
*/ | |
function save_post() | |
{ | |
add_action('save_post', function() | |
{ | |
// Only do the following if we physically submit the form, | |
// and now when autosave occurs. | |
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; | |
global $post; | |
if ($_POST && !wp_verify_nonce($_POST['jw_nonce'], plugin_basename(__FILE__))) { | |
return; | |
} | |
// Get all the form fields that were saved in the session, | |
// and update their values in the db. | |
if (isset($_SESSION['taxonomy_data'])) { | |
foreach ($_SESSION['taxonomy_data'] as $form_name) { | |
if (!empty($_FILES[$form_name]) ) { | |
if ( !empty($_FILES[$form_name]['tmp_name']) ) { | |
$upload = wp_upload_bits($_FILES[$form_name]['name'], null, file_get_contents($_FILES[$form_name]['tmp_name'])); | |
if (isset($upload['error']) && $upload['error'] != 0) { | |
wp_die('There was an error uploading your file. The error is: ' . $upload['error']); | |
} else { | |
update_post_meta($post->ID, $form_name, $upload['url']); | |
} | |
} | |
} else { | |
// Make better. Have to do this, because I can't figure | |
// out a better way to deal with checkboxes. If deselected, | |
// they won't be represented here, but I still need to | |
// update the value to false to blank in the table. Hmm... | |
if (!isset($_POST[$form_name])) $_POST[$form_name] = ''; | |
if (isset($post->ID) ) { | |
update_post_meta($post->ID, $form_name, $_POST[$form_name]); | |
} | |
} | |
} | |
$_SESSION['taxonomy_data'] = array(); | |
} | |
}); | |
} | |
} | |
/*********/ | |
/* USAGE */ | |
/*********/ | |
// $product = new PostType("movie"); | |
// $product->add_taxonomy('Actor'); | |
// $product->add_taxonomy('Director'); | |
// $product->add_meta_box('Movie Info', array( | |
// 'name' => 'text', | |
// 'rating' => 'text', | |
// 'review' => 'textarea', | |
// 'Profile Image' => 'file' | |
// )); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment