Support

Account

Home Forums Search Search Results for 'pre_get_posts'

Search Results for 'pre_get_posts'

reply

  • Hi @almer1984

    It is possible to query more than one custom field by first allowing for multiple $_GET variables in your pre_get_posts filter. To do this, simply copy and paste your onderwerp code and change the field_name.

    You will need to change quite a bit of your JS to allow for multiple values to be added to the URL. I would advise that you write a function that returns the URL based on all the selected checkbox values.

    You can then attach another ‘click’ event to the second checkbox inputs and use this function to redirect the URL.

    I would just like to point out that this PHP and JS logic is quite advanced, and I won’t be able to help much on this free ACF support forum. If the task seems too complicated, perhaps try breaking it up into steps and research these independently.

    Hope that helps.

    Thanks
    E

  • Hi @megancm

    Sorry to hear you are still having the issue. There is definitely a conflict in code happening, as the relationship field works fine on my install and all others that I know of.

    Can you try changing $posts = get_field('store-type'); to $posts = get_field('store-type', false, false);

    This will prevent any loading of actual posts and if this fixes the issue, then the issue must be a filter hooked into the pre_get_posts or similar.

    Thanks
    E

  • Here’s the code from functions.php

    add_action( 'pre_get_posts', 'vendor_sort' );
    function vendor_sort( WP_Query $wp_query ) {
        // Ensure it is the global $wp_query
        if ( ! $wp_query->is_main_query() )
            return;
        
        if ( $wp_query->is_tax( 'vendor-type' ) ) {
            $wp_query->set( 'meta_key', 'crfp-average-rating' );
            $wp_query->set( 'orderby', 'meta_value_num' );
            $wp_query->set( 'meta_compare', '>' );
            $wp_query->set( 'order', 'DESC' );
        }
    }
  • Progress.

    With this code in functions.php I can get the AND posts; that is, posts tagged with “Toronto” AND posts that have “Toronto” assigned to the meta_city field.

    I need the “OR” of course. Still searching. All feedback is welcome.

    
    add_action( 'pre_get_posts', 'md_modify_tag_archive_to_include_acf_fields' );
    
    function md_modify_tag_archive_to_include_acf_fields( $query ) {
    	if( $query->is_main_query() && $query->is_tag ) {
    		$term_name = $query->query[tag];
    		$term = get_term_by('name',$term_name, 'post_tag');
    
    		$meta_query = array(
    			'relation' => 'OR',
    			array(
    				'key' => 'meta_city', // name of custom field
    				'value' => $term->term_id, 
    				'compare' => 'LIKE'
    			)
    		);
    		$query->set( 'meta_query', $meta_query);
    	}
    
    }
    
  • Hi @realph

    Yes, becuase ACF is saving the checked values as a serialized array, the ‘IN’ compare will not work. The IN compare is used when the database value is a single string value, and the value used in the $meta_query is an array. This is not the data setup you have, so you should not use this.

    The pseudo code for this query is:

    
    get all posts where the meta_value for is 'a' or 
    the meta_value for is 'b' or
    the meta_value for is 'c'
    

    You can write this like so:

    
    <?php 
    
    add_action('pre_get_posts', 'my_pre_get_posts');
     
    function my_pre_get_posts( $query ) {
    
        if( is_admin() ) { return; }
     
        $meta_query = $query->get('meta_query'); // get original meta query
        
        
        // validate type
        if( empty($_GET['type']) )
        {
    	    return;
        }
        
        
        // get types as an array
        // - use explode to get an array of values from type=a|b|c
        $types = explode('|', $_GET['type']);
        
        
        // set compare for the meta_query
        // - http://codex.wordpress.org/Class_Reference/WP_Query
        $meta_query['relation'] = 'OR';
        
        
        foreach( $types as $type )
        {
    	    $meta_query[] = array(
                'key'       => 'type',
                'value'     => '"' . $type . '"',
                'compare'   => 'LIKE',
            );
        }
    	
    	
        $query->set('meta_query', $meta_query); // update the meta query args
        
        return; // always return
    }
    
    ?>
    

    Hope that helps

    Thanks
    E

  • @elliot Do you think this has anything to do with the serialized data the Checkbox Field outputs?

    Some of my books are assigned to multiple Book Types, like so:

    Book Title: Mums and Babies
    Book Type:

    • Women
    • Babies
    • Children

    Wondering if this is what’s causing the issue.

    This is where I’m at currently:

    add_action('pre_get_posts', 'my_pre_get_posts');
     
    function my_pre_get_posts( $query ) {
        if( is_admin() ) { return; }
     
        $meta_query = $query->get('meta_query'); // get original meta query
            
            if( isset($_GET['type']) ) {                        
            
            $type = '"' . $_GET['type'] . '"';      
    
            $meta_query[] = array(
                'key'       => 'type',
                'value'     => $type,
                'compare'   => 'LIKE',
            );
        }
        $query->set('meta_query', $meta_query); // update the meta query args
        return; // always return
    }

    Works with one value, but not multiple values (.com/?type=women,babies):

  • Ok, false alarm. The code above was wrong. @elliot Some people over on the Stack Exchange forum are saying I shouldn’t be using a LIKE compare, and an IN instead when using arrays.

    Not sure which is right. But when I try to use an IN compare, I get a blank page when querying my posts.

    add_action('pre_get_posts', 'my_pre_get_posts');
    function my_pre_get_posts( $query ) {
    	if( is_admin() ) {
    		return;
    	}
    	$meta_query = $query->get('meta_query');
            if( !empty($_GET['type']) ) {				
            	$type = explode('|', $_GET['type']);	
    
    	    	$meta_query[] = array(							
                    'key'		=> 'type',
                    'value'		=> $type,
                    'compare'	=> 'IN',
                );
            }
    	$query->set('meta_query', $meta_query);
    	return;	// always return
    }
    
  • @elliot *Exhale* I feel to cry! After a whole day of staring at my functions.php, I think I may have finally cracked it!

    add_action('pre_get_posts', 'my_pre_get_posts');
     
    function my_pre_get_posts( $query ) {
    	if( is_admin() ) {
    		return;
    	}
     
    	$book_format = $query->get('meta_query');
     
            if( !empty($_GET['type']) ) {
            
    	    	$book_format[] = array(
                    'key'		=> 'type',
                    'value'		=> $_GET['type'],
                    'compare'	=> 'LIKE',
                );
            }
     
    	$query->set('meta_query', $book_format);
     
    	return;
    }

    Now when I append this to my url:

    dev.com/books?=home

    it displays an archive of all my books with the ‘type’ of ‘home’. This is fantastic!

    The only problem I’m having now is, separating these in the url with the ‘|’ character doesn’t seem to yield any results. Any idea why that might be happening, or is that normal?

  • Hi @retotito

    It is possible that there is a filter in your theme or a plugin which is modifying the WP_Query args. This filter is most likely called ‘pre_get_posts’.

    Perhaps as a test, create a simple text field and enter the value ‘test’. Then change your query args to find posts where the field_name = ‘test’.

    Does this work?

    Thanks
    E

  • Just to clarify for anyone who comes across this later:

    My pre_get_posts action was setting query parameters not just for the main query (as I intended) but also the query by the Gallery plugin that gets the attachment data. These query parameters caused the get_posts query in gallery.php to return nothing.

  • What happens if you add $query->is_main_query() to your if statement?

    
    function allstar_buzzworthy_published_sort( $query ) {
            // If not the admin section
            if ( !is_admin() &&  $query->is_main_query()) {
                // If on a taxonomy page
                if ( is_tax() ) {
                    $query->set( 'meta_key', 'date_published' );
                    $query->set( 'orderby', 'meta_value' );
                    $query->set( 'order', 'DESC' );
                }
            }
        }
        add_action( 'pre_get_posts', 'allstar_buzzworthy_published_sort' );
    
  • The issue for me was specific to $query->set('s', ' ');. I added it to fix empty search queries returning a 404 page.

    I set a bunch of other query vars in the same function but going through one by one, this was the only one to cause error.

    Btw, you’re missing a single quote before date_published.

      
    function property_filters($query) {
    
      // ...
    
      /**
       * Fixes issue with blank search queries returning 404
       */
      if (!is_admin() && isset($query->query_vars['s']) && empty($query->query_vars['s'])) {
        $query->set('s', ' ');
      }
    }
    add_action('pre_get_posts', 'property_filters');
    
  • What are you doing inside your pre_get_posts action? I don’t believe it’s the pre_get_posts action that’s causing the problem. If I just have it echo out some text, get_field returns an array of images as expected. It’s when I modify the query by adding $query->set( 'meta_key', date_published' ); that I run into a problem.

  • I am also seeing the same behaviour after upgrading to Gallery 1.1.0 and ACF 4.3.0.

    With add_action('pre_get_posts'... called in functions.php, get_field for a gallery field returns an empty array.

    If I comment out the pre_get_posts action everything works as expected.

  • (This is going to be interesting to work out since we’re in basically opposite time zones)

    I will check the $post-ID in the morning when I get to the office, as well as testing a basic function, but everything else for the post is displaying properly…the name, permalink, even other metadata I’ve set using ACF and am accessing with get_field(). The ONLY thing that isn’t working is that the gallery is returning an empty array rather than an array of images.

    I am certain that the posts have gallery data, because on their individual pages the gallery is being displayed fine, and when I remove my pre_get_posts filter, the galleries show up on the correct posts.

    Thanks,
    Ryan

  • Hi @bounty_digital

    I don’t think your code is following the correct logic path for this to work.
    Your code needs to be spit up into 2 parts:

    1. Create the radio button where a user can select the category and then be redirected to the archive url with the $_GET param

    2. hook into the pre_get_posts filter and look for the $_GET param. If it exists, add the meta query in.

    I should really write a tutorial for this one, so I’m happy to write the code. This is the most simple way to get it working:

    
    <?php 
    
    $field = get_field_object("field_5039a99716d1d");
    
    ?>
    <form action="<?php echo home_url('slug/to/archive'); ?>" method="get">
    	<ul>
    	<?php foreach( $field['choices'] as $k => $v ): ?>
    		<li>
    			<label><input type="radio" name="acf_category" value="<?php echo $k; ?>" /><?php echo $v; ?></label>
    		</li>
    	<?php endforeach; ?>
    	</ul>
    	<input type="submit" value="Go" />
    </form>
    
    <?php 
    
    add_filter( 'pre_get_posts', 'my_pre_get_posts' );
    
    function my_pre_get_posts( $query ) {
    	
    	if( isset($_GET['my_custom_category']) )
    	{
    		// $query is the WP_Query object, set is simply a method of the WP_Query class that sets a query var parameter
    		$query->set( 'meta_key', 'acf_field_name' );
    		$query->set( 'meta_value', $_GET['acf_category'] );
    	}
    	return $query;
    }
    
     ?>
    

    This code has not been tested, you can see the 2 parts of code. The rest will be up to you to test it and fix any issues it contains!

    Good luck

    Thanks
    E

  • This reply has been marked as private.
  • Fixed.

    I’ve replaced the above filter with the following from here -> http://blog.rutwick.com/display-only-the-posts-authored-by-the-current-wp-user-on-the-posts-page-in-the-back-end.

    add_action('pre_get_posts', 'filter_posts_list');
    function filter_posts_list($query)
    {
        //$pagenow holds the name of the current page being viewed
         global $pagenow;
     
        //$current_user uses the get_currentuserinfo() method to get the currently logged in user's data
         global $current_user;
         get_currentuserinfo();
         
         //Shouldn't happen for the admin, but for any role with the edit_posts capability and only on the posts list page, that is edit.php
          if(!current_user_can('administrator') && current_user_can('edit_posts') && ('edit.php' == $pagenow)){
            //global $query's set() method for setting the author as the current user's id
            $query->set('author', $current_user->ID);
            }
    }
  • Update,

    i’ve narrowed it down to the fact that i’m using this code to stop anyone who is logged in as a role of school being able to see anyone elses posts.

    function posts_for_current_author($query) {
    	global $user_level;
    
    	if($query->is_admin && $user_level < 5) {
    		global $user_ID;
    		$query->set('author',  $user_ID);
    		unset($user_ID);
    	}
    	unset($user_level);
    
    	return $query;
    }
    add_filter('pre_get_posts', 'posts_for_current_author');

    If i remove that, the custom fields show fine.

    Any idea how to modify that code so it doesnt interfere with ACF?

  • Hi @Romain9p

    The only thing I can think of is that there is a filter running on the pre_get_posts which is overriding this setting.

    Hopefuly that points you in the right direction.

    Thanks
    E

  • You can use this code in your functions.php file

    // Restrict media library to show only own user files
    add_action('pre_get_posts','ml_restrict_media_library');
    function ml_restrict_media_library( $wp_query_obj ) {
    
    	global $current_user, $pagenow;
    
    	if( !is_a( $current_user, 'WP_User') )
    
    		return;
    
    	if( 'admin-ajax.php' != $pagenow || $_REQUEST['action'] != 'query-attachments' )
    
    		return;
    
    	if( !current_user_can('delete_pages') )
    
    		$wp_query_obj->set('author', $current_user->ID );
    
    	return;
    
    }
    
  • Hi,
    i solved it this way:

    if( isset($query->query_vars[‘post_type’]) && $query->query_vars[‘post_type’] == ‘acf’ ){
    return $query;
    }

    Thanks for your excellent plugin!

  • Hi @homax

    On this page, you will find examples of sorting by a custom field:
    http://www.advancedcustomfields.com/resources/getting-started/code-examples/

    To orderby a custom field value, it is very simple but you will need to read up on it here:
    http://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters

    Also, these examples use the get_posts function, but you may need to use the pre_get_posts filter if you want to override the core query!

    Cheers
    E

  • Since I’m using it for the post type “course”, I changed the post_type=post into post_type=course.

    However, the count still doesn’t work (it still counts everything).

    Also, the 1st part of your code (that you last posted) doesn’t work (to show only the authors content) – while an earlier example of you did work – so I used the code below for the first part and added the “Fix post counts” count only.

    What I’m currently using (working code).

    // So authors can only see their own content (e.g. courses etc)
    function posts_for_current_author($query) {
    	
    	if( !$query->is_admin )
    		return $query;
    		
    	$screen = get_current_screen();
    	
    	if ($screen->base === 'post')
        		return $query;
    	
    	if( !current_user_can( 'activate_plugins' ) ) {
    		global $user_ID;
    		$query->set('author', $user_ID );
    		
    	}
    	return $query;
    	
    	
    }
    
    add_filter('pre_get_posts', 'posts_for_current_author');

    I haven’t been able to get the count correct, see http://d.pr/i/Ijhs.

  • oh yes, sorry… the filter call needs to be changed and the post type in the filter callback need to changed – in fact there is a bit where I commented out the post in the original – here is some changed code with comments as I can’t test it fully without setting up a new site for posts and creating users etc..

    function posts_for_current_author($query) {
    	
    	if( !$query->is_admin )
    		return $query;
    		
    	if( isset($query->query_vars['post_type']) &&  $query->query_vars['post_type'] == 'acf' )
    {
    	return $query;
    }
    		
    	
    	if( !current_user_can( 'moderate_comments' ) ) {
    		global $user_ID;
    		$query->set('author', $user_ID );
    
                    // filter for changing the numbers on the list
                    // its called for views_edit-xxx where xxx is the post/custom post type
    		add_filter('views_edit-post', 'fix_post_counts');
                    add_filter('views_upload', 'fix_media_counts');
    	}
    	return $query;
    }
    
    add_action('pre_get_posts', 'posts_for_current_author');
    
    // Fix post counts
    function fix_post_counts($views) {
        global $current_user, $wp_query;
    	
    	
    	
        unset($views['mine']);
        $types = array(
            array( 'status' =>  NULL ),
            array( 'status' => 'publish' ),
            array( 'status' => 'draft' ),
            array( 'status' => 'pending' ),
            array( 'status' => 'trash' )
        );
        foreach( $types as $type ) {
            $query = array(
                'author'      => $current_user->ID,
                // the post type/custom post type we are modifying
                'post_type'   => 'post',
    			
                'post_status' => $type['status']
            );
            $result = new WP_Query($query);
            if( $type['status'] == NULL ):
                $class = ($wp_query->query_vars['post_status'] == NULL) ? ' class="current"' : '';
                $views['all'] = sprintf(__('<a href="%s"'. $class .'>All <span class="count">(%d)</span></a>', 'all'),
                    admin_url('edit.php?post_type=post'),
                    $result->found_posts);
            elseif( $type['status'] == 'publish' ):
                $class = ($wp_query->query_vars['post_status'] == 'publish') ? ' class="current"' : '';
                $views['publish'] = sprintf(__('<a href="%s"'. $class .'>Published <span class="count">(%d)</span></a>', 'publish'),
                    admin_url('edit.php?post_status=publish&post_type=post'),
                    $result->found_posts);
            elseif( $type['status'] == 'draft' ):
                $class = ($wp_query->query_vars['post_status'] == 'draft') ? ' class="current"' : '';
                $views['draft'] = sprintf(__('<a href="%s"'. $class .'>Draft'. ((sizeof($result->posts) > 1) ? "s" : "") .' <span class="count">(%d)</span></a>', 'draft'),
                    admin_url('edit.php?post_status=draft&post_type=post'),
                    $result->found_posts);
            elseif( $type['status'] == 'pending' ):
                $class = ($wp_query->query_vars['post_status'] == 'pending') ? ' class="current"' : '';
                $views['pending'] = sprintf(__('<a href="%s"'. $class .'>Pending <span class="count">(%d)</span></a>', 'pending'),
                    admin_url('edit.php?post_status=pending&post_type=post'),
                    $result->found_posts);
            elseif( $type['status'] == 'trash' ):
                $class = ($wp_query->query_vars['post_status'] == 'trash') ? ' class="current"' : '';
                $views['trash'] = sprintf(__('<a href="%s"'. $class .'>Trash <span class="count">(%d)</span></a>', 'trash'),
                    admin_url('edit.php?post_status=trash&post_type=post'),
                    $result->found_posts);
            endif;
        }
    	
        return $views;
    }
    
Viewing 25 results - 326 through 350 (of 361 total)