Passed
Pull Request — master (#375)
by Brian
63:08
created

GetPaid_Meta_Box_Payment_Form::save()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 35
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 14
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 35
rs 9.4888
1
<?php
2
/**
3
 * Payment Form
4
 *
5
 * Displays the payment form editing meta box.
6
 *
7
 */
8
9
if ( ! defined( 'ABSPATH' ) ) {
10
	exit; // Exit if accessed directly
11
}
12
13
/**
14
 * GetPaid_Meta_Box_Payment_Form Class.
15
 */
16
class GetPaid_Meta_Box_Payment_Form {
17
18
    /**
19
	 * Output the metabox.
20
	 *
21
	 * @param WP_Post $post
22
	 */
23
    public static function output( $post ) {
24
        ?>
25
        <div id="wpinv-form-builder" class="bsui">
26
            <div class="row">
27
                <div class="col-sm-4">
28
29
                    <!-- Builder tabs -->
30
                    <button class="button button-primary" v-if="active_tab!='new_item'" @click.prevent="active_tab='new_item'"><?php _e( 'Go Back', 'invoicing' ); ?></button>
31
32
                    <!-- Builder tab content -->
33
                    <div class="mt-4">
34
35
                        <!-- Available builder elements -->
36
                        <div class="wpinv-form-builder-tab-pane" v-if="active_tab=='new_item'">
37
                            <div class="wpinv-form-builder-add-field-types">
38
                                <small class='form-text text-muted'><?php _e( 'Add an element by dragging it to the payment form.', 'invoicing' ); ?></small>
39
                                <draggable class="section mt-2" style="display: flex; flex-flow: wrap; justify-content: space-between;" v-model="elements" :group="{ name: 'fields', pull: 'clone', put: false }" :sort="false" :clone="addDraggedField" tag="ul" filter=".wpinv-undraggable">
40
                                    <li v-for="element in elements" class= "wpinv-payment-form-left-fields-field" @click.prevent="addField(element)" :class="{ 'd-none': element.defaults.premade }">
41
                                        <button class="button btn">
42
                                            <span v-if="element.icon" class="dashicons dashicon-" :class="'dashicon-' + element.icon"></span>
43
                                            {{element.name}}
44
                                        </button>
45
                                    </li>
46
                                </draggable>
47
                            </div>
48
                        </div>
49
50
                        <!-- Edit an element -->
51
                        <div class="wpinv-form-builder-tab-pane" v-if="active_tab=='edit_item'" style="font-size: 16px;">
52
                            <div class="wpinv-form-builder-edit-field-wrapper">
53
                                <?php do_action( 'wpinv_payment_form_edit_element_template', 'active_form_element', $post ); ?>
54
                                <div>
55
                                    <button type="button" class="button button-link button-link-delete" @click.prevent="removeField(active_form_element)" v-show="! active_form_element.premade"><?php _e( 'Delete Element', 'invoicing' ); ?></button>
56
                                </div>
57
                            </div>
58
                        </div>
59
60
                    </div>
61
62
                </div>
63
                <div class="col-sm-8 border-left">
64
                    <small class='form-text text-muted' v-if='form_elements.length'><?php _e( 'Click on any element to edit or delete it.', 'invoicing' ); ?></small>
65
                    <p class='form-text text-muted' v-if='! form_elements.length'><?php _e( 'This form is empty. Add new elements by dragging them from the right.', 'invoicing' ); ?></p>
66
67
                    <draggable class="section bsui" v-model="form_elements" @add="highlightLastDroppedField" group="fields" tag="div" style="min-height: 100%; font-size: 16px;">
68
                        <div v-for="form_element in form_elements" class="wpinv-form-builder-element-preview" :class="{ active: active_form_element==form_element &&  active_tab=='edit_item' }" @click="active_tab = 'edit_item'; active_form_element = form_element">
69
                            <?php do_action( 'wpinv_payment_form_render_element_template', 'form_element', $post ); ?>
70
                        </div>
71
                    </draggable>
72
73
                    <textarea style="display:none;" name="wpinv_form_elements" v-model="elementString"></textarea>
74
                    <textarea style="display:none;" name="wpinv_form_items" v-model="itemString"></textarea>
75
                </div>
76
77
            </div>
78
        </div>
79
        <?php
80
81
        wp_nonce_field( 'wpinv_save_payment_form', 'wpinv_save_payment_form' ) ;
82
    }
83
84
    /**
85
	 * Save meta box data.
86
	 *
87
	 * @param int $post_id
88
	 */
89
	public static function save( $post_id ) {
90
91
        // verify nonce
92
        if ( ! isset( $_POST['wpinv_save_payment_form'] ) || ! wp_verify_nonce( $_POST['wpinv_save_payment_form'], 'wpinv_save_payment_form' ) ) {
93
            return;
94
        }
95
96
        // Prepare the form.
97
        $form = new GetPaid_Payment_Form( $post_id );
98
99
        // Fetch form items.
100
        $form_items = json_decode( wp_unslash( $_POST['wpinv_form_items'] ), true );
0 ignored issues
show
Bug introduced by
It seems like wp_unslash($_POST['wpinv_form_items']) can also be of type string[]; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

100
        $form_items = json_decode( /** @scrutinizer ignore-type */ wp_unslash( $_POST['wpinv_form_items'] ), true );
Loading history...
101
102
        // Ensure that we have an array...
103
        if ( empty( $form_items ) ) {
104
            $form_items = array();
105
        }
106
107
        // ... and that new items are saved to the db.
108
        $form_items = self::maybe_save_items( $form_items );
109
110
        // Add it to the form.
111
        $form->set_items( $form_items );
112
113
        // Save form elements.
114
        $form_elements = json_decode( wp_unslash( $_POST['wpinv_form_elements'] ), true );
115
        if ( empty( $form_elements ) ) {
116
            $form_elements = array();
117
        }
118
119
        $form->set_elements( $form_elements );
120
121
        // Persist data to the datastore.
122
        $form->save();
123
        do_action( 'getpaid_payment_form_metabox_save', $post_id, $form );
124
125
    }
126
127
    /**
128
     * Saves unsaved form items.
129
     */
130
    public static function maybe_save_items( $items ) {
131
132
        $saved = array();
133
134
        foreach( $items as $item ) {
135
136
            if ( is_numeric( $item['id'] ) ) {
137
                $saved[] = $item;
138
                continue;
139
            }
140
141
            $new_item = new WPInv_Item();
142
143
            // Save post data.
144
            $new_item->set_props(
145
                array(
146
                    'name'               => sanitize_text_field( $item['title'] ),
147
                    'description'        => wp_kses_post( $item['description'] ),
148
                    'status'             => 'publish',
149
                    'type'               => empty( $item['type'] ) ? 'custom' : $item['type'],
150
                    'price'              => wpinv_sanitize_amount( $item['price'] ),
151
                    'vat_rule'           => empty( $item['rule'] ) ? 'digital' : $item['rule'],
152
                    'vat_class'          => empty( $item['class'] ) ? '_standard' : $item['class'],
153
                    'is_dynamic_pricing' => empty( $item['custom_price'] ) ? 0 : (int) $item['custom_price'],
154
                    'minimum_price'      => empty( $item['minimum_price'] ) ? 0 : (float) $item['minimum_price'],
155
                )
156
            );
157
158
            // Save the item.
159
            $new_item->save();
160
161
            if ( $new_item->get_id() ) {
162
                $item['id'] = $new_item->get_id();
163
                $saved[] = $item;
164
            }
165
166
        }
167
168
        foreach ( $saved as $i => $item ) {
169
            foreach ( array( 'new', 'type', 'class', 'rule', 'price', 'title', 'custom_price', 'minimum_price', 'recurring' ) as $key ) {
170
                if ( isset( $item[ $key ] ) ) {
171
                    unset( $saved[ $i ][ $key ] );
172
                }
173
            }
174
        }
175
176
        return $saved;
177
178
    }
179
180
}
181