Link to home
Start Free TrialLog in
Avatar of Alicia St Rose
Alicia St RoseFlag for United States of America

asked on

How to append taxonomy terms to six most recent published custom post types

Okay here is my scenario:

I'm using the Memberpress plugin and I need to allow a certain number of custom post types (chapters) to be available for different membership levels. These would be the most recent chapters.

There's:

Tier 1 (2 chapters)
Tier 2 (4 chapters)
Tier 3 (6 chapters)

I've created a taxonomy called Member Type and added the tiers as terms. I will be adding the terms to the most recent 6 Chapters. I need this to happen automatically because I'll be designating that content as paid subscription content depending on the level. I can target content by taxonomy in MemberPress.

I've got some code working that will add all three tiers to any new chapter. But, what I really need it for these terms to be only limited to the most recent 6 chapters in this way:

Most recent 6 chapters have terms: Tier 1, Tier 2, Tier 3
Most recent 4 chapters have terms: Tier 1, Tier 2
Most recent 2 chapters have term: Tier 1

I have NO idea how to make this happen. Well, maybe a teeny bit, because I've been googling for hours! Can anyone set me in the right direction?

Here's the code I have:

add_action( 'save_post_chapter', 'myprefix_set_default_object_terms', 11, 2 );
function myprefix_set_default_object_terms( $post_id, $post ) {
	if ( 'publish' === $post->post_status ) {
		// Change here your custom taxonomy slugs and term slugs
		$defaults = array(
			'member-type' => array( 'tier-1', 'tier-2', 'tier-3' )
		);
		$taxonomies = get_object_taxonomies( $post->post_type );
		foreach ( (array) $taxonomies as $taxonomy ) {
			$terms = wp_get_post_terms( $post_id, $taxonomy );
			$append = ! empty( $terms );

			if ( array_key_exists( $taxonomy, $defaults ) ) {
				// usage: wp_set_object_terms( $object_id, $terms, $taxonomy, $append );
				$term_taxonomy_ids = wp_set_object_terms( $post_id, $defaults[$taxonomy], $taxonomy, $append );

				if ( is_wp_error( $term_taxonomy_ids ) ) {
					// There was an error somewhere and the terms couldn't be set.
				} else {
					// Success! These terms were added to the post.
				}					
			}
		}
	}
}

Open in new window

Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Let me try and understand.

When a chapter is added it gets tier1
As soon as it moves to position 3 (i.e. after two more chapters are added) it gets tier2
Then after it moves to position 5 (an additional 2 chapters are added) it gets tier3

Is that correct?
Avatar of Alicia St Rose

ASKER

Yikes! I can see where I may have screwed it up in my initial post. It looks like I really want oldest, not most recent. So, new one's get term: Tier 3.

Tier 3 can see all 6  latest chapters: Newest to Oldest

Tier 2 can only see 4 of the latest chapters: 4 Oldest

Tier 1 can only see 2 of the latest chapters: 2 Oldest

A chapter is released everyday for 6 days. Tier 1 has to wait an additional 4 days to see all six.

So let's say there are 10 chapters already published once it's launched.

Tier 1 can only see 6 (1 - 6)
Tier 2 can only see 8 (1 - 8)
Tier 3 can see all 10 (1 - 10)

When a new one is published:

Tier 1 can see 7 Chapters
Tier 2 can see 9 Chapters
Tier 3 can see 11Chapters

The latest six should have terms as such:

Chapter 6: Tier 1, Tier 2, Tier 3
Chapter 7: Tier 1, Tier 2, Tier 3
Chapter 8: Tier 2, Tier 3
Chapter 9: Tier 2, Tier 3
Chapter 10: Tier 3
Chapter 11: Tier 3

The Chapters work their way through the gamut starting with Tier 3, having the other terms appended, then losing them all when 6 chapters are published after they've appeared.  

Does that make more sense or did I just make it so much more complicated?
I understand
Tier 1 can see 7 Chapters
The six it could see before + the new 1?

Tier 2 can see 9 Chapters
So Tier 2 is not restricted to 8 chapters they can always see ALL chapters except the 2 most recent ones?
Tier 1 can see 7 Chapters
The six it could see before + the new 1?
Yes

So Tier 2 is not restricted to 8 chapters they can always see ALL chapters except the 2 most recent ones?
Yes! :)
What you need to do is keep the trigger on the publish - you then need to iterate over all chapters in date order

$position = 1;
$posts = // query posts that are chapters in descending publish date order
foreach($posts as $post) {
   clearExistingTaxonomyAssignments();
  // add Tier 1
   if ($postion >2) {
        // add tier 2
   } 
   if ($postion > 4) {
      // add tier 3
   }

   $postion++;
}

Open in new window


A more complicated solution would be to add / remove specific tiers rather than clearing and re-assiging but that might end up being overly complicated - a simple clear and re-assign is the simplest approach.
Okay.

I've tried to incorporate the code into my existing code and clearly I'm doing it wrong. My foreach loops may not be nested properly, if they should be nested at all. Here's what I've got:

function myprefix_set_default_object_terms( $post_id, $post ) {
	if ( 'publish' === $post->post_status ) {
		$position = 1;
		$args = array( 'post_type' => 'chapter', 'order' => 'DESC', 'orderby' => 'date');
		$posts = get_posts( $args )// query posts that are chapters in descending publish date order
		foreach($posts as $post) {
		   clearExistingTaxonomyAssignments();
		  $defaults = array(
					'member-type' => array('tier-1' )
				);
				
		   if ($postion >2) {
		      $defaults = array(
					'member-type' => array('tier-2' )
				);
		   } 
		   if ($postion > 4) {
		      $defaults = array(
					'member-type' => array('tier-3' )
				);
		   }
			
		   $postion++;
		   
		   $taxonomies = get_object_taxonomies( $post->post_type );
				foreach ( (array) $taxonomies as $taxonomy ) {
					$terms = wp_get_post_terms( $post_id, $taxonomy );
					$append = ! empty( $terms );
		
					if ( array_key_exists( $taxonomy, $defaults ) ) {
						// usage: wp_set_object_terms( $object_id, $terms, $taxonomy, $append );
						$term_taxonomy_ids = wp_set_object_terms( $post_id, $defaults[$taxonomy], $taxonomy, $append );
		
						if ( is_wp_error( $term_taxonomy_ids ) ) {
							// There was an error somewhere and the terms couldn't be set.
						} else {
							// Success! These terms were added to the post.
						}					
					}
				}
			}
		}
	}

Open in new window

UPDATE:

I was missing a semicolon right before first foreach. So now going to see if this code works...🤓
Not working.

I'm getting "Publishing failed" and "Updating failed" error messages.

Sooo.... I'll just hang out to see what I did wrong here.
Probably because of this line
clearExistingTaxonomyAssignments();

Open in new window

You need to define this function / code - what I posted was pseudo code to paint a general picture of the approach.
I have not worked much with taxonomies but I am guessing you use this function
wp_delete_object_term_relationships().

Probably something like this (untested)
wp_delete_object_term_relationships($post->ID, ['tier1','tier2','tier3']);

Open in new window

O.M.G. Wow!

I really need to systematically dig through WordPress hooks, actions and functions. There's something for everything!

Of course, I'm at the stage where I can't discern pseudo code from real code, but I had my suspicions about that line. LOL!

Okay, I'm going to play around with this!
Of course, I'm at the stage where I can't discern pseudo code from real code
That was my fault - rushed answer I should have explained a bit more.
No Worries!

Okay, So I played around with the code.

This is what I have:

add_action( 'save_post_chapter', 'myprefix_set_default_object_terms', 11, 2 );

function myprefix_set_default_object_terms( $post_id, $post ) {
	if ( 'publish' === $post->post_status ) {
		$position = 1;
		$args = array( 'post_type' => 'chapter', 'order' => 'DESC', 'orderby' => 'date');
		$posts = get_posts( $args );// query posts that are chapters in descending publish date order
		foreach($posts as $post) {
		 wp_delete_object_term_relationships($post->ID, 'member-type');
		  
		  $defaults = array(
					'member-type' => array('tier-1')
				);
		   if ($postion > 2) {
		      $defaults = array(
					'member-type' => array('tier-2')
				);
		   } 
		    
		   if ($postion > 4) {
		      $defaults = array(
					'member-type' => array('tier-3')
				);
		   }
			
		   $postion++;
		   
		   $taxonomies = get_object_taxonomies( $post->post_type );
				foreach ( (array) $taxonomies as $taxonomy ) {
					$terms = wp_get_post_terms( $post_id, $taxonomy );
					//$append = ! empty( $terms );
		
					if ( array_key_exists( $taxonomy, $defaults ) ) {
						// usage: wp_set_object_terms( $object_id, $terms, $taxonomy, $append );
						$term_taxonomy_ids = wp_set_object_terms( $post_id, $defaults[$taxonomy], $taxonomy);
		
						if ( is_wp_error( $term_taxonomy_ids ) ) {
							// There was an error somewhere and the terms couldn't be set.
						} else {
							// Success! These terms were added to the post.
						}					
					}
				}
			}
		}
	}

Open in new window


I've concluded:

1. I don't want to append the terms. I want it this way:

Most recent two: tier 3
2nd recent two: tier 2
least recent two: tier 1

The rest are no term

User generated image
I can't seem to get tier 3 to show up no matter what I do. And when i refresh the admin, the terms disappear.
Change your if's to if elses

if (position <= 2) {
  $defaults = ['member-type' => ['tier-3']];
} else if (position <= 4) {
  $defaults = ['member-type' => ['tier-2']];
} else {
  $defaults = ['member-type' => ['tier-1']];
}

Open in new window

The above will assign tier-3 only to the newest 2 chapters, tier-2 to the next newest 2 and tier-1 to everything else.
I'm getting Tier 3 for everything when I update. And when I refresh the page, position 1, 3, 4, 5 lose their terms.
I added taxonomy to the query arguments to see if that would help because there are two taxonomies connected to the post type. It didn't.

function myprefix_set_default_object_terms( $post_id, $post ) {
	if ( 'publish' === $post->post_status ) {
		$position = 1;
		$args = array( 'post_type' => 'chapter', 'order' => 'DESC', 'orderby' => 'date', 'taxonomy' => 'member-type');
		$posts = get_posts( $args );// query posts that are chapters in descending publish date order
		foreach($posts as $post) {
		 wp_delete_object_term_relationships($post->ID, 'member-type');
		  
		  if ($position <= 2) {
			  $defaults = ['member-type' => ['tier-3']];
			} else if ($position <= 4) {
			  $defaults = ['member-type' => ['tier-2']];
			} else {
			  $defaults = ['member-type' => ['tier-1']];
			}
			
		   $postion++;
		   
		   $taxonomies = get_object_taxonomies( $post->post_type );
				foreach ( (array) $taxonomies as $taxonomy ) {
					$terms = wp_get_post_terms( $post_id, $taxonomy );
					//$append = ! empty( $terms );
		
					if ( array_key_exists( $taxonomy, $defaults ) ) {
						// usage: wp_set_object_terms( $object_id, $terms, $taxonomy, $append );
						$term_taxonomy_ids = wp_set_object_terms( $post_id, $defaults[$taxonomy], $taxonomy);
		
						if ( is_wp_error( $term_taxonomy_ids ) ) {
							// There was an error somewhere and the terms couldn't be set.
						} else {
							// Success! These terms were added to the post.
						}					
					}
				}
			}
		}
	}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
What happened here is that the postion++ has a typo

Oh geesh! I looked at that over and over again, too. I like the idea of typing it out. Maybe I can figure out what I'm doing along the way!

The code works really well and I even edited the "member_type" to "member-type". That's how I set up the taxonomy. I think I will lean towards underscores in the future.  AND...I was also able to add a free level for all chapters beyond 6!

I've got to do this for another project, except it's the opposite scenario, the latest 10 podcasts are public, but the archive is behind a paywall. I'll see if I can work this code and make that happen. It should be fairly easy. I need to add the term "premium" to every thing beyond 10.

I'll start another thread if I get stuck. LOL!
One of the best Experts on EE. You consistently provide solutions that save the day! And I learn from each one! Thank you!
Thank you - and you are most welcome.