Skip Navigation

[Resolved] #menu item leading to latest of a CPT — need menu item to disappear if no valid

This support ticket is created 4 years, 10 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
- 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 5 replies, has 3 voices.

Last updated by Minesh 4 years, 10 months ago.

Assisted by: Minesh.

Author
Posts
#1421409

I can't find it in my earlier support threads, but I'm virtually certain I got this code from the forum somewhere....

/**
* Replaces a custom URL placeholder with the URL to the latest post
*
* @param array $items The menu items
* @param array $menu The menu name
* @param string $args The command arguments
*
* @return void
*/
function sub_disc_placeholder_with_latest_discussion( $items, $menu, $args ) {
// Loop through the menu items looking for placeholder(s)
foreach ( $items as $item ) {
// Is this the placeholder we're looking for?
if ( '#disc' != $item->url)
continue;
// Get the latest post
$disc = get_posts(
array(
'numberposts' => 1,
'post_type' => 'discussion',
)
);

if ( empty( $disc ) )
continue;

// Replace the placeholder with the real URL
$item->url = get_permalink( $disc[0]->ID );
}

// Return the modified (or maybe unmodified) menu items array
return $items;
}

It works beautifully. However, these items have expiration dates and I'd like to hide the menu item if the post it would lead to is expired.

So the condition would be
if ( valid-starting <= now() <= valid-through ) then set style for the menu item to display: none

Suggestions?

#1422097

Hello, I don't see anything here in the forums using that exact function name. Changing function names is pretty common though. I searched Google and found an exact match here:
http://t-machine.org/index.php/author/adam/feed/

Digging in there, you can see the function in the contents of this post:
http://t-machine.org/index.php/2016/05/19/wordpress-plugin-insert-link-to-latest-post-in-category-on-your-menu/

So maybe the code came directly from this post, or maybe someone copied it from there and pasted it in a post in our forums? Anyway, it sounds like the URL placeholder replacement part is working well and should not be changed. In addition to that, you want to hide a menu item when the corresponding post has expired. I'm not clear about two things, so I need your feedback:

1. How is the post expiration defined? The conditional hints that there is a custom date field for valid start date and another custom date field for valid end date. I assume both of those are date fields created in Types. Are those assumptions correct, or can you explain more about how the expiration is determined? If custom fields are involved please tell me the slugs.

2. Do you want to hide/remove all expired menu items in this foreach loop, or just the one menu item whose placeholder URL #disc is being replaced with a discussion post URL?

#1422125

We'll, that would explain why I don't find it I'm my old tickets. I thought it was toolset related, but it's related generally to CPTs.

To answer your questions:
1) There is a custom meta field for valid starting and valid ending. They are date/time fields managed by Toolset.

2) There is a single top level menu item "Latest Discussion. That's what has #disc as its link. I only need to hide that one menu item. I've already confirmed in developer tools that display: none in the CSS will do exactly what I want. I'm just not sure how to modify this code to add that in. Elsewhere on the site I use a meta field to complete a CSS class name so an item is hidden.

#1422425

1) There is a custom meta field for valid starting and valid ending. They are date/time fields managed by Toolset.
Managed by Toolset and created in Types can mean different things, so I'm going to assume these are Toolset Types custom date fields. A conditional for testing whether or not the current date falls in between two date fields from the current post might look like this:

$is_valid = 0; // for now, assume the post is invalid
$post_id = 12345; // the ID of the post whose expiration you want to check
$start_slug = 'valid-start-date'; // the slug of the start date field as seen in wp-admin
$end_slug = 'valid-end-date'; // the slug of the end date field as seen in wp-admin
$valid_start = get_post_meta( $post_id, 'wpcf-' . $start_slug, true ); // types date field stores a unix timestamp for the start date
$valid_end = get_post_meta( $post_id, 'wpcf-' . $end_slug, true ); // types date field stores a unix timestamp for the end date
$now = time(); // date & time comparison reference
if( ($now >= $valid_start) && ($now <= $valid_end) ) {
  // this post is valid right now
  $is_valid=1;
}

2)...I'm just not sure how to modify this code to add that in. Elsewhere on the site I use a meta field to complete a CSS class name so an item is hidden.
Hmmm, okay I don't have a cut-and-paste snippet available to do that - it's not something Toolset is designed to customize. I think each $item has a key classes holding CSS classes for each menu item. I would try to dump or log $item->classes to confirm. It might be an array, in which case you could push your CSS class onto that array. To delete the menu item instead, I guess you could delete/unset the $item from $items.

#1426355

To close the loop on this ticket, here is working code. Changes to the code earlier in the thread are explained at the end.

/**
 * Replaces a custom URL placeholder with the URL to the latest post
 *
 * @param mixed $items The menu items
 * @param mixed $menu  The menu name
 * @param mixed $args  The command arguments
 *
 * @return void
 */
function sub_brief_placeholder_with_latest_briefing( $items, $menu, $args ) {
	// Loop through the menu items looking for placeholder(s)
	foreach ( $items as $key => $item ) {
		// Is this the placeholder we're looking for?
		if ( '#briefing' != $item->url )
			continue;

			// else get the latest post
			$brief = get_posts(
				array(
					'numberposts' => 1,
					'post_type' => 'briefing',
				)
			);

			$post_id = $brief[0]->ID; // the ID of the post whose expiration you want to check
			$start_slug = 'valid-start'; // the slug of the start date field as seen in wp-admin
			$end_slug = 'valid-through'; // the slug of the end date field as seen in wp-admin
			$valid_start = get_post_meta( $post_id, 'wpcf-' . $start_slug, true ); // types date field stores a unix timestamp for the start date
			$valid_end = get_post_meta( $post_id, 'wpcf-' . $end_slug, true ); // types date field stores a unix timestamp for the end date
			$now = time(); // date & time comparison reference
		if ( ( $now >= $valid_start ) && ( $now <= $valid_end ) ) {
			// this post is valid right now
			$is_valid = 1;
		}

		if ( 0 == $is_valid ) {
			unset( $items[ $key ] );  // remove the menu item completely
			continue;
		}

		// Replace the placeholder with the real URL
		$item->url = get_permalink( $post_id );

	}

	// Return the modified (or maybe unmodified) menu items array
	return $items;
}

The key change (irony intentional) was to setup the items array so the key (which loop through the foreach it is) is accessible later. Then if there is nothing current (in this case a briefing, but the discussion code does this, too), then $key is used to identify which member to remove from the $items array.
The post ID to use in your line starting with $post_id is available in $brief[0]->ID.

Thanks for your help getting this started!

#1427853

Minesh
Supporter

Languages: English (English )

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

Christian is on vacation. He will get back to work this Sunday. I'm stepping in, hope this is ok.

Thank you for sharing the latest code that will help other users searching on the forum.