Skip Navigation

[Resolved] Sorting view by author role

This support ticket is created 3 years, 11 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

No supporters are available to work today on Toolset forum. Feel free to create tickets and we will handle it as soon as we are online. Thank you for your understanding.

Sun Mon Tue Wed Thu Fri Sat
- 10:00 – 13:00 10:00 – 13:00 10:00 – 13:00 10:00 – 13:00 10:00 – 13:00 -
- 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 -

Supporter timezone: Asia/Kolkata (GMT+05:30)

This topic contains 11 replies, has 3 voices.

Last updated by fatios 3 years, 11 months ago.

Assisted by: Minesh.

Author
Posts
#1873591

Hello,

I'm looking to filter a view based on the role of the post author.
I have two types of authors: "teachers" and "interns".
I would like in my view that posts published by teachers appear first (then sorted alphabetically) and only then posts published by interns (again in alphabetical order).

I have this code in my function.php file:

add_shortcode('author-has-role', function($atts, $content){
    $atts = shortcode_atts( array(
        'role' => '',
    ), $atts);
    global $authordata;
    $author_roles = $authordata->roles;
    $res = 0;
    if ( $atts['role'] && in_array($atts['role'], $author_roles) ){
        $res = 1;
    }
    return $res;
});

I'm blocking just to add the first sort (by role) to my view.
I had been thinking about making two views (one for each role) but got stuck with ajax search fields not working for two views.
I also thought about creating a custom field for my posts that would be self-completed according to the role of its author (for example 1 for teachers and 2 for interns) and then use this custom field to sort my view. But I did not succeed.

Any idea to help me?

#1874005

Hello and thank you for contacting the Toolset support.

Even though Toolset views allow us to hook into their filters, so we can modify the underlying SQL query, I don't think we'll be able to sort by role, because roles are saved as a serialized array in the database. Check this screenshot hidden link
https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query

Check this StackOverflow thread about a function(note how SQL is built) that can return posts for a certain role https://stackoverflow.com/a/52856016
But, I still don't see a way to sort using the role.

So, I guess that using two views is probably a good solution. We can make the AJAX search work for both views by implementing a custom Javascript code, that will:
- First, hide the second view search box.
- Second, sync the search value from the first view to the second view.

But, I think that using a custom field to store for each post the role of its author is probably the best solution.

To save the author's role in the custom field, you will need some custom PHP. Depending on how you create the posts, I'll suggest the best hook to use. Or you can do that using a private page. The page can use a view that queries posts that do not have a value for this custom field. In the view's loop, you can put a form that will save the author's role in the custom field value.

I hope this helps. Let me know if you have any questions.

#1874553

Hello Jamal,
Thank you very much for your constructive feedback!
The problem of the custom field containing a variable linked to the user role is that some users change roles (from wordpress admin dashboard) and there is a risk of having to update the custom field in this case.
If there is a solution to use two views with ajax search (without having to submit the form with a button), I'm totally into! A solution of this kind could also help me for other views later. Unfortunately, I don't know enough about JS...

#1874857

Sure, we can do that. Please login to this test site where I implemented a test on the default post type "Posts" hidden link

As you can see, I have created two views in the page hidden link
Each view has a search form, but the second view has the form hidden using custom CSS and custom CSS classes on its filters.

Then I used a custom code that makes the first view query only posts from administrator users, and the second view to query only posts from editor users. This is the code I used, you can check it in Toolset->Settings->Custom Code.

add_filter( 'wpv_filter_query', 'prefix_show_only_members', 99, 3 );
  
function prefix_show_only_members( $query, $view, $view_id ) {
  if ( $view_id == 33 ) {
    $admins = get_users('role=administrator&fields=id');
    $query['author__in'] = $admins;
  }
  if ( $view_id == 44 ) {
    $editors = get_users('role=editor&fields=id');
    $query['author__in'] = $editors;
  }
    return $query;
}

Then I used the following Javascript code to sync the search box from the first view to the second, I added this code to the first view JS section, check this screenshot hidden link

jQuery( document ).on( 'js_event_wpv_parametric_search_triggered', function( event, data ) {
	/**
	* data.view_unique_id (string) The View unique ID hash
	* data.form (object) The jQuery object for the View form
	* data.update_form (bool) Whether the custom search form will be updated
	* data.update_results (bool) Whether the custom search results will be updated
	*/
	// console.log('js_event_wpv_parametric_search_triggered', event, data)

    if ( data.view_unique_id != 33 ) return;

    // console.log('view id', data.view_unique_id);
    var keywords = data.form.find('input[name="wpv_post_search"]').val()
    // console.log('search keywords', keywords);

    setTimeout( function(){
        jQuery('form[name="wpv-filter-44"] input[name="wpv_post_search"]').val(keywords)
        jQuery('form[name="wpv-filter-44"] input[type="submit"]').click()
    }, 300)
    return data
});

Similarly to this custom code, I added custom CSS code to the second view to hide the filters, check these screenshots:
- hidden link
- hidden link
- hidden link

Note that my view's IDs are respectively (33 and 44).

I hope this helps. Let me know if you have any questions.

#1879569

Good evening Jamal,

Thank you for this very complete feedback. The query filter to display posts according to the role of the author works very well!
However, I have a problem with the JS code. I followed all your directions but when I do a search in the first view (for example the word "France", it echoes the term in the search box of the second view but does not submit. I also tried with my two drop-down custom fields, without success Here is the JS code that I integrated:

jQuery( document ).on( 'js_event_wpv_parametric_search_triggered', function( event, data ) {
    /**
    * data.view_unique_id (string) The View unique ID hash
    * data.form (object) The jQuery object for the View form
    * data.update_form (bool) Whether the custom search form will be updated
    * data.update_results (bool) Whether the custom search results will be updated
    */
    // console.log('js_event_wpv_parametric_search_triggered', event, data)
 
    if ( data.view_unique_id != 3807 ) return;
 
    // console.log('view id', data.view_unique_id);
    var keywords = data.form.find('input[name="wpv_post_search"]').val()
    var secteur = data.form.find('input[name="wpv-secteur"]').val()
    var dock = data.form.find('input[name="wpv-wpcf-dock"]').val()


    // console.log('search keywords', keywords);
 
    setTimeout( function(){
        jQuery('form[name="wpv-filter-3785"] input[name="wpv_post_search"]').val(keywords)
        jQuery('form[name="wpv-filter-3785"] input[name="wpv-secteur"]').val(keywords)
        jQuery('form[name="wpv-filter-3785"] input[name="wpv-wpcf-dock"]').val(keywords)
        jQuery('form[name="wpv-filter-3785"] input[type="submit"]').click()
    }, 300)
    return data
});

Maybe it's because I'm using roles created with Toolset ("exposant" and "exposant_actif") ? Here is my custom function :

add_filter( 'wpv_filter_query', 'prefix_show_only_members', 99, 3 );
   
function prefix_show_only_members( $query, $view, $view_id ) {
  if ( $view_id == 3807 ) {
    $exposant_actif = get_users('role=exposant_actif&fields=id');
    $query['author__in'] = $exposant_actif;
  }
  if ( $view_id == 3785 ) {
    $exposant = get_users('role=exposant&fields=id');
    $query['author__in'] = $exposant;
  }
    return $query;
}

I've left both search boxes visible for now to try and see what's going on.
Am I missing something? Here is the page : hidden link

Thanks a lot

#1880235

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

Jamal is on Vacation. This is Minesh and let me step in here.

Do you mean that you tried to implement the solution shared by Jamal on your site and its not working as expected with your setup? If this is correct.

Can you please share problem URL where you added your view as well as access details.

In addition to that, please mention what is your expected results.

*** Please make a FULL BACKUP of your database and website.***
I would also eventually need to request temporary access (WP-Admin and FTP) to your site. Preferably to a test site where the problem has been replicated if possible in order to be of better help and check if some configurations might need to be changed.

I have set the next reply to private which means only you and I have access to it.

#1882425

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

The thing was that - you set your both view "Custom Search" setting to "AJAX refresh when changing any filter" that will not work in your case, so I've changed both block view "Custom Search" setting to "Full page refresh when clicking Submit" and added the "Search" button to your first view.

I can see now when I change the filter and click on search button both views are filtered correctly. Can you please confirm.

#1882533

Hello Minesh,
The problem is that there should not be a "submit" button visible. This is the reason why Jamal created the javascript code which allowed to automatically refresh the two views in ajax. This worked fine for the text field but not for the selection fields.

#1882541

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

Can you please check now:

I've adjusted the JS code as given under:

jQuery( document ).on( 'js_event_wpv_parametric_search_triggered', function( event, data ) {
    /**
    * data.view_unique_id (string) The View unique ID hash
    * data.form (object) The jQuery object for the View form
    * data.update_form (bool) Whether the custom search form will be updated
    * data.update_results (bool) Whether the custom search results will be updated
    */
    // console.log('js_event_wpv_parametric_search_triggered', event, data)
 
    if ( data.view_unique_id != 3807 ) return;
 
    // console.log('view id', data.view_unique_id);
    var keywords = jQuery('form[name="wpv-filter-3807"] input[name="wpv_post_search"]').val()
    var secteur = jQuery('form[name="wpv-filter-3807"] select[name="wpv-secteur"]').val()
    var dock = jQuery('form[name="wpv-filter-3807"] select[name="wpv-wpcf-dock"]').val()

     
    setTimeout( function(){
        jQuery('form[name="wpv-filter-3785"] input[name="wpv_post_search"]').val(keywords)
        jQuery('form[name="wpv-filter-3785"] input[name="wpv-secteur"]').val(secteur)
        jQuery('form[name="wpv-filter-3785"] input[name="wpv-wpcf-dock"]').val(dock)
        jQuery('form[name="wpv-filter-3785"] input[type="submit"]').click()
    }, 300)
    return data
  
});

I've also removed the search button from your top view which you do not want and I checked and it seems working as expected now. Can you please confirm?

#1882977

Hello Minesh,
A big thank you for your feedback, that's almost it indeed. Unfortunately it seems that the selection "secteur" or "dock" does not work on the second view ... I tried for example the "audio" sector and all the results of view 2 remain displayed and unfiltered.

#1883361

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

For that I've again adjusted the JS code added to custom JS section as given under:

jQuery( document ).on( 'js_event_wpv_parametric_search_triggered', function( event, data ) {
    /**
    * data.view_unique_id (string) The View unique ID hash
    * data.form (object) The jQuery object for the View form
    * data.update_form (bool) Whether the custom search form will be updated
    * data.update_results (bool) Whether the custom search results will be updated
    */
    // console.log('js_event_wpv_parametric_search_triggered', event, data)
 
    if ( data.view_unique_id != 3807 ) return;
 
    // console.log('view id', data.view_unique_id);
    var keywords = jQuery('form[name="wpv-filter-3807"] input[name="wpv_post_search"]').val()
    var secteur = jQuery('form[name="wpv-filter-3807"] select[name="wpv-secteur"]').val()
    var dock = jQuery('form[name="wpv-filter-3807"] select[name="wpv-wpcf-dock"]').val()

     console.log('search keywords==', keywords);
   console.log('secteur==', secteur);
   console.log('dock==', dock);
 
  
    setTimeout( function(){
        jQuery('form[name="wpv-filter-3785"] input[name="wpv_post_search"]').val(keywords)
        jQuery('form[name="wpv-filter-3785"] select[name="wpv-secteur"] option[value="'+secteur+'"]').attr("selected","selected");
        jQuery('form[name="wpv-filter-3785"] select[name="wpv-wpcf-dock"] option[value="'+dock+'"]').attr("selected","selected");
        jQuery('form[name="wpv-filter-3785"] input[type="submit"]').click()
    }, 300)
    return data
  
});

Can you please confirm it works as expected now.

#1892733

Hello Minesh,
Sorry for the delay...
I just tested everything, it works perfectly, thank you very much!
Happy new year to you by the way 😉