| |
| <?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function wpforms_inventory_get_config() {
|
| return [
|
| 123 => [ 6 ],
|
| ];
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function wpforms_inventory_get_counter_config() {
|
| return [
|
| 123 => 8,
|
| ];
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function wpforms_inventory_get_units_sold( $form_id, array $field_ids ) {
|
|
|
| $units_sold = 0;
|
|
|
| $entries = wpforms()->obj( 'entry' )->get_entries(
|
| [
|
| 'form_id' => $form_id,
|
| 'status' => [ 'not_in' => [ 'abandoned', 'partial' ] ],
|
| ]
|
| );
|
|
|
| if ( empty( $entries ) || ! is_array( $entries ) ) {
|
| return 0;
|
| }
|
|
|
| foreach ( $entries as $entry ) {
|
| $fields = ! empty( $entry->fields ) ? json_decode( $entry->fields, true ) : [];
|
|
|
| if ( empty( $fields ) || ! is_array( $fields ) ) {
|
| continue;
|
| }
|
|
|
| foreach ( $field_ids as $field_id ) {
|
| if ( ! isset( $fields[ $field_id ] ) ) {
|
| continue;
|
| }
|
|
|
|
|
|
|
| $quantity = isset( $fields[ $field_id ]['quantity'] )
|
| ? absint( $fields[ $field_id ]['quantity'] )
|
| : 1;
|
|
|
| $units_sold += $quantity;
|
| }
|
| }
|
|
|
| return $units_sold;
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function wpforms_inventory_get_stock_limit( $form_id ) {
|
|
|
| $form = wpforms()->obj( 'form' )->get( $form_id );
|
|
|
| if ( empty( $form ) ) {
|
| return 0;
|
| }
|
|
|
| $settings = wpforms_decode( $form->post_content );
|
|
|
| if (
|
| empty( $settings['settings']['form_locker_entry_limit_enable'] ) ||
|
| empty( $settings['settings']['form_locker_entry_limit'] )
|
| ) {
|
| return 0;
|
| }
|
|
|
| return absint( $settings['settings']['form_locker_entry_limit'] );
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function wpforms_inventory_get_units_available( $form_id, array $field_ids ) {
|
|
|
| $stock_limit = wpforms_inventory_get_stock_limit( $form_id );
|
|
|
| if ( $stock_limit <= 0 ) {
|
| return 0;
|
| }
|
|
|
| $units_sold = wpforms_inventory_get_units_sold( $form_id, $field_ids );
|
|
|
| return max( 0, $stock_limit - $units_sold );
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function wpforms_inventory_get_sold_out_message( $form_id ) {
|
|
|
| $form = wpforms()->obj( 'form' )->get( $form_id );
|
|
|
| if ( empty( $form ) ) {
|
| return '';
|
| }
|
|
|
| $settings = wpforms_decode( $form->post_content );
|
| $message = $settings['settings']['form_locker_entry_limit_message'] ?? '';
|
|
|
| if ( empty( $message ) ) {
|
| $message = __( 'Sorry, this item is sold out.', 'wpforms-lite' );
|
| }
|
|
|
| return $message;
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function wpforms_inventory_block_overpurchase( $errors, $form_data ) {
|
|
|
| $config = wpforms_inventory_get_config();
|
| $form_id = absint( $form_data['id'] );
|
|
|
| if ( ! isset( $config[ $form_id ] ) ) {
|
| return $errors;
|
| }
|
|
|
| $field_ids = $config[ $form_id ];
|
| $available = wpforms_inventory_get_units_available( $form_id, $field_ids );
|
|
|
| $requested = 0;
|
|
|
| foreach ( $field_ids as $field_id ) {
|
|
|
| $qty = isset( $_POST['wpforms']['quantities'][ $field_id ] )
|
| ? absint( $_POST['wpforms']['quantities'][ $field_id ] )
|
| : 0;
|
|
|
| $requested += $qty;
|
| }
|
|
|
| if ( $requested <= 0 ) {
|
| return $errors;
|
| }
|
|
|
| if ( $available <= 0 ) {
|
| $errors[ $form_id ]['form_locker'] = 'entry_limit';
|
| $errors[ $form_id ]['header'] = wpforms_inventory_get_sold_out_message( $form_id );
|
|
|
| return $errors;
|
| }
|
|
|
| if ( $requested > $available ) {
|
| foreach ( $field_ids as $field_id ) {
|
| $errors[ $form_id ][ $field_id ] = sprintf(
|
|
|
| _n(
|
| 'Only %d unit is available. Please reduce your quantity.',
|
| 'Only %d units are available. Please reduce your quantity.',
|
| $available,
|
| 'wpforms-lite'
|
| ),
|
| $available
|
| );
|
| }
|
| }
|
|
|
| return $errors;
|
| }
|
|
|
| add_filter( 'wpforms_process_initial_errors', 'wpforms_inventory_block_overpurchase', 20, 2 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function wpforms_inventory_lock_frontend( $load_form, $form_data ) {
|
|
|
| $config = wpforms_inventory_get_config();
|
| $form_id = absint( $form_data['id'] );
|
|
|
| if ( ! isset( $config[ $form_id ] ) ) {
|
| return $load_form;
|
| }
|
|
|
| $field_ids = $config[ $form_id ];
|
| $available = wpforms_inventory_get_units_available( $form_id, $field_ids );
|
|
|
| if ( $available > 0 ) {
|
| return $load_form;
|
| }
|
|
|
| add_action(
|
| 'wpforms_frontend_not_loaded',
|
| function () use ( $form_id ) {
|
| $message = wpforms_inventory_get_sold_out_message( $form_id );
|
|
|
| if ( ! $message ) {
|
| return;
|
| }
|
|
|
| echo '<div class="wpforms-container">';
|
| echo '<div class="form-locked-message">';
|
| echo wp_kses_post( wpautop( $message ) );
|
| echo '</div>';
|
| echo '</div>';
|
| },
|
| 10
|
| );
|
|
|
| return false;
|
| }
|
|
|
| add_filter( 'wpforms_frontend_load', 'wpforms_inventory_lock_frontend', 20, 2 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function wpforms_inventory_inject_counter( $field, $form_data ) {
|
|
|
| $config = wpforms_inventory_get_config();
|
| $counter_config = wpforms_inventory_get_counter_config();
|
| $form_id = absint( $form_data['id'] );
|
| $field_id = absint( $field['id'] );
|
|
|
| if (
|
| ! isset( $counter_config[ $form_id ] ) ||
|
| (int) $counter_config[ $form_id ] !== $field_id
|
| ) {
|
| return $field;
|
| }
|
|
|
| if ( $field['type'] !== 'html' ) {
|
| return $field;
|
| }
|
|
|
| if ( ! isset( $config[ $form_id ] ) ) {
|
| return $field;
|
| }
|
|
|
| $quantity_field_ids = $config[ $form_id ];
|
| $stock_limit = wpforms_inventory_get_stock_limit( $form_id );
|
| $available = wpforms_inventory_get_units_available( $form_id, $quantity_field_ids );
|
|
|
| if ( $available > 0 ) {
|
| $counter_html = sprintf(
|
| '<p class="wpforms-inventory-counter"><strong>%s</strong></p>',
|
| sprintf(
|
|
|
| esc_html__( 'Available: %1$d of %2$d', 'wpforms-lite' ),
|
| $available,
|
| $stock_limit
|
| )
|
| );
|
| } else {
|
| $counter_html = sprintf(
|
| '<p class="wpforms-inventory-counter wpforms-inventory-sold-out"><strong>%s</strong></p>',
|
| wp_strip_all_tags( wpforms_inventory_get_sold_out_message( $form_id ) )
|
| );
|
| }
|
|
|
| $field['code'] = $counter_html;
|
|
|
| return $field;
|
| }
|
|
|
| add_filter( 'wpforms_field_data', 'wpforms_inventory_inject_counter', 10, 2 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function wpforms_inventory_realtime_validation() {
|
|
|
| $config = wpforms_inventory_get_config();
|
| $js_config = [];
|
|
|
| foreach ( $config as $form_id => $field_ids ) {
|
| $available = wpforms_inventory_get_units_available( $form_id, $field_ids );
|
|
|
| foreach ( $field_ids as $field_id ) {
|
| $js_config[ $form_id ][ $field_id ] = $available;
|
| }
|
| }
|
|
|
| if ( empty( $js_config ) ) {
|
| return;
|
| }
|
|
|
| ?>
|
| <script type="text/javascript">
|
| ( function( $ ) {
|
|
|
| var wpformsInventory = <?php echo wp_json_encode( $js_config ); ?>;
|
|
|
| $( document ).on( 'wpformsReady', function() {
|
|
|
| if ( typeof $.fn.validate === 'undefined' ) {
|
| return;
|
| }
|
|
|
|
|
|
|
|
|
| $.validator.addMethod(
|
| 'inventory_limit',
|
| function( value, element, param ) {
|
| return this.optional( element ) || parseInt( value, 10 ) <= param;
|
| },
|
| function( param ) {
|
| if ( param === 1 ) {
|
| return 'Only 1 unit is available. Please reduce your quantity.';
|
| }
|
| return 'Only ' + param + ' units are available. Please reduce your quantity.';
|
| }
|
| );
|
|
|
|
|
|
|
| $( '.wpforms-form' ).each( function() {
|
| var validator = $( this ).data( 'validator' );
|
|
|
| if ( ! validator ) {
|
| return;
|
| }
|
|
|
| var originalErrorPlacement = validator.settings.errorPlacement;
|
|
|
| validator.settings.errorPlacement = function( error, element ) {
|
| if ( element.hasClass( 'wpforms-inventory-quantity' ) ) {
|
| var $description = element
|
| .closest( '.wpforms-field' )
|
| .find( '.wpforms-field-description' );
|
|
|
| if ( $description.length ) {
|
| error.insertAfter( $description );
|
| } else {
|
| error.insertAfter(
|
| element.closest( '.wpforms-single-item-price-content' )
|
| );
|
| }
|
|
|
| return;
|
| }
|
|
|
| if ( typeof originalErrorPlacement === 'function' ) {
|
| originalErrorPlacement.call( this, error, element );
|
| } else {
|
| error.insertAfter( element );
|
| }
|
| };
|
| } );
|
|
|
|
|
| $.each( wpformsInventory, function( formId, fields ) {
|
| $.each( fields, function( fieldId, available ) {
|
| var $select = $( '#wpforms-' + formId + '-field_' + fieldId + '-quantity' );
|
|
|
| if ( ! $select.length ) {
|
| return;
|
| }
|
|
|
| $select.addClass( 'wpforms-inventory-quantity' );
|
|
|
| $select.rules( 'add', {
|
| inventory_limit: available,
|
| messages: {
|
| inventory_limit: available === 1
|
| ? 'Only 1 unit is available. Please reduce your quantity.'
|
| : 'Only ' + available + ' units are available. Please reduce your quantity.'
|
| }
|
| } );
|
| } );
|
| } );
|
|
|
| } );
|
|
|
| } )( jQuery );
|
| </script>
|
| <?php
|
| }
|
|
|
| add_action( 'wpforms_wp_footer_end', 'wpforms_inventory_realtime_validation', 30 );
|
| |
| |
Comments