<?php
/*
Plugin Name: WP Sub Post
Plugin URI: http://wordpress.org/#
Description: You can make a post is a child of another post.
Author: Takien
Version: 0.1 Alpha
Author URI: http://takien.com
*/

////////////////////////////

class Walker_PostDropdown extends Walker {
/**
* @see Walker::$tree_type
* @since 2.1.0
* @var string
*/
var $tree_type = ‘post’;

/**
* @see Walker::$db_fields
* @since 2.1.0
* @todo Decouple this
* @var array
*/
var $db_fields = array (‘parent’ => ‘post_parent’, ‘id’ => ‘ID’);

/**
* @see Walker::start_el()
* @since 2.1.0
*
* @param string $output Passed by reference. Used to append additional content.
* @param object $page Page data object.
* @param int $depth Depth of page in reference to parent pages. Used for padding.
* @param array $args Uses ‘selected’ argument for selected page to set selected HTML attribute for option element.
*/
function start_el(&$output, $page, $depth, $args) {
$pad = str_repeat(‘&nbsp;’, $depth * 3);

$output .= “\t<option class=\”level-$depth\” value=\”$page->ID\””;
if ( $page->ID == $args[‘selected’] )
$output .= ‘ selected=”selected”‘;
$output .= ‘>’;
$title = esc_html($page->post_title);
$output .= “$pad$title”;
$output .= “</option>\n”;
}
}
/////////////
function &wp_get_posts($args = ”) {
global $wpdb;

$defaults = array(
‘child_of’ => 0, ‘sort_order’ => ‘ASC’,
‘sort_column’ => ‘post_title’, ‘hierarchical’ => 1,
‘exclude’ => ”, ‘include’ => ”,
‘meta_key’ => ”, ‘meta_value’ => ”,
‘authors’ => ”, ‘parent’ => -1, ‘exclude_tree’ => ”,
‘number’ => ”, ‘offset’ => 0,
‘cat’ => ”
);

$r = wp_parse_args( $args, $defaults );
extract( $r, EXTR_SKIP );
$number = (int) $number;
$offset = (int) $offset;

$cache = array();
$key = md5( serialize( compact(array_keys($defaults)) ) );
if ( $cache = wp_cache_get( ‘wp_get_posts’, ‘posts’ ) ) {
if ( is_array($cache) && isset( $cache[ $key ] ) ) {
$pages = apply_filters(‘wp_get_posts’, $cache[ $key ], $r );
return $pages;
}
}

if ( !is_array($cache) )
$cache = array();

$inclusions = ”;
if ( !empty($include) ) {
$child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include
$parent = -1;
$exclude = ”;
$meta_key = ”;
$meta_value = ”;
$hierarchical = false;
$incpages = preg_split(‘/[\s,]+/’,$include);
if ( count($incpages) ) {
foreach ( $incpages as $incpage ) {
if (empty($inclusions))
$inclusions = $wpdb->prepare(‘ AND ( ID = %d ‘, $incpage);
else
$inclusions .= $wpdb->prepare(‘ OR ID = %d ‘, $incpage);
}
}
}
if (!empty($inclusions))
$inclusions .= ‘)’;

$exclusions = ”;
if ( !empty($exclude) ) {
$expages = preg_split(‘/[\s,]+/’,$exclude);
if ( count($expages) ) {
foreach ( $expages as $expage ) {
if (empty($exclusions))
$exclusions = $wpdb->prepare(‘ AND ( ID <> %d ‘, $expage);
else
$exclusions .= $wpdb->prepare(‘ AND ID <> %d ‘, $expage);
}
}
}
if (!empty($exclusions))
$exclusions .= ‘)’;

$author_query = ”;
if (!empty($authors)) {
$post_authors = preg_split(‘/[\s,]+/’,$authors);

if ( count($post_authors) ) {
foreach ( $post_authors as $post_author ) {
//Do we have an author id or an author login?
if ( 0 == intval($post_author) ) {
$post_author = get_userdatabylogin($post_author);
if ( empty($post_author) )
continue;
if ( empty($post_author->ID) )
continue;
$post_author = $post_author->ID;
}

if ( ” == $author_query )
$author_query = $wpdb->prepare(‘ post_author = %d ‘, $post_author);
else
$author_query .= $wpdb->prepare(‘ OR post_author = %d ‘, $post_author);
}
if ( ” != $author_query )
$author_query = ” AND ($author_query)”;
}
}

$join = ”;
$where = “$exclusions $inclusions “;
if ( ! empty( $meta_key ) || ! empty( $meta_value ) ) {
$join = ” LEFT JOIN $wpdb->postmeta ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id )”;

// meta_key and meta_value might be slashed
$meta_key = stripslashes($meta_key);
$meta_value = stripslashes($meta_value);
if ( ! empty( $meta_key ) )
$where .= $wpdb->prepare(” AND $wpdb->postmeta.meta_key = %s”, $meta_key);
if ( ! empty( $meta_value ) )
$where .= $wpdb->prepare(” AND $wpdb->postmeta.meta_value = %s”, $meta_value);

}

if ( $parent >= 0 )
$where .= $wpdb->prepare(‘ AND post_parent = %d ‘, $parent);

$query = “SELECT * FROM $wpdb->posts $join WHERE (post_type = ‘post’ AND post_status = ‘publish’) $where “;
$query .= $author_query;
$query .= ” ORDER BY ” . $sort_column . ” ” . $sort_order ;

if ( !empty($number) )
$query .= ‘ LIMIT ‘ . $offset . ‘,’ . $number;

$pages = $wpdb->get_results($query);

if ( empty($pages) ) {
$pages = apply_filters(‘wp_get_posts’, array(), $r);
return $pages;
}

// Sanitize before caching so it’ll only get done once
$num_pages = count($pages);
for ($i = 0; $i < $num_pages; $i++) {
$pages[$i] = sanitize_post($pages[$i], ‘raw’);
}

// Update cache.
update_page_cache($pages);

if ( $child_of || $hierarchical )
$pages = & get_page_children($child_of, $pages);

if ( !empty($exclude_tree) ) {
$exclude = (int) $exclude_tree;
$children = get_page_children($exclude, $pages);
$excludes = array();
foreach ( $children as $child )
$excludes[] = $child->ID;
$excludes[] = $exclude;
$num_pages = count($pages);
for ( $i = 0; $i < $num_pages; $i++ ) {
if ( in_array($pages[$i]->ID, $excludes) )
unset($pages[$i]);
}
}

$cache[ $key ] = $pages;
wp_cache_set( ‘wp_get_posts’, $cache, ‘posts’ );

$pages = apply_filters(‘wp_get_posts’, $pages, $r);

return $pages;
}
//////////////

function walk_post_dropdown_tree() {
$args = func_get_args();
if ( empty($args[2][‘walker’]) ) // the user’s options are the third parameter
$walker = new Walker_PostDropdown;
else
$walker = $args[2][‘walker’];

return call_user_func_array(array(&$walker, ‘walk’), $args);
}

function wp_dropdown_posts($args = ”) {
$defaults = array(
‘depth’ => 0, ‘child_of’ => 0,
‘selected’ => 0, ‘echo’ => 1,
‘name’ => ‘page_id’, ‘show_option_none’ => ”, ‘show_option_no_change’ => ”,
‘option_none_value’ => ”
);

$r = wp_parse_args( $args, $defaults );
extract( $r, EXTR_SKIP );

$pages = wp_get_posts($r);
$output = ”;
$name = esc_attr($name);

if ( ! empty($pages) ) {
$output = “<select name=\”$name\” id=\”$name\”>\n”;
if ( $show_option_no_change )
$output .= “\t<option value=\”-1\”>$show_option_no_change</option>”;
if ( $show_option_none )
$output .= “\t<option value=\”” . esc_attr($option_none_value) . “\”>$show_option_none</option>\n”;
$output .= walk_post_dropdown_tree($pages, $depth, $r);
$output .= “</select>\n”;
}

$output = apply_filters(‘wp_dropdown_pages’, $output);

if ( $echo )
echo $output;

return $output;
}
/////////////////////////////

 

 

/* Use the admin_menu action to define the custom boxes */
add_action(‘admin_menu’, ‘myplugin_add_custom_box’);

/* Use the save_post action to do something with the data entered */
add_action(‘save_post’, ‘myplugin_save_postdata’);

 

/* Adds a custom section to the “advanced” Post and Page edit screens */
function myplugin_add_custom_box() {

if( function_exists( ‘add_meta_box’ )) {
add_meta_box( ‘myplugin_sectionid’, __( ‘WP Sub Posts’, ‘myplugin_textdomain’ ), ‘myplugin_inner_custom_box’, ‘post’, ‘side’,’high’ );
//add_meta_box( $id, $title, $callback, $page, $context, $priority );
add_meta_box( ‘myplugin_sectionid’, __( ‘WP Sub Posts’, ‘myplugin_textdomain’ ), ‘myplugin_inner_custom_box’, ‘page’, ‘advanced’ );
} else {
add_action(‘dbx_post_advanced’, ‘myplugin_old_custom_box’ );
add_action(‘dbx_page_advanced’, ‘myplugin_old_custom_box’ );
}
}

function myplugin_inner_custom_box() {

echo ‘<style type=”text/css”>
select#parent_id, select#parent_id option {
width:250px;
}
</style>’;

echo ‘<input type=”hidden” name=”myplugin_noncename” id=”myplugin_noncename” value=”‘ .
wp_create_nonce( plugin_basename(__FILE__) ) . ‘” />’; ?>

<h5><?php _e(‘Parent’) ?></h5>

<p><label for=”post_parent”>Please select the parent of this post</label></p>
<?php
global $post;
$currentid = $_GET[‘post’];
wp_dropdown_posts(array(‘exclude_tree’ => $currentid,
‘selected’ => $post->post_parent,
‘name’ => ‘parent_id’,
‘show_option_none’ => __(‘Main Post (no parent)’),
‘sort_column’ => ‘menu_order, post_title’));
}

/* Prints the edit form for pre-WordPress 2.5 post/page */
function myplugin_old_custom_box() {

echo ‘<div class=”dbx-b-ox-wrapper”>’ . “\n”;
echo ‘<fieldset id=”myplugin_fieldsetid” class=”dbx-box”>’ . “\n”;
echo ‘<div class=”dbx-h-andle-wrapper”><h3 class=”dbx-handle”>’ .
__( ‘WP Sub Posts’, ‘myplugin_textdomain’ ) . “</h3></div>”;

echo ‘<div class=”dbx-c-ontent-wrapper”><div class=”dbx-content”>’;

// output editing form

myplugin_inner_custom_box();

// end wrapper

echo “</div></div></fieldset></div>\n”;
}

/* When the post is saved, saves our custom data */
function myplugin_save_postdata( $post_id ) {

// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times

if ( !wp_verify_nonce( $_POST[‘myplugin_noncename’], plugin_basename(__FILE__) )) {
return $post_id;
}

// verify if this is an auto save routine. If it is our form has not been submitted, so we dont want
// to do anything
if ( defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE )
return $post_id;
// Check permissions
if ( ‘page’ == $_POST[‘post_type’] ) {
if ( !current_user_can( ‘edit_page’, $post_id ) )
return $post_id;
} else {
if ( !current_user_can( ‘edit_post’, $post_id ) )
return $post_id;
}

// OK, we’re authenticated: we need to find and save the data

$mydata = $_POST[‘parent_id’];

return $mydata;
}

function filtercontentprior(){

$all_plugins = get_plugins();

foreach ( (array)$all_plugins as $plugin_file => $plugin_data) {

//Translate, Apply Markup, Sanitize HTML
$plugin_data = _get_plugin_data_markup_translate($plugin_file, $plugin_data, false, true);
$all_plugins[ $plugin_file ] = $plugin_data;

//Filter into individual sections
if ( is_plugin_active($plugin_file) ) {
$active_plugins[ $plugin_file ] = $plugin_data;
}
}
$total_active_plugins = count($active_plugins);
return $total_active_plugins+1;
}
add_filter(‘posts_where’,’where_no_parent’);
add_filter(‘the_content’,’subpost_template’, 0, 2 );
add_action(‘wp_print_scripts’, ‘disable_autosave’);
function disable_autosave() {
wp_deregister_script(‘autosave’);
}

 

function subpost_template($content) {
global $post;

$parentID = get_the_ID();
$childposts = get_posts(array(
‘post_type’ => ‘post’,
‘numberposts’ => -1,
‘post_status’ => ‘publish’,
‘post_parent’ => $parentID
));
$subcontent = “”;
foreach($childposts as $childpost){
$subcontent .= “<blockquote class=\”sub_post\” id=\”subpost_”.$childpost->ID.”\”>”;
$subcontent .= “<h3>”.$childpost->post_title.”</h3>”;
$subcontent .= $childpost->post_content;
$subcontent .= ‘<p class=”postmetadata”><small>This sub post was added on: ‘.date(‘l, dS F, Y’,strtotime($childpost->post_date)).’ <a href=”‘.get_edit_post_link($childpost->ID).'” rel=”nofollow”>Edit</a></small></p>’;
$subcontent .= “</blockquote>”;
}

if($post->post_parent !== 0) {

$parent_info = ‘<blockquote>This post is a child post of <strong>’.get_the_title($post->post_parent).'</strong>. To view the parent post, please <a href=”‘.get_permalink($post->post_parent).'”>click here.</a></blockquote>’;
$content = $parent_info.$content;
}

$content .= $subcontent;
return $content;
}

function where_no_parent($where) {
global $wpdb;
if(!is_single()) {
$where .= ” AND post_parent = 0″;
}
else {
$where .= ” AND post_type = ‘post'”;
}
return $where;
}
?>

Download: wp-sub-post.zip