Ich möchte ein WooCommerce-Plugin erstellen, um einige Angebote für Kunden hinzuzufügen (die eine Kaufhistorie haben).
Wie kann ich überprüfen, ob ein Benutzer zuvor etwas gekauft hat?
Danke.
Mosi
Ich möchte ein WooCommerce-Plugin erstellen, um einige Angebote für Kunden hinzuzufügen (die eine Kaufhistorie haben).
Wie kann ich überprüfen, ob ein Benutzer zuvor etwas gekauft hat?
Danke.
LoicTheAztec
AKTUALISIERUNG 2021 – Handhabung Gäste “Rechnungs-E-Mail” – Verbesserte und gesicherte SQL-Abfrage
Hier ist ein viel Licht und schnellere bedingte Funktion das wird wahr zurückgeben, wenn ein Kunde bereits einen Kauf getätigt hat.
Es behandelt registrierte Benutzer als Gast von ihrer Benutzer-ID und Gäste von ihrer Rechnungs-E-Mail:
Dadurch leichter und verbesserte Funktion (teilweise basierend auf wc_customer_bought_product()
Funktionsquellcode) gibt einen booleschen Wert basierend auf der Anzahl der Bestellungen zurück (falsch für O-Bestellungen und wahr, wenn es mindestens eine bezahlte Bestellung gibt):
function has_bought( $value = 0 ) {
if ( ! is_user_logged_in() && $value === 0 ) {
return false;
}
global $wpdb;
// Based on user ID (registered users)
if ( is_numeric( $value) ) {
$meta_key = '_customer_user';
$meta_value = $value == 0 ? (int) get_current_user_id() : (int) $value;
}
// Based on billing email (Guest users)
else {
$meta_key = '_billing_email';
$meta_value = sanitize_email( $value );
}
$paid_order_statuses = array_map( 'esc_sql', wc_get_is_paid_statuses() );
$count = $wpdb->get_var( $wpdb->prepare("
SELECT COUNT(p.ID) FROM {$wpdb->prefix}posts AS p
INNER JOIN {$wpdb->prefix}postmeta AS pm ON p.ID = pm.post_id
WHERE p.post_status IN ( 'wc-" . implode( "','wc-", $paid_order_statuses ) . "' )
AND p.post_type LIKE 'shop_order'
AND pm.meta_key = '%s'
AND pm.meta_value = %s
LIMIT 1
", $meta_key, $meta_value ) );
// Return a boolean value based on orders count
return $count > 0;
}
Code geht in die functions.php-Datei Ihres aktiven Child-Themes (oder Themes) oder auch in jede Plugin-Datei.
Dieser Code wurde auf Woocommerce 3+ getestet und funktioniert (er sollte auch auf früheren Versionen funktionieren).
Für mehrere Produkte: Überprüfen Sie, ob ein Benutzer bestimmte Produkte in WooCommerce gekauft hat
Anwendungsbeispiel 1 (eingeloggter Kunde)
if( has_bought() )
echo '<p>You have already made a purchase</p>';
else
echo '<p>Welcome, for your first purchase you will get a discount of 10%</p>';
Anwendungsbeispiel 2 (Einstellen der Benutzer-ID)
// Define the user ID
$user_id = 85;
if( has_bought( $user_id ) )
echo '<p>customer have already made a purchase</p>';
else
echo '<p>Customer with 0 purchases</p>';
Wenn die $user_id
nicht definiert ist und der aktuelle Benutzer nicht angemeldet ist, wird diese Funktion zurückgegeben false
.
Anwendungsbeispiel 3 – Für Gäste (Einstellung der Rechnungs-E-Mail)
// Define the billing email (string)
$email="[email protected]";
if( has_bought( $email ) )
echo '<p>customer have already made a purchase</p>';
else
echo '<p>Customer with 0 purchases</p>'
Der Code dieser Funktion basiert teilweise auf der eingebauten WooCommerce-Funktion
wc_customer_bought_product()
Quellcode.
Gedanken darüber, wie man das in einen Shortcode umwandelt, damit ich Inhalte damit verpacken kann?
– Garconis
13. Dezember 2017 um 14:48 Uhr
Ja, das geht ganz einfach mit einem kurzen Code … Welche Spezifikationen benötigen Sie? (Wenn Sie möchten/möchten, können Sie diese nützliche Antwort positiv bewerten)…
– LoicTheAztec
13. Dezember 2017 um 16:18 Uhr
LoicTheAztec
Aktualisierung 2020: Neue aktualisierte, verbesserte, leichtere und schnellere Version HIER die auch Gäste von Rechnungs-E-Mails behandeln
Ja, es ist möglich ein … Erstellen bedingte Funktion, die zurückkehrt
true
Wenn ein Kunde hat bereits mindestens eine Bestellung mit Status abgeschlossen.
Hier ist der Code für diese bedingte Funktion:
function has_bought() {
// Get all customer orders
$customer_orders = get_posts( array(
'numberposts' => 1, // one order is enough
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => 'shop_order', // WC orders post type
'post_status' => 'wc-completed', // Only orders with "completed" status
'fields' => 'ids', // Return Ids "completed"
) );
// return "true" when customer has already at least one order (false if not)
return count($customer_orders) > 0 ? true : false;
}
Dieser Code ist getestet und funktioniert.
Dieser Code wird in die function.php-Datei Ihres aktiven untergeordneten Designs oder Designs oder in eine Plugin-PHP-Datei eingefügt.
VERWENDUNGSZWECK (als Bedingung):
Verweise
Gibt es eine Möglichkeit, das Datum des letzten Einkaufs gleichzeitig anzuzeigen/zurückzugeben?
– Rodrigo M
13. August 2016 um 16:20 Uhr
@RodrigoM Gibt true zurück, wenn ein Kunde auf einmal erfolgreich gekauft hat
– LoicTheAztec
13. August 2016 um 16:32 Uhr
die Funktion hat sehr geholfen. Derzeit muss ich prüfen, ob der Kunde bereits einen Kauf getätigt hat. Wenn nicht, möchte ich einen Rabatt gewähren, wie ändere ich den aktuellen Wert des Kaufs? (Diese Funktion wird bei Kaufbestätigung / Warenkorb aufgerufen)
– Rafa Acioly
29. August 2016 um 20:21 Uhr
Warum fragen wir ALLE Bestellungen ab, brauchen wir nicht nur 'numberposts' => 1,
?
– Philipp F
23. Juli 2020 um 3:26 Uhr
@LoicTheAztec Wie verwende ich diese Funktion auf der Checkout-Seite?
– BInjal Patel
27. August 2020 um 9:10 Uhr
Rakesh Roy
Wenn Guest Checking aktiviert ist, kann diese Funktion hilfreich sein
Einfach senden $customer_email Als Argument und Funktion werden alle Bestellungen für diese E-Mail überprüft und wahr oder falsch zurückgegeben.
function has_bought($customer_email){
$orders = get_posts(array(
'numberposts' => -1,
'post_type' => 'shop_order',
'post_status' => array('wc-processing', 'wc-completed'),
));
$email_array = array();
foreach($orders as $order) {
$order_obj = wc_get_order($order->ID);
$order_obj_data = $order_obj->get_data();
array_push($email_array, $order_obj_data['billing']['email']);
}
if (in_array($customer_email, $email_array)) {
return true;
} else {
return false;
}
}
Jeff Monteiro
Ausgehend von der vereinfachten Version von @Antonio Novak habe ich einige Verbesserungen vorgenommen, um alle möglichen Bestellstatus abzudecken, die anzeigen würden, dass der Benutzer bereits gekauft hat.
Die Statusliste
Der WooCommerce bietet eine detaillierte Dokumentation über den Status. Hör zu: https://docs.woocommerce.com/document/managing-orders/
Aber hier übertrage ich die Liste mit den Slugs:
$order_statuses = array(
'wc-pending' => _x( 'Pending payment', 'Order status', 'woocommerce' ),
'wc-processing' => _x( 'Processing', 'Order status', 'woocommerce' ),
'wc-on-hold' => _x( 'On hold', 'Order status', 'woocommerce' ),
'wc-completed' => _x( 'Completed', 'Order status', 'woocommerce' ),
'wc-cancelled' => _x( 'Cancelled', 'Order status', 'woocommerce' ),
'wc-refunded' => _x( 'Refunded', 'Order status', 'woocommerce' ),
'wc-failed' => _x( 'Failed', 'Order status', 'woocommerce' ),
);
Außerdem habe ich beschlossen, den WC-Shipping-Status hinzuzufügen. Ist natürlich ein benutzerdefinierter Status, wird aber normalerweise vom E-Commerce verwendet, oder?
Anstatt mich zu fragen, ob der Benutzer bereits gekauft hat, in der Annahme, dass das größte Interesse darin besteht, mehr Anreize zu bieten, um einen neuen Benutzer zu gewinnen, habe ich mir erlaubt, die Frage und auch die Antwort der Funktion umzukehren.
Bei Verwendung der vorgeschlagenen Funktion ist die Rückgabe wahr, wenn es um den ersten Einkauf des Benutzers geht, und falsch, wenn er bereits eine Bestellung in den in der Abfrage aufgeführten Status hat.
Außerdem habe ich den Benutzer-ID-Parameter optional gemacht, sodass die Funktion in mehreren Fällen wiederverwendet werden kann, und nicht nur in einer Benutzersitzung.
Die Funktion
function is_the_first_purchase( $user_id = 0) {
if( $user_id == 0 ){
$user_id = get_current_user_id();
}
if( ! $user_id ){
return true;
}
$customer_orders = get_posts( array(
'numberposts' => -1,
'post_type' => 'shop_order',
'post_status' => array(
'wc-completed',
'wc-on-hold',
'wc-processing',
'wc-shipped',
'wc-refunded'
),
'meta_query' => array(
array(
'key' => '_customer_user',
'meta_value' => $user_id,
)
)
));
// return "true" when customer
// does not have an completed order
return count( $customer_orders ) > 0 ? false : true;
}
Vereinfachte Version:
function has_bought() {
// Get all customer orders
$customer_orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => 'shop_order', // WC orders post type
'post_status' => 'wc-completed' // Only orders with status "completed"
) );
// return "true" when customer has already one order
return count( $customer_orders ) > 0 ? true : false;
}
Matt Loye
Erweiterte Version mit bezahltem Status oder nur Status-agnostischer Abfrage, auch verbesserte Bitcode-Eingabe für PHP 5.4+:
function has_bought(int $user_id = 0, bool $paid = true ) {
global $wpdb;
$user_id = (empty($user_id)) ? get_current_user_id() : $user_id;
$sql_str = "
SELECT p.ID FROM ".$wpdb->posts." AS p
INNER JOIN
".$wpdb->postmeta." AS pm ON p.ID = pm.post_id
WHERE
p.post_type LIKE 'shop_order'
AND pm.meta_key = '_customer_user'
AND pm.meta_value = %d
";
$args = [(int) $user_id];
if ($paid === true) {
$paid_order_statuses = array_map( 'esc_sql', wc_get_is_paid_statuses() );
$sql_str .= "AND p.post_status IN ( 'wc-" . implode( "','wc-", $paid_order_statuses ) . "' )";
}
$sql = $wpdb->prepare($sql_str, $args);
return (bool) $wpdb->get_var( $sql );
}
frafor
Version mit Cache-Layer (mit transientem API-Schlüssel, eine Woche lang). Nicht angemeldeter Benutzer gibt false zurück.
function has_bought() {
if(!is_user_logged_in()) return false;
$transient="has_bought_".get_current_user_id();
$has_bought = get_transient($transient);
if(!$has_bought) {
// Get all customer orders
$customer_orders = get_posts( array(
'numberposts' => 1, // one order is enough
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => 'shop_order', // WC orders post type
'post_status' => 'wc-completed', // Only orders with "completed" status
'fields' => 'ids', // Return Ids "completed"
) );
$has_bought = count($customer_orders) > 0 ? true : false;
set_transient($transient, $has_bought, WEEK_IN_SECONDS);
}
// return "true" when customer has already at least one order (false if not)
return $has_bought;
}