Make WordPress Core

Opened 7 years ago

Closed 7 years ago

#40042 closed defect (bug) (invalid)

Empty Author ID on first time action pre_get_post is called.

Reported by: backups's profile BackuPs Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.7.2
Component: Query Keywords:
Focuses: Cc:

Description

Hi

I want to set pagination for authors by grabbing a field which is attached to the user record. But the first time the action is called in pre_get_posts $query only has a username. And that is the only moment one can set the $query->set( 'posts_per_page', XXXX ); where XXX is the amount set for that user.

So i can only do this hardcoded. But i want to be able to call the user meta by its id and set the amount of posts by that setting.

http://i.imgur.com/2IaFTeC.png

How to work around this? Why is the author ID not set and only the name?

Change History (5)

#1 @BackuPs
7 years ago

Note: I am talking about the author page listing all his posts he created. The only way to get to the user meta is by the user id. But that id is missing from the query.

The code is pretty simple but does not work as the author field has no info about the id and thus cant work.

<?php
function set_user_pagination( $query ) {
        if (is_admin()) return;
        if (is_author() && $query->is_main_query()) {
                $author_id = get_query_var('author');
                if (!empty($author_id)) {
                        $pagination=get_the_author_meta('pagination',$author_id);
                        //$pagination= get_user_meta($author_id, 'pagination', true);
                        if (!empty($pagination)) {
                                $query->set( 'posts_per_page', $pagination );
                        }
                }
        }
}
add_action( 'pre_get_posts', 'set_user_pagination' );

Now i know i can code around this issue. But the question is why in the first time the action is called the $query does not have the user id set?

function set_user_pagination( $query ) {
	if (is_admin()) return;
	if (is_author() && $query->is_main_query()) {
		$author_id = get_query_var('author');
		if (empty($author_id)) $author_id=get_query_var('author_name');
		if (!is_numeric($author_id) && !empty($author_id)) {
			$authorname=$author_id;
			$author_id='';
			$user = get_user_by( 'login', $authorname);
			if (isset($user->ID)) $author_id=$user->ID;
		}
		if (!empty($author_id)) {
			$pagination= get_user_meta($author_id, 'pagination', true);
			if (!empty($pagination)) {
				$query->set( 'posts_per_page', $pagination );
			}
		}
	}
}
add_action( 'pre_get_posts', 'set_user_pagination' );
Last edited 7 years ago by BackuPs (previous) (diff)

#2 @dd32
7 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed

Put simply - the array of fields passed to the pre_get_posts call is the raw arguments as parsed from the URL.
In the case of /author/dd32 the author_name = dd32 field will be set, in the case of ?author=123 author = 123 will be set.

You should handle both of those cases and find the user_id by calling get_user_by( 'user_nicename', $author_name )

#3 @BackuPs
7 years ago

Hi

Did you try your solution as it does not work for me whereas mine works. But still why is not the id set to the query record? That is easy to do from within the wp system.

<?php
function theme_set_pre_get_posts_vars( $query ) {
        if (is_admin()) {
                return;
        }

        if (is_author()) {
                $author_name=get_query_var('author_name');

                $user = get_user_by( 'user_nicename', $author_name);
                Echo '------------> : ';var_dump($user);
        }
}

add_action( 'pre_get_posts', 'theme_set_pre_get_posts_vars');

http://i.imgur.com/oDvECDf.png

That is why i was using this

function theme_set_pre_get_posts_vars( $query ) {
        if (is_admin()) {
                return;
        }

        if (is_author()) {
                $author_id=get_query_var('author_name');
                if (!is_numeric($author_id) && !empty($author_id)) {
                        $user = get_user_by( 'login', $author_id);
                        if (isset($user->ID)) $author_id=$user->ID; else $author_id='';
                        echo 'the user id'; var_dump($user);
                }
        }
}
add_action( 'pre_get_posts', 'theme_set_pre_get_posts_vars');
<?php

http://i.imgur.com/XaLh6Hf.png

http://i.imgur.com/kxrBdcM.png

Note: tested with Twenty Sixteen Theme

Last edited 7 years ago by BackuPs (previous) (diff)

#4 @BackuPs
7 years ago

  • Resolution invalid deleted
  • Status changed from closed to reopened

#5 @dd32
7 years ago

  • Component changed from General to Query
  • Resolution set to invalid
  • Status changed from reopened to closed

Did you try your solution as it does not work for me whereas mine works. But still why is not the id set to the query record? That is easy to do from within the wp system.

I'm not sure what you're asking here, the code I gave was an example, not a full solution.
What you describe in your ticket is expected - the author query variable will be empty during a URL query such as /author/admin.

The ticket is invalid due to what I explained above, I'm re-closing it as such. Discussion can continue after a ticket is closed, and people will still see it.

Note: See TracTickets for help on using tickets.