Hintergrund
Ich verwende Advanced Custom Fields Pro, um meine benutzerdefinierten Felder zu verwalten, und sie haben ein “Wiederholungsfeld”, das Unterfelder enthält, die als gespeichert werden repeatername_X_fieldname
wobei X die Zeilennummer des Repeaters ist.
Ich habe einen benutzerdefinierten Beitragstyp student
das hat den Repeater attendance
was beinhaltet date
und class
.
Wenn also ein Schüler an einer Klasse teilnimmt, wird seine Anwesenheit wie folgt gespeichert
- meta_key:’Anwesenheit_X_Datum’ meta_wert:’20170701′
- meta_key:’Anwesenheit_X_Klasse’ meta_wert:’Geschichte 101′
Um nach Schülern zu suchen, die an einem bestimmten Kurs teilgenommen oder innerhalb eines bestimmten Datumsbereichs teilgenommen haben, muss ich mich einklinken get_meta_sql
und konvertieren Sie meine meta_query
benutzen LIKE
Anstatt von =
wenn der Wert enthält %
function key_rewrite($parts){
foreach($parts as &$part){
$part = preg_replace("/(meta_key = )(\'[^']*[%][^']*\')/", "meta_key LIKE $2", $part);
}
return $parts;
}
add_action( 'get_meta_sql', 'key_rewrite');
Damit kann ich so etwas machen
$args = array(
'post_type' => 'student',
'meta_query' => array(
array(
'key'=>'attendance_%_class',
'compare'=>'=',
'value'=>'History 101'
)
)
);
$my_query = new WP_Query($args);
um nach Personen zu suchen, die an History 101 OR teilgenommen haben
$args = array(
'post_type' => 'student',
'meta_query' => array(
array(
'key'=>'attendance_%_date',
'compare'=>'>=',
'value'=>'20170101'
)
)
);
Um nach allen zu suchen, die dieses Jahr teilgenommen haben.
Problemteil 1
Ich muss in der Lage sein, nach jedem zu suchen, der dieses Jahr an „History 101“ teilgenommen hat.
Zunächst scheint es, als würde ein einfaches AND auf der meta_query ausreichen:
$args = array(
'post_type' => 'student',
'meta_query' => array(
'relation' => 'AND',
array(
'key'=>'attendance_%_class',
'compare'=>'=',
'value'=>'History 101'
),
array(
'key'=>'attendance_%_date',
'compare'=>'>=',
'value'=>'20170101'
)
)
);
Da die Wildcards jedoch nicht verknüpft sind, könnte dies tatsächlich jemanden zurückgeben, der letztes Jahr „Geschichte 101“ besucht hat, aber dieses Jahr eine andere Klasse.
Problemteil 2
ich eigentlich müssen in der Lage sein, eine Liste von allen zu bekommen, die dieses Jahr an „Geschichte 101“ teilgenommen haben, aber in der vergangenen Woche überhaupt nicht zum Unterricht erschienen sind. Dies verkompliziert das Problem weiter, da ich meta_query’s kombinieren muss EXISTS
und NOT EXISTS
mit einer zusätzlichen Bedingung. Oberflächlich betrachtet klingt dies mit verschachtelten meta_queries recht einfach:
$args = array(
'post_type' => 'student',
'meta_query' => array(
'relation' => 'AND',
array(
'relation' => 'AND',
array(
//Just assume by some magic we resolved Problem part 1
'key'=>'attendance_%_class',
'compare'=>'=',
'value'=>'History 101'
),
array(
'key'=>'attendance_%_date',
'compare'=>'>=',
'value'=>'20170101'
)
),
array(
'relation' => 'AND',
array(
//again... magic!
'key'=>'attendance_%_class',
'compare'=>'=',
'value'=>'History 101'
),
array(
'key'=>'attendance_%_date',
'compare'=>'>',
'value'=>'20170821'
),
array(
'key'=>'attendance_%_date',
'compare'=>'NOT EXISTS'
)
)
)
);
Offensichtlich ist dies mit logischen Problemen verbunden, aber beeindruckenderweise löst WordPress die meisten davon, indem es die Postmeta-Tabelle einmal pro Verwendung in die Metaabfrage einfügt. Leider bedeutet das, dass der > Datumsteil in der nicht verwendet wird NOT EXISTS
ON
und kann die somit nicht nutzen IS NULL
zum Testen nicht vorhanden.
Ich verstehe, dass dies sehr komplex war, und wenn Sie mir gefolgt sind, bin ich sehr beeindruckt. Wenn nicht, stellen Sie bitte Fragen, damit ich bei der Klärung helfen kann.
Ja, mir ist bewusst, dass ich meine eigene Abfrage einfach komplett schreiben könnte, aber ich versuche, mich an die eingebauten WordPress-Tools zu halten.
HILFE!