Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Function fix - media libary filter WordPress

  • SOLVED

Hello,

I am trying to create Media Libray filter drop downs.

The filters:

1. For pages - filter media by page ID
2. For a post type - filter media by post ID
3. Is for a post type - filter media by post ID
4. is post types - filter media by post type

This is my code, which is not broken, but it's not working as desired. Can any fix code, person who fixes code will get full amount.


---


The desired outcome of this function is to add these dropdowns into the media library as filters to display attachments which assigned to specific post ids. [[LINK href="http://i.imgur.com/AZxxhCv.png"]]See screenshot[[/LINK]].

This function below only includes 1, 2 and 3 from above list. This function only works on the last dropdown.

[[LINK href="https://gist.github.com/jcranny/8804798"]]https://gist.github.com/jcranny/8804798[[/LINK]]

You should be able to drop this function into your theme and adjust the post types to your registered ones.


---


This function below is the same as above but includes 4, which is a filter to display attachments that exist in selected post type.

I have a feeling this won't work - but if anyone knows how it can work then please have a go too.

[[LINK href="https://gist.github.com/jcranny/8803305"]]https://gist.github.com/jcranny/8803305[[/LINK]]


---


Thanks
Josh


---


Function 1 (includes filter 1, 2, and 3) - but only the last drop down works.


/* MEDIA LIBRARY FILTER */
add_filter('parse_query', 'node_admin_posts_filter');
add_action('restrict_manage_posts', 'node_admin_posts_filter_restrict_manage_posts');
function node_admin_posts_filter($wp_query)
{
if (is_admin() && isset($_GET['page_id']) && $_GET['page_id'] != '')
{
$original_query = $wp_query;
$wp_query->set('post_parent', $_GET['page_id']);
$wp_query = $original_query;
wp_reset_postdata();
}
else if (is_admin() && isset($_GET['download_id']) && $_GET['download_id'] != '')
{
$original_query = $wp_query;
$wp_query->set('post_parent', $_GET['download_id']);
$wp_query = $original_query;
wp_reset_postdata();
}
else if (is_admin() && isset($_GET['report_id']) && $_GET['report_id'] != '')
{
$original_query = $wp_query;
$wp_query->set('post_parent', $_GET['report_id']);
$wp_query = $original_query;
wp_reset_postdata();
}
}
function node_admin_posts_filter_restrict_manage_posts()
{
global $wpdb;
$screen = get_current_screen();
if ($screen->id == "upload")
{



$get_pages = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type IN ('page') AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_title ASC");
echo '<select name="page_id">';
echo '<option value="">Filter by page...</option>';
$current_page = isset($_GET['page_id']) ? $_GET['page_id'] : '';
foreach ($get_pages as $get_page)
{
$select = null;
if ($current_page == $get_page->ID)
{
$select = ' selected="selected"';
}
echo '<option value="' . $get_page->ID . '" ' . $select . '>' . $get_page->post_title . '</option>';
}
echo '</select>';



$get_downloads = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type IN ('download') AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_date DESC");
echo '<select name="download_id">';
echo '<option value="">Filter by downloads...</option>';
$current_download = isset($_GET['download_id']) ? $_GET['download_id'] : '';
foreach ($get_downloads as $get_download)
{
$select = null;
if ($current_download == $get_download->ID)
{
$select = ' selected="selected"';
}
echo '<option value="' . $get_download->ID . '" ' . $select . '>' . $get_download->post_title . '</option>';
}
echo '</select>';



$get_reports = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type IN ('reports') AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_date DESC");
echo '<select name="report_id">';
echo '<option value="">Filter by report...</option>';
$current_report = isset($_GET['report_id']) ? $_GET['report_id'] : '';
foreach ($get_reports as $get_report)
{
$select = null;
if ($current_report == $get_report->ID)
{
$select = ' selected="selected"';
}
echo '<option value="' . $get_report->ID . '" ' . $select . '>' . $get_report->post_title . '</option>';
}
echo '</select>';



}
}



---


Function 2 (includes filter 1, 2, 3 and 4) - nothing seems to work now I've added the 4th filter.



/* MEDIA LIBRARY FILTER */
add_filter('parse_query', 'node_admin_posts_filter');
add_action('restrict_manage_posts', 'node_admin_posts_filter_restrict_manage_posts');
function node_admin_posts_filter($wp_query)
{
if (is_admin() && isset($_GET['page_id']) && $_GET['page_id'] != '')
{
$original_query = $wp_query;
$wp_query->set('post_parent', $_GET['page_id']);
$wp_query = $original_query;
wp_reset_postdata();
}
else if (is_admin() && isset($_GET['download_id']) && $_GET['download_id'] != '')
{
$original_query = $wp_query;
$wp_query->set('post_parent', $_GET['download_id']);
$wp_query = $original_query;
wp_reset_postdata();
}
else if (is_admin() && isset($_GET['report_id']) && $_GET['report_id'] != '')
{
$original_query = $wp_query;
$wp_query->set('post_parent', $_GET['report_id']);
$wp_query = $original_query;
wp_reset_postdata();
}
else if (is_admin() && isset($_GET['post_type']) && $_GET['post_type'] != '')
{
$original_query = $wp_query;
$wp_query->set('post_type', $_GET['post_type']);
$wp_query = $original_query;
wp_reset_postdata();
}
}
function node_admin_posts_filter_restrict_manage_posts()
{
global $wpdb;
$screen = get_current_screen();
if ($screen->id == "upload")
{



$get_pages = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type IN ('page') AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_title ASC");
echo '<select name="page_id">';
echo '<option value="">Filter by page...</option>';
$current_page = isset($_GET['page_id']) ? $_GET['page_id'] : '';
foreach ($get_pages as $get_page)
{
$select = null;
if ($current_page == $get_page->ID)
{
$select = ' selected="selected"';
}
echo '<option value="' . $get_page->ID . '" ' . $select . '>' . $get_page->post_title . '</option>';
}
echo '</select>';



$get_downloads = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type IN ('download') AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_date DESC");
echo '<select name="download_id">';
echo '<option value="">Filter by downloads...</option>';
$current_download = isset($_GET['download_id']) ? $_GET['download_id'] : '';
foreach ($get_downloads as $get_download)
{
$select = null;
if ($current_download == $get_download->ID)
{
$select = ' selected="selected"';
}
echo '<option value="' . $get_download->ID . '" ' . $select . '>' . $get_download->post_title . '</option>';
}
echo '</select>';



$get_reports = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type IN ('reports') AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_date DESC");
echo '<select name="report_id">';
echo '<option value="">Filter by report...</option>';
$current_report = isset($_GET['report_id']) ? $_GET['report_id'] : '';
foreach ($get_reports as $get_report)
{
$select = null;
if ($current_report == $get_report->ID)
{
$select = ' selected="selected"';
}
echo '<option value="' . $get_report->ID . '" ' . $select . '>' . $get_report->post_title . '</option>';
}
echo '</select>';



$get_types = get_post_types();
echo '<select name="post_type">';
echo '<option value="">Filter by type...</option>';
$current_type = isset($_GET['post_type']) ? $_GET['post_type'] : '';
foreach ($get_types as $get_type)
{
$select = null;
if ($current_type == $get_type)
{
$select = ' selected="selected"';
}
echo '<option value="' . $get_type . '" ' . $select . '>' . $get_type . '</option>';
}
echo '</select>';


}
}

Answers (4)

2014-02-04

John Cotton answers:

<blockquote>This is my code, which is not broken, but it's not working as desired.</blockquote>

If it's not broken, it's hard to fix!

Unless you say, we can't know what's desired :)


John Cotton comments:


foreach ($get_types as $get_type)

{

$select = null;

if ($current_type == $get_type)

{

$select = ' selected="selected"';

}

echo '<option value="' . $get_type . '" ' . $select . '>' . $get_type . '</option>';

}

echo '</select>';


You have bug in this code in that $select doesn't get reset during the loop. So if the first item is selected, all other items will get set as selected too (meaning the last one will actually be active).

Either add an else $select = '' to your test, or, better, rewrite the echo line using the handy WP function selected:

echo sprintf( '<option value="%1$s"%2$s>%1$s</option>', $get_type, selected($current_type, $get_type, false ) );


Josh Cranwell comments:

OK I think I'm with you.

Do I need to do this on each filter loop?

Thanks


John Cotton comments:

<blockquote>Do I need to do this on each filter loop?</blockquote>
Absolutely.

Really, the code for each loop is so similar it should be in a function of it's own with params passed in.


Josh Cranwell comments:

Of course. I will do that.


John Cotton comments:

<blockquote>$select = null;</blockquote>
I've just seen this which means the bug is no longer a problem. <strong>Apologies if it was there all along</strong>.

However, my rewrite will give you neater code.


Josh Cranwell comments:

Yeah it was there.

Have you tried this in your theme... https://gist.github.com/jcranny/8804798

Maybe just change the post types to post, pages and another post type.

Basically only the last drop down seems to be filtering.


John Cotton comments:

It was too messy for me to try as-was ;)

So I tidied it up:


function node_admin_posts_filter($wp_query) {
if( is_admin() ) {
foreach( array( 'page_id' => 'post_parent', 'download_id' => 'post_parent', 'report_id' => 'post_parent', 'post_type' => 'post_type' ) as $var => $setting ) {
if( !empty($_GET[$var]) ) {
$wp_query->set( $setting, $_GET[$var] );
break;
}
}
}
}
add_filter('parse_query', 'node_admin_posts_filter');

function output_select( $post_type = null ) {
$options = '';

if( $post_type ) {
global $wpdb;

$posts = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type = '{$post_type}' AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_title ASC");

$current_id = isset($_GET["{$post_type}_id"]) ? intval($_GET["{$post_type}_id"]) : 0;

foreach( $posts as $post ) {
$options .= sprintf( '<option value="%s"%s>%s</option>', $post->ID, selected( $post->ID, $current_id, false ), $post->post_title );
}

} else {
$post_type = 'type';

$types = get_post_types();

$current_id = isset($_GET["type_id"]) ? $_GET["type_id"] : '';

foreach( $types as $type ) {
$options .= sprintf( '<option value="%1$s"%2$s>%1$s</option>', $type, selected( $type, $current_id, false ) );
}
}

echo sprintf( '<select name="%1$s_id"><option>Filter by %1$s</option>%2$s</select>', $post_type, $options );
}

function node_admin_posts_filter_restrict_manage_posts() {
global $wpdb;

$screen = get_current_screen();

if ($screen->id == 'upload') {
output_select('page');

output_select('download');

output_select('report');

output_select();
}
}
add_action( 'restrict_manage_posts', 'node_admin_posts_filter_restrict_manage_posts' );


But since it wasn't working before, it's hard to tell why it still isn't working!

Is it that you don't get the dropdowns displaying when you filter?


Josh Cranwell comments:

Thanks for tidying this up.

Wow.

Yeah I'm still having trouble having getting the thing to work. Erm will look into more a bit later. and see if I can get a working example for just a singular one.

Thanks for you help so far John


John Cotton comments:

foreach( array( 'page_id' => 'post_parent', 'download_id' => 'post_parent', 'report_id' => 'post_parent', 'post_type' => 'post_type' ) as $var => $setting ) {


The above line should read

foreach( array( 'page_id' => 'post_parent', 'download_id' => 'post_parent', 'report_id' => 'post_parent', 'type_id' => 'post_type' ) as $var => $setting ) {


and the global $wpdb line in admin_posts_filter_restrict_manage_posts can be removed.


Josh Cranwell comments:

Thanks for your help John but I had to award the cash to Bhavesh Vaghela as he fixed the bug.

But appreciate your help muchly - and learnt a bit too.

Thanks

2014-02-05

Bob answers:

Filtering for page is working for me by doing following changes.

I think there is something wrong with "page_id "

change "page_id" to something different like "parent_page"
here is the first condition in <strong>"node_admin_posts_filter"</strong> function

if (is_admin() && isset($_GET['parent_page']) && $_GET['parent_page'] != '')
{
$original_query = $wp_query;
$wp_query->set('post_parent', $_GET['parent_page']);
$wp_query = $original_query;
wp_reset_postdata();
}


and another change for dropdown name in <strong>"node_admin_posts_filter_restrict_manage_posts"</strong> function


echo '<select name="parent_page">';
echo '<option value="">Filter by page...</option>';
$current_page = isset($_GET['page']) ? $_GET['page'] : '';
foreach ($get_pages as $get_page)
{
$select = null;
if ($current_page == $get_page->ID)
{
$select = ' selected="selected"';
}
echo '<option value="' . $get_page->ID . '" ' . $select . '>' . $get_page->post_title . '</option>';
}
echo '</select>';


Bob comments:

I have tested above code and for pages only in my local host and it's working.
I can see filtered images of that page only.

If you see here [[LINK href="http://codex.wordpress.org/Class_Reference/WP_Query"]]http://codex.wordpress.org/Class_Reference/WP_Query[[/LINK]] we can pass page_id parameter.

I think it was affecting "post_parent" output. So try something different name for your dropdown and get values using that name.


Josh Cranwell comments:

Hi Bhavesh.

Yes it now works! Changing page_id to something else and that fixed all the filters! Thank you for spotting it.

Though I want add a little script to reset all the drop downs on page load, so I added a bit of jquery below, but I can't get it to fire. And I'm getting no script errors.

See working code below with script...


/* MEDIA LIBRARY FILTER */

add_filter('parse_query', 'node_admin_posts_filter');

add_action('restrict_manage_posts', 'node_admin_posts_filter_restrict_manage_posts');

function node_admin_posts_filter($wp_query)

{

if (is_admin() && isset($_GET['parent_page']) && $_GET['parent_page'] != '')

{

$original_query = $wp_query;

$wp_query->set('post_parent', $_GET['parent_page']);

$wp_query = $original_query;

wp_reset_postdata();

}


else if (is_admin() && isset($_GET['download_id']) && $_GET['download_id'] != '')

{

$original_query = $wp_query;

$wp_query->set('post_parent', $_GET['download_id']);

$wp_query = $original_query;

wp_reset_postdata();

}

else if (is_admin() && isset($_GET['report_id']) && $_GET['report_id'] != '')

{

$original_query = $wp_query;

$wp_query->set('post_parent', $_GET['report_id']);

$wp_query = $original_query;

wp_reset_postdata();

}

}

function node_admin_posts_filter_restrict_manage_posts()

{

global $wpdb;

$screen = get_current_screen();

if ($screen->id == "upload")

{





$get_pages = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type IN ('page') AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_title ASC");

echo '<select name="parent_page" class="clear-filter">';

echo '<option value="">Filter by page...</option>';

$current_page = isset($_GET['page']) ? $_GET['page'] : '';

foreach ($get_pages as $get_page)

{

$select = null;

if ($current_page == $get_page->ID)

{

$select = ' selected="selected"';

}

echo '<option value="' . $get_page->ID . '" ' . $select . '>' . $get_page->post_title . '</option>';

}

echo '</select>';







$get_downloads = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type IN ('download') AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_date DESC");

echo '<select name="download_id" class="clear-filter">';

echo '<option value="">Filter by downloads...</option>';

$current_download = isset($_GET['download_id']) ? $_GET['download_id'] : '';

foreach ($get_downloads as $get_download)

{

$select = null;

if ($current_download == $get_download->ID)

{

$select = ' selected="selected"';

}

echo '<option value="' . $get_download->ID . '" ' . $select . '>' . $get_download->post_title . '</option>';

}

echo '</select>';







$get_reports = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type IN ('reports') AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_date DESC");

echo '<select name="report_id" class="clear-filter">';

echo '<option value="">Filter by report...</option>';

$current_report = isset($_GET['report_id']) ? $_GET['report_id'] : '';

foreach ($get_reports as $get_report)

{

$select = null;

if ($current_report == $get_report->ID)

{

$select = ' selected="selected"';

}

echo '<option value="' . $get_report->ID . '" ' . $select . '>' . $get_report->post_title . '</option>';

}

echo '</select>';



?>


<script type="text/javascript">
(function($){
$(function() {

$("#posts-filter").find('option').removeAttr("selected");

});
});
</script>


<?php



}

}


Bob comments:

on page load means after someone filter it through your dropdown right?

if yes then simply remove below types of <em>if conditions</em> where you are setting <em>selected</em> attribute.

if ($current_report == $get_report->ID)
{
$select = ' selected="selected"';
}


Bob comments:

and remove . $select . from options tag of your dropdown.


Bob comments:

Here is final full working code :)

/* MEDIA LIBRARY FILTER */
add_filter('parse_query', 'node_admin_posts_filter');
add_action('restrict_manage_posts', 'node_admin_posts_filter_restrict_manage_posts');
function node_admin_posts_filter($wp_query)
{
if (is_admin() && isset($_GET['parent_page']) && $_GET['parent_page'] != '')
{
$original_query = $wp_query;
$wp_query->set('post_parent', $_GET['parent_page']);
$wp_query = $original_query;
wp_reset_postdata();
}
else if (is_admin() && isset($_GET['download_id']) && $_GET['download_id'] != '')
{
$original_query = $wp_query;
$wp_query->set('post_parent', $_GET['download_id']);
$wp_query = $original_query;
wp_reset_postdata();
}
else if (is_admin() && isset($_GET['report_id']) && $_GET['report_id'] != '')
{
$original_query = $wp_query;
$wp_query->set('post_parent', $_GET['report_id']);
$wp_query = $original_query;
wp_reset_postdata();
}
}
function node_admin_posts_filter_restrict_manage_posts()
{
global $wpdb;
$screen = get_current_screen();
if ($screen->id == "upload")
{
$get_pages = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type IN ('page') AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_title ASC");
echo '<select name="parent_page" class="clear-filter">';
echo '<option value="">Filter by page...</option>';
$current_page = isset($_GET['page']) ? $_GET['page'] : '';
foreach ($get_pages as $get_page)
{
echo '<option value="' . $get_page->ID . '" >' . $get_page->post_title . '</option>';
}
echo '</select>';
$get_downloads = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type IN ('download') AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_date DESC");
echo '<select name="download_id" class="clear-filter">';
echo '<option value="">Filter by downloads...</option>';
$current_download = isset($_GET['download_id']) ? $_GET['download_id'] : '';
foreach ($get_downloads as $get_download)
{
echo '<option value="' . $get_download->ID . '">' . $get_download->post_title . '</option>';
}
echo '</select>';
$get_reports = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type IN ('reports') AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_date DESC");
echo '<select name="report_id" class="clear-filter">';
echo '<option value="">Filter by report...</option>';
$current_report = isset($_GET['report_id']) ? $_GET['report_id'] : '';
foreach ($get_reports as $get_report)
{
echo '<option value="' . $get_report->ID . '">' . $get_report->post_title . '</option>';
}
echo '</select>';
}
}


Josh Cranwell comments:

Thanks for fixing. Have voted cash to you. Again thank you for your help finding the bug.

2014-02-04

Sébastien | French WordpressDesigner answers:

what is the question ?

2014-02-04

Hariprasad Vijayan answers:

Hello Josh,

I think the issue is here

$original_query = $wp_query;

$wp_query->set('post_parent', $_GET['page_id']);

$wp_query = $original_query;

wp_reset_postdata();

change it like
$wp_query->set('post_parent', $_GET['page_id']);
return $wp_query;

Let me know.