How to speed up a wordpress function with multiple loops?

How to speed up a wordpress function with multiple loops?

  • I am a PHP novice and wrote this function. It is an alphabetical navigation which shows only the letter that have posts in both that letter and the currently filtered "genero" taxonomy term. I use multiple taxonomy queries to find "artistas" posts that, for example, are tagged as both "rock" and "funk". The function works perfectly and outputs exactly what I want it to, but... The multiple loops are really lagging the load time and, being the n00b that I am, am uncertain of how to optimize the function. Any pointers or guidance would be VERY much appreciated. If you want I can trade time for time (i write some mean CSS) :) thank you! <?php function bam_artist_alfa() { $taxonomy = 'alfa'; $uri = my_url(); $home = 'http://buenosairesmusic.com/'; // save the terms that have posts in an array as a transient if ( false === ( $alphabet = get_transient( 'bam_archive_alphabet' ) ) ) { // It wasn't there, so regenerate the data and save the transient $terms = get_terms($taxonomy); $alphabet = array(); if($terms){ foreach ($terms as $term){ $alphabet[] = $term->slug; } } set_transient( 'bam_archive_alphabet', $alphabet ); } if(strstr($uri, '/artista/') ) { $uri = str_replace('/artista/','/?alfa=', $uri); $uri = substr_replace($uri ,"",-1); } $all_link = removeqsvar($uri, 'alfa'); $last = $all_link[strlen($all_link)-1]; if($last == '?') $all_link = substr_replace($all_link ,"",-1); if($all_link == $home) $all_link = $home.'artistas'; if( isset($_GET) && isset($_GET['alfa']) ) { $is_alfa = (!is_tax('alfa') && !$_GET['alfa'] ? false : true ); } else { $is_alfa = (!is_tax('alfa') ? false : true ); } $all_current = ($is_alfa == true ? null : ' bg1 round-res' ); ?> <ul class="bbw bo alfa-nav c2"> <li class="all-link<?php echo $all_current; ?>"> <?php if(!$is_alfa) { echo 'A&ndash;Z'; } else { ?> <a href="<?php echo $all_link; ?>">A&ndash;Z</a> <?php }?> </li> <?php $query = $_SERVER['QUERY_STRING']; $genre = null; $orden = (isset($_GET) && isset($_GET['orden']) ? '&orden=fecha' : null); if( strstr($uri,'/genero/') ) { $genre = str_replace('/genero/','/?genero=', $uri); $genre = substr_replace($uri ,"",-1); $genre = explode('/',$genre); $genre = end($genre); } elseif( isset($_GET) && isset($_GET['genero']) ) { $genre = $_GET['genero']; } if(!empty($genre)) { $spaces = strpos($genre,' '); $genre = ($spaces === false ? $genre : explode(' ', $genre) ); } function has_artists($i, $genre) { if(empty($genre)) { $termquery['tax_query'] = array( array( 'taxonomy' => 'alfa', 'terms' => $i, 'field' => 'slug', ), ); $termquery['post_type'] = 'artistas'; } else { $alfaquery[] = array( 'taxonomy' => 'alfa', 'terms' => $i, 'field' => 'slug', ); if(is_array($genre)) { $genres[] = array( 'taxonomy' => 'genero', 'terms' => $genre, 'field' => 'slug', 'operator' => 'AND' ); } else { $genres[] = array( 'taxonomy' => 'genero', 'terms' => $genre, 'field' => 'slug', ); } $termquery['tax_query'] = array_merge($genres, $alfaquery); $termquery['tax_query']['relation'] = "AND"; $termquery['post_type'] = 'artistas'; } $has_artists = get_posts($termquery); if($has_artists) { return true; } else { return false; } } foreach(range('a', 'z') as $i) : $current = ($i == get_query_var($taxonomy)) ? "bg1 round-res" : "menu-item"; if(empty($genre)) { $link = $home.'?alfa='.$i.$orden; } else { $genrestring = (is_array($genre) ? implode('+',$genre) : $genrestring = $genre ); $link = $home.'?alfa='.$i.'&genero='.$genrestring.$orden; } if ( has_artists($i,$genre) && $i != get_query_var($taxonomy) ){ ?> <li class="<?php echo $current; ?>"> <?php printf('<a href="%s">%s</a>', $link, strtoupper($i) ) ?> </li> <?php } else { ?> <li class="<?php echo $current; if($i != get_query_var($taxonomy)) {echo ' empty';} ?>"> <?php echo strtoupper($i); ?> </li> <?php } endforeach; ?> </ul> <?php } ?>

  • Answer:

    I would just retrieve an array of alphabet/taxonomy terms that have posts. You do this, but doesn't actually use it. This function will return an array of non-empty (alphabet) terms: (Transient? - unless you have multiple post types using this taxonomy, (see below) I'm not sure if much is gained from using transients - and you can just call to get_terms and use wp_list_pluck as shown). The following function uses transients. wpse50148_get_used_alpha(){ if ( false === ( $alphabet = get_transient( 'bam_archive_alphabet' ) ) ) { //It wasn't there, so regenerate the data and save the transient $terms = get_terms('alfa'); $alphabet =array(); if($terms){ $alphabet = wp_list_pluck($terms,'slug'); } set_transient( 'bam_archive_alphabet', $alphabet ); } return $alphabet; } Don't forget to update the transient when a post is updated. This method assumes that the only post type using this taxonomy is 'artistas' - if it is being shared then a letter may claim to have artistas associated with it (in your menu) when it does not. Shared taxonomy work-around To get round this, you would have to query the posts and then loop through them and collect their terms. Either way - only 1, not 26 queries are being performed to get the 'used' alphabet. A transient would be more obviously time-saving in this scenario. Usage: $alphabet = wpse50148_get_used_alpha(); foreach(range('a', 'z') as $i) : if( in_array($i,$alphabet) ){ //Letter has terms }else{ //Letter does not have terms } endif;

j-man86 at WordPress Visit the source

Was this solution helpful to you?

Other answers

I didn't use the transients API yet but in this case I think it's a good choice. You use it but only for a small part of the data. To cache artists per alfa and genre you could do something like this (I assume): if ( false === ( $has_artists = get_transient( "bam_artist_$i_$genre" ) ) ) { $has_artists = get_posts($termquery); set_transient( "bam_artist_$i_$genre", $has_artists ); }

offroff

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.