Skip to content

Adding a filter to the Object field

Radoslav Georgiev edited this page Oct 21, 2018 · 2 revisions

Intro

You can also change the available filters by using the uf.object.filters filter. It receives an existing array of filters and the actual field as parameters. The format of the filters array looks like this:

array(
	__( 'Type' ) => array(
		'type:post' => 'Post',
		'type:page' => 'Page',
		'type:user' => 'User'
	),
	__( 'Category' ) => array(
		'post-term:4' => 'Ultimate Fields',
		'post-term:1' => 'Uncategorized'
	)
)

Filters are grouped by labels. Also, the key for each option includes both the type of option it is, as well as the actual value.

Adding filter options

We will add an additional "Photographer" filter, which loads options from a custom post type. Later we will actually apply the filter.

<?php
/**
 * Parameters for the filter:
 *
 * @param mixed[]         $filters The filters, which are already in place.
 * @param UF\Field\Object $field   The field whose filters are being modified.
 * @return mixed[]
 */
function my_change_object_filters( $filters, $field ) {
  	// Check for a particular field first
  	if( 'album' != $field->get_name() ) {
    	return $filters;
  	}
  
  	// Load the photographers
	$photographers = array();

	foreach( get_posts( 'post_type=photographer&posts_per_page=-1' ) as $photohrapher ) {
		$photographers[ 'photographer:' . $photographer->ID ] = $photographer->post_title;
	}

	$filters[ __( 'Photographer' ) ] = $photographers;

	return $filters;
}

add_filter( 'uf.object.filters', 'my_change_object_filters', 10, 2 );

Doing this will add a new "Photographer" group to the filter dropdown. This however is all it does, meaning that the filter will not applied automatically - you have to do this yourself.

Applying filters

For this you need the uf.object.<type_slug>.args filter with <type_slug> being replaced by the actual data type that you want to alter, ex. posts.

It receives 4 parameters:

/**
 * @param mixed[]               $args      The arguments that are already prepared.
 * @param UF\Field\Object       $field     The field that is loading data.
 * @param mixed[]               $selection The filters, search and pagination that are applied.
 * @param UF\Helper\Object\Type $type      The type of items that is being loaded.
 */

In this example, we'd like to use the photographer filter to sort by the photographer meta field of posts. The code for this looks like this:

function apply_photographers_filter( $args, $field, $filters, $type ) {
	// Check for the field
	if( 'album' != $field->get_name() ) {
		return $args;
	}

	if( isset( $filters['filters'] ) && isset( $filters['filters']['photographer'] ) ) {
		$photographers = $filters['filters']['photographer'];

		$args[ 'meta_query' ] = array(
			array(
				'key'     => 'photographer',
				'value'   => $photographers,
				'compare' => 'IN'
			)
		);
	}
  
    // NB: Because of the alien "photographer" filter, the Posts type would think that
    // you are trying to select another type and will mark itself as "impossible".
    $type->impossible = false;

	return $args;
}

add_filter( 'uf.object.posts.args', 'apply_photographers_filter', 10, 4 );
Clone this wiki locally