Ich habe eine Funktion, die den "Gefällt mir" -Status eines Posts als Post-Meta speichert. Ich möchte dieses "Gefällt mir" mit dem Benutzer verknüpfen, dem es gefallen hat. Daher richte ich ein benutzerdefiniertes Feld mit dem Namen "like_status_ {user_id}" ein (wobei {user_id} die ID des derzeit angemeldeten Benutzers ist), das ich als 0 oder 0 speichere 1. Für einen Post mit mehreren "Likes" gäbe es also mehrere Meta-Werte in der Datenbank, die wie folgt eingerichtet sind:
'meta_key' = 'like_status_0'
'meta_value' = 1
'meta_key' = 'like_status_2'
'meta_value' = 1
'meta_key' = 'like_status_34'
'meta_value' = 1
....und so weiter.
Es gibt möglicherweise Tausende von Likes für einen bestimmten Beitrag. Wie würde ich eine Abfrage ausführen, die zeigt, ob jemand anderem dieser Beitrag gefällt?
Ich dachte so etwas:
$query = new WP_Query(array(
'meta_key' => 'like_status_{user_id}',
'meta_value' => 1,
));
Ich versuche, eine Benachrichtigung an alle zu senden, denen ein Beitrag gefallen hat, wenn jemand anderem dieser Beitrag gefällt ... so etwas wie "Hey, jemand anderem hat dieser Beitrag gefallen, den Sie gefallen haben. Sie sollten ihn sich ansehen!" Aber ich brauche einen Weg, um herauszufinden, ob jemandem dieser Beitrag gefallen hat und wenn ja, wer er wäre, könnte ich ihn benachrichtigen.
Wenn dies nicht möglich ist, können Sie eine bessere Methode zum Speichern dieser Daten als post_meta vorschlagen und gleichzeitig die Effizienz beibehalten, mit der der Status eines einzelnen Benutzers für einen Beitrag schnell aktualisiert werden kann?
Leider können Sie bei Verwendung von meta_query
keinen meta_key
mit einem LIKE
-Vergleich für den WP_Query
-Wert durchführen. Ich war auf diesem Weg ...
Stattdessen haben Sie einige andere Optionen, wenn Sie ähnliche Statusbeziehungen als Post-Meta und nicht als Benutzer-Meta und/oder Meta in einer benutzerdefinierten Tabelle beibehalten möchten.
wpdb
, um eine benutzerdefinierte Abfrage durchzuführenBeispiel:
//when a user likes a post...
$current_user_id = get_current_user_id();
add_post_meta($current_user_id, "like_status_{$current_user_id}", 1, false);
//later in the request...
global $wpdb;
$results = $wpdb->get_results(
"
SELECT meta_key
FROM {$wpdb->prefix}postmeta
WHERE meta_key
LIKE 'like_status_%'
",
ARRAY_N
);
$results = array_map(function($value){
return (int) str_replace('like_status_', '', $value[0]);
}, $results);
array_walk($results, function($notify_user_id, $key){
//apply to all users except the user who just liked the post
if ( $notify_user_id !== $current_user_id ) {
//notify logic here...
}
});
Hinweis: Die Logik kann auf Wunsch weiter vereinfacht werden.
WP_Query
zusammen mit meta_query
Option 2 erfordert, dass Sie Ihren Metaschlüssel von like_status_{user_id}
in einen universellen Schlüssel wie like_status
oder liked_by_user_id
ändern. Statt den Wert von 1
für den Schlüssel zu speichern, speichern Sie stattdessen die ID des Benutzers als Wert.
//when a user likes a post...
$current_user_id = get_current_user_id();
add_post_meta($current_user_id, "liked_by_user_id", $current_user_id, false);
//later in the request
$args = array(
'post_type' => 'post', //or a post type of your choosing
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'liked_by_user_id',
'value' => 0,
'type' => 'numeric'
'compare' => '>'
)
)
);
$query = new WP_Query($args);
array_walk($query->posts, function($post, $key){
$user_ids = get_post_meta($post->ID, 'liked_by_user_id');
array_walk($user_ids, function($notify_user_id, $key){
//notify all users except the user who just like the post
if ( $notify_user_id !== $current_user_id ) {
//notify logic here...
//get user e.g. $user = get_user_by('id', $notify_user_id);
}
});
});
Es ist ziemlich schwierig, Ihre Frage konkret zu beantworten. Der erste Teil ist jedoch einfach. Ich habe vor kurzem etwas gemacht ähnlich wie bei stackoverflow
Metaschlüssel werden verglichen und stimmen genau überein. WP_Query
hat keine Möglichkeit, dieses Verhalten mit einem einfachen Parameter anzupassen. Wir können uns jedoch jederzeit einen vorstellen und dann die posts_where
-Klausel anpassen, um einen LIKE
-Vergleich für Metaschlüssel durchzuführen.
Dies ist nur ein grundlegender Filter, passen Sie ihn nach Bedarf an.
add_filter( 'posts_where', function ( $where, \WP_Query $q )
{
// Check for our custom query var
if ( true !== $q->get( 'wildcard_on_key' ) )
return $where;
// Lets filter the clause
$where = str_replace( 'meta_key =', 'meta_key LIKE', $where );
return $where;
}, 10, 2 );
Wie Sie sehen, wird der Filter nur ausgelöst, wenn wir unseren neuen benutzerdefinierten Parameter wildcard_on_key
auf true
setzen. Wenn dies auscheckt, ändern wir einfach den =
-Komparator in den LIKE
-Komparator
Nur eine Anmerkung dazu: LIKE
Vergleiche sind von Natur aus teurer als andere Vergleiche
Sie können Ihre Beiträge einfach wie folgt abfragen, um alle Beiträge mit Metaschlüsseln zu erhalten. like_status_{user_id}
$args = [
'wildcard_on_key' => true,
'meta_query' => [
[
'key' => 'like_status_',
'value' => 1,
]
]
];
$query = new WP_Query( $args );
Benutzerdefinierte Felder haben keinen Einfluss auf die Leistung. Sie können meinen Beitrag zu diesem Thema lesen hier . Ich bin jedoch beunruhigt darüber, dass Sie sagen, dass jeder Beitrag Hunderte oder Tausende von Likes haben kann. Dies kann sich negativ auf das Abrufen und Zwischenspeichern einer so großen Menge benutzerdefinierter Felddaten auswirken. Es kann auch Ihre Datenbank mit einer großen Menge an unnötigen benutzerdefinierten Felddaten verstopfen, was die Wartung ziemlich schwierig macht.
Ich bin kein großer Fan von Speichern serialisierter Daten in benutzerdefinierten Feldern, da nach serialisierten Daten nicht gesucht oder bestellt werden kann. Ich würde jedoch vorschlagen, alle Benutzer-IDs in einem Array unter einem benutzerdefinierten Feld zu speichern. Sie können das Array einfach mit der Benutzer-ID aktualisieren, wenn ein Benutzer einen Beitrag mag. Das Abrufen der benutzerdefinierten Felddaten und das Durchlaufen des Arrays von IDs und das Ausführen von Aktionen mit den IDs sind einfach. Schauen Sie sich einfach get_post_meta()
an.
Das Aktualisieren eines benutzerdefinierten Felds ist ebenfalls einfach. Dazu müssen Sie sich mit update_post_meta()
befassen. Ich weiß nicht, wie Sie Ihre benutzerdefinierten Felder erstellen, aber update_post_meta()
ist definitiv etwas, das Sie verwenden möchten.
Wenn Sie E-Mails oder Push-Benachrichtigungen senden müssen, wenn ein benutzerdefiniertes Feld aktualisiert wird, können Sie mit den folgenden Hooks arbeiten. ( Siehe update_metadata()
für den Kontext )
Bevor ich dies wieder veröffentliche, stellen Sie sicher, dass Sie nicht nach den sortierten Daten sortieren oder nach bestimmten Daten in den serialisierten Daten suchen müssen, bevor Sie die serialisierte Route gehen.
Wenn Sie dies später mit detaillierteren Statistiken, Funktionen usw. erweitern möchten, könnte eine weitere Alternative sein: benutzerdefinierte Tabelle (n)
Profis : Auf Ihre Bedürfnisse zugeschnitten und können indexiert werden, um eine bessere Leistung zu erzielen.
cons : Mehr Arbeit
Möglicherweise gibt es auch eine Problemumgehung mit einer benutzerdefinierten Taxonomie, die aufgrund der Indizierung der Kerntabellen eine bessere Abfrageleistung bietet als Post-Meta-Abfragen.
Ich versuche, eine Benachrichtigung an alle zu senden, denen ein Beitrag gefallen hat, wenn jemand anderem dieser Beitrag gefällt ... so etwas wie "Hey, jemand anderem hat dieser Beitrag gefallen, den Sie gefallen haben. Sie sollten ihn sich ansehen!" Aber ich brauche einen Weg, um herauszufinden, ob jemandem dieser Beitrag gefallen hat und wenn ja, wer er wäre, könnte ich ihn benachrichtigen.
Nicht sicher, welche Art von Benachrichtigungen Sie hier meinen, aber dies kann schnell unhandlich werden.
Beispiel : Ein Benutzer, der ~ 1000 Posts mag und jeder Post ~ 1000 Likes bekommt, dann gibt es 1 Million Benachrichtigungen in den Pipes, nur für diesen Benutzer! Wenn dies E-Mail-Benachrichtigungen sind, ist der Host-Anbieter möglicherweise nicht zufrieden und der Benutzer wird verrückt. Dies kann auch bei einem E-Mail-Dienst eines Drittanbieters teuer sein.
Seit WordPress 5.1 ist es nun möglich, Meta-Abfragen wie die folgenden zu verwenden:
In der WP_Meta_Query Dokumentation können Sie das Argument compare
im Argument meta_query
von WP_Query verwenden. Sie können jedoch nur die value
und nicht die key
vergleichen, sodass Sie möglicherweise überdenken möchten, wie Sie dies strukturieren.
Ein like
Argument würde so aussehen:
$arguments = array(
'meta_query' => array(
array(
'key' => 'foo',
'value' => 'ba',
'compare' => 'LIKE'
)
)
);
$query = new WP_Query($arguments);
Da Sie in der key
keine 'LIKE'-Suche durchführen können, empfehlen wir Ihnen, die gewünschten Beiträge in das Benutzer-Meta aufzunehmen und eine WP_User_Query -Suche nach Benutzern durchzuführen, denen dieser Beitrag gefallen hat:
$arguments = array(
'meta_query' => array(
array(
'key' => 'liked_post',
'value' => '<post_id>'
)
)
);
$users = new WP_User_Query($arguments);