Add support for custom single product page fields

This commit is contained in:
Pedro Silva 2023-08-09 17:50:03 +01:00
parent 02de8ada7f
commit 7baee26194
No known key found for this signature in database
GPG key ID: E2EE20C0669D24B3
5 changed files with 50 additions and 12 deletions

View file

@ -73,7 +73,7 @@ class SingleProductActionHandler {
getSubscriptionProducts() getSubscriptionProducts()
{ {
const id = document.querySelector('[name="add-to-cart"]').value; const id = document.querySelector('[name="add-to-cart"]').value;
return [new Product(id, 1, null)]; return [new Product(id, 1, null, this.extraFields())];
} }
configuration() configuration()
@ -107,7 +107,7 @@ class SingleProductActionHandler {
{ {
if ( this.isBookingProduct() ) { if ( this.isBookingProduct() ) {
const id = document.querySelector('[name="add-to-cart"]').value; const id = document.querySelector('[name="add-to-cart"]').value;
return [new BookingProduct(id, 1, FormHelper.getPrefixedFields(this.formElement, "wc_bookings_field"))]; return [new BookingProduct(id, 1, FormHelper.getPrefixedFields(this.formElement, "wc_bookings_field"), this.extraFields())];
} else if ( this.isGroupedProduct() ) { } else if ( this.isGroupedProduct() ) {
const products = []; const products = [];
this.formElement.querySelectorAll('input[type="number"]').forEach((element) => { this.formElement.querySelectorAll('input[type="number"]').forEach((element) => {
@ -120,17 +120,25 @@ class SingleProductActionHandler {
} }
const id = parseInt(elementName[1]); const id = parseInt(elementName[1]);
const quantity = parseInt(element.value); const quantity = parseInt(element.value);
products.push(new Product(id, quantity, null)); products.push(new Product(id, quantity, null, this.extraFields()));
}) })
return products; return products;
} else { } else {
const id = document.querySelector('[name="add-to-cart"]').value; const id = document.querySelector('[name="add-to-cart"]').value;
const qty = document.querySelector('[name="quantity"]').value; const qty = document.querySelector('[name="quantity"]').value;
const variations = this.variations(); const variations = this.variations();
return [new Product(id, qty, variations)]; return [new Product(id, qty, variations, this.extraFields())];
} }
} }
extraFields() {
return FormHelper.getFilteredFields(
this.formElement,
['add-to-cart', 'quantity', 'product_id', 'variation_id'],
['attribute_', 'wc_bookings_field']
);
}
createOrder() createOrder()
{ {
this.cartHelper = null; this.cartHelper = null;

View file

@ -2,15 +2,17 @@ import Product from "./Product";
class BookingProduct extends Product { class BookingProduct extends Product {
constructor(id, quantity, booking) { constructor(id, quantity, booking, extra) {
super(id, quantity, null); super(id, quantity, null);
this.booking = booking; this.booking = booking;
this.extra = extra;
} }
data() { data() {
return { return {
...super.data(), ...super.data(),
booking: this.booking booking: this.booking,
extra: this.extra
} }
} }
} }

View file

@ -1,16 +1,17 @@
class Product { class Product {
constructor(id, quantity, variations) { constructor(id, quantity, variations, extra) {
this.id = id; this.id = id;
this.quantity = quantity; this.quantity = quantity;
this.variations = variations; this.variations = variations;
this.extra = extra;
} }
data() { data() {
return { return {
id:this.id, id:this.id,
quantity:this.quantity, quantity: this.quantity,
variations:this.variations variations: this.variations,
extra: this.extra,
} }
} }
} }

View file

@ -7,11 +7,29 @@ export default class FormHelper {
static getPrefixedFields(formElement, prefix) { static getPrefixedFields(formElement, prefix) {
let fields = {}; let fields = {};
for(const element of formElement.elements) { for(const element of formElement.elements) {
if( element.name.startsWith(prefix) ) { if( ( ! prefix ) || element.name.startsWith(prefix) ) {
fields[element.name] = element.value; fields[element.name] = element.value;
} }
} }
return fields; return fields;
} }
static getFilteredFields(formElement, exactFilters, prefixFilters) {
let fields = {};
for(const element of formElement.elements) {
if (!element.name) {
continue;
}
if (exactFilters && (exactFilters.indexOf(element.name) !== -1)) {
continue;
}
if (prefixFilters && prefixFilters.some(prefixFilter => element.name.startsWith(prefixFilter))) {
continue;
}
fields[element.name] = element.value;
}
return fields;
}
} }

View file

@ -112,6 +112,14 @@ abstract class AbstractCartEndpoint implements EndpointInterface {
$success = true; $success = true;
foreach ( $products as $product ) { foreach ( $products as $product ) {
// Add extras to POST, they are usually added by custom plugins.
if ( $product['extra'] && is_array( $product['extra'] ) ) {
foreach ( $product['extra'] as $key => $value ) {
$_POST[ $key ] = $value;
}
}
if ( $product['product']->is_type( 'booking' ) ) { if ( $product['product']->is_type( 'booking' ) ) {
$success = $success && $this->add_booking_product( $success = $success && $this->add_booking_product(
$product['product'], $product['product'],
@ -229,6 +237,7 @@ abstract class AbstractCartEndpoint implements EndpointInterface {
'quantity' => (int) $product['quantity'], 'quantity' => (int) $product['quantity'],
'variations' => $product['variations'] ?? null, 'variations' => $product['variations'] ?? null,
'booking' => $product['booking'] ?? null, 'booking' => $product['booking'] ?? null,
'extra' => $product['extra'] ?? null,
); );
} }
return $products; return $products;