WP_QUERY – avanzato

Dopo aver visto come si fanno delle ricerche semplici in wordpress, vedremo ora come creare un form di ricerca che cerch in base a dei parametri che possono essere selezionati dall’utente. Creeremo quindi alcuni esempi di form di ricerca.

Esempio 1

Ecco un form che mostra all’utente l’elenco delle lettere dell’alfabeto ed un campio di input. Al clic sulla lettera, il sistema cercherà i custom post type il cui titolo inizia con quella lettera, mentre inserendo un testo nel campo di input e facendo submit del form, il sistema cercherà quel testo nel titolo ed in un ACF definito in precedenza.

<?php 
	$lettera = sanitize_text_field($_GET["letter"]); //ricevo la lettera come parametro GET
	$nome = sanitize_text_field($_POST["nome"]); // ricevo il testo digitato come parametro POST
	define(PRINCIPIO_ATTIVO, $nome); // definisco la variabile PRINCIPIO_ATTIVO

	// funzione per output delle lettere
	function html_lettera($lettera,$inputlettera){
		echo 'href="?letter='.$lettera.'"';
		if ($lettera == $inputlettera){
			echo " class='sel'";
		}
	}

	// elenco prodotti
	// imposto la query

	// se ricevo la prima lettera
	if ($lettera != ""){
		$postids = $wpdb->get_col($wpdb->prepare("
			SELECT      ID
			FROM        $wpdb->posts
			WHERE       SUBSTR($wpdb->posts.post_title,1,1) = %s
			ORDER BY    $wpdb->posts.post_title",$lettera)); 
	}

	// join tra tabella post e postmeta
	function create_join_tables($join) {
		global $wp_query, $wpdb;

			$join .= "LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id ";

		return $join;
	}
	add_filter('posts_join', 'create_join_tables');

	// where conditions
	function posts_where( $where ) {
		global $wpdb;

		if (PRINCIPIO_ATTIVO != ""){
			$where .= " AND ( 
				($wpdb->posts.post_title  LIKE '%".PRINCIPIO_ATTIVO."%') OR 
				($wpdb->postmeta.meta_key = 'active_ingredient' AND $wpdb->postmeta.meta_value LIKE '%".PRINCIPIO_ATTIVO."%') )";
		}

		return $where;
	}
	add_filter( 'posts_where' , 'posts_where' );

	// filtro risultati doppi
	function search_distinct() { return "DISTINCT"; }
	add_filter('posts_distinct', 'search_distinct');

	if (PRINCIPIO_ATTIVO == ""){
		$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
	}
	else{
		$paged = 0;
	}

	$wpquery = new WP_Query(array(
		'post_type'      => "pharmaproducts",
		'posts_per_page' => 12,
		'paged' =>$paged,
		'orderby' => 'title',
		'order' => 'ASC',
		'post__in' => $postids
	));

?>

	<div class="header-prodotto clearfix">
		<form method="post" class="form-prodotto">
			<input type="text" name="nome" placeholder="<?php _e("Search a product","pharma"); ?>">
		</form>
		<?php paginazione(__("Page","pharma"), $wpquery->found_posts, $wpquery->query_vars['posts_per_page'],true); ?>
		<div class="conteggio-prodotti">
			<?php
				echo $wpquery->post_count." ";
				if ($wpquery->post_count > 1){echo __("products of","pharma");}
				else{echo __("product of","pharma");}
				echo " ".$wpquery->found_posts; ?>
		</div>
	</div>

	<div class="letter-search clearfix">
		<span class="letter-search-title"><?php _e("Filter products by name"); ?></span>
		<ul class="lettere clearfix">
			<li><a <?php html_lettera("a",$lettera);?>>a</a></li>
			<li><a <?php html_lettera("b",$lettera);?>>b</a></li>
			<li><a <?php html_lettera("c",$lettera);?>>c</a></li>
			<li><a <?php html_lettera("d",$lettera);?>>d</a></li>
			<li><a <?php html_lettera("r",$lettera);?>>e</a></li>
			<li><a <?php html_lettera("f",$lettera);?>>f</a></li>
			<li><a <?php html_lettera("g",$lettera);?>>g</a></li>
			<li><a <?php html_lettera("h",$lettera);?>>h</a></li>
			<li><a <?php html_lettera("i",$lettera);?>>i</a></li>
			<li><a <?php html_lettera("j",$lettera);?>>j</a></li>
			<li><a <?php html_lettera("k",$lettera);?>>k</a></li>
			<li><a <?php html_lettera("l",$lettera);?>>l</a></li>
			<li><a <?php html_lettera("m",$lettera);?>>m</a></li>
			<li><a <?php html_lettera("n",$lettera);?>>n</a></li>
			<li><a <?php html_lettera("o",$lettera);?>>o</a></li>
			<li><a <?php html_lettera("p",$lettera);?>>p</a></li>
			<li><a <?php html_lettera("q",$lettera);?>>q</a></li>
			<li><a <?php html_lettera("r",$lettera);?>>r</a></li>
			<li><a <?php html_lettera("s",$lettera);?>>s</a></li>
			<li><a <?php html_lettera("t",$lettera);?>>t</a></li>
			<li><a <?php html_lettera("u",$lettera);?>>u</a></li>
			<li><a <?php html_lettera("v",$lettera);?>>v</a></li>
			<li><a <?php html_lettera("w",$lettera);?>>w</a></li>
			<li><a <?php html_lettera("x",$lettera);?>>x</a></li>
			<li><a <?php html_lettera("y",$lettera);?>>y</a></li>
			<li><a <?php html_lettera("z",$lettera);?>>z</a></li>
		</ul>
	</div>

	<div class="cont-prodotti">

	<?php
		while ($wpquery->have_posts()): $wpquery->the_post();
	?>
		<div class="singolo-prodotto">
			<div class="img-prodotto"><?php the_post_thumbnail(); ?></div>
			<div class="spacer"></div>
			<div class="titolo-prodotto"><?php the_title(); ?></div>
			<div class="sottotitolo-prodotto"><?php echo get_field("active_ingredient"); ?></div>
			<div class="testo-prodotto"><?php the_content(); ?></div>
		</div>

	<?php
		endwhile; 
	?>

	</div>

<div class="header-prodotto clearfix">
	<?php paginazione(__("Page","pharma"), $wpquery->found_posts, $wpquery->query_vars['posts_per_page'],true); ?>
	<div class="conteggio-prodotti">
		<?php
			echo $wpquery->post_count." ";
			if ($wpquery->post_count > 1){echo __("products of","pharma");}
			else{echo __("product of","pharma");}
			echo " ".$wpquery->found_posts; ?>
	</div>
</div>

<?php 
	wp_reset_postdata();
	remove_filter( 'posts_search', 'search_by_title', 500 );

 

Esempio 2

Ecco ora un form che cerca sempre un custom post type in base a

  • testo digitato, intero e parola per parola da cercare nel titolo e/o sottotitolo (campo ACF) e/o nel testo del post stesso
  • per anno di pubblicazione tramite select con elenco anni
<form method="post" class="ricerca-sidebar">
	<div class='titolo-sidebar'><?php _e("Ricerca Massima","cameracivile"); ?></div>
	<input type="text" name="testo-ricerca">
	<button type="submit"><?php _e("Cerca","cameracivile"); ?></button>
</form>

<?php

	// imposto la query per cercare l'elenco degli anni e popolare la select
	$wpquery_anni = new WP_Query(array(
		'post_type' => "massimario",
		'numberposts' => -1,
		'posts_per_page' => -1,
		'orderby' => 'date',
		'order' => 'desc'
	));

	$array_anni = array();

	while ($wpquery_anni->have_posts()): $wpquery_anni->the_post();
		$post_id = get_the_ID();
		$anno = get_the_date( "Y", $post_id );
		array_push($array_anni, $anno);
	endwhile;

	$array_anni = array_unique($array_anni); // ottengo un array con l'elenco degli anni senza doppioni

	// mi preparo a creare la select
	if ( sizeof($array_anni) > 0 ){
		echo "<div class='titolo-sidebar'>".__("Archivio per anni","cameracivile")."</div>";
		echo "<form method='get' class='form-select'>";
		echo "<select name='anno' class='select2'>";

		foreach($array_anni as $anno){
				echo "<option value='{$anno}'>{$anno}</option>";
		}
		echo "</select><button type='submit'>".__("Cerca","cameracivile")."</button></form>";
	}

?>

<div class="contenitore clearfix">
	<?php
		// imposto la query

		$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

		$anno = sanitize_text_field( $_GET['anno'] ); // 
		$array_anno = array();

		if (isset($anno)){
			$array_anno["year"] = $anno;
		}

		global $testo_ricerca;
		global $array_ricerca_parole;
		$testo_ricerca = sanitize_text_field( $_POST['testo-ricerca'] );
		$array_ricerca_parole = explode(" ",$testo_ricerca);

		// imposto la query in caso di ricerca
		if ($testo_ricerca != ""){

			$postids = $wpdb->get_col($wpdb->prepare("
				SELECT      ID
				FROM        $wpdb->posts
				WHERE       $wpdb->posts.post_type = 'massimario' "));

			// join tra tabella post e postmeta
			function create_join_tables($join) {
				global $wp_query, $wpdb;

					$join .= "LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id ";

				return $join;
			}
			add_filter('posts_join', 'create_join_tables');

			// where conditions
			function posts_where( $where ) {
				global $wpdb;
				global $testo_ricerca;
				global $array_ricerca_parole;

				if ( sizeof($array_ricerca_parole) > 0 ){

					// ricerca intera stringa digitata
					$where .= " AND ( (";
					$where .= " $wpdb->posts.post_title LIKE '%%{$testo_ricerca}%%' OR ";
					$where .= " ($wpdb->postmeta.meta_key = 'sottotitolo_massima' AND $wpdb->postmeta.meta_value LIKE '%%{$testo_ricerca}%%') OR ";
					$where .= " ($wpdb->postmeta.meta_key = 'testo_massima' AND $wpdb->postmeta.meta_value LIKE '%%{$testo_ricerca}%%')";
					$where .= ") OR ((";

					// ricerca delle parole separate all'interno del titolo
					$condizioni_titolo = array();
					foreach($array_ricerca_parole as $parola){
						$condizioni_titolo[] = "$wpdb->posts.post_title LIKE '%%{$parola}%%'";
					}
					$where .= implode(' AND ', $condizioni_titolo);
					$where .= ") OR (";

					// ricerca delle parole separate all'interno del sottotitolo
					$condizioni_sottotitolo = array();
					foreach($array_ricerca_parole as $parola){
						$condizioni_sottotitolo[] = "($wpdb->postmeta.meta_key = 'sottotitolo_massima' AND $wpdb->postmeta.meta_value LIKE '%%{$parola}%%')";
					}
					$where .= implode(' AND ', $condizioni_sottotitolo);
					$where .= ") OR (";

					// ricerca delle parole separate all'interno del testo
					$condizioni_testo = array();
					foreach($array_ricerca_parole as $parola){
						$condizioni_testo[] = "($wpdb->postmeta.meta_key = 'testo_massima' AND $wpdb->postmeta.meta_value LIKE '%%{$parola}%%')";
					}
					$where .= implode(' AND ', $condizioni_testo);
					$where .= ")";

					$where .= " ) )";

					return $where;
				}
				return $where;
			}
			add_filter( 'posts_where' , 'posts_where' );

			// filtro risultati doppi
			function search_distinct() { return "DISTINCT"; }
			add_filter('posts_distinct', 'search_distinct');
		}

		// imposto la query
		$wpquery = new WP_Query(array(
			'post_type'      => "massimario",
			'posts_per_page' => 10,
			'paged' => $paged,
			'orderby' => 'date',
			'order' => 'desc',
			'date_query' => array($array_anno),
			'post__in' => $postids
		));

		while ($wpquery->have_posts()): $wpquery->the_post();

			$post_id = get_the_ID();

			$sottotitolo_massima = get_field("sottotitolo_massima",$post_id);
			$testo_massima = get_field("testo_massima",$post_id);

	?>
		<div class="singolo-evento clearfix">
			<div class="cont-data-evento">
				<div class="data-evento">
					<div class="giorno-evento"><?php echo get_the_date('d'); ?></div>
					<div class="mese-evento"><?php echo get_the_date('M'); ?></div>
					<div class="anno-evento"><?php echo get_the_date('Y'); ?></div>
				</div>
			</div>
			<div class="cont-dati-evento">
				<div class="titolo-evento"><?php echo get_the_title(); ?></div>

				<?php
					echo "<div class='sottotitolo-evento'>".$sottotitolo_massima."</div>";
				?>

				<div class="testo-evento">
					<?php
						echo $testo_massima;
					?>
				</div>
				<?php
						echo "<a class='link-go-to' href='".get_the_permalink()."'>".__("Leggi di più","cameracivile")."</a>";
				?>
			</div>
		</div>

	<?php
		endwhile;
	?>
	</div>

	<?php 
		paginazione(__("Vedi altri","qrpinternational"), $wpquery->found_posts, $wpquery->query_vars['posts_per_page'],true);
		wp_reset_postdata();
	?>
</div>


ESERCIZI

  1. Utilizzando parti del primo e del secondo esempio, definire un form di ricerca sul custom post type creato in precedenza, in modo che si possa cercare per anno di pubblicazione. Aggiungere al form un campo di input per immettere del testo che andrà cercato solo nel campo testo del post ed in un suo campo ACF da creare a piacimento. Infine aggiungere al form elenco delle lettere dell’alfabeto per cercare, al clic, i titoli dei post di quel custom post type che iniziano con quella lettera