Skip to content

Instantly share code, notes, and snippets.

@mikeschinkel
Created August 3, 2010 23:16
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mikeschinkel/507345 to your computer and use it in GitHub Desktop.
<?php
/*
Plugin Name: Taxonomy Mirrored Posts
Description: Enables PHP/Theme Developers to register post types that will use Taxonomy Terms to Mirror Posts.
Version: 0.1
Author: Mike Schinkel
Author URI: http://mikeschinkel.com
*/
/*
* TODD: Need to delete _mirrored_term_id when a post is deleted.
* TODD: Need to delete term when post is deleted (or maybe not?)
* TODD: Need to disallow deletion of non-orphaned terms.
*/
if (!class_exists('TMP_Hooks')) {
class TMP_Hooks {
function __construct($args=array()) {
$this->TMP_Hooks($args);
}
function TMP_Hooks($args=array()) {
}
static function on_load() {
add_action('save_post', array(__CLASS__,'save_post'),10,2);
add_action('init',array(__CLASS__,'init'));
}
static function init() {
do_action('register_taxonomy_mirrored_post_types');
}
static function save_post($post_id, $post) {
$mirrored_post_types = array_keys(get_taxonomy_mirrored_post_types());
if (in_array($post->post_type,$mirrored_post_types)) {
$post_type_object = get_post_type_object($post->post_type);
if (strlen(trim($post->post_title))==0) { // This happens during auto-draft, maybe other times.
if (!in_array($post->post_status,array('auto-draft','trash','hidden'))) { // Trap this to gain insight; insight helps us make it more robust.
$mirrored_post_types = implode(' or ',$mirrored_post_types);
echo "ERROR: Unexpected during insert of either $mirrored_post_types post types:\n<br/>";
echo "post_status: $post->post_status\n<br/>";
echo "post_title: $post->post_title\n<br/>";
echo "post_name: $post->post_name\n<br/>";
exit;
}
} else if ($post->post_status!='auto-draft') {
$mirrored_id = get_mirrored_post_term_id($post_id);
$type_name = strtolower($post_type_object->labels->singular_name);
$updated_term = array(
'name' => $post->post_title,
'description' => "Mirrored taxonomy term for $type_name {$post->post_title}",
'slug' => (is_numeric($post->post_name) ? sanitize_title_with_dashes($post->post_title) : $post->post_name),
);
$term = get_term($mirrored_id,$post->post_type,ARRAY_A);
if (is_wp_error($term)) {
$term = get_term_by('name',$post->post_title,$post->post_type);
}
if (is_wp_error($term)) {
echo 'ERROR: We should not get a WP_Error here. If it does need to validate assumptions.';
print_r($term);
die();
}
//print_r($term); TODO: Need to deal with duplicate slugs
if (is_array($term) || is_object($term)) { // Not sure if the object test is needed, but just in case
$updated_term = array_merge((array)$term,$updated_term);
//$updated_term[$term_id] = $mirrored_id;
$new_term = wp_update_term($updated_term['term_id'],$post->post_type,$updated_term);
if (is_wp_error($new_term) && isset($new_term->errors['duplicate_term_slug'])) {
//TODO: Fixed duplicated terms
}
} else {
$new_term = wp_insert_term($post->post_title,$post->post_type,$updated_term);
}
if (is_wp_error($new_term)) {
header('Content-type:text/plain');
echo 'ERROR: We should not get a WP_Error here. If it does we need to validate our assumptions.';
print_r($new_term);
die();
}
update_mirrored_post_term_id($post_id,$new_term['term_id']);
}
}
}
}
}
TMP_Hooks::on_load();
global $tmp_taxonomy_mirrored_post_types;
$tmp_taxonomy_mirrored_post_types = array();
function register_taxonomy_mirrored_post_type($post_type) {
global $tmp_taxonomy_mirrored_post_types;
$tmp_taxonomy_mirrored_post_types[$post_type] = array(
'post_type' => $post_type,
);
}
function get_taxonomy_mirrored_post_types() {
global $tmp_taxonomy_mirrored_post_types;
return $tmp_taxonomy_mirrored_post_types;
}
function is_post_type_mirrored($post_type) {
global $tmp_taxonomy_mirrored_post_types;
return isset($tmp_taxonomy_mirrored_post_types[$post_type]);
}
function get_mirrored_post_term_id($post_id) {
return (int)get_post_meta($post_id,'_mirrored_term_id',true);
}
function update_mirrored_post_term_id($post_id,$value) {
update_post_meta($post_id,'_mirrored_term_id',$value);
}
function get_mirrored_post_id($term_id) {
global $wpdb;
$sql = $wpdb->prepare("SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='_mirrored_term_id' AND meta_value=%d",$term_id);
$post_id = (int)$wpdb->get_var($sql);
return $post_id;
}
function get_taxonomy_mirrored_post( $taxonomy_term ) {
static $taxonomy_posts;
if (!isset($taxonomy_posts)) {
$taxonomy_posts = array(); // TODO: Optimize in case the query returns large data set
$result = new WP_Query("post_type={$taxonomy_term->taxonomy}&posts_per_page=-1");
foreach($result->posts as $post) {
$term_id = get_mirrored_post_term_id($post->ID);
$taxonomy_posts[$term_id] = $post;
}
}
return (isset($taxonomy_posts[$taxonomy_term->term_id]) ? $taxonomy_posts[$taxonomy_term->term_id] : false);
}
function get_post_taxonomy_mirrored_posts($post,$taxonomy) {
if (is_numeric($post))
$post = get_post($post);
$terms = wp_get_post_terms($post->ID,$taxonomy);
$term_ids = array();
foreach($terms as $term)
$term_ids[] = $term->term_id;
$term_ids = implode(',',$term_ids);
global $wpdb;
$sql = $wpdb->prepare("SELECT post_id FROM wp_postmeta WHERE meta_key='_mirrored_term_id' AND meta_value IN ($term_ids)");
$post_ids = array();
$posts = $wpdb->get_results($sql);
foreach($posts as $post)
$post_ids[] = $post->post_id;
$post_ids = implode(',',$post_ids);
$posts = get_posts("post_type=$taxonomy&numberposts=-1&include=$post_ids");
return $posts;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment