add_template( $this->get_type() . '_item', array( $this, 'item_template' ) ); parent::admin_init(); } /** * Set the post type of the entries. * * @param string|array $post_type Post type */ public function set_post_type( $post_type ) { if ( ! is_array( $post_type ) ) { $post_type = array( $post_type ); } $this->post_type = $post_type; return $this; } /** * Set the maximum allowed number of selected entries. * * @param int $max */ public function set_max( $max ) { $this->max = intval( $max ); return $this; } /** * Specify whether to allow each entry to be selected multiple times. * * @param boolean $allow */ public function allow_duplicates( $allow = true ) { $this->allow_duplicates = (bool) $allow; return $this; } /** * Used to get the title of an item. * * Can be overriden or extended by the `carbon_relationship_title` filter. * * @param int $id The database ID of the item. * @param string $type Item type (post, term, user, comment, or a custom one). * @param string $subtype The subtype - "page", "post", "category", etc. * @return string $title The title of the item. */ public function get_title_by_type( $id, $type, $subtype = '' ) { $title = get_the_title( $id ); if ( ! $title ) { $title = '(no title) - ID: ' . $id; } /** * Filter the title of the relationship item. * * @param string $title The unfiltered item title. * @param string $name Name of the relationship field. * @param int $id The database ID of the item. * @param string $type Item type (post, term, user, comment, or a custom one). * @param string $subtype Subtype - "page", "post", "category", etc. */ return apply_filters( 'carbon_relationship_title', $title, $this->get_name(), $id, $type, $subtype ); } /** * Used to get the label of an item. * * Can be overriden or extended by the `carbon_relationship_item_label` filter. * * @param int $id The database ID of the item. * @param string $type Item type (post, term, user, comment, or a custom one). * @param string $subtype Subtype - "page", "post", "category", etc. * @return string $label The label of the item. */ public function get_item_label( $id, $type, $subtype = '' ) { $object = get_post_type_object( $subtype ); $label = $object->labels->singular_name; /** * Filter the label of the relationship item. * * @param string $label The unfiltered item label. * @param string $name Name of the relationship field. * @param int $id The database ID of the item. * @param string $type Item type (post, term, user, comment, or a custom one). * @param string $subtype Subtype - "page", "post", "category", etc. */ return apply_filters( 'carbon_relationship_item_label', $label, $this->get_name(), $id, $type, $subtype ); } /** * Generate the item options for the relationship field. * * @return array $options The selectable options of the relationship field. */ public function get_options() { $options = array(); /** * Filter the default query when fetching posts for a particular field. * * @param array $args The parameters, passed to get_posts(). */ foreach ( $this->post_type as $post_type ) { $filter_name = 'carbon_relationship_options_' . $this->get_name() . '_post_' . $post_type; $args = apply_filters( $filter_name, array( 'post_type' => $post_type, 'posts_per_page' => -1, 'fields' => 'ids', 'suppress_filters' => false, ) ); // fetch and prepare posts as relationship items $new_options = get_posts( $args ); foreach ( $new_options as &$p ) { $p = array( 'id' => $p, 'title' => $this->get_title_by_type( $p, 'post', $post_type ), 'type' => 'post', 'subtype' => $post_type, 'label' => $this->get_item_label( $p, 'post', $post_type ), 'is_trashed' => ( get_post_status( $p ) == 'trash' ), 'edit_link' => get_edit_post_link( $p ), ); } $options = array_merge( $options, $new_options ); } /** * Filter the final list of options, available to a certain relationship field. * * @param array $options Unfiltered options items. * @param string $name Name of the relationship field. */ $options = apply_filters( 'carbon_relationship_options', $options, $this->get_name() ); return $options; } /** * Returns an array that holds the field data, suitable for JSON representation. * This data will be available in the Underscore template and the Backbone Model. * * @param bool $load Should the value be loaded from the database or use the value from the current instance. * @return array */ public function to_json( $load ) { $field_data = parent::to_json( $load ); if ( ! empty( $field_data['value'] ) ) { $value = array(); $field_data['value'] = maybe_unserialize( $field_data['value'] ); foreach ( $field_data['value'] as $single_value ) { $post_type = get_post_type( $single_value ); $value[] = array( 'id' => $single_value, 'title' => $this->get_title_by_type( $single_value, 'post', $post_type ), 'type' => 'post', 'subtype' => $post_type, 'label' => $this->get_item_label( $single_value, 'post', $post_type ), 'is_trashed' => ( get_post_status( $single_value ) == 'trash' ), ); } $field_data['value'] = $value; } $field_data = array_merge( $field_data, array( 'options' => $this->get_options(), 'max' => $this->max, 'allow_duplicates' => $this->allow_duplicates, ) ); return $field_data; } /** * The main Underscore template of this field. */ public function template() { ?>
<# var selected_items_length = 0; if ( value ) { selected_items_length = value.length; } #> {{{ selected_items_length }}} <# if ( max !== -1 ) { #> {{{ max }}} <# } #>
  • <# if ( item.edit_link ) { #> <# } #> {{{ item.label }}} {{{ item.title }}}