<?php if(!defined('ABSPATH')) { die(); }
if( !class_exists('WPObjectRelationships') ) {
class WPObjectRelationships {
protected $version = '0.1.0';
protected $domain = 'object-relationships';
protected $plugin_dir;
protected $plugin_uri;
const TABLE_PREFIX = 'wpor_';
const RELATE_TABLE_BASE = 'relationships';
const RELATE_META_TABLE_BASE = 'relationshipmeta';
protected $relate_table;
protected $meta_table;
public static function Instance() {
static $instance = null;
if ($instance === null) {
$instance = new self();
}
return $instance;
}
protected function __construct() {
$this->register_tables();
register_activation_hook( __FILE__, array( $this, 'install' ) );
}
public function register_tables() {
global $wpdb;
$this->relate_table = $wpdb->prefix . self::TABLE_PREFIX . self::RELATE_TABLE_BASE;
$this->meta_table = $wpdb->prefix . self::TABLE_PREFIX . self::RELATE_META_TABLE_BASE;
}
public function install() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$relate_table = "CREATE TABLE ".$this->relate_table." (\n".
" relationship_id bigint(20) unsigned NOT NULL auto_increment,\n".
" object_1_id bigint(20) unsigned NOT NULL default 0,\n".
" object_2_id bigint(20) unsigned NOT NULL default 0,\n".
" object_1_type varchar(255) NULL,\n".
" object_2_type varchar(255) NULL,\n".
" relationship_type varchar(255) NULL,\n".
" object_1_order int(11) NOT NULL default 0,\n".
" object_2_order int(11) NOT NULL default 0,\n".
" PRIMARY KEY (relationship_id),\n".
" KEY object_1 (object_1_id,object_1_type),\n".
" KEY object_2 (object_2_id,object_2_type)\n".
") ".$charset_collate.";";
$meta_table = "CREATE TABLE ".$this->meta_table." (\n".
" meta_id bigint(20) unsigned NOT NULL auto_increment,\n".
" relationship_id bigint(20) unsigned NOT NULL default 0,\n".
" meta_key varchar(255) NULL,\n".
" meta_value longtext NULL,\n".
" PRIMARY KEY (meta_id),\n".
" KEY relationship_id (relationship_id),\n".
" KEY meta_key (meta_key)\n".
") ".$charset_collate.";";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta( $relate_table );
dbDelta( $meta_table );
}
public function get_relationship( $relationship_id = null ) {
global $wpdb;
if( !$relationship_id || !is_numeric( $relationship_id ) ) {
return false;
}
$sql = "SELECT * FROM ".$this->relate_table." WHERE relationship_id=%d LIMIT 1";
return $wpdb->get_row( $wpdb->prepare( $sql, $relationship_id ), ARRAY_A );
}
public function add_relationship( $args = array(), $error = false ) {
return $this->update_relationship( $args );
}
public function update_relationship( $args = array(), $error = false ) {
global $wpdb;
// normalize all attributes
$filtered_args = shortcode_atts( array(
'relationship_type' => 'related',
'object_1_type' => 'post',
'object_1_id' => 0,
'object_2_type' => 'post',
'object_2_id' => 0,
'object_1_order' => 'default',
'object_2_order' => 'default',
'meta' => array(),
'replace_meta' => false
), $args );
// do all my input checks
if( !$filtered_args['object_1_type'] || !$filtered_args['object_1_id'] || !is_numeric( $filtered_args['object_1_id'] ) ) {
if( $error ) {
return new WP_Error( 'relationship_update_error', __( 'Could not update relationship. Object 1 not properly defined', $this->domain ) );
}
return false;
}
if( !$filtered_args['object_2_type'] || !$filtered_args['object_2_id'] || !is_numeric( $filtered_args['object_2_id'] ) ) {
if( $error ) {
return new WP_Error( 'relationship_update_error', __( 'Could not update relationship. Object 2 not properly defined', $this->domain ) );
}
return false;
}
if( !$filtered_args['relationship_type'] ) {
if( $error ) {
return new WP_Error( 'relationship_update_error', __( 'Could not update relationship. Relationship type not defined', $this->domain ) );
}
return false;
}
if( $filtered_args['meta'] && !is_array( $filtered_args['meta'] ) ) {
if( $error ) {
return new WP_Error( 'relationship_update_error', __( 'Could not update relationship. Meta must be an array', $this->domain ) );
}
return false;
}
$data = array(
'relationship_type' => $filtered_args['relationship_type'],
);
// order ids, to prevent duplicate rows
if( $filtered_args['object_1_id'] <= $filtered_args['object_2_id'] ) {
$data['object_1_type'] = $filtered_args['object_1_type'];
$data['object_1_id' ] = $filtered_args['object_1_id'];
$data['object_1_order'] = $filtered_args['object_1_order'];
$data['object_2_type'] = $filtered_args['object_2_type'];
$data['object_2_id' ] = $filtered_args['object_2_id'];
if( is_numeric( $filtered_args['object_1_order'] ) ) {
$data['object_1_order'] = $filtered_args['object_1_order'];
}
if( is_numeric( $filtered_args['object_2_order'] ) ) {
$data['object_2_order'] = $filtered_args['object_2_order'];
}
} else {
$data['object_1_type'] = $filtered_args['object_2_type'];
$data['object_1_id' ] = $filtered_args['object_2_id'];
$data['object_2_type'] = $filtered_args['object_1_type'];
$data['object_2_id' ] = $filtered_args['object_1_id'];
if( is_numeric( $filtered_args['object_1_order'] ) ) {
$data['object_2_order'] = $filtered_args['object_1_order'];
}
if( is_numeric( $filtered_args['object_2_order'] ) ) {
$data['object_1_order'] = $filtered_args['object_2_order'];
}
}
// check if this pairing exists
$sql = "SELECT relationship_id FROM ".$this->relate_table." WHERE".
" relationship_type=%s AND".
" object_1_type=%s AND object_1_id=%d AND".
" object_2_type=%s AND object_2_id=%d".
" LIMIT 1";
$params = array(
$data['relationship_type'],
$data['object_1_type'],
$data['object_1_id'],
$data['object_2_type'],
$data['object_2_id']
);
$id = $wpdb->get_var( $wpdb->prepare( $sql, $params ) );
if( $id ) {
// update
$where = array(
'relationship_id' => $id
);
$updated = $wpdb->update( $this->relate_table, $data, $where );
if( !$updated ) {
if( $error ) {
return new WP_Error( 'relationship_update_error', __( 'Could not update relationship in the database', $this->domain ), $wpdb->last_error );
}
return false;
}
if( $filtered_args['replace_meta'] ) {
$this->delete_relationship_meta( $id );
}
} else {
$inserted = $wpdb->insert( $this->relate_table, $data );
if( !$inserted ) {
if( $error ) {
return new WP_Error( 'relationship_update_error', __( 'Could not insert relationship in the database', $this->domain ), $wpdb->last_error );
}
return false;
}
$id = $wpdb->insert_id;
}
// clear caches
if( isset( $data['object_1_id'] ) && isset( $data['object_1_type'] ) ) {
wp_cache_delete( $data['object_1_id'], $data['object_1_type'] . '_relationships');
}
if( isset( $data['object_2_id'] ) && isset( $data['object_2_type'] ) ) {
wp_cache_delete( $data['object_2_id'], $data['object_2_type'] . '_relationships');
}
if( $filtered_args['meta'] ) {
foreach( $filtered_args['meta'] as $key => $val ) {
$this->update_relationship_meta( $id, $key, $val );
}
}
// TODO: Clear Meta Caches
return $id;
}
public function delete_relationship( $args, $error = false ) {
global $wpdb;
$id = 0;
$row = array();
if( is_numeric( $args ) ) {
$possible_id = $args;
$sql = "SELECT * FROM ".$this->relate_table." WHERE relationship_id=%d LIMIT 1";
$row = $wpdb->get_row( $wpdb->prepare( $sql, $possible_id ) );
if( !$row || !isset( $row['relationship_id'] ) ) {
if( $error ) {
return new WP_Error( 'relationship_delete_error', __( 'Could not delete relationship. No matching relationship found', $this->domain ) );
}
return false;
}
$id = $row['relationship_id'];
} else {
$filtered_args = shortcode_atts( array(
'relationship_type' => 'related',
'object_1_type' => 'post',
'object_1_id' => 0,
'object_2_type' => 'post',
'object_2_id' => 0
), $args );
// do all my input checks
if( !$filtered_args['object_1_type'] || !$filtered_args['object_1_id'] || !is_numeric( $filtered_args['object_1_id'] ) ) {
if( $error ) {
return new WP_Error( 'relationship_delete_error', __( 'Could not delete relationship. Object 1 not properly defined', $this->domain ) );
}
return false;
}
if( !$filtered_args['object_2_type'] || !$filtered_args['object_2_id'] || !is_numeric( $filtered_args['object_2_id'] ) ) {
if( $error ) {
return new WP_Error( 'relationship_delete_error', __( 'Could not delete relationship. Object 2 not properly defined', $this->domain ) );
}
return false;
}
if( !$filtered_args['relationship_type'] ) {
if( $error ) {
return new WP_Error( 'relationship_delete_error', __( 'Could not delete relationship. Relationship type not defined', $this->domain ) );
}
return false;
}
// strictly order the query parameters to match our standard
if( $filtered_args['object_1_id'] <= $filtered_args['object_2_id'] ) {
$data['object_1_type'] = $filtered_args['object_1_type'];
$data['object_1_id' ] = $filtered_args['object_1_id'];
$data['object_2_type'] = $filtered_args['object_2_type'];
$data['object_2_id' ] = $filtered_args['object_2_id'];
} else {
$data['object_1_type'] = $filtered_args['object_2_type'];
$data['object_1_id' ] = $filtered_args['object_2_id'];
$data['object_2_type'] = $filtered_args['object_1_type'];
$data['object_2_id' ] = $filtered_args['object_1_id'];
}
// check if this pairing exists
$sql = "SELECT * FROM ".$this->relate_table." WHERE".
" relationship_type=%s AND".
" object_1_type=%s AND object_1_id=%d AND".
" object_2_type=%s AND object_2_id=%d".
" LIMIT 1";
$params = array(
$data['relationship_type'],
$data['object_1_type'],
$data['object_1_id'],
$data['object_2_type'],
$data['object_2_id']
);
$row = $wpdb->get_row( $wpdb->prepare( $sql, $params ) );
if( !$row || !isset( $row['relationship_id'] ) ) {
if( $error ) {
return new WP_Error( 'relationship_delete_error', __( 'Could not delete relationship. No matching relationship found', $this->domain ) );
}
return false;
}
$id = $row['relationship_id'];
}
if( !$id ) {
if( $error ) {
return new WP_Error( 'relationship_delete_error', __( 'Could not delete relationship. No matching relationship found', $this->domain ) );
}
return false;
}
// try deleting
$deleted = $wpdb->delete( $this->relate_table, array(
'relationship_id' => $id
) );
if( !$deleted ) {
if( $error ) {
return new WP_Error( 'relationship_delete_error', __( 'Could not delete relationship. No matching relationship found', $this->domain ) );
}
return false;
}
// clear caches
if( isset( $row['object_1_id'] ) && isset( $row['object_1_type'] ) ) {
wp_cache_delete( $row['object_1_id'], $row['object_1_type'] . '_relationships');
}
if( isset( $row['object_2_id'] ) && isset( $row['object_2_type'] ) ) {
wp_cache_delete( $row['object_2_id'], $row['object_2_type'] . '_relationships');
}
// clear meta
$wpdb->delete( $this->meta_table, array(
'relationship_id' => $id
) );
// TODO: Clear Meta Caches
return true;
}
public function set_relationships( $object_type = null, $object_id = null, $relationship_type = null, $relationships = array() ) {
if( !$object_type || !is_numeric( $object_id ) ) {
return false;
}
if( $relationship_type ) {
$relationships = array(
$relationship_type => $relationships
);
}
// TODO: Add shortcircuit filter?
// get cached relationships
$relationship_cache = wp_cache_get($object_id, $object_type . '_relationships');
if( !$relationship_cache ) {
$relationship_cache = $this->update_relationship_cache( $object_type, array( $object_id ) );
$relationship_cache = $relationship_cache[$object_id];
}
$old_relationships = $relationship_cache;
if( $relationships && is_array( $relationships ) ) {
foreach( $relationships as $name => $values ) {
if( !$values ) {
continue;
}
$temp = array();
if( isset( $old_relationships[$name] ) ) {
$temp = $old_relationships[$name];
}
foreach( $values as $relationship ) {
if( !is_array( $relationship ) ) {
continue;
}
if( !isset( $relationship['object_type'] ) || !isset( $relationship['object_id'] ) ) {
continue;
}
if( !isset( $relationship['meta'] ) ) {
$relationship['meta'] = array();
}
$insert = array(
'relationship_type' => $name,
'object_1_type' => $object_type,
'object_1_id' => $object_id,
'object_2_type' => $relationship['object_type'],
'object_2_id' => $relationship['object_id'],
'meta' => $relationship['meta'],
'replace_meta' => true
);
if( isset( $relationship['object_1_order'] ) ) {
$insert['object_1_order'] = $relationship['object_1_order'];
}
if( isset( $relationship['object_2_order'] ) ) {
$insert['object_2_order'] = $relationship['object_2_order'];
}
$updated = $this->update_relationship( $insert );
foreach( $temp as $i => $rel ) {
if( ( $rel['object_type'] == $relationship['object_type'] ) && ( $rel['object_id'] == $relationship['object_id'] ) ) {
unset( $temp[$i] );
}
}
}
// delete old relationships
foreach( $temp as $rel ) {
$deleted = $this->delete_relationship( $rel['relationship_id'] );
}
}
}
}
public function get_relationships( $object_type = null, $object_id = null, $relationship_type = null ) {
if( !$object_type || !is_numeric( $object_id ) ) {
return false;
}
$object_id = absint( $object_id );
if ( !$object_id ) {
return false;
}
// TODO: Add shortcircuit filter?
// get cached relationships
$relationship_cache = wp_cache_get($object_id, $object_type . '_relationships');
if( !$relationship_cache ) {
$relationship_cache = $this->update_relationship_cache( $object_type, array( $object_id ) );
$relationship_cache = $relationship_cache[$object_id];
}
if( !$relationship_type ) {
return $relationship_cache;
}
if( isset( $relationship_cache[$relationship_type] ) ) {
return $relationship_cache[$relationship_type];
}
return array();
}
public function update_relationship_cache( $object_type, $object_ids ) {
global $wpdb;
if( !$object_type || !$object_ids ) {
return false;
}
if( !is_array( $object_ids ) ) {
$object_ids = preg_replace( '|[^0-9,]|', '', $object_ids );
$object_ids = explode( ',', $object_ids );
}
$object_ids = array_map( 'intval', $object_ids );
$cache_key = $object_type . '_relationships';
$ids = array();
$cache = array();
foreach( $object_ids as $id ) {
$cached_object = wp_cache_get( $id, $cache_key );
if( false === $cached_object ) {
$ids[] = $id;
} else {
$cache[$id] = $cached_object;
}
}
if( empty( $ids ) ) {
return $cache;
}
// Get meta info
$id_list = join( ',', $ids );
$query = "SELECT * FROM ".$this->relate_table." WHERE (\n".
"object_1_type=%s AND object_1_id IN (".$id_list."\n".
") OR (\n".
"object_2_type=%s AND object_2_id IN (".$id_list."\n".
") ORDER BY case \n".
" when object_1_type=%s AND object_1_id IN(".$id_list.") then object_1_order\n".
" when object_2_type=%s AND object_2_id IN(".$id_list.") then object_2_order\n".
"end ASC";
$query = $wpdb->prepare( $query, array( $object_type, $object_type ) );
$relate_list = $wpdb->get_results( $query, ARRAY_A );
if( !empty( $relate_list ) ) {
foreach( $relate_list as $row ) {
$o1id = intval( $row['object_1_id'] );
$o2id = intval( $row['object_2_id'] );
$parsed_row = array();
if( $row['object_1_type'] === $object_type && in_array( $o1id, $ids ) ) {
$parsed_row[$o1id] = array(
'relationship_id' => $row['relationship_id'],
'object_id' => $o2id,
'object_type' => $row['object_2_type'],
'relationship_type' => $row['relationship_type'],
);
}
if( $row['object_2_type'] === $object_type && in_array( $o2id, $ids ) ) {
$parsed_row[$o2id] = array(
'relationship_id' => $row['relationship_id'],
'object_id' => $o1id,
'object_type' => $row['object_1_type'],
'relationship_type' => $row['relationship_type'],
);
}
foreach( $parsed_row as $oid => $val ) {
// Force subkeys to be array type:
if( !isset( $cache[$oid] ) || !is_array( $cache[$oid] ) ) {
$cache[$oid] = array();
}
$rtype = $val['relationship_type'];
unset( $val['relationship_type'] );
if( !isset( $cache[$oid][$rtype] ) || !is_array( $cache[$oid][$rtype] ) ) {
$cache[$oid][$rtype] = array();
}
$cache[$oid][$rtype][] = $val;
}
}
}
foreach( $ids as $id ) {
if( !isset( $cache[$id] ) ) {
$cache[$id] = array();
}
wp_cache_add( $id, $cache[$id], $cache_key );
}
return $cache;
}
public function get_relationship_meta( $relationship_id, $meta_key, $single = false ) {
if( !is_numeric( $relationship_id ) ) {
return false;
}
$relationship_id = absint( $relationship_id );
if( !$relationship_id ) {
return false;
}
$meta_cache = wp_cache_get( $relationship_id, 'relationship_meta' );
if( !$meta_cache ) {
$meta_cache = $this->update_meta_cache( array( $relationship_id ) );
$meta_cache = $meta_cache[$relationship_id];
}
if( !$meta_key ) {
return $meta_cache;
}
if( isset( $meta_cache[$meta_key] ) ) {
if ( $single ) {
return maybe_unserialize( $meta_cache[$meta_key][0] );
} else {
return array_map( 'maybe_unserialize', $meta_cache[$meta_key] );
}
}
if( $single ) {
return '';
} else {
return array();
}
}
public function add_relationship_meta( $relationship_id, $meta_key, $meta_value, $unique = false ) {
global $wpdb;
if( !$meta_key || !is_numeric( $relationship_id ) ) {
return false;
}
$object_id = absint( $object_id );
if( !$object_id ) {
return false;
}
// expected_slashed ($meta_key)
$meta_key = wp_unslash($meta_key);
$meta_value = wp_unslash($meta_value);
$meta_value = sanitize_meta( $meta_key, $meta_value, 'relationship' );
$sql = "SELECT COUNT(*) FROM " . $this->meta_table . " WHERE meta_key = %s AND relationship_id = %d";
$row_exists = $wpdb->get_var( $wpdb->prepare( $sql, $meta_key, $object_id ) );
if( $unique && $row_exists ) {
return false;
}
$_meta_value = $meta_value;
$meta_value = maybe_serialize( $meta_value );
do_action( "add_relationship_meta", $relationship_id, $meta_key, $_meta_value );
$result = $wpdb->insert( $this->meta_table, array(
'relationship_id' => $relationship_id,
'meta_key' => $meta_key,
'meta_value' => $meta_value
) );
if ( !$result ) {
return false;
}
$mid = (int) $wpdb->insert_id;
wp_cache_delete( $relationship_id, 'relationship_meta');
do_action( "added_relationship_meta", $mid, $relationship_id, $meta_key, $_meta_value );
return $mid;
}
public function update_relationship_meta( $relationship_id, $meta_key, $meta_value, $prev_value = '' ) {
global $wpdb;
if ( !$meta_key || !is_numeric( $relationship_id ) ) {
return false;
}
$relationship_id = absint( $relationship_id );
if ( !$relationship_id ) {
return false;
}
// expected_slashed ($meta_key)
$raw_meta_key = $meta_key;
$meta_key = wp_unslash($meta_key);
$passed_value = $meta_value;
$meta_value = wp_unslash($meta_value);
$meta_value = sanitize_meta( $meta_key, $meta_value, 'relationship' );
// Compare existing value to new value if no prev value given and the key exists only once.
if( empty( $prev_value ) ) {
$old_value = $this->get_relationship_meta( $relationship_id, $meta_key );
if( count( $old_value ) == 1 ) {
if( $old_value[0] === $meta_value ) {
return false;
}
}
}
$sql = "SELECT meta_id FROM " . $this->meta_table . " WHERE meta_key = %s AND relationship_id = %d";
$meta_ids = $wpdb->get_col( $wpdb->prepare( $sql, $meta_key, $relationship_id ) );
if( empty( $meta_ids ) ) {
return $this->add_relationship_meta( $relationship_id, $raw_meta_key, $passed_value );
}
$_meta_value = $meta_value;
$meta_value = maybe_serialize( $meta_value );
$data = compact( 'meta_value' );
$where = array( 'relationship_id' => $relationship_id, 'meta_key' => $meta_key );
if ( !empty( $prev_value ) ) {
$prev_value = maybe_serialize( $prev_value );
$where['meta_value'] = $prev_value;
}
foreach ( $meta_ids as $meta_id ) {
do_action( "update_relationship_meta", $meta_id, $relationship_id, $meta_key, $_meta_value );
}
$result = $wpdb->update( $this->meta_table, $data, $where );
if( !$result ){
return false;
}
wp_cache_delete( $relationship_id, 'relationship_meta' );
foreach( $meta_ids as $meta_id ) {
do_action( "updated_relationship_meta", $meta_id, $relationship_id, $meta_key, $_meta_value );
}
return true;
}
public function delete_relationship_meta( $relationship_id, $meta_key = '', $meta_value = '', $delete_all = false ) {
global $wpdb;
if( !$meta_key || !is_numeric( $relationship_id ) && !$delete_all ) {
return false;
}
$relationship_id = absint( $relationship_id );
if( !$relationship_id && !$delete_all ) {
return false;
}
// expected_slashed ($meta_key)
$meta_key = wp_unslash( $meta_key );
$meta_value = wp_unslash( $meta_value );
$_meta_value = $meta_value;
$meta_value = maybe_serialize( $meta_value );
$query = $wpdb->prepare( "SELECT meta_id FROM " . $this->meta_table . " WHERE meta_key = %s", $meta_key );
if( !$delete_all ) {
$query .= $wpdb->prepare(" AND relationship_id = %d", $relationship_id );
}
if( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) {
$query .= $wpdb->prepare(" AND meta_value = %s", $meta_value );
}
$meta_ids = $wpdb->get_col( $query );
if( !count( $meta_ids ) ) {
return false;
}
if( $delete_all ) {
if( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) {
$object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT relationship_id FROM " . $this->meta_table . " WHERE meta_key = %s AND meta_value = %s", $meta_key, $meta_value ) );
} else {
$object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT relationship_id FROM " . $this->meta_table . " WHERE meta_key = %s", $meta_key ) );
}
}
do_action( "delete_relationship_meta", $meta_ids, $relationship_id, $meta_key, $_meta_value );
$query = "DELETE FROM " . $this->meta_table . " WHERE meta_id IN( " . implode( ',', $meta_ids ) . " )";
$count = $wpdb->query( $query );
if( !$count ) {
return false;
}
if( $delete_all ) {
foreach( (array) $object_ids as $o_id ) {
wp_cache_delete($o_id, 'relationship_meta');
}
} else {
wp_cache_delete($relationship_id, 'relationship_meta');
}
do_action( "deleted_relationship_meta", $meta_ids, $relationship_id, $meta_key, $_meta_value );
return true;
}
public function update_meta_cache( $relationship_ids = array() ) {
global $wpdb;
if ( !$relationship_ids ) {
return false;
}
if ( !is_array( $relationship_ids ) ) {
$relationship_ids = preg_replace( '|[^0-9,]|', '', $relationship_ids );
$relationship_ids = explode( ',', $relationship_ids );
}
$relationship_ids = array_map( 'intval', $relationship_ids );
$cache_key = 'relationship_meta';
$ids = array();
$cache = array();
foreach( $relationship_ids as $id ) {
$cached_object = wp_cache_get( $id, $cache_key );
if( false === $cached_object ) {
$ids[] = $id;
} else {
$cache[$id] = $cached_object;
}
}
if ( empty( $ids ) ) {
return $cache;
}
// Get meta info
$id_list = join( ',', $ids );
$meta_list = $wpdb->get_results( "SELECT relationship_id, meta_key, meta_value FROM " . $this->meta_table . " WHERE relationship_id IN (" . $id_list . ") ORDER BY meta_id ASC", ARRAY_A );
if ( !empty( $meta_list ) ) {
foreach ( $meta_list as $meta_row) {
$mpid = intval( $meta_row['relationship_id'] );
$mkey = $meta_row['meta_key'];
$mval = $meta_row['meta_value'];
// Force subkeys to be array type:
if ( !isset($cache[$mpid]) || !is_array($cache[$mpid]) ) {
$cache[$mpid] = array();
}
if ( !isset($cache[$mpid][$mkey]) || !is_array($cache[$mpid][$mkey]) ) {
$cache[$mpid][$mkey] = array();
}
// Add a value to the current pid/key:
$cache[$mpid][$mkey][] = $mval;
}
}
foreach ( $ids as $id ) {
if ( !isset( $cache[$id] ) ) {
$cache[$id] = array();
}
wp_cache_add( $id, $cache[$id], $cache_key );
}
return $cache;
}
}
WPObjectRelationships::Instance();
}