Archive for the ‘How-To’ Category

Get Categories Author has Posted in for Custom Post Types

I needed to list all the categories of a custom post type that an author had posted in.

I found code to do that with regular posts in the wordpress.org forums and I modified it to use with custom post types.

Be sure to replace customposttype with the name of your custom post type.

Place this into your theme file where you want the list to appear.

<?php
$author = get_the_author_meta('ID');

$categories = $wpdb->get_results("
SELECT DISTINCT(terms.term_id) as ID, terms.name, terms.slug
FROM $wpdb->posts as posts
LEFT JOIN $wpdb->term_relationships as relationships ON posts.ID = relationships.object_ID
LEFT JOIN $wpdb->term_taxonomy as tax ON relationships.term_taxonomy_id = tax.term_taxonomy_id
LEFT JOIN $wpdb->terms as terms ON tax.term_id = terms.term_id
WHERE 1=1 AND (
	posts.post_status = 'publish' AND
	posts.post_author = '$author' AND
	tax.taxonomy = 'customposttype' )
ORDER BY terms.name ASC
");
?>
<ul>
<?php foreach( $categories as $category ) : ?>
	<li>
		<a href="<?php echo get_term_link( $category->name, 'customposttype' ); ?>" title="<?php echo $category->name ?>"><?php echo $category->name ?></a>
	</li>
<?php endforeach; ?>
</ul>


Limit Number of Posts Per User in WordPress

This code will limit the number of posts a user can make.

At first, I was trying to limit each user to one post and I had that working. Then I realized that I needed to have different numbers of posts for different users, so I created an option in a user’s profile that only people with the right capability (manage_options) can edit. I’ll be changing this in the future for that number to be automatically changed depending on a user’s subscription type, but I needed this for testing purposes.

The option in the profile shows up under the contact info section, which I know is an odd place, but it was the easiest place to put it.

Put the following into your functions.php file:

// limit number of posts per user
// provided by cleverness.org
if ( !current_user_can('manage_options') ) {
	$default = 1; // default number of posts
	$count_posts = 0;
	global $wpdb;
	$poststable = $wpdb->prefix.'posts';
	$postlimit = get_user_meta($current_user->id, 'postlimit', true);
	if ( $postlimit == '' ) $postlimit = $default;
	$query = "SELECT COUNT(*) FROM $poststable WHERE post_author = '$current_user->id' AND (post_status = 'pending' OR post_status = 'draft' OR post_status = 'publish' ) ";
	$count_posts = $wpdb->get_var($query);
	if ($count_posts >= $postlimit) {
		if ( $_SERVER['REQUEST_URI'] == '/wp-admin/post-new.php' )
			Header("Location: index.php");//redirects to dashboard
		if ( is_admin() ){
			$stylesheet =  get_stylesheet_directory_uri() . '/css/limitposts.css';
   			wp_register_style('limitpost_admin_css', $stylesheet, false, '1', 'screen');
   			wp_enqueue_style('limitpost_admin_css');
			}
	}
}

// add post limit option to profile
add_filter('user_contactmethods','hide_profile_fields',10,1);

function hide_profile_fields( $contactmethods ) {
	if( current_user_can( 'manage_options' ) )
		$contactmethods['postlimit'] = 'Post Limit';
  	return $contactmethods;
}

Create a file called limitposts.css, put the following into it, and save it in a directory called css in your theme folder (you can change where you save it, but be sure to change the location in functions.php).

#menu-posts .wp-first-item + li {
	display: none;
}

If you want to use this for custom post types, change:

if ( $_SERVER['REQUEST_URI'] == '/wp-admin/post-new.php' )

to:

if ( $_SERVER['REQUEST_URI'] == '/wp-admin/post-new.php?post_type=customposttype' )

and change the id name in your CSS:

#menu-posts-customposttype .wp-first-item + li {
	display: none;
}

Be sure to replace customposttype with the name of your custom post type.


Add User Types to WordPress and BuddyPress

I’ve been working on some more complicated sites than usual at work. One is a social networking site that uses BuddyPress. It’s my first BuddyPress site, so it’s been a learning experience. Additionaly, it was my first WordPress Multi-Site.

One thing I needed to do was allow people to choose a user type at registration. I also needed the user to be assigned a custom Role based on their user type.

I used the Capability Manager Plugin to set the custom roles.

The code is based off How to add custom $usermeta to registration and How to change a users role on the wordpress registration form.

Change the User Type A, user-type-a, etc. to whatever you want your user types to be.

Put this in you BuddyPress theme /registration/register.php file:

<label>Account Type:</label>
<select>
	<option value="user-type-a">User Type A</option>
	<option value="user-type-b">User Type B</option>
	<option value="user-type-c">User Type C</option>
</select>

Put the following code in your theme’s functions.php:

<?php
/* Add sign-up field to BuddyPress sign-up array*/
function bp_custom_user_signup_field( $usermeta ) {
	$usermeta['signup_type'] = $_POST['signup_type'];

	return $usermeta;
}
add_filter( 'bp_signup_usermeta', 'bp_custom_user_signup_field' );

/* Add field_name from sign-up to usermeta on activation */
function bp_user_activate_field( $signup ) {

	update_usermeta( $signup['user_id'], 'signup_type', $signup['meta']['signup_type'] );

	return $signup;
}
add_filter( 'bp_core_activate_account', 'bp_user_activate_field' );

function synchro_wp_usermeta($user_id, $password, $meta) {
	global $bp, $wpdb;

	$type = $meta[signup_type];

	update_usermeta( $user_id, 'signup_type', $type );

}
add_action( 'wpmu_activate_user', 'synchro_wp_usermeta', 10, 3);

// change user role on registration

function register_role($user_id, $password, $meta) {

	global $bp, $wpdb;

   	$userdata = array();
   	$userdata['ID'] = $user_id;
   	$userdata['role'] = $meta[signup_type];

   	//only allow if user role is my_role

   	if ($userdata['role'] == 'user-type-a' || $userdata['role'] == 'user-type-b' || $userdata['role'] == 'user-type-c' ){
      	wp_update_user($userdata);
   	}
}

add_action('wpmu_activate_user', 'register_role', 10, 3);
?>

You can use get_user_meta() in your theme files to show different things to different user types.

<?php
global $bp;
if ( get_user_meta($bp->displayed_user->id, 'signup_type') == 'user-type-a' ) : ?>
	Put your HTML code here
<?php endif; ?>
?>


Show number of posts in a category

Tonight I needed to figure out how to display the number of posts that were in a specific category.

This post on Getting the number of posts per category showed me how to do that.

This goes into your template where you want the number to appear:

<?php echo get_category_by_slug('category-slug')->category_count; ?>

Replace category-slug with the slug of your category.


Replacing Core Functions

Replacing template core functions is easy and doesn’t require editing core files.

Copy the code for that function to functions.php in your theme, change the function name, and call it in your template using it’s new name.


Yearly Archives

Place the following in functions.php to list the archives for a specific month and year:

function getarchives_filter($where, $args) {
	if (isset($args['year'])) {
		$where .= ' AND YEAR(post_date) = ' . intval($args['year']);
	}
	if (isset($args['month'])) {
		$here .= ' AND MONTH(post_date) = ' . intval($args['month']);
	}
	return $where;
}

add_filter('getarchives_where', 'getarchives_filter', 10, 2);

This is what you will add to your template file:

<?php wp_get_archives('type=daily&month='.get_the_time('m').'&year=' . get_the_time('Y')); ?>

If you’ve been blogging for a number of years, it can sometimes be helpful to list your archives by years, then by months, then by days.

If you use this method, your archive page will list every year you have a post in. Then when you click on a year, it will take you to a list of the months you posted in that year. Then when clicking on a month, you go to a list of days you posted.

If you want to use this method, add the following code to archive.php:

	<?php while (have_posts()) : the_post(); ?>
        <?php if ( is_year() ) : ?>
			<ul id="archives"><?php new_get_archives('type=monthly&year=' . get_the_time('Y')); ?></ul>
		<?php elseif ( is_month() ) : ?>
			<ul id="archives"><?php new_get_archives('type=daily&month='.get_the_time('m').'&year=' . get_the_time('Y').'&format=custom&before=&after='); ?></ul>
		<?php elseif ( is_day() ) : ?>
        	<div class="entry">
				<?php the_content('<p class="serif">Read the rest of this entry &raquo;</p>'); ?>

				<?php wp_link_pages(array('before' => '<p><strong>Pages:</strong> ', 'after' => '</p>', 'next_or_number' => 'number')); ?>

				<?php edit_post_link('Edit this entry','','.'); ?>
			</div>
		<?php else : ?>
		<div <?php post_class() ?>>
				<h3 id="post-<?php the_ID(); ?>"><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h3>
				<p><?php the_time('l, F jS, Y') ?></p>

				<div class="entry">
					<?php the_content() ?>
				</div>

				<p class="postmetadata"><?php the_tags('Tags: ', ', ', '<br />'); ?> Posted in <?php the_category(', ') ?> | <?php edit_post_link('Edit', '', ' | '); ?>  <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?></p>

			</div>

	<?php endif; ?>

		<?php endwhile; ?>

Put this in archives.php:

<?php wp_get_archives('type=yearly&format=custom&before=|&after=|'); ?>

I also had to edit the get_archives function. I’m attaching a text file of that code because it’s a little long. To use, paste it into your functions.php (inside opening and closing PHP tags if they’re not already there). Be sure to also include the getarchives_filter function at the top of this page.

Download new_get_archives.txt – version 1.0 posted 01-10-2010