3
\$\begingroup\$

This code comes from a Wordpress plugin's forum called Vote it Up. It sort posts by vote. A lotof people say that there is more code than is needed. So I was wondering if someone have any idea about how to clean it a bit.

votingfunctions.php:

function ShowPostByVotes() {
    global $wpdb, $voteiu_databasetable;

    mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) or die(mysql_error());
    mysql_select_db(DB_NAME) or die(mysql_error());
    //Set a limit to reduce time taken for script to run
    $upperlimit = get_option('voteiu_limit');
    if ($upperlimit == '') {
        $upperlimit = 100;
    }
    $lowerlimit = 0;

    $votesarray = array();
        $querystr = "
            SELECT *
            FROM $wpdb->posts
            WHERE post_status = 'publish'
            AND post_type = 'post'
            ORDER BY post_date DESC
         ";
        $pageposts = $wpdb->get_results($querystr, OBJECT);
    //Use wordpress posts table
    //For posts to be available for vote editing, they must be published posts.
    mysql_connect(DB_HOST, DB_USER, DB_PASSWORD) or die(mysql_error());
    mysql_select_db(DB_NAME) or die(mysql_error());
    //Sorts by date instead of ID for more accurate representation
    $posttablecontents = mysql_query("SELECT ID FROM ".$wpdb->prefix."posts WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_date_gmt DESC LIMIT ".$lowerlimit.", ".$upperlimit."") or die(mysql_error());

    $returnarray = array();
    while ($row = mysql_fetch_array($posttablecontents)) {
        $post_id = $row['ID'];
        $vote_array = GetVotes($post_id, "array");
        array_push($votesarray, array(GetVotes($post_id)));
    }
    array_multisort($votesarray, SORT_DESC, $pageposts);
    $output = $pageposts;
    return $output;

}

index.php:

$pageposts = ShowPostByVotes();

?>
 <?php if ($pageposts): ?>
  <?php foreach ($pageposts as $post): ?>
    <?php setup_postdata($post); ?>

Attention! Code above is something like:

<?php if (have_posts()) : ?>

        <?php while (have_posts()) : the_post(); ?>

so in foreach loop you can use statements like in standard "The Loop" for example the_content, the_time(). To end this add

<?php endforeach; ?>

  <?php else : ?>
    <h2 class="center">Not Found</h2>
    <p class="center">Sorry, but you are looking for something that isn't here.</p>
    <?php include (TEMPLATEPATH . "/searchform.php"); ?>
 <?php endif; ?>

EDIT:

How I run a custom loop:

        <?php $custom_posts = new WP_Query(); ?>
        <?php $custom_posts->query('category_name=Pictures'); ?>
        <?php while ($custom_posts->have_posts()) : $custom_posts->the_post(); ?>
            <div class="content-block-2">
                <a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'twentyten' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark"><?php the_content(); ?></a>
            </div>
        <?php endwhile; ?>
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

These are my suggestions

  1. Don't use mysql functions to connect and query Wordpress posts. You can replace the first SQL statement with this WP_Query.

    $query = new WP_Query('post_type=post&post_status=publish&orderby=date&order=DESC');
    $pageposts = $query->get_posts();  
    

    This way the code is somewhat protected from future Wordpress database changes.

  2. The second select statement is a bit unnecessary as each $post in the $pagepost already contains the post id. Only thing missing is the limit, but we'll add that to the WP_Query by adding

    $query = new WP_Query('post_type=post&post_status=publish&orderby=date&posts_per_page='.$upperlimit);
    
  3. Refactor and remove unused/unnecessary code

    global $wpdb, $voteiu_databasetable - are not needed anymore
    $upperlimit - assignment can be done on one line $lowerlimit - not used anymore as it's enough with the $upperlimit $output = $pageposts; - assigmentent before return is unnecessary

So the complete ShowPostByVotes in votingfunctions.php would look something like this now:

function ShowPostByVotes() {

    $upperlimit = is_numeric(get_option('voteiu_limit')) ? get_option('voteiu_limit') : 100 ;

    $query = new WP_Query('post_type=post&post_status=publish&orderby=date&posts_per_page='.$upperlimit);
    $pageposts = $query->get_posts();        
    $votesarray = array();
    foreach ($pageposts as $post) {
        $vote_array = GetVotes($post->ID, "array");
        array_push($votesarray, array(GetVotes($post->ID)));
    }

    array_multisort($votesarray, SORT_DESC, $pageposts);
    return $pageposts;

}

And you can use it in your index.php by using this code

 <?php $pageposts = ShowPostByVotes();  ?>
 <?php if ($pageposts): ?>
  <?php global $post; ?>
  <?php foreach ($pageposts as $post): ?>
    <?php setup_postdata($post); ?>

    <div class="post" id="post-<?php the_ID(); ?>">
      <h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>">
      <?php the_title(); ?></a></h2>
      <small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --></small>
      <div class="entry">
         <?php the_content('Read the rest of this entry »'); ?>
      </div>

      <p class="postmetadata">Posted in <?php the_category(', ') ?> | <?php edit_post_link('Edit', '', ' | '); ?>  
      <?php comments_popup_link('No Comments »', '1 Comment »', '% Comments »'); ?></p>
    </div>
  <?php endforeach; ?>

  <?php else : ?>
    <h2 class="center">Not Found</h2>
    <p class="center">Sorry, but you are looking for something that isn't here.</p>
    <?php include (TEMPLATEPATH . "/searchform.php"); ?>
 <?php endif; ?>
\$\endgroup\$
5
  • \$\begingroup\$ @Jonas Oh my god, I've been looking for this for years. How come you only have one badge? Thanks! (one more thing, how can move the WP_Query to the index page and use a while loop instead)? \$\endgroup\$
    – wyc
    Mar 27, 2011 at 20:10
  • \$\begingroup\$ I assume you're trying to run your code in a recent version of Wordpress (?) WP_Query exists in /wp-includes/query.php and should be included and made available to you automatically in index.php (done in wp-settings.php , around line 105). \$\endgroup\$
    – Jonas
    Mar 27, 2011 at 20:22
  • \$\begingroup\$ @Jonas I'm using Wordpress 3.1. I always start custom loops like I show in the EDIT I included above. Is there any way of starting a loop like that with the code you provided? \$\endgroup\$
    – wyc
    Mar 27, 2011 at 20:39
  • \$\begingroup\$ Ok, I'm not sure If I understand your problem, I think you should be able to retrieve exactly the same information by using the code I provided, only difference is the foreach instead of while and the extra call to setup_postdata(). Sorry but I don't see an easy way to sort the WP_Query using the Vote details. Once the WP_Query is executed you need to do the loop as I suggested \$\endgroup\$
    – Jonas
    Mar 27, 2011 at 21:13
  • 1
    \$\begingroup\$ Had some issues editing my post so sorry for the "nonexisting formatting" This code should present the same result as your custom query loop <?php global $post; ?> <?php $custom_posts =ShowPostByVotes(); ?> <?php foreach ($custom_posts as $post){ ?> <?php setup_postdata($post); ?> <div class="content-block-2"> <a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'twentyten' ), the_title_attribute( 'echo=0' ) ); ?>" ><?php the_content(); ?></a> </div> <?php } ?> \$\endgroup\$
    – Jonas
    Mar 27, 2011 at 21:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.