Skip Navigation

[Resolved] Show only terms created by current user in taxonomy dropdown on the form

This thread is resolved. Here is a description of the problem and solution.

Problem: I have a Form used to create posts. There is a taxonomy field in the Form so Users can choose which term(s) to apply to the new post. I would like to display only terms that were created by the current logged-in User.

Solution: Since WordPress does not natively track the author of each term, you must programmatically add that term author ID in a custom field associated with each term when the term is created. Once that custom field value is added successfully, you can then use the get_terms hook to filter the terms available in the taxonomy field options. Here is an example of the code:

// RESTRICT TAXONOMY TERM FIELD OPTIONS TO USER'S OWN TERMS BY TERM FIELD VALUE
// https://toolset.com/forums/topic/show-only-terms-created-by-current-user-in-taxonomy-dropdown-on-the-form/
function tssupp_terms_by_current_user( $terms, $taxonomies, $args, $term_query ){
  $pages = array( 123, 456 ); // comma-separated list of page IDs where this Form is displayed
  $taxonomy_slug = 'tax-slug'; // slug of the taxonomy to filter
  $author_field_slug = 'field-slug'; // slug of the post author id field
 
  // you should not edit below this line
 
  // loop over each term and get its custom field value
  // compare that field value against the current user id and drop any terms with a different value
  $user_id = get_current_user_id();
  if ( is_page( $pages ) && $taxonomies[0] == $taxonomy_slug ) {
      foreach($terms as $key=>$term)  {
        $term_author = get_term_meta($term->term_id, 'wpcf-' . $author_field_slug, true);
        if( $term_author != $user_id ) {
          unset( $terms[$key] );
        }
      }
    }
  return $terms;
}
add_filter( 'get_terms', 'tssupp_terms_by_current_user',10,4);

Relevant Documentation:
https://developer.wordpress.org/reference/functions/get_terms/

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.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

Author
Posts
#1892821

I want to show only terms created by current user in the dropdown on the form. I am allowing users to enter taxonomy terms so there will be lot of them but I only want to show the ones that they have created.

I referenced notes by Minesh:
https://toolset.com/forums/topic/how-do-i-limit-my-dropdown-to-show-only-first-level-in-a-taxonomy/#post-1343875

and

https://toolset.com/forums/topic/exclude-pages-from-search-minesh-help-requested/#post-1622377

to write this code in toolset custom code section but it does not work.

<?php
/**
* New custom code snippet (replace this with snippet description).
*/

toolset_snippet_security_check() or die( 'Direct access is not allowed' );

// Put the code of your snippet below this comment.
function display_only_series_terms_by_current_user( $query ){
global $wpdb;
global $post;

if ($query->query_vars['taxonomy'][0] == 'series' && !is_admin() ) {

$query->query_vars['author'] = get_current_user_id();
};
}
add_action( 'pre_get_terms', 'display_only_series_terms_by_current_user',10,1);
?>

Can you please suggest what am I missing? It seems like I followed the step requested.

Thanks a lot for your help.

#1893385

I want to show only terms created by current user in the dropdown on the form. I am allowing users to enter taxonomy terms so there will be lot of them but I only want to show the ones that they have created...Can you please suggest what am I missing? It seems like I followed the step requested.
As far as I know, the author of a term cannot be reliably determined in WordPress. The database architecture for taxonomies and terms is not designed to store author information for taxonomies or terms. Each entry in the terms database table includes a term ID, the term name, the term slug, and an optional term group id. Author information is not stored for each term like it is for each post, so there is no reliable way to determine an individual term's author given the default information available here. I think the most effective way to handle this would be to add a numeric custom field to the Series taxonomy, which will hold the ID of the author who created that term. Then you could filter the terms by that custom field value in your pre_get_terms filter. This process would require you to programmatically add the author information to each term's custom field value when a new term is created. You could use the create_term hook for this purpose, similar to examples here:
https://stackoverflow.com/questions/27538205/wordpress-hook-execute-code-after-adding-a-new-tag
Note that Types field slugs use a prefix of wpcf- in the database, so when getting or setting a custom field value programmatically you must include that wpcf- prefix with the field slug. For example, let us assume you create a numeric custom field for the Series taxonomy, with the slug term-author-id. To set a value for that field programmatically, you would use code like this:

$author_id = 123; // for example, the author ID is 123
$term_id = 45; // for example, we will update the author field for the term with ID 45
$field_slug = "term-author-id"; // the slug of the numeric custom field
update_term_meta( $term_id, "wpcf-" . $field_slug, $author_id );

You can find more details about the update_term_meta API here:
https://developer.wordpress.org/reference/functions/update_term_meta/

This process will add the author information to each new term created on the site. However, it does not add author information to existing terms in the database. In fact it is not really possible to determine the author of existing terms in a reliable way, since that information was not stored for each term when it was created.

#1893411
Blank form.png

Chris,

That worked like charm. I was able to add a author id in the custom field on the form. But, when I am trying to filter terms based on the custom field, the cred form does not show up. I am using meta key and meta value to get term with current user id.
Cleary the code below breaks the form. What am I doing wrong?

Here is the code:
function display_only_series_terms_by_current_user( $query ){
global $wpdb;
global $post;
$user_id = get_current_user_id();
if ($query->query_vars['taxonomy'][0] == 'series' && !is_admin() ) {

// $query->query_vars['wpcf-term-author-id'] = $user_id;
$query->set('wpcf-term-author-id', '$user_id');
};
}
add_action( 'pre_get_terms', 'display_only_series_terms_by_current_user',10,1);

#1893451

It's hard to say for sure because pre_get_terms can be triggered in different contexts. Can you turn on error logging and see if any server-side errors are logged here? If you're not famliar with error logging, I can show you how to temporarily activate a log and capture information about any errors that may be thrown. These instructions assume you have a generic wp-config.php file. A customized wp-config.php file may have some of these definitions already set, and you must modify the existing definitions rather than adding new definitions.

Go in your wp-config.php file and look for

define('WP_DEBUG', false);

Change it to:

define('WP_DEBUG', true);

Then add these lines, just after the WP_DEBUG line:

define('WP_DEBUG_LOG', dirname(__FILE__) . '/error_log.txt');
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );
define('WP_DISABLE_FATAL_ERROR_HANDLER',true);

Then load or refresh the page containing the form on the front-end of the site. Any errors that are thrown will be written into a file on your server called "error_log.txt". The file will be located at the root site folder, usually in the same directory that contains the wp-config.php file. If you're using FTP, you may need to "refresh" the remote folder to see the new error_log.txt file. Download that file to your computer, then open it in any basic text editing application. Copy the contents of that file and paste them in your next reply here. Then you can delete the log file from the server and revert the changes you made in wp-config.php

#1893903

My guess is this is the main issue:

04-Jan-2021 03:22:40 UTC] PHP Fatal error: Uncaught Error: Call to undefined method WP_Term_Query::set() ...

In other words, the $query->set line in your code is triggering errors. It seems Minesh's example uses $query->meta_query instead of $query->set:
https://toolset.com/forums/topic/exclude-pages-from-search-minesh-help-requested/#post-1622377

I can dig a bit deeper in this and try to give you some more feedback later today.

#1894007

Thanks Chris!

#1894327

Unfortunately I wasn't able to get this working with the pre_get_terms hook. No matter how I applied the filter, it never seemed to have the desired effect. I'm not very well versed in that specific filter, so I'm a bit stumped and wasn't able to get more information about it quickly. Instead, I was able to get the results I wanted by implementing the get_terms hook, where I have the ability to more directly manipulate the term list produced by the term query. Here is an example:

// RESTRICT TAXONOMY TERM FIELD OPTIONS TO USER'S OWN TERMS BY TERM FIELD VALUE
// https://toolset.com/forums/topic/show-only-terms-created-by-current-user-in-taxonomy-dropdown-on-the-form/
//
function tssupp_terms_by_current_user( $terms, $taxonomies, $args, $term_query ){
  $pages = array( 123, 456 ); // comma-separated list of page IDs where this Form is displayed
  $taxonomy_slug = 'tax-slug'; // slug of the taxonomy to filter
  $author_field_slug = 'field-slug'; // slug of the post author id field

  // you should not edit below this line

  // loop over each term and get its custom field value
  // compare that field value against the current user id and drop any terms with a different value
  $user_id = get_current_user_id();
  if ( is_page( $pages ) && $taxonomies[0] == $taxonomy_slug ) {
      foreach($terms as $key=>$term)  {
        $term_author = get_term_meta($term->term_id, 'wpcf-' . $author_field_slug, true);
        if( $term_author != $user_id ) {
          unset( $terms[$key] );
        }
      }
    }
  return $terms;
}
add_filter( 'get_terms', 'tssupp_terms_by_current_user',10,4);

In this example you would replace 123, 456 with a comma-separated list of the IDs of each Page where this Form will be displayed. Then you would replace tax-slug with the slug of the taxonomy. I think in your case that would be series. Finally you would replace field-slug with the slug of the author ID field (without the wpcf- prefix). I think in your case this would be term-author-id.

For best results, this code should be included in a child theme's functions.php file rather than in Toolset's custom code snippets section. Toolset's Custom Code snippets may not be fired early enough in the initialization sequence to have the desired effect.

#1894397

Chris!

You are the man. This works well even if I use Toolset custom code functionality.

Thanks a lot!

#1894399

My issue is resolved now. Thank you!