Je suis un novice PHP et j'ai écrit cette fonction. Il s’agit d’une navigation alphabétique qui ne montre que les lettres qui ont des messages dans cette lettre et le terme de taxonomie "genero" actuellement filtré.
J'utilise plusieurs requêtes de taxonomie pour trouver des articles "artistas" qui, par exemple, sont marqués à la fois par "rock" et "funk".
La fonction fonctionne parfaitement et affiche exactement ce que je veux, mais ...
Les multiples boucles sont vraiment en retard sur le temps de chargement et, étant le n00b que je suis, je ne sais pas comment optimiser cette fonction.
N'importe quel pointeur ou guide serait TRÈS très apprécié. Si vous voulez, je peux gagner du temps (j'écris des CSS) :)
je vous remercie!
<?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–Z'; } else { ?>
<a href="<?php echo $all_link; ?>">A–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 } ?>
Je voudrais juste récupérer un tableau de termes alphabet/taxonomie qui ont des messages. Vous faites cela, mais ne l'utilisez pas réellement. Cette fonction renverra un tableau de termes non vides (alphabet):
( Transitoire? - sauf si vous avez plusieurs types de publication utilisant cette taxonomie, ( voir ci-dessous ) I ' m pas sûr de gagner beaucoup à utiliser des transitoires - vous pouvez simplement appeler get_terms
et utiliser wp_list_pluck
comme indiqué). La fonction suivante utilise des transitoires.
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;
}
N'oubliez pas de mettre à jour le transitoire lorsqu'un message est mis à jour.
Cette méthode suppose que le seul type de publication utilisant cette taxonomie est "artistas" - si elle est partagée, une lettre peut prétendre avoir des artistes associées (dans votre menu), dans le cas contraire.
Pour contourner ce problème, il vous faudrait interroger les publications, les parcourir en boucle et en collecter les termes. Quoi qu'il en soit, seules 1, et non 26 requêtes sont exécutées pour obtenir l'alphabet "utilisé". Un transitoire permettrait évidemment de gagner du temps dans ce scénario.
$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;
Je n'ai pas encore utilisé l'API transitoires, mais dans ce cas, je pense que c'est un bon choix. Vous l'utilisez mais seulement pour une petite partie des données.
Pour mettre en cache des artistes par alfa et genre, vous pouvez faire quelque chose comme ceci (je suppose):
if ( false === ( $has_artists = get_transient( "bam_artist_$i_$genre" ) ) ) {
$has_artists = get_posts($termquery);
set_transient( "bam_artist_$i_$genre", $has_artists );
}