Skip to content

Instantly share code, notes, and snippets.

@styledev
Created August 29, 2012 21:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save styledev/3519381 to your computer and use it in GitHub Desktop.
Save styledev/3519381 to your computer and use it in GitHub Desktop.
This code will upgrade ACF to allow for multi-item reverse loopkup by giving each relationship connection a 'rel_$post_type' meta_key with a serialized array of posts containing the post_ids of the originating post.
// Added "before_delete_post" action to trigger rel_cleanup (cleans up all associated posts with rel_ meta_keys when a post is deleted)
function Acf()
{
// vars
$this->path = plugin_dir_path(__FILE__);
$this->dir = plugins_url('',__FILE__);
$this->version = '3.3.9';
$this->upgrade_version = '3.3.3'; // this is the latest version which requires an upgrade
$this->cache = array(); // basic array cache to hold data throughout the page load
// set text domain
load_plugin_textdomain('acf', false, basename(dirname(__FILE__)).'/lang' );
// controllers
$this->setup_controllers();
// actions
add_action('init', array($this, 'init'));
add_filter('post_updated_messages', array($this, 'post_updated_messages'));
add_filter('manage_edit-acf_columns', array($this, 'acf_columns_filter'));
add_action('admin_menu', array($this,'admin_menu'));
add_action('admin_head', array($this,'admin_head'));
add_action('wp_ajax_get_input_metabox_ids', array($this, 'get_input_metabox_ids'));
add_action('before_delete_post', array($this, 'rel_cleanup'));
return true;
}
/*
* rel_cleanup
*
* @description: Cleans up any reverse relationships when you delete a post.
* @since ...
* @created: 30/08/12
*/
function rel_cleanup($post_id) {
$meta = get_post_custom($post_id);
$acf = get_post_custom_keys($post_id);
if( $acf ) {
foreach($acf as $field_name) {
if( strpos($field_name,'_') === 0 ) {
$field = get_post_meta($post_id, $field_name, true);
$field_id = $this->get_post_meta_post_id($field);
if( $field_id ) {
$field_meta = get_post_meta($field_id, $field, true);
if( $field_meta['type'] == 'relationship' ) {
$name = str_replace('_','',$field_name);
$rel_items = maybe_unserialize($meta[$name][0]);
acf_Field::update_rel( $post_id, $rel_items );
}
}
}
}
}
}
// Creates the 'rel_$post_type' meta to store the reverse lookup
function update_rel( $post_id, $items ) {
if( $items ) {
global $post_type;
foreach($items as $rel_id) {
$current = get_post_meta($rel_id, "rel_$post_type", true);
if( !empty($current) ) {
$item = array_search($post_id,$current);
unset($current[$item]);
if( !empty($current) ) update_post_meta($rel_id, "rel_$post_type", $current);
else delete_post_meta($rel_id, "rel_$post_type");
}
}
}
}
function update_value($post_id, $field, $value)
{
// strip slashes
$value = stripslashes_deep($value);
// Setup reverse lookup
if( $field['type'] == 'relationship' ) {
global $post_type;
// Get the current related posts
$related_current = get_post_meta($post_id, $field['name'], true);
// If we are saving any values and already have saved related posts, do a diff to see if any related posts are being removed
if( $value && $related_current ) $remove = array_diff($related_current, $value);
else $remove = $related_current;
// If we are removing posts then loop through them and update/delete the related post's rel_ meta.
if( $remove ) self::update_rel( $post_id, $remove );
// For all values left over create new or update the meta for the related post only if the value isn't currently there.
if( $value ) {
foreach($value as $rel_post) {
$current = get_post_meta($rel_post, "rel_$post_type", true);
if( $current ) {
$search = array_search($post_id,$current);
if( $search === false ) array_push($current,$post_id);
}else $current = array($post_id);
update_post_meta($rel_post, "rel_$post_type", $current);
}
}
}
// if $post_id is a string, then it is used in the everything fields and can be found in the options table
if( is_numeric($post_id) )
{
update_post_meta($post_id, $field['name'], $value);
update_post_meta($post_id, '_' . $field['name'], $field['key']);
}
else
{
update_option( $post_id . '_' . $field['name'], $value );
update_option( '_' . $post_id . '_' . $field['name'], $field['key'] );
}
//clear the cache for this field
wp_cache_delete('acf_get_field_' . $post_id . '_' . $field['name']);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment