Exemple #1
0
 /**
  * Create instance from mixed query vars; also returns the modified query vars.
  *
  * @param array Query vars to collect parameters from
  * @return:
  * - null means ignore current query
  * - WP_Error instance if the query is invalid
  * - array( P2P_Query, array )
  */
 public static function create_from_qv($q, $object_type)
 {
     $q = self::expand_shortcuts($q);
     if (!isset($q['connected_type'])) {
         if (isset($q['connected_items'])) {
             return new WP_Error('no_connection_type', "Queries without 'connected_type' are no longer supported.");
         }
         return;
     }
     if (isset($q['connected_direction'])) {
         $directions = (array) _p2p_pluck($q, 'connected_direction');
     } else {
         $directions = array();
     }
     $item = isset($q['connected_items']) ? $q['connected_items'] : 'any';
     $ctypes = (array) _p2p_pluck($q, 'connected_type');
     $p2p_types = self::expand_ctypes($item, $directions, $object_type, $ctypes);
     if (empty($p2p_types)) {
         return new WP_Error('no_direction', "Could not find direction(s).");
     }
     if (1 == count($p2p_types)) {
         $q = self::finalize_query_vars($q, $p2p_types[0], $item);
     }
     $p2p_q = new P2P_Query();
     $p2p_q->ctypes = $p2p_types;
     $p2p_q->items = $item;
     foreach (array('meta', 'orderby', 'order_num', 'order') as $key) {
         $p2p_q->{$key} = isset($q["connected_{$key}"]) ? $q["connected_{$key}"] : false;
     }
     $p2p_q->query = isset($q['connected_query']) ? $q['connected_query'] : array();
     return array($p2p_q, $q);
 }
Exemple #2
0
/**
 * Register a connection between two post types.
 *
 * This creates the appropriate meta box in the admin edit screen.
 *
 * Takes the following parameters, as an associative array:
 *
 * - 'name' - string A unique identifier for this connection type.
 *
 * - 'from' - string|array The first end of the connection.
 *
 * - 'from_query_vars' - array Additional query vars to pass to WP_Query. Default: none.
 *
 * - 'to' - string|array The second end of the connection.
 *
 * - 'to_query_vars' - array Additional query vars to pass to WP_Query. Default: none.
 *
 * - 'fields' - array( key => Title ) Metadata fields editable by the user. Default: none.
 *
 * - 'cardinality' - string How many connection can each post have: 'one-to-many', 'many-to-one' or 'many-to-many'. Default: 'many-to-many'
 *
 * - 'duplicate_connections' - bool Whether to allow more than one connection between the same two posts. Default: false.
 *
 * - 'self_connections' - bool Whether to allow a post to connect to itself. Default: false.
 *
 * - 'sortable' - bool|string Whether to allow connections to be ordered via drag-and-drop. Can be 'from', 'to', 'any' or false. Default: false.
 *
 * - 'title' - string|array The box's title. Default: 'Connected {$post_type}s'
 *
 * - 'from_labels' - array Additional labels for the admin box (optional)
 *
 * - 'to_labels' - array Additional labels for the admin box (optional)
 *
 * - 'reciprocal' - bool For indeterminate connections: True means all connections are displayed in a single box. False means 'from' connections are shown in one box and 'to' connections are shown in another box. Default: false.
 *
 * - 'admin_box' - bool|string|array Whether and where to show the admin connections box.
 *
 * - 'can_create_post' - bool Whether to allow post creation via the connection box. Default: true.
 *
 * @param array $args
 *
 * @return bool|object False on failure, P2P_Connection_Type instance on success.
 */
function p2p_register_connection_type($args)
{
    if (!did_action('init')) {
        trigger_error("Connection types should not be registered before the 'init' hook.");
    }
    $argv = func_get_args();
    if (count($argv) > 1) {
        $args = array();
        foreach (array('from', 'to', 'reciprocal') as $i => $key) {
            if (isset($argv[$i])) {
                $args[$key] = $argv[$i];
            }
        }
    } else {
        $args = $argv[0];
    }
    if (isset($args['id'])) {
        $args['name'] = _p2p_pluck($args, 'id');
    }
    if (isset($args['prevent_duplicates'])) {
        $args['duplicate_connections'] = !$args['prevent_duplicates'];
    }
    if (isset($args['show_ui'])) {
        $args['admin_box'] = array('show' => _p2p_pluck($args, 'show_ui'));
        if (isset($args['context'])) {
            $args['admin_box']['context'] = _p2p_pluck($args, 'context');
        }
    }
    $ctype = P2P_Connection_Type_Factory::register($args);
    do_action('p2p_registered_connection_type', $ctype, $args);
    return $ctype;
}
 function expand_connected_type(&$q)
 {
     if (!isset($q['connected_type'])) {
         return;
     }
     $ctype = p2p_type(_p2p_pluck($q, 'connected_type'));
     if (!$ctype) {
         return false;
     }
     if (isset($q['connected_direction'])) {
         $directed = $ctype->set_direction(_p2p_pluck($q, 'connected_direction'));
     } else {
         if ('any' == $q['connected_items']) {
             $post_type = isset($q['post_type']) ? $q['post_type'] : 'post';
         } else {
             $post_type = $q['connected_items'];
         }
         $directed = P2P_Query::find_direction($ctype, $post_type, 'post');
     }
     if (!$directed) {
         trigger_error("Can't determine direction", E_USER_WARNING);
         return false;
     }
     $q = $directed->get_connected_args($q);
     return true;
 }
Exemple #4
0
 /**
  * Create instance from mixed query vars
  *
  * @param array Query vars to collect parameters from
  * @return:
  * - null means ignore current query
  * - WP_Error instance if the query is invalid
  * - P2P_Query instance on success
  */
 public static function create_from_qv(&$q, $object_type)
 {
     $shortcuts = array('connected' => 'any', 'connected_to' => 'to', 'connected_from' => 'from');
     foreach ($shortcuts as $key => $direction) {
         if (!empty($q[$key])) {
             $q['connected_items'] = _p2p_pluck($q, $key);
             $q['connected_direction'] = $direction;
         }
     }
     if (!isset($q['connected_type'])) {
         if (isset($q['connected_items'])) {
             return new WP_Error('no_connection_type', "Queries without 'connected_type' are no longer supported.");
         }
         return;
     }
     $ctypes = (array) _p2p_pluck($q, 'connected_type');
     if (isset($q['connected_direction'])) {
         $directions = (array) _p2p_pluck($q, 'connected_direction');
     } else {
         $directions = array();
     }
     $item = isset($q['connected_items']) ? $q['connected_items'] : 'any';
     $p2p_types = array();
     foreach ($ctypes as $i => $p2p_type) {
         $ctype = p2p_type($p2p_type);
         if (!$ctype) {
             continue;
         }
         if (isset($directions[$i])) {
             $directed = $ctype->set_direction($directions[$i]);
         } else {
             $directed = $ctype->find_direction($item, true, $object_type);
         }
         if (!$directed) {
             continue;
         }
         $p2p_types[] = $directed;
     }
     if (empty($p2p_types)) {
         return new WP_Error('no_direction', "Could not find direction(s).");
     }
     if (1 == count($p2p_types)) {
         $directed = $p2p_types[0];
         if ($orderby_key = $directed->get_orderby_key()) {
             $q = wp_parse_args($q, array('connected_orderby' => $orderby_key, 'connected_order' => 'ASC', 'connected_order_num' => true));
         }
         $q = array_merge_recursive($q, array('connected_meta' => $directed->data));
         $q = $directed->get_final_qv($q, 'opposite');
         $q = apply_filters('p2p_connected_args', $q, $directed, $item);
     }
     $p2p_q = new P2P_Query();
     $p2p_q->ctypes = $p2p_types;
     $p2p_q->items = $item;
     foreach (array('meta', 'orderby', 'order_num', 'order') as $key) {
         $p2p_q->{$key} = isset($q["connected_{$key}"]) ? $q["connected_{$key}"] : false;
     }
     $p2p_q->query = isset($q['connected_query']) ? $q['connected_query'] : array();
     return $p2p_q;
 }
 function translate_qv($qv)
 {
     $map = array('include' => 'post__in', 'exclude' => 'post__not_in', 'search' => 's', 'page' => 'paged', 'per_page' => 'posts_per_page');
     foreach ($map as $old => $new) {
         if (isset($qv["p2p:{$old}"])) {
             $qv[$new] = _p2p_pluck($qv, "p2p:{$old}");
         }
     }
     return $qv;
 }
 function expand_shortcut_qv(&$q)
 {
     $qv_map = array('connected' => 'any', 'connected_to' => 'to', 'connected_from' => 'from');
     foreach ($qv_map as $key => $direction) {
         if (!empty($q[$key])) {
             $q['connected_items'] = _p2p_pluck($q, $key);
             $q['connected_direction'] = $direction;
         }
     }
 }
Exemple #7
0
 private static function expand_shortcuts($q)
 {
     $shortcuts = array('connected' => 'any', 'connected_to' => 'to', 'connected_from' => 'from');
     foreach ($shortcuts as $key => $direction) {
         if (!empty($q[$key])) {
             $q['connected_items'] = _p2p_pluck($q, $key);
             $q['connected_direction'] = $direction;
         }
     }
     return $q;
 }
 function expand_arg($args)
 {
     $box_args = parent::expand_arg($args);
     foreach (array('can_create_post') as $key) {
         if (isset($args[$key])) {
             $box_args[$key] = _p2p_pluck($args, $key);
         }
     }
     $box_args = wp_parse_args($box_args, array('context' => 'side', 'priority' => 'default', 'can_create_post' => true));
     return $box_args;
 }
Exemple #9
0
 private function set_labels(&$args)
 {
     foreach (array('from', 'to') as $key) {
         $labels = _p2p_pluck($args, $key . '_labels');
         if (empty($labels)) {
             $labels = $this->side[$key]->get_labels();
         } else {
             $labels = (object) $labels;
         }
         $this->labels[$key] = $labels;
     }
 }
Exemple #10
0
 function filter_ctypes($ctype, $args)
 {
     if (isset($args['admin_column'])) {
         $column_args = _p2p_pluck($args, 'admin_column');
         if (!is_array($column_args)) {
             $column_args = array('show' => $column_args);
         }
     } else {
         $column_args = array();
     }
     $column_args = wp_parse_args($column_args, array('show' => false));
     $this->register($ctype->name, $column_args);
     return $args;
 }
 private static function create_side(&$args, $direction)
 {
     $object = _p2p_pluck($args, $direction);
     if (in_array($object, array('user', 'attachment'))) {
         $object_type = $object;
     } else {
         $object_type = 'post';
     }
     $query_vars = _p2p_pluck($args, $direction . '_query_vars');
     if ('post' == $object_type) {
         $query_vars['post_type'] = (array) $object;
     }
     $class = 'P2P_Side_' . ucfirst($object_type);
     return new $class($query_vars);
 }
Exemple #12
0
 public function __construct($args, $sides)
 {
     $this->side = $sides;
     $this->set_self_connections($args);
     $this->set_cardinality(_p2p_pluck($args, 'cardinality'));
     $labels = array();
     foreach (array('from', 'to') as $key) {
         $labels[$key] = (array) _p2p_pluck($args, $key . '_labels');
     }
     $this->labels = $labels;
     $this->fields = $this->expand_fields(_p2p_pluck($args, 'fields'));
     foreach ($args as $key => $value) {
         $this->{$key} = $value;
     }
 }
 public static function register($args)
 {
     if (isset($args['name'])) {
         if (strlen($args['name']) > 44) {
             trigger_error(sprintf("Connection name '%s' is longer than 44 characters.", $args['name']), E_USER_WARNING);
             return false;
         }
     } else {
         trigger_error("Connection types without a 'name' parameter are deprecated.", E_USER_WARNING);
     }
     $args = wp_parse_args($args, array('name' => false, 'from_object' => 'post', 'to_object' => 'post', 'from' => 'post', 'to' => 'post', 'from_query_vars' => array(), 'to_query_vars' => array(), 'data' => array(), 'cardinality' => 'many-to-many', 'prevent_duplicates' => true, 'self_connections' => false, 'sortable' => false, 'title' => array(), 'from_labels' => '', 'to_labels' => '', 'reciprocal' => false));
     $sides = array();
     foreach (array('from', 'to') as $direction) {
         $object = _p2p_pluck($args, $direction);
         if ('user' == $object) {
             $args[$direction . '_object'] = 'user';
         } elseif ('attachment' == $object) {
             $args[$direction . '_object'] = 'attachment';
         }
         if ('post' == $args[$direction . '_object']) {
             $validated = array();
             foreach ((array) $object as $ptype) {
                 if (!post_type_exists($ptype)) {
                     trigger_error("Post type '{$ptype}' is not defined.");
                 } else {
                     $validated[] = $ptype;
                 }
             }
             if (empty($validated)) {
                 $validated = array('post');
             }
             $args[$direction . '_query_vars']['post_type'] = $validated;
         }
     }
     if (!$args['name']) {
         $args['name'] = md5(serialize(array_values(wp_array_slice_assoc($args, array('from_object', 'to_object', 'from_query_vars', 'to_query_vars', 'data')))));
     }
     $args = apply_filters('p2p_connection_type_args', $args);
     $ctype = new P2P_Connection_Type($args);
     if (isset(self::$instances[$ctype->name])) {
         trigger_error("Connection type '{$ctype->name}' is already defined.", E_USER_NOTICE);
     }
     self::$instances[$ctype->name] = $ctype;
     return $ctype;
 }
Exemple #14
0
 function filter_ctypes($ctype, $args)
 {
     if (isset($args['admin_box'])) {
         $box_args = _p2p_pluck($args, 'admin_box');
         if (!is_array($box_args)) {
             $box_args = array('show' => $box_args);
         }
     } else {
         $box_args = array();
     }
     foreach (array('can_create_post') as $key) {
         if (isset($args[$key])) {
             $box_args[$key] = _p2p_pluck($args, $key);
         }
     }
     $box_args = wp_parse_args($box_args, array('show' => 'any', 'context' => 'side', 'priority' => 'default', 'can_create_post' => true));
     $this->register($ctype->name, $box_args);
     return $args;
 }
Exemple #15
0
 function translate_qv($qv)
 {
     if (isset($qv['p2p:include'])) {
         $qv['include'] = _p2p_pluck($qv, 'p2p:include');
     }
     if (isset($qv['p2p:exclude'])) {
         $qv['exclude'] = _p2p_pluck($qv, 'p2p:exclude');
     }
     if (isset($qv['p2p:search']) && $qv['p2p:search']) {
         $qv['search'] = '*' . _p2p_pluck($qv, 'p2p:search') . '*';
     }
     if (isset($qv['p2p:page']) && $qv['p2p:page'] > 0) {
         if (isset($qv['p2p:per_page']) && $qv['p2p:per_page'] > 0) {
             $qv['number'] = $qv['p2p:per_page'];
             $qv['offset'] = $qv['p2p:per_page'] * ($qv['p2p:page'] - 1);
         }
     }
     return $qv;
 }
 public static function register($args)
 {
     $args = wp_parse_args($args, array('name' => false, 'from_object' => 'post', 'to_object' => 'post', 'from' => 'post', 'to' => 'post', 'from_query_vars' => array(), 'to_query_vars' => array(), 'data' => array(), 'cardinality' => 'many-to-many', 'prevent_duplicates' => true, 'sortable' => false, 'title' => array(), 'from_labels' => '', 'to_labels' => '', 'reciprocal' => false));
     $sides = array();
     foreach (array('from', 'to') as $direction) {
         $object = _p2p_pluck($args, $direction);
         if ('user' == $object) {
             $args[$direction . '_object'] = 'user';
         } elseif ('attachment' == $object) {
             $args[$direction . '_object'] = 'attachment';
         }
         if ('post' == $args[$direction . '_object']) {
             $validated = array();
             foreach ((array) $object as $ptype) {
                 if (!post_type_exists($ptype)) {
                     trigger_error("Post type '{$ptype}' is not defined.");
                 } else {
                     $validated[] = $ptype;
                 }
             }
             if (empty($validated)) {
                 $validated = array('post');
             }
             $args[$direction . '_query_vars']['post_type'] = $validated;
         }
     }
     if (!$args['name']) {
         $args['name'] = md5(serialize(array_values(wp_array_slice_assoc($args, array('from_object', 'to_object', 'from_query_vars', 'to_query_vars', 'data')))));
     }
     if ($args['from_object'] == $args['to_object'] && 'post' == $args['from_object']) {
         $class = 'P2P_Connection_Type';
     } else {
         $class = 'Generic_Connection_Type';
     }
     $ctype = new $class($args);
     if (isset(self::$instances[$ctype->name])) {
         trigger_error('Connection type is already defined.', E_USER_NOTICE);
     }
     self::$instances[$ctype->name] = $ctype;
     return $ctype;
 }
Exemple #17
0
 /**
  * Sets 'p2p_type' => array( connection_type => direction )
  *
  * @return:
  * null means ignore current query
  * false means trigger 404
  * true means proceed
  */
 static function expand_connected_type(&$q, $item, $object_type)
 {
     if (!isset($q['connected_type'])) {
         return;
     }
     $ctypes = (array) _p2p_pluck($q, 'connected_type');
     if (isset($q['connected_direction'])) {
         $directions = (array) _p2p_pluck($q, 'connected_direction');
     } else {
         $directions = array();
     }
     $p2p_types = array();
     foreach ($ctypes as $i => $p2p_type) {
         $ctype = p2p_type($p2p_type);
         if (!$ctype) {
             continue;
         }
         if (isset($directions[$i])) {
             $directed = $ctype->set_direction($directions[$i]);
         } else {
             $directed = self::find_direction($ctype, $item, $object_type);
         }
         if (!$directed) {
             continue;
         }
         $p2p_types[$p2p_type] = $directed->get_direction();
     }
     if (empty($p2p_types)) {
         return false;
     }
     if (1 == count($p2p_types)) {
         $q = $directed->get_connected_args($q);
     } else {
         $q['p2p_type'] = $p2p_types;
     }
     return true;
 }
/** @internal */
function _p2p_back_compat_args($argv)
{
    if (count($argv) > 1) {
        $args = array();
        foreach (array('from', 'to', 'reciprocal') as $i => $key) {
            if (isset($argv[$i])) {
                $args[$key] = $argv[$i];
            }
        }
    } else {
        $args = $argv[0];
    }
    if (isset($args['id'])) {
        $args['name'] = _p2p_pluck($args, 'id');
    }
    if (isset($args['show_ui'])) {
        $args['admin_box'] = array('show' => _p2p_pluck($args, 'show_ui'));
        if (isset($args['context'])) {
            $args['admin_box']['context'] = _p2p_pluck($args, 'context');
        }
    }
    return $args;
}