Passed
Push — master ( c0eaca...2632ed )
by Brian
04:50
created
includes/data-stores/class-getpaid-data.php 1 patch
Indentation   +862 added lines, -862 removed lines patch added patch discarded remove patch
@@ -9,7 +9,7 @@  discard block
 block discarded – undo
9 9
  */
10 10
 
11 11
 if ( ! defined( 'ABSPATH' ) ) {
12
-	exit;
12
+    exit;
13 13
 }
14 14
 
15 15
 /**
@@ -21,356 +21,356 @@  discard block
 block discarded – undo
21 21
  */
22 22
 abstract class GetPaid_Data {
23 23
 
24
-	/**
25
-	 * ID for this object.
26
-	 *
27
-	 * @since 1.0.19
28
-	 * @var int
29
-	 */
30
-	protected $id = 0;
31
-
32
-	/**
33
-	 * Core data for this object. Name value pairs (name + default value).
34
-	 *
35
-	 * @since 1.0.19
36
-	 * @var array
37
-	 */
38
-	protected $data = array();
39
-
40
-	/**
41
-	 * Core data changes for this object.
42
-	 *
43
-	 * @since 1.0.19
44
-	 * @var array
45
-	 */
46
-	protected $changes = array();
47
-
48
-	/**
49
-	 * This is false until the object is read from the DB.
50
-	 *
51
-	 * @since 1.0.19
52
-	 * @var bool
53
-	 */
54
-	protected $object_read = false;
55
-
56
-	/**
57
-	 * This is the name of this object type.
58
-	 *
59
-	 * @since 1.0.19
60
-	 * @var string
61
-	 */
62
-	protected $object_type = 'data';
63
-
64
-	/**
65
-	 * Extra data for this object. Name value pairs (name + default value).
66
-	 * Used as a standard way for sub classes (like item types) to add
67
-	 * additional information to an inherited class.
68
-	 *
69
-	 * @since 1.0.19
70
-	 * @var array
71
-	 */
72
-	protected $extra_data = array();
73
-
74
-	/**
75
-	 * Set to _data on construct so we can track and reset data if needed.
76
-	 *
77
-	 * @since 1.0.19
78
-	 * @var array
79
-	 */
80
-	protected $default_data = array();
81
-
82
-	/**
83
-	 * Contains a reference to the data store for this class.
84
-	 *
85
-	 * @since 1.0.19
86
-	 * @var GetPaid_Data_Store
87
-	 */
88
-	protected $data_store;
89
-
90
-	/**
91
-	 * Stores meta in cache for future reads.
92
-	 * A group must be set to to enable caching.
93
-	 *
94
-	 * @since 1.0.19
95
-	 * @var string
96
-	 */
97
-	protected $cache_group = '';
98
-
99
-	/**
100
-	 * Stores the last error.
101
-	 *
102
-	 * @since 1.0.19
103
-	 * @var string
104
-	 */
105
-	public $last_error = '';
106
-
107
-	/**
108
-	 * Stores additional meta data.
109
-	 *
110
-	 * @since 1.0.19
111
-	 * @var array
112
-	 */
113
-	protected $meta_data = null;
114
-
115
-	/**
116
-	 * Default constructor.
117
-	 *
118
-	 * @param int|object|array|string $read ID to load from the DB (optional) or already queried data.
119
-	 */
120
-	public function __construct( $read = 0 ) {
121
-		$this->data         = array_merge( $this->data, $this->extra_data );
122
-		$this->default_data = $this->data;
123
-	}
124
-
125
-	/**
126
-	 * Only store the object ID to avoid serializing the data object instance.
127
-	 *
128
-	 * @return array
129
-	 */
130
-	public function __sleep() {
131
-		return array( 'id' );
132
-	}
133
-
134
-	/**
135
-	 * Re-run the constructor with the object ID.
136
-	 *
137
-	 * If the object no longer exists, remove the ID.
138
-	 */
139
-	public function __wakeup() {
140
-		$this->__construct( absint( $this->id ) );
141
-
142
-		if ( ! empty( $this->last_error ) ) {
143
-			$this->set_id( 0 );
144
-		}
145
-
146
-	}
147
-
148
-	/**
149
-	 * When the object is cloned, make sure meta is duplicated correctly.
150
-	 *
151
-	 * @since 1.0.19
152
-	 */
153
-	public function __clone() {
154
-		$this->maybe_read_meta_data();
155
-		if ( ! empty( $this->meta_data ) ) {
156
-			foreach ( $this->meta_data as $array_key => $meta ) {
157
-				$this->meta_data[ $array_key ] = clone $meta;
158
-				if ( ! empty( $meta->id ) ) {
159
-					$this->meta_data[ $array_key ]->id = null;
160
-				}
161
-			}
162
-		}
163
-	}
164
-
165
-	/**
166
-	 * Get the data store.
167
-	 *
168
-	 * @since  1.0.19
169
-	 * @return object
170
-	 */
171
-	public function get_data_store() {
172
-		return $this->data_store;
173
-	}
174
-
175
-	/**
176
-	 * Get the object type.
177
-	 *
178
-	 * @since  1.0.19
179
-	 * @return string
180
-	 */
181
-	public function get_object_type() {
182
-		return $this->object_type;
183
-	}
184
-
185
-	/**
186
-	 * Returns the unique ID for this object.
187
-	 *
188
-	 * @since  1.0.19
189
-	 * @return int
190
-	 */
191
-	public function get_id() {
192
-		return $this->id;
193
-	}
194
-
195
-	/**
196
-	 * Get form status.
197
-	 *
198
-	 * @since 1.0.19
199
-	 * @param  string $context View or edit context.
200
-	 * @return string
201
-	 */
202
-	public function get_status( $context = 'view' ) {
203
-		return $this->get_prop( 'status', $context );
204
-    }
205
-
206
-	/**
207
-	 * Delete an object, set the ID to 0, and return result.
208
-	 *
209
-	 * @since  1.0.19
210
-	 * @param  bool $force_delete Should the data be deleted permanently.
211
-	 * @return bool result
212
-	 */
213
-	public function delete( $force_delete = false ) {
214
-		if ( $this->data_store && $this->exists() ) {
215
-			$this->data_store->delete( $this, array( 'force_delete' => $force_delete ) );
216
-			$this->set_id( 0 );
217
-			return true;
218
-		}
219
-		return false;
220
-	}
221
-
222
-	/**
223
-	 * Save should create or update based on object existence.
224
-	 *
225
-	 * @since  1.0.19
226
-	 * @return int
227
-	 */
228
-	public function save() {
229
-		if ( ! $this->data_store ) {
230
-			return $this->get_id();
231
-		}
232
-
233
-		/**
234
-		 * Trigger action before saving to the DB. Allows you to adjust object props before save.
235
-		 *
236
-		 * @param GetPaid_Data          $this The object being saved.
237
-		 * @param GetPaid_Data_Store_WP $data_store The data store persisting the data.
238
-		 */
239
-		do_action( 'getpaid_before_' . $this->object_type . '_object_save', $this, $this->data_store );
240
-
241
-		if ( $this->get_id() ) {
242
-			$this->data_store->update( $this );
243
-		} else {
244
-			$this->data_store->create( $this );
245
-		}
246
-
247
-		/**
248
-		 * Trigger action after saving to the DB.
249
-		 *
250
-		 * @param GetPaid_Data          $this The object being saved.
251
-		 * @param GetPaid_Data_Store_WP $data_store The data store persisting the data.
252
-		 */
253
-		do_action( 'getpaid_after_' . $this->object_type . '_object_save', $this, $this->data_store );
254
-
255
-		return $this->get_id();
256
-	}
257
-
258
-	/**
259
-	 * Change data to JSON format.
260
-	 *
261
-	 * @since  1.0.19
262
-	 * @return string Data in JSON format.
263
-	 */
264
-	public function __toString() {
265
-		return wp_json_encode( $this->get_data() );
266
-	}
267
-
268
-	/**
269
-	 * Returns all data for this object.
270
-	 *
271
-	 * @since  1.0.19
272
-	 * @return array
273
-	 */
274
-	public function get_data() {
275
-		return array_merge( array( 'id' => $this->get_id() ), $this->data, array( 'meta_data' => $this->get_meta_data() ) );
276
-	}
277
-
278
-	/**
279
-	 * Returns array of expected data keys for this object.
280
-	 *
281
-	 * @since   1.0.19
282
-	 * @return array
283
-	 */
284
-	public function get_data_keys() {
285
-		return array_keys( $this->data );
286
-	}
287
-
288
-	/**
289
-	 * Returns all "extra" data keys for an object (for sub objects like item types).
290
-	 *
291
-	 * @since  1.0.19
292
-	 * @return array
293
-	 */
294
-	public function get_extra_data_keys() {
295
-		return array_keys( $this->extra_data );
296
-	}
297
-
298
-	/**
299
-	 * Filter null meta values from array.
300
-	 *
301
-	 * @since  1.0.19
302
-	 * @param mixed $meta Meta value to check.
303
-	 * @return bool
304
-	 */
305
-	protected function filter_null_meta( $meta ) {
306
-		return ! is_null( $meta->value );
307
-	}
308
-
309
-	/**
310
-	 * Get All Meta Data.
311
-	 *
312
-	 * @since 1.0.19
313
-	 * @return array of objects.
314
-	 */
315
-	public function get_meta_data() {
316
-		$this->maybe_read_meta_data();
317
-		return array_values( array_filter( $this->meta_data, array( $this, 'filter_null_meta' ) ) );
318
-	}
319
-
320
-	/**
321
-	 * Check if the key is an internal one.
322
-	 *
323
-	 * @since  1.0.19
324
-	 * @param  string $key Key to check.
325
-	 * @return bool   true if it's an internal key, false otherwise
326
-	 */
327
-	protected function is_internal_meta_key( $key ) {
328
-		$internal_meta_key = ! empty( $key ) && $this->data_store && in_array( $key, $this->data_store->get_internal_meta_keys(), true );
329
-
330
-		if ( ! $internal_meta_key ) {
331
-			return false;
332
-		}
333
-
334
-		$has_setter_or_getter = is_callable( array( $this, 'set_' . $key ) ) || is_callable( array( $this, 'get_' . $key ) );
335
-
336
-		if ( ! $has_setter_or_getter ) {
337
-			return false;
338
-		}
339
-
340
-		/* translators: %s: $key Key to check */
341
-		getpaid_doing_it_wrong( __FUNCTION__, sprintf( __( 'Generic add/update/get meta methods should not be used for internal meta data, including "%s". Use getters and setters.', 'invoicing' ), $key ), '1.0.19' );
342
-
343
-		return true;
344
-	}
345
-
346
-	/**
347
-	 * Magic method for setting data fields.
348
-	 *
349
-	 * This method does not update custom fields in the database.
350
-	 *
351
-	 * @since 1.0.19
352
-	 * @access public
353
-	 *
354
-	 */
355
-	public function __set( $key, $value ) {
356
-
357
-		if ( 'id' == strtolower( $key ) ) {
358
-			return $this->set_id( $value );
359
-		}
360
-
361
-		if ( method_exists( $this, "set_$key") ) {
362
-
363
-			/* translators: %s: $key Key to set */
364
-			getpaid_doing_it_wrong( __FUNCTION__, sprintf( __( 'Object data such as "%s" should not be accessed directly. Use getters and setters.', 'invoicing' ), $key ), '1.0.19' );
365
-
366
-			call_user_func( array( $this, "set_$key" ), $value );
367
-		} else {
368
-			$this->set_prop( $key, $value );
369
-		}
370
-
371
-	}
372
-
373
-	/**
24
+    /**
25
+     * ID for this object.
26
+     *
27
+     * @since 1.0.19
28
+     * @var int
29
+     */
30
+    protected $id = 0;
31
+
32
+    /**
33
+     * Core data for this object. Name value pairs (name + default value).
34
+     *
35
+     * @since 1.0.19
36
+     * @var array
37
+     */
38
+    protected $data = array();
39
+
40
+    /**
41
+     * Core data changes for this object.
42
+     *
43
+     * @since 1.0.19
44
+     * @var array
45
+     */
46
+    protected $changes = array();
47
+
48
+    /**
49
+     * This is false until the object is read from the DB.
50
+     *
51
+     * @since 1.0.19
52
+     * @var bool
53
+     */
54
+    protected $object_read = false;
55
+
56
+    /**
57
+     * This is the name of this object type.
58
+     *
59
+     * @since 1.0.19
60
+     * @var string
61
+     */
62
+    protected $object_type = 'data';
63
+
64
+    /**
65
+     * Extra data for this object. Name value pairs (name + default value).
66
+     * Used as a standard way for sub classes (like item types) to add
67
+     * additional information to an inherited class.
68
+     *
69
+     * @since 1.0.19
70
+     * @var array
71
+     */
72
+    protected $extra_data = array();
73
+
74
+    /**
75
+     * Set to _data on construct so we can track and reset data if needed.
76
+     *
77
+     * @since 1.0.19
78
+     * @var array
79
+     */
80
+    protected $default_data = array();
81
+
82
+    /**
83
+     * Contains a reference to the data store for this class.
84
+     *
85
+     * @since 1.0.19
86
+     * @var GetPaid_Data_Store
87
+     */
88
+    protected $data_store;
89
+
90
+    /**
91
+     * Stores meta in cache for future reads.
92
+     * A group must be set to to enable caching.
93
+     *
94
+     * @since 1.0.19
95
+     * @var string
96
+     */
97
+    protected $cache_group = '';
98
+
99
+    /**
100
+     * Stores the last error.
101
+     *
102
+     * @since 1.0.19
103
+     * @var string
104
+     */
105
+    public $last_error = '';
106
+
107
+    /**
108
+     * Stores additional meta data.
109
+     *
110
+     * @since 1.0.19
111
+     * @var array
112
+     */
113
+    protected $meta_data = null;
114
+
115
+    /**
116
+     * Default constructor.
117
+     *
118
+     * @param int|object|array|string $read ID to load from the DB (optional) or already queried data.
119
+     */
120
+    public function __construct( $read = 0 ) {
121
+        $this->data         = array_merge( $this->data, $this->extra_data );
122
+        $this->default_data = $this->data;
123
+    }
124
+
125
+    /**
126
+     * Only store the object ID to avoid serializing the data object instance.
127
+     *
128
+     * @return array
129
+     */
130
+    public function __sleep() {
131
+        return array( 'id' );
132
+    }
133
+
134
+    /**
135
+     * Re-run the constructor with the object ID.
136
+     *
137
+     * If the object no longer exists, remove the ID.
138
+     */
139
+    public function __wakeup() {
140
+        $this->__construct( absint( $this->id ) );
141
+
142
+        if ( ! empty( $this->last_error ) ) {
143
+            $this->set_id( 0 );
144
+        }
145
+
146
+    }
147
+
148
+    /**
149
+     * When the object is cloned, make sure meta is duplicated correctly.
150
+     *
151
+     * @since 1.0.19
152
+     */
153
+    public function __clone() {
154
+        $this->maybe_read_meta_data();
155
+        if ( ! empty( $this->meta_data ) ) {
156
+            foreach ( $this->meta_data as $array_key => $meta ) {
157
+                $this->meta_data[ $array_key ] = clone $meta;
158
+                if ( ! empty( $meta->id ) ) {
159
+                    $this->meta_data[ $array_key ]->id = null;
160
+                }
161
+            }
162
+        }
163
+    }
164
+
165
+    /**
166
+     * Get the data store.
167
+     *
168
+     * @since  1.0.19
169
+     * @return object
170
+     */
171
+    public function get_data_store() {
172
+        return $this->data_store;
173
+    }
174
+
175
+    /**
176
+     * Get the object type.
177
+     *
178
+     * @since  1.0.19
179
+     * @return string
180
+     */
181
+    public function get_object_type() {
182
+        return $this->object_type;
183
+    }
184
+
185
+    /**
186
+     * Returns the unique ID for this object.
187
+     *
188
+     * @since  1.0.19
189
+     * @return int
190
+     */
191
+    public function get_id() {
192
+        return $this->id;
193
+    }
194
+
195
+    /**
196
+     * Get form status.
197
+     *
198
+     * @since 1.0.19
199
+     * @param  string $context View or edit context.
200
+     * @return string
201
+     */
202
+    public function get_status( $context = 'view' ) {
203
+        return $this->get_prop( 'status', $context );
204
+    }
205
+
206
+    /**
207
+     * Delete an object, set the ID to 0, and return result.
208
+     *
209
+     * @since  1.0.19
210
+     * @param  bool $force_delete Should the data be deleted permanently.
211
+     * @return bool result
212
+     */
213
+    public function delete( $force_delete = false ) {
214
+        if ( $this->data_store && $this->exists() ) {
215
+            $this->data_store->delete( $this, array( 'force_delete' => $force_delete ) );
216
+            $this->set_id( 0 );
217
+            return true;
218
+        }
219
+        return false;
220
+    }
221
+
222
+    /**
223
+     * Save should create or update based on object existence.
224
+     *
225
+     * @since  1.0.19
226
+     * @return int
227
+     */
228
+    public function save() {
229
+        if ( ! $this->data_store ) {
230
+            return $this->get_id();
231
+        }
232
+
233
+        /**
234
+         * Trigger action before saving to the DB. Allows you to adjust object props before save.
235
+         *
236
+         * @param GetPaid_Data          $this The object being saved.
237
+         * @param GetPaid_Data_Store_WP $data_store The data store persisting the data.
238
+         */
239
+        do_action( 'getpaid_before_' . $this->object_type . '_object_save', $this, $this->data_store );
240
+
241
+        if ( $this->get_id() ) {
242
+            $this->data_store->update( $this );
243
+        } else {
244
+            $this->data_store->create( $this );
245
+        }
246
+
247
+        /**
248
+         * Trigger action after saving to the DB.
249
+         *
250
+         * @param GetPaid_Data          $this The object being saved.
251
+         * @param GetPaid_Data_Store_WP $data_store The data store persisting the data.
252
+         */
253
+        do_action( 'getpaid_after_' . $this->object_type . '_object_save', $this, $this->data_store );
254
+
255
+        return $this->get_id();
256
+    }
257
+
258
+    /**
259
+     * Change data to JSON format.
260
+     *
261
+     * @since  1.0.19
262
+     * @return string Data in JSON format.
263
+     */
264
+    public function __toString() {
265
+        return wp_json_encode( $this->get_data() );
266
+    }
267
+
268
+    /**
269
+     * Returns all data for this object.
270
+     *
271
+     * @since  1.0.19
272
+     * @return array
273
+     */
274
+    public function get_data() {
275
+        return array_merge( array( 'id' => $this->get_id() ), $this->data, array( 'meta_data' => $this->get_meta_data() ) );
276
+    }
277
+
278
+    /**
279
+     * Returns array of expected data keys for this object.
280
+     *
281
+     * @since   1.0.19
282
+     * @return array
283
+     */
284
+    public function get_data_keys() {
285
+        return array_keys( $this->data );
286
+    }
287
+
288
+    /**
289
+     * Returns all "extra" data keys for an object (for sub objects like item types).
290
+     *
291
+     * @since  1.0.19
292
+     * @return array
293
+     */
294
+    public function get_extra_data_keys() {
295
+        return array_keys( $this->extra_data );
296
+    }
297
+
298
+    /**
299
+     * Filter null meta values from array.
300
+     *
301
+     * @since  1.0.19
302
+     * @param mixed $meta Meta value to check.
303
+     * @return bool
304
+     */
305
+    protected function filter_null_meta( $meta ) {
306
+        return ! is_null( $meta->value );
307
+    }
308
+
309
+    /**
310
+     * Get All Meta Data.
311
+     *
312
+     * @since 1.0.19
313
+     * @return array of objects.
314
+     */
315
+    public function get_meta_data() {
316
+        $this->maybe_read_meta_data();
317
+        return array_values( array_filter( $this->meta_data, array( $this, 'filter_null_meta' ) ) );
318
+    }
319
+
320
+    /**
321
+     * Check if the key is an internal one.
322
+     *
323
+     * @since  1.0.19
324
+     * @param  string $key Key to check.
325
+     * @return bool   true if it's an internal key, false otherwise
326
+     */
327
+    protected function is_internal_meta_key( $key ) {
328
+        $internal_meta_key = ! empty( $key ) && $this->data_store && in_array( $key, $this->data_store->get_internal_meta_keys(), true );
329
+
330
+        if ( ! $internal_meta_key ) {
331
+            return false;
332
+        }
333
+
334
+        $has_setter_or_getter = is_callable( array( $this, 'set_' . $key ) ) || is_callable( array( $this, 'get_' . $key ) );
335
+
336
+        if ( ! $has_setter_or_getter ) {
337
+            return false;
338
+        }
339
+
340
+        /* translators: %s: $key Key to check */
341
+        getpaid_doing_it_wrong( __FUNCTION__, sprintf( __( 'Generic add/update/get meta methods should not be used for internal meta data, including "%s". Use getters and setters.', 'invoicing' ), $key ), '1.0.19' );
342
+
343
+        return true;
344
+    }
345
+
346
+    /**
347
+     * Magic method for setting data fields.
348
+     *
349
+     * This method does not update custom fields in the database.
350
+     *
351
+     * @since 1.0.19
352
+     * @access public
353
+     *
354
+     */
355
+    public function __set( $key, $value ) {
356
+
357
+        if ( 'id' == strtolower( $key ) ) {
358
+            return $this->set_id( $value );
359
+        }
360
+
361
+        if ( method_exists( $this, "set_$key") ) {
362
+
363
+            /* translators: %s: $key Key to set */
364
+            getpaid_doing_it_wrong( __FUNCTION__, sprintf( __( 'Object data such as "%s" should not be accessed directly. Use getters and setters.', 'invoicing' ), $key ), '1.0.19' );
365
+
366
+            call_user_func( array( $this, "set_$key" ), $value );
367
+        } else {
368
+            $this->set_prop( $key, $value );
369
+        }
370
+
371
+    }
372
+
373
+    /**
374 374
      * Margic method for retrieving a property.
375 375
      */
376 376
     public function __get( $key ) {
@@ -378,10 +378,10 @@  discard block
 block discarded – undo
378 378
         // Check if we have a helper method for that.
379 379
         if ( method_exists( $this, 'get_' . $key ) ) {
380 380
 
381
-			if ( 'post_type' != $key ) {
382
-				/* translators: %s: $key Key to set */
383
-				getpaid_doing_it_wrong( __FUNCTION__, sprintf( __( 'Object data such as "%s" should not be accessed directly. Use getters and setters.', 'invoicing' ), $key ), '1.0.19' );
384
-			}
381
+            if ( 'post_type' != $key ) {
382
+                /* translators: %s: $key Key to set */
383
+                getpaid_doing_it_wrong( __FUNCTION__, sprintf( __( 'Object data such as "%s" should not be accessed directly. Use getters and setters.', 'invoicing' ), $key ), '1.0.19' );
384
+            }
385 385
 
386 386
             return call_user_func( array( $this, 'get_' . $key ) );
387 387
         }
@@ -391,514 +391,514 @@  discard block
 block discarded – undo
391 391
             return $this->post->$key;
392 392
         }
393 393
 
394
-		return $this->get_prop( $key );
395
-
396
-    }
397
-
398
-	/**
399
-	 * Get Meta Data by Key.
400
-	 *
401
-	 * @since  1.0.19
402
-	 * @param  string $key Meta Key.
403
-	 * @param  bool   $single return first found meta with key, or all with $key.
404
-	 * @param  string $context What the value is for. Valid values are view and edit.
405
-	 * @return mixed
406
-	 */
407
-	public function get_meta( $key = '', $single = true, $context = 'view' ) {
408
-
409
-		// Check if this is an internal meta key.
410
-		$_key = str_replace( '_wpinv', '', $key );
411
-		$_key = str_replace( 'wpinv', '', $_key );
412
-		if ( $this->is_internal_meta_key( $key ) ) {
413
-			$function = 'get_' . $_key;
414
-
415
-			if ( is_callable( array( $this, $function ) ) ) {
416
-				return $this->{$function}();
417
-			}
418
-		}
419
-
420
-		// Read the meta data if not yet read.
421
-		$this->maybe_read_meta_data();
422
-		$meta_data  = $this->get_meta_data();
423
-		$array_keys = array_keys( wp_list_pluck( $meta_data, 'key' ), $key, true );
424
-		$value      = $single ? '' : array();
425
-
426
-		if ( ! empty( $array_keys ) ) {
427
-			// We don't use the $this->meta_data property directly here because we don't want meta with a null value (i.e. meta which has been deleted via $this->delete_meta_data()).
428
-			if ( $single ) {
429
-				$value = $meta_data[ current( $array_keys ) ]->value;
430
-			} else {
431
-				$value = array_intersect_key( $meta_data, array_flip( $array_keys ) );
432
-			}
433
-		}
434
-
435
-		if ( 'view' === $context ) {
436
-			$value = apply_filters( $this->get_hook_prefix() . $key, $value, $this );
437
-		}
438
-
439
-		return $value;
440
-	}
441
-
442
-	/**
443
-	 * See if meta data exists, since get_meta always returns a '' or array().
444
-	 *
445
-	 * @since  1.0.19
446
-	 * @param  string $key Meta Key.
447
-	 * @return boolean
448
-	 */
449
-	public function meta_exists( $key = '' ) {
450
-		$this->maybe_read_meta_data();
451
-		$array_keys = wp_list_pluck( $this->get_meta_data(), 'key' );
452
-		return in_array( $key, $array_keys, true );
453
-	}
454
-
455
-	/**
456
-	 * Set all meta data from array.
457
-	 *
458
-	 * @since 1.0.19
459
-	 * @param array $data Key/Value pairs.
460
-	 */
461
-	public function set_meta_data( $data ) {
462
-		if ( ! empty( $data ) && is_array( $data ) ) {
463
-			$this->maybe_read_meta_data();
464
-			foreach ( $data as $meta ) {
465
-				$meta = (array) $meta;
466
-				if ( isset( $meta['key'], $meta['value'], $meta['id'] ) ) {
467
-					$this->meta_data[] = new GetPaid_Meta_Data(
468
-						array(
469
-							'id'    => $meta['id'],
470
-							'key'   => $meta['key'],
471
-							'value' => $meta['value'],
472
-						)
473
-					);
474
-				}
475
-			}
476
-		}
477
-	}
478
-
479
-	/**
480
-	 * Add meta data.
481
-	 *
482
-	 * @since 1.0.19
483
-	 *
484
-	 * @param string       $key Meta key.
485
-	 * @param string|array $value Meta value.
486
-	 * @param bool         $unique Should this be a unique key?.
487
-	 */
488
-	public function add_meta_data( $key, $value, $unique = false ) {
489
-		if ( $this->is_internal_meta_key( $key ) ) {
490
-			$function = 'set_' . $key;
491
-
492
-			if ( is_callable( array( $this, $function ) ) ) {
493
-				return $this->{$function}( $value );
494
-			}
495
-		}
496
-
497
-		$this->maybe_read_meta_data();
498
-		if ( $unique ) {
499
-			$this->delete_meta_data( $key );
500
-		}
501
-		$this->meta_data[] = new GetPaid_Meta_Data(
502
-			array(
503
-				'key'   => $key,
504
-				'value' => $value,
505
-			)
506
-		);
507
-
508
-		$this->save();
509
-	}
510
-
511
-	/**
512
-	 * Update meta data by key or ID, if provided.
513
-	 *
514
-	 * @since  1.0.19
515
-	 *
516
-	 * @param  string       $key Meta key.
517
-	 * @param  string|array $value Meta value.
518
-	 * @param  int          $meta_id Meta ID.
519
-	 */
520
-	public function update_meta_data( $key, $value, $meta_id = 0 ) {
521
-		if ( $this->is_internal_meta_key( $key ) ) {
522
-			$function = 'set_' . $key;
523
-
524
-			if ( is_callable( array( $this, $function ) ) ) {
525
-				return $this->{$function}( $value );
526
-			}
527
-		}
528
-
529
-		$this->maybe_read_meta_data();
530
-
531
-		$array_key = false;
532
-
533
-		if ( $meta_id ) {
534
-			$array_keys = array_keys( wp_list_pluck( $this->meta_data, 'id' ), $meta_id, true );
535
-			$array_key  = $array_keys ? current( $array_keys ) : false;
536
-		} else {
537
-			// Find matches by key.
538
-			$matches = array();
539
-			foreach ( $this->meta_data as $meta_data_array_key => $meta ) {
540
-				if ( $meta->key === $key ) {
541
-					$matches[] = $meta_data_array_key;
542
-				}
543
-			}
544
-
545
-			if ( ! empty( $matches ) ) {
546
-				// Set matches to null so only one key gets the new value.
547
-				foreach ( $matches as $meta_data_array_key ) {
548
-					$this->meta_data[ $meta_data_array_key ]->value = null;
549
-				}
550
-				$array_key = current( $matches );
551
-			}
552
-		}
553
-
554
-		if ( false !== $array_key ) {
555
-			$meta        = $this->meta_data[ $array_key ];
556
-			$meta->key   = $key;
557
-			$meta->value = $value;
558
-		} else {
559
-			$this->add_meta_data( $key, $value, true );
560
-		}
561
-	}
562
-
563
-	/**
564
-	 * Delete meta data.
565
-	 *
566
-	 * @since 1.0.19
567
-	 * @param string $key Meta key.
568
-	 */
569
-	public function delete_meta_data( $key ) {
570
-		$this->maybe_read_meta_data();
571
-		$array_keys = array_keys( wp_list_pluck( $this->meta_data, 'key' ), $key, true );
572
-
573
-		if ( $array_keys ) {
574
-			foreach ( $array_keys as $array_key ) {
575
-				$this->meta_data[ $array_key ]->value = null;
576
-			}
577
-		}
578
-	}
579
-
580
-	/**
581
-	 * Delete meta data.
582
-	 *
583
-	 * @since 1.0.19
584
-	 * @param int $mid Meta ID.
585
-	 */
586
-	public function delete_meta_data_by_mid( $mid ) {
587
-		$this->maybe_read_meta_data();
588
-		$array_keys = array_keys( wp_list_pluck( $this->meta_data, 'id' ), (int) $mid, true );
589
-
590
-		if ( $array_keys ) {
591
-			foreach ( $array_keys as $array_key ) {
592
-				$this->meta_data[ $array_key ]->value = null;
593
-			}
594
-		}
595
-	}
596
-
597
-	/**
598
-	 * Read meta data if null.
599
-	 *
600
-	 * @since 1.0.19
601
-	 */
602
-	protected function maybe_read_meta_data() {
603
-		if ( is_null( $this->meta_data ) ) {
604
-			$this->read_meta_data();
605
-		}
606
-	}
607
-
608
-	/**
609
-	 * Read Meta Data from the database. Ignore any internal properties.
610
-	 * Uses it's own caches because get_metadata does not provide meta_ids.
611
-	 *
612
-	 * @since 1.0.19
613
-	 * @param bool $force_read True to force a new DB read (and update cache).
614
-	 */
615
-	public function read_meta_data( $force_read = false ) {
616
-
617
-		// Reset meta data.
618
-		$this->meta_data = array();
619
-
620
-		// Maybe abort early.
621
-		if ( ! $this->get_id() || ! $this->data_store ) {
622
-			return;
623
-		}
624
-
625
-		// Only read from cache if the cache key is set.
626
-		$cache_key = null;
627
-		if ( ! $force_read && ! empty( $this->cache_group ) ) {
628
-			$cache_key     = GetPaid_Cache_Helper::get_cache_prefix( $this->cache_group ) . GetPaid_Cache_Helper::get_cache_prefix( 'object_' . $this->get_id() ) . 'object_meta_' . $this->get_id();
629
-			$raw_meta_data = wp_cache_get( $cache_key, $this->cache_group );
630
-		}
631
-
632
-		// Should we force read?
633
-		if ( empty( $raw_meta_data ) ) {
634
-			$raw_meta_data = $this->data_store->read_meta( $this );
635
-
636
-			if ( ! empty( $cache_key ) ) {
637
-				wp_cache_set( $cache_key, $raw_meta_data, $this->cache_group );
638
-			}
639
-
640
-		}
641
-
642
-		// Set meta data.
643
-		if ( is_array( $raw_meta_data ) ) {
644
-
645
-			foreach ( $raw_meta_data as $meta ) {
646
-				$this->meta_data[] = new GetPaid_Meta_Data(
647
-					array(
648
-						'id'    => (int) $meta->meta_id,
649
-						'key'   => $meta->meta_key,
650
-						'value' => maybe_unserialize( $meta->meta_value ),
651
-					)
652
-				);
653
-			}
654
-
655
-		}
656
-
657
-	}
658
-
659
-	/**
660
-	 * Update Meta Data in the database.
661
-	 *
662
-	 * @since 1.0.19
663
-	 */
664
-	public function save_meta_data() {
665
-		if ( ! $this->data_store || is_null( $this->meta_data ) ) {
666
-			return;
667
-		}
668
-		foreach ( $this->meta_data as $array_key => $meta ) {
669
-			if ( is_null( $meta->value ) ) {
670
-				if ( ! empty( $meta->id ) ) {
671
-					$this->data_store->delete_meta( $this, $meta );
672
-					unset( $this->meta_data[ $array_key ] );
673
-				}
674
-			} elseif ( empty( $meta->id ) ) {
675
-				$meta->id = $this->data_store->add_meta( $this, $meta );
676
-				$meta->apply_changes();
677
-			} else {
678
-				if ( $meta->get_changes() ) {
679
-					$this->data_store->update_meta( $this, $meta );
680
-					$meta->apply_changes();
681
-				}
682
-			}
683
-		}
684
-		if ( ! empty( $this->cache_group ) ) {
685
-			$cache_key = GetPaid_Cache_Helper::get_cache_prefix( $this->cache_group ) . GetPaid_Cache_Helper::get_cache_prefix( 'object_' . $this->get_id() ) . 'object_meta_' . $this->get_id();
686
-			wp_cache_delete( $cache_key, $this->cache_group );
687
-		}
688
-	}
689
-
690
-	/**
691
-	 * Set ID.
692
-	 *
693
-	 * @since 1.0.19
694
-	 * @param int $id ID.
695
-	 */
696
-	public function set_id( $id ) {
697
-		$this->id = absint( $id );
698
-	}
699
-
700
-	/**
701
-	 * Sets item status.
702
-	 *
703
-	 * @since 1.0.19
704
-	 * @param string $status New status.
705
-	 * @return array details of change.
706
-	 */
707
-	public function set_status( $status ) {
394
+        return $this->get_prop( $key );
395
+
396
+    }
397
+
398
+    /**
399
+     * Get Meta Data by Key.
400
+     *
401
+     * @since  1.0.19
402
+     * @param  string $key Meta Key.
403
+     * @param  bool   $single return first found meta with key, or all with $key.
404
+     * @param  string $context What the value is for. Valid values are view and edit.
405
+     * @return mixed
406
+     */
407
+    public function get_meta( $key = '', $single = true, $context = 'view' ) {
408
+
409
+        // Check if this is an internal meta key.
410
+        $_key = str_replace( '_wpinv', '', $key );
411
+        $_key = str_replace( 'wpinv', '', $_key );
412
+        if ( $this->is_internal_meta_key( $key ) ) {
413
+            $function = 'get_' . $_key;
414
+
415
+            if ( is_callable( array( $this, $function ) ) ) {
416
+                return $this->{$function}();
417
+            }
418
+        }
419
+
420
+        // Read the meta data if not yet read.
421
+        $this->maybe_read_meta_data();
422
+        $meta_data  = $this->get_meta_data();
423
+        $array_keys = array_keys( wp_list_pluck( $meta_data, 'key' ), $key, true );
424
+        $value      = $single ? '' : array();
425
+
426
+        if ( ! empty( $array_keys ) ) {
427
+            // We don't use the $this->meta_data property directly here because we don't want meta with a null value (i.e. meta which has been deleted via $this->delete_meta_data()).
428
+            if ( $single ) {
429
+                $value = $meta_data[ current( $array_keys ) ]->value;
430
+            } else {
431
+                $value = array_intersect_key( $meta_data, array_flip( $array_keys ) );
432
+            }
433
+        }
434
+
435
+        if ( 'view' === $context ) {
436
+            $value = apply_filters( $this->get_hook_prefix() . $key, $value, $this );
437
+        }
438
+
439
+        return $value;
440
+    }
441
+
442
+    /**
443
+     * See if meta data exists, since get_meta always returns a '' or array().
444
+     *
445
+     * @since  1.0.19
446
+     * @param  string $key Meta Key.
447
+     * @return boolean
448
+     */
449
+    public function meta_exists( $key = '' ) {
450
+        $this->maybe_read_meta_data();
451
+        $array_keys = wp_list_pluck( $this->get_meta_data(), 'key' );
452
+        return in_array( $key, $array_keys, true );
453
+    }
454
+
455
+    /**
456
+     * Set all meta data from array.
457
+     *
458
+     * @since 1.0.19
459
+     * @param array $data Key/Value pairs.
460
+     */
461
+    public function set_meta_data( $data ) {
462
+        if ( ! empty( $data ) && is_array( $data ) ) {
463
+            $this->maybe_read_meta_data();
464
+            foreach ( $data as $meta ) {
465
+                $meta = (array) $meta;
466
+                if ( isset( $meta['key'], $meta['value'], $meta['id'] ) ) {
467
+                    $this->meta_data[] = new GetPaid_Meta_Data(
468
+                        array(
469
+                            'id'    => $meta['id'],
470
+                            'key'   => $meta['key'],
471
+                            'value' => $meta['value'],
472
+                        )
473
+                    );
474
+                }
475
+            }
476
+        }
477
+    }
478
+
479
+    /**
480
+     * Add meta data.
481
+     *
482
+     * @since 1.0.19
483
+     *
484
+     * @param string       $key Meta key.
485
+     * @param string|array $value Meta value.
486
+     * @param bool         $unique Should this be a unique key?.
487
+     */
488
+    public function add_meta_data( $key, $value, $unique = false ) {
489
+        if ( $this->is_internal_meta_key( $key ) ) {
490
+            $function = 'set_' . $key;
491
+
492
+            if ( is_callable( array( $this, $function ) ) ) {
493
+                return $this->{$function}( $value );
494
+            }
495
+        }
496
+
497
+        $this->maybe_read_meta_data();
498
+        if ( $unique ) {
499
+            $this->delete_meta_data( $key );
500
+        }
501
+        $this->meta_data[] = new GetPaid_Meta_Data(
502
+            array(
503
+                'key'   => $key,
504
+                'value' => $value,
505
+            )
506
+        );
507
+
508
+        $this->save();
509
+    }
510
+
511
+    /**
512
+     * Update meta data by key or ID, if provided.
513
+     *
514
+     * @since  1.0.19
515
+     *
516
+     * @param  string       $key Meta key.
517
+     * @param  string|array $value Meta value.
518
+     * @param  int          $meta_id Meta ID.
519
+     */
520
+    public function update_meta_data( $key, $value, $meta_id = 0 ) {
521
+        if ( $this->is_internal_meta_key( $key ) ) {
522
+            $function = 'set_' . $key;
523
+
524
+            if ( is_callable( array( $this, $function ) ) ) {
525
+                return $this->{$function}( $value );
526
+            }
527
+        }
528
+
529
+        $this->maybe_read_meta_data();
530
+
531
+        $array_key = false;
532
+
533
+        if ( $meta_id ) {
534
+            $array_keys = array_keys( wp_list_pluck( $this->meta_data, 'id' ), $meta_id, true );
535
+            $array_key  = $array_keys ? current( $array_keys ) : false;
536
+        } else {
537
+            // Find matches by key.
538
+            $matches = array();
539
+            foreach ( $this->meta_data as $meta_data_array_key => $meta ) {
540
+                if ( $meta->key === $key ) {
541
+                    $matches[] = $meta_data_array_key;
542
+                }
543
+            }
544
+
545
+            if ( ! empty( $matches ) ) {
546
+                // Set matches to null so only one key gets the new value.
547
+                foreach ( $matches as $meta_data_array_key ) {
548
+                    $this->meta_data[ $meta_data_array_key ]->value = null;
549
+                }
550
+                $array_key = current( $matches );
551
+            }
552
+        }
553
+
554
+        if ( false !== $array_key ) {
555
+            $meta        = $this->meta_data[ $array_key ];
556
+            $meta->key   = $key;
557
+            $meta->value = $value;
558
+        } else {
559
+            $this->add_meta_data( $key, $value, true );
560
+        }
561
+    }
562
+
563
+    /**
564
+     * Delete meta data.
565
+     *
566
+     * @since 1.0.19
567
+     * @param string $key Meta key.
568
+     */
569
+    public function delete_meta_data( $key ) {
570
+        $this->maybe_read_meta_data();
571
+        $array_keys = array_keys( wp_list_pluck( $this->meta_data, 'key' ), $key, true );
572
+
573
+        if ( $array_keys ) {
574
+            foreach ( $array_keys as $array_key ) {
575
+                $this->meta_data[ $array_key ]->value = null;
576
+            }
577
+        }
578
+    }
579
+
580
+    /**
581
+     * Delete meta data.
582
+     *
583
+     * @since 1.0.19
584
+     * @param int $mid Meta ID.
585
+     */
586
+    public function delete_meta_data_by_mid( $mid ) {
587
+        $this->maybe_read_meta_data();
588
+        $array_keys = array_keys( wp_list_pluck( $this->meta_data, 'id' ), (int) $mid, true );
589
+
590
+        if ( $array_keys ) {
591
+            foreach ( $array_keys as $array_key ) {
592
+                $this->meta_data[ $array_key ]->value = null;
593
+            }
594
+        }
595
+    }
596
+
597
+    /**
598
+     * Read meta data if null.
599
+     *
600
+     * @since 1.0.19
601
+     */
602
+    protected function maybe_read_meta_data() {
603
+        if ( is_null( $this->meta_data ) ) {
604
+            $this->read_meta_data();
605
+        }
606
+    }
607
+
608
+    /**
609
+     * Read Meta Data from the database. Ignore any internal properties.
610
+     * Uses it's own caches because get_metadata does not provide meta_ids.
611
+     *
612
+     * @since 1.0.19
613
+     * @param bool $force_read True to force a new DB read (and update cache).
614
+     */
615
+    public function read_meta_data( $force_read = false ) {
616
+
617
+        // Reset meta data.
618
+        $this->meta_data = array();
619
+
620
+        // Maybe abort early.
621
+        if ( ! $this->get_id() || ! $this->data_store ) {
622
+            return;
623
+        }
624
+
625
+        // Only read from cache if the cache key is set.
626
+        $cache_key = null;
627
+        if ( ! $force_read && ! empty( $this->cache_group ) ) {
628
+            $cache_key     = GetPaid_Cache_Helper::get_cache_prefix( $this->cache_group ) . GetPaid_Cache_Helper::get_cache_prefix( 'object_' . $this->get_id() ) . 'object_meta_' . $this->get_id();
629
+            $raw_meta_data = wp_cache_get( $cache_key, $this->cache_group );
630
+        }
631
+
632
+        // Should we force read?
633
+        if ( empty( $raw_meta_data ) ) {
634
+            $raw_meta_data = $this->data_store->read_meta( $this );
635
+
636
+            if ( ! empty( $cache_key ) ) {
637
+                wp_cache_set( $cache_key, $raw_meta_data, $this->cache_group );
638
+            }
639
+
640
+        }
641
+
642
+        // Set meta data.
643
+        if ( is_array( $raw_meta_data ) ) {
644
+
645
+            foreach ( $raw_meta_data as $meta ) {
646
+                $this->meta_data[] = new GetPaid_Meta_Data(
647
+                    array(
648
+                        'id'    => (int) $meta->meta_id,
649
+                        'key'   => $meta->meta_key,
650
+                        'value' => maybe_unserialize( $meta->meta_value ),
651
+                    )
652
+                );
653
+            }
654
+
655
+        }
656
+
657
+    }
658
+
659
+    /**
660
+     * Update Meta Data in the database.
661
+     *
662
+     * @since 1.0.19
663
+     */
664
+    public function save_meta_data() {
665
+        if ( ! $this->data_store || is_null( $this->meta_data ) ) {
666
+            return;
667
+        }
668
+        foreach ( $this->meta_data as $array_key => $meta ) {
669
+            if ( is_null( $meta->value ) ) {
670
+                if ( ! empty( $meta->id ) ) {
671
+                    $this->data_store->delete_meta( $this, $meta );
672
+                    unset( $this->meta_data[ $array_key ] );
673
+                }
674
+            } elseif ( empty( $meta->id ) ) {
675
+                $meta->id = $this->data_store->add_meta( $this, $meta );
676
+                $meta->apply_changes();
677
+            } else {
678
+                if ( $meta->get_changes() ) {
679
+                    $this->data_store->update_meta( $this, $meta );
680
+                    $meta->apply_changes();
681
+                }
682
+            }
683
+        }
684
+        if ( ! empty( $this->cache_group ) ) {
685
+            $cache_key = GetPaid_Cache_Helper::get_cache_prefix( $this->cache_group ) . GetPaid_Cache_Helper::get_cache_prefix( 'object_' . $this->get_id() ) . 'object_meta_' . $this->get_id();
686
+            wp_cache_delete( $cache_key, $this->cache_group );
687
+        }
688
+    }
689
+
690
+    /**
691
+     * Set ID.
692
+     *
693
+     * @since 1.0.19
694
+     * @param int $id ID.
695
+     */
696
+    public function set_id( $id ) {
697
+        $this->id = absint( $id );
698
+    }
699
+
700
+    /**
701
+     * Sets item status.
702
+     *
703
+     * @since 1.0.19
704
+     * @param string $status New status.
705
+     * @return array details of change.
706
+     */
707
+    public function set_status( $status ) {
708 708
         $old_status = $this->get_status();
709 709
 
710
-		$this->set_prop( 'status', $status );
711
-
712
-		return array(
713
-			'from' => $old_status,
714
-			'to'   => $status,
715
-		);
716
-    }
717
-
718
-	/**
719
-	 * Set all props to default values.
720
-	 *
721
-	 * @since 1.0.19
722
-	 */
723
-	public function set_defaults() {
724
-		$this->data    = $this->default_data;
725
-		$this->changes = array();
726
-		$this->set_object_read( false );
727
-	}
728
-
729
-	/**
730
-	 * Set object read property.
731
-	 *
732
-	 * @since 1.0.19
733
-	 * @param boolean $read Should read?.
734
-	 */
735
-	public function set_object_read( $read = true ) {
736
-		$this->object_read = (bool) $read;
737
-	}
738
-
739
-	/**
740
-	 * Get object read property.
741
-	 *
742
-	 * @since  1.0.19
743
-	 * @return boolean
744
-	 */
745
-	public function get_object_read() {
746
-		return (bool) $this->object_read;
747
-	}
748
-
749
-	/**
750
-	 * Set a collection of props in one go, collect any errors, and return the result.
751
-	 * Only sets using public methods.
752
-	 *
753
-	 * @since  1.0.19
754
-	 *
755
-	 * @param array  $props Key value pairs to set. Key is the prop and should map to a setter function name.
756
-	 * @param string $context In what context to run this.
757
-	 *
758
-	 * @return bool|WP_Error
759
-	 */
760
-	public function set_props( $props, $context = 'set' ) {
761
-		$errors = false;
762
-
763
-		foreach ( $props as $prop => $value ) {
764
-			try {
765
-				/**
766
-				 * Checks if the prop being set is allowed, and the value is not null.
767
-				 */
768
-				if ( is_null( $value ) || in_array( $prop, array( 'prop', 'date_prop', 'meta_data' ), true ) ) {
769
-					continue;
770
-				}
771
-				$setter = "set_$prop";
772
-
773
-				if ( is_callable( array( $this, $setter ) ) ) {
774
-					$this->{$setter}( $value );
775
-				}
776
-			} catch ( Exception $e ) {
777
-				if ( ! $errors ) {
778
-					$errors = new WP_Error();
779
-				}
780
-				$errors->add( $e->getCode(), $e->getMessage() );
781
-				$this->last_error = $e->getMessage();
782
-			}
783
-		}
784
-
785
-		return $errors && count( $errors->get_error_codes() ) ? $errors : true;
786
-	}
787
-
788
-	/**
789
-	 * Sets a prop for a setter method.
790
-	 *
791
-	 * This stores changes in a special array so we can track what needs saving
792
-	 * the the DB later.
793
-	 *
794
-	 * @since 1.0.19
795
-	 * @param string $prop Name of prop to set.
796
-	 * @param mixed  $value Value of the prop.
797
-	 */
798
-	protected function set_prop( $prop, $value ) {
799
-		if ( array_key_exists( $prop, $this->data ) ) {
800
-			if ( true === $this->object_read ) {
801
-				if ( $value !== $this->data[ $prop ] || array_key_exists( $prop, $this->changes ) ) {
802
-					$this->changes[ $prop ] = $value;
803
-				}
804
-			} else {
805
-				$this->data[ $prop ] = $value;
806
-			}
807
-		}
808
-	}
809
-
810
-	/**
811
-	 * Return data changes only.
812
-	 *
813
-	 * @since 1.0.19
814
-	 * @return array
815
-	 */
816
-	public function get_changes() {
817
-		return $this->changes;
818
-	}
819
-
820
-	/**
821
-	 * Merge changes with data and clear.
822
-	 *
823
-	 * @since 1.0.19
824
-	 */
825
-	public function apply_changes() {
826
-		$this->data    = array_replace( $this->data, $this->changes );
827
-		$this->changes = array();
828
-	}
829
-
830
-	/**
831
-	 * Prefix for action and filter hooks on data.
832
-	 *
833
-	 * @since  1.0.19
834
-	 * @return string
835
-	 */
836
-	protected function get_hook_prefix() {
837
-		return 'wpinv_get_' . $this->object_type . '_';
838
-	}
839
-
840
-	/**
841
-	 * Gets a prop for a getter method.
842
-	 *
843
-	 * Gets the value from either current pending changes, or the data itself.
844
-	 * Context controls what happens to the value before it's returned.
845
-	 *
846
-	 * @since  1.0.19
847
-	 * @param  string $prop Name of prop to get.
848
-	 * @param  string $context What the value is for. Valid values are view and edit.
849
-	 * @return mixed
850
-	 */
851
-	protected function get_prop( $prop, $context = 'view' ) {
852
-		$value = null;
853
-
854
-		if ( array_key_exists( $prop, $this->data ) ) {
855
-			$value = array_key_exists( $prop, $this->changes ) ? $this->changes[ $prop ] : $this->data[ $prop ];
856
-
857
-			if ( 'view' === $context ) {
858
-				$value = apply_filters( $this->get_hook_prefix() . $prop, $value, $this );
859
-			}
860
-		}
861
-
862
-		return $value;
863
-	}
864
-
865
-	/**
866
-	 * Sets a date prop whilst handling formatting and datetime objects.
867
-	 *
868
-	 * @since 1.0.19
869
-	 * @param string         $prop Name of prop to set.
870
-	 * @param string|integer $value Value of the prop.
871
-	 */
872
-	protected function set_date_prop( $prop, $value ) {
873
-
874
-		if ( empty( $value ) ) {
875
-			$this->set_prop( $prop, null );
876
-			return;
877
-		}
878
-		$this->set_prop( $prop, $value );
879
-
880
-	}
881
-
882
-	/**
883
-	 * When invalid data is found, throw an exception unless reading from the DB.
884
-	 *
885
-	 * @since 1.0.19
886
-	 * @param string $code             Error code.
887
-	 * @param string $message          Error message.
888
-	 */
889
-	protected function error( $code, $message ) {
890
-		$this->last_error = $message;
891
-	}
892
-
893
-	/**
894
-	 * Checks if the object is saved in the database
895
-	 *
896
-	 * @since 1.0.19
897
-	 * @return bool
898
-	 */
899
-	public function exists() {
900
-		$id = $this->get_id();
901
-		return ! empty( $id );
902
-	}
710
+        $this->set_prop( 'status', $status );
711
+
712
+        return array(
713
+            'from' => $old_status,
714
+            'to'   => $status,
715
+        );
716
+    }
717
+
718
+    /**
719
+     * Set all props to default values.
720
+     *
721
+     * @since 1.0.19
722
+     */
723
+    public function set_defaults() {
724
+        $this->data    = $this->default_data;
725
+        $this->changes = array();
726
+        $this->set_object_read( false );
727
+    }
728
+
729
+    /**
730
+     * Set object read property.
731
+     *
732
+     * @since 1.0.19
733
+     * @param boolean $read Should read?.
734
+     */
735
+    public function set_object_read( $read = true ) {
736
+        $this->object_read = (bool) $read;
737
+    }
738
+
739
+    /**
740
+     * Get object read property.
741
+     *
742
+     * @since  1.0.19
743
+     * @return boolean
744
+     */
745
+    public function get_object_read() {
746
+        return (bool) $this->object_read;
747
+    }
748
+
749
+    /**
750
+     * Set a collection of props in one go, collect any errors, and return the result.
751
+     * Only sets using public methods.
752
+     *
753
+     * @since  1.0.19
754
+     *
755
+     * @param array  $props Key value pairs to set. Key is the prop and should map to a setter function name.
756
+     * @param string $context In what context to run this.
757
+     *
758
+     * @return bool|WP_Error
759
+     */
760
+    public function set_props( $props, $context = 'set' ) {
761
+        $errors = false;
762
+
763
+        foreach ( $props as $prop => $value ) {
764
+            try {
765
+                /**
766
+                 * Checks if the prop being set is allowed, and the value is not null.
767
+                 */
768
+                if ( is_null( $value ) || in_array( $prop, array( 'prop', 'date_prop', 'meta_data' ), true ) ) {
769
+                    continue;
770
+                }
771
+                $setter = "set_$prop";
772
+
773
+                if ( is_callable( array( $this, $setter ) ) ) {
774
+                    $this->{$setter}( $value );
775
+                }
776
+            } catch ( Exception $e ) {
777
+                if ( ! $errors ) {
778
+                    $errors = new WP_Error();
779
+                }
780
+                $errors->add( $e->getCode(), $e->getMessage() );
781
+                $this->last_error = $e->getMessage();
782
+            }
783
+        }
784
+
785
+        return $errors && count( $errors->get_error_codes() ) ? $errors : true;
786
+    }
787
+
788
+    /**
789
+     * Sets a prop for a setter method.
790
+     *
791
+     * This stores changes in a special array so we can track what needs saving
792
+     * the the DB later.
793
+     *
794
+     * @since 1.0.19
795
+     * @param string $prop Name of prop to set.
796
+     * @param mixed  $value Value of the prop.
797
+     */
798
+    protected function set_prop( $prop, $value ) {
799
+        if ( array_key_exists( $prop, $this->data ) ) {
800
+            if ( true === $this->object_read ) {
801
+                if ( $value !== $this->data[ $prop ] || array_key_exists( $prop, $this->changes ) ) {
802
+                    $this->changes[ $prop ] = $value;
803
+                }
804
+            } else {
805
+                $this->data[ $prop ] = $value;
806
+            }
807
+        }
808
+    }
809
+
810
+    /**
811
+     * Return data changes only.
812
+     *
813
+     * @since 1.0.19
814
+     * @return array
815
+     */
816
+    public function get_changes() {
817
+        return $this->changes;
818
+    }
819
+
820
+    /**
821
+     * Merge changes with data and clear.
822
+     *
823
+     * @since 1.0.19
824
+     */
825
+    public function apply_changes() {
826
+        $this->data    = array_replace( $this->data, $this->changes );
827
+        $this->changes = array();
828
+    }
829
+
830
+    /**
831
+     * Prefix for action and filter hooks on data.
832
+     *
833
+     * @since  1.0.19
834
+     * @return string
835
+     */
836
+    protected function get_hook_prefix() {
837
+        return 'wpinv_get_' . $this->object_type . '_';
838
+    }
839
+
840
+    /**
841
+     * Gets a prop for a getter method.
842
+     *
843
+     * Gets the value from either current pending changes, or the data itself.
844
+     * Context controls what happens to the value before it's returned.
845
+     *
846
+     * @since  1.0.19
847
+     * @param  string $prop Name of prop to get.
848
+     * @param  string $context What the value is for. Valid values are view and edit.
849
+     * @return mixed
850
+     */
851
+    protected function get_prop( $prop, $context = 'view' ) {
852
+        $value = null;
853
+
854
+        if ( array_key_exists( $prop, $this->data ) ) {
855
+            $value = array_key_exists( $prop, $this->changes ) ? $this->changes[ $prop ] : $this->data[ $prop ];
856
+
857
+            if ( 'view' === $context ) {
858
+                $value = apply_filters( $this->get_hook_prefix() . $prop, $value, $this );
859
+            }
860
+        }
861
+
862
+        return $value;
863
+    }
864
+
865
+    /**
866
+     * Sets a date prop whilst handling formatting and datetime objects.
867
+     *
868
+     * @since 1.0.19
869
+     * @param string         $prop Name of prop to set.
870
+     * @param string|integer $value Value of the prop.
871
+     */
872
+    protected function set_date_prop( $prop, $value ) {
873
+
874
+        if ( empty( $value ) ) {
875
+            $this->set_prop( $prop, null );
876
+            return;
877
+        }
878
+        $this->set_prop( $prop, $value );
879
+
880
+    }
881
+
882
+    /**
883
+     * When invalid data is found, throw an exception unless reading from the DB.
884
+     *
885
+     * @since 1.0.19
886
+     * @param string $code             Error code.
887
+     * @param string $message          Error message.
888
+     */
889
+    protected function error( $code, $message ) {
890
+        $this->last_error = $message;
891
+    }
892
+
893
+    /**
894
+     * Checks if the object is saved in the database
895
+     *
896
+     * @since 1.0.19
897
+     * @return bool
898
+     */
899
+    public function exists() {
900
+        $id = $this->get_id();
901
+        return ! empty( $id );
902
+    }
903 903
 
904 904
 }
Please login to merge, or discard this patch.
includes/payments/class-getpaid-payment-form-submission.php 1 patch
Indentation   +793 added lines, -793 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 if ( ! defined( 'ABSPATH' ) ) {
3
-	exit;
3
+    exit;
4 4
 }
5 5
 
6 6
 /**
@@ -10,187 +10,187 @@  discard block
 block discarded – undo
10 10
 class GetPaid_Payment_Form_Submission {
11 11
 
12 12
     /**
13
-	 * Submission ID
14
-	 *
15
-	 * @var string
16
-	 */
17
-	public $id = null;
18
-
19
-	/**
20
-	 * The raw submission data.
21
-	 *
22
-	 * @var array
23
-	 */
24
-	protected $data = null;
25
-
26
-	/**
27
-	 * Submission totals
28
-	 *
29
-	 * @var array
30
-	 */
31
-	protected $totals = array(
32
-
33
-		'subtotal'      => array(
34
-			'initial'   => 0,
35
-			'recurring' => 0,
36
-		),
37
-
38
-		'discount'      => array(
39
-			'initial'   => 0,
40
-			'recurring' => 0,
41
-		),
42
-
43
-		'fees'          => array(
44
-			'initial'   => 0,
45
-			'recurring' => 0,
46
-		),
47
-
48
-		'taxes'         => array(
49
-			'initial'   => 0,
50
-			'recurring' => 0,
51
-		),
52
-
53
-	);
54
-
55
-	/**
56
-	 * Sets the associated payment form.
57
-	 *
58
-	 * @var GetPaid_Payment_Form
59
-	 */
13
+     * Submission ID
14
+     *
15
+     * @var string
16
+     */
17
+    public $id = null;
18
+
19
+    /**
20
+     * The raw submission data.
21
+     *
22
+     * @var array
23
+     */
24
+    protected $data = null;
25
+
26
+    /**
27
+     * Submission totals
28
+     *
29
+     * @var array
30
+     */
31
+    protected $totals = array(
32
+
33
+        'subtotal'      => array(
34
+            'initial'   => 0,
35
+            'recurring' => 0,
36
+        ),
37
+
38
+        'discount'      => array(
39
+            'initial'   => 0,
40
+            'recurring' => 0,
41
+        ),
42
+
43
+        'fees'          => array(
44
+            'initial'   => 0,
45
+            'recurring' => 0,
46
+        ),
47
+
48
+        'taxes'         => array(
49
+            'initial'   => 0,
50
+            'recurring' => 0,
51
+        ),
52
+
53
+    );
54
+
55
+    /**
56
+     * Sets the associated payment form.
57
+     *
58
+     * @var GetPaid_Payment_Form
59
+     */
60 60
     protected $payment_form = null;
61 61
 
62 62
     /**
63
-	 * The country for the submission.
64
-	 *
65
-	 * @var string
66
-	 */
67
-	public $country = null;
68
-
69
-    /**
70
-	 * The state for the submission.
71
-	 *
72
-	 * @since 1.0.19
73
-	 * @var string
74
-	 */
75
-	public $state = null;
76
-
77
-	/**
78
-	 * The invoice associated with the submission.
79
-	 *
80
-	 * @var WPInv_Invoice
81
-	 */
82
-	protected $invoice = null;
83
-
84
-	/**
85
-	 * The recurring item for the submission.
86
-	 *
87
-	 * @var int
88
-	 */
89
-	public $has_recurring = 0;
90
-
91
-	/**
92
-	 * An array of fees for the submission.
93
-	 *
94
-	 * @var array
95
-	 */
96
-	protected $fees = array();
97
-
98
-	/**
99
-	 * An array of discounts for the submission.
100
-	 *
101
-	 * @var array
102
-	 */
103
-	protected $discounts = array();
104
-
105
-	/**
106
-	 * An array of taxes for the submission.
107
-	 *
108
-	 * @var array
109
-	 */
110
-	protected $taxes = array();
111
-
112
-	/**
113
-	 * An array of items for the submission.
114
-	 *
115
-	 * @var GetPaid_Form_Item[]
116
-	 */
117
-	protected $items = array();
118
-
119
-	/**
120
-	 * The last error.
121
-	 *
122
-	 * @var string
123
-	 */
124
-	public $last_error = null;
125
-
126
-    /**
127
-	 * Class constructor.
128
-	 *
129
-	 */
130
-	public function __construct() {
131
-
132
-		// Set the state and country to the default state and country.
133
-		$this->country = wpinv_default_billing_country();
134
-		$this->state   = wpinv_get_default_state();
135
-
136
-		// Do we have an actual submission?
137
-		if ( isset( $_POST['getpaid_payment_form_submission'] ) ) {
138
-			$this->load_data( $_POST );
139
-		}
140
-
141
-	}
142
-
143
-	/**
144
-	 * Loads submission data.
145
-	 *
146
-	 * @param array $data
147
-	 */
148
-	public function load_data( $data ) {
149
-
150
-		// Remove slashes from the submitted data...
151
-		$data       = wp_unslash( $data );
152
-
153
-		// Allow plugins to filter the data.
154
-		$data       = apply_filters( 'getpaid_submission_data', $data, $this );
155
-
156
-		// Cache it...
157
-		$this->data = $data;
158
-
159
-		// Then generate a unique id from the data.
160
-		$this->id   = md5( wp_json_encode( $data ) );
161
-
162
-		// Finally, process the submission.
163
-		try {
164
-
165
-			// Each process is passed an instance of the class (with reference)
166
-			// and should throw an Exception whenever it encounters one.
167
-			$processors = apply_filters(
168
-				'getpaid_payment_form_submission_processors',
169
-				array(
170
-					array( $this, 'process_payment_form' ),
171
-					array( $this, 'process_invoice' ),
172
-					array( $this, 'process_fees' ),
173
-					array( $this, 'process_items' ),
174
-					array( $this, 'process_discount' ),
175
-					array( $this, 'process_taxes' ),
176
-				),
177
-				$this		
178
-			);
179
-
180
-			foreach ( $processors as $processor ) {
181
-				call_user_func_array( $processor, array( &$this ) );
182
-			}
183
-
184
-		} catch ( Exception $e ) {
185
-			$this->last_error = $e->getMessage();
186
-		}
187
-
188
-		// Fired when we are done processing a submission.
189
-		do_action_ref_array( 'getpaid_process_submission', array( &$this ) );
190
-
191
-	}
192
-
193
-	/*
63
+     * The country for the submission.
64
+     *
65
+     * @var string
66
+     */
67
+    public $country = null;
68
+
69
+    /**
70
+     * The state for the submission.
71
+     *
72
+     * @since 1.0.19
73
+     * @var string
74
+     */
75
+    public $state = null;
76
+
77
+    /**
78
+     * The invoice associated with the submission.
79
+     *
80
+     * @var WPInv_Invoice
81
+     */
82
+    protected $invoice = null;
83
+
84
+    /**
85
+     * The recurring item for the submission.
86
+     *
87
+     * @var int
88
+     */
89
+    public $has_recurring = 0;
90
+
91
+    /**
92
+     * An array of fees for the submission.
93
+     *
94
+     * @var array
95
+     */
96
+    protected $fees = array();
97
+
98
+    /**
99
+     * An array of discounts for the submission.
100
+     *
101
+     * @var array
102
+     */
103
+    protected $discounts = array();
104
+
105
+    /**
106
+     * An array of taxes for the submission.
107
+     *
108
+     * @var array
109
+     */
110
+    protected $taxes = array();
111
+
112
+    /**
113
+     * An array of items for the submission.
114
+     *
115
+     * @var GetPaid_Form_Item[]
116
+     */
117
+    protected $items = array();
118
+
119
+    /**
120
+     * The last error.
121
+     *
122
+     * @var string
123
+     */
124
+    public $last_error = null;
125
+
126
+    /**
127
+     * Class constructor.
128
+     *
129
+     */
130
+    public function __construct() {
131
+
132
+        // Set the state and country to the default state and country.
133
+        $this->country = wpinv_default_billing_country();
134
+        $this->state   = wpinv_get_default_state();
135
+
136
+        // Do we have an actual submission?
137
+        if ( isset( $_POST['getpaid_payment_form_submission'] ) ) {
138
+            $this->load_data( $_POST );
139
+        }
140
+
141
+    }
142
+
143
+    /**
144
+     * Loads submission data.
145
+     *
146
+     * @param array $data
147
+     */
148
+    public function load_data( $data ) {
149
+
150
+        // Remove slashes from the submitted data...
151
+        $data       = wp_unslash( $data );
152
+
153
+        // Allow plugins to filter the data.
154
+        $data       = apply_filters( 'getpaid_submission_data', $data, $this );
155
+
156
+        // Cache it...
157
+        $this->data = $data;
158
+
159
+        // Then generate a unique id from the data.
160
+        $this->id   = md5( wp_json_encode( $data ) );
161
+
162
+        // Finally, process the submission.
163
+        try {
164
+
165
+            // Each process is passed an instance of the class (with reference)
166
+            // and should throw an Exception whenever it encounters one.
167
+            $processors = apply_filters(
168
+                'getpaid_payment_form_submission_processors',
169
+                array(
170
+                    array( $this, 'process_payment_form' ),
171
+                    array( $this, 'process_invoice' ),
172
+                    array( $this, 'process_fees' ),
173
+                    array( $this, 'process_items' ),
174
+                    array( $this, 'process_discount' ),
175
+                    array( $this, 'process_taxes' ),
176
+                ),
177
+                $this		
178
+            );
179
+
180
+            foreach ( $processors as $processor ) {
181
+                call_user_func_array( $processor, array( &$this ) );
182
+            }
183
+
184
+        } catch ( Exception $e ) {
185
+            $this->last_error = $e->getMessage();
186
+        }
187
+
188
+        // Fired when we are done processing a submission.
189
+        do_action_ref_array( 'getpaid_process_submission', array( &$this ) );
190
+
191
+    }
192
+
193
+    /*
194 194
 	|--------------------------------------------------------------------------
195 195
 	| Payment Forms.
196 196
 	|--------------------------------------------------------------------------
@@ -199,39 +199,39 @@  discard block
 block discarded – undo
199 199
 	| submission has an active payment form etc.
200 200
     */
201 201
 
202
-	/**
203
-	 * Prepares the submission's payment form.
204
-	 *
205
-	 * @since 1.0.19
206
-	 */
207
-	public function process_payment_form() {
202
+    /**
203
+     * Prepares the submission's payment form.
204
+     *
205
+     * @since 1.0.19
206
+     */
207
+    public function process_payment_form() {
208 208
 
209
-		// Every submission needs an active payment form.
210
-		if ( empty( $this->data['form_id'] ) ) {
211
-			throw new Exception( __( 'Missing payment form', 'invoicing' ) );
212
-		}
209
+        // Every submission needs an active payment form.
210
+        if ( empty( $this->data['form_id'] ) ) {
211
+            throw new Exception( __( 'Missing payment form', 'invoicing' ) );
212
+        }
213 213
 
214
-		// Fetch the payment form.
215
-		$this->payment_form = new GetPaid_Payment_Form( $this->data['form_id'] );
214
+        // Fetch the payment form.
215
+        $this->payment_form = new GetPaid_Payment_Form( $this->data['form_id'] );
216 216
 
217
-		if ( ! $this->payment_form->is_active() ) {
218
-			throw new Exception( __( 'Payment form not active', 'invoicing' ) );
219
-		}
217
+        if ( ! $this->payment_form->is_active() ) {
218
+            throw new Exception( __( 'Payment form not active', 'invoicing' ) );
219
+        }
220 220
 
221
-		do_action_ref_array( 'getpaid_submissions_process_payment_form', array( &$this ) );
222
-	}
221
+        do_action_ref_array( 'getpaid_submissions_process_payment_form', array( &$this ) );
222
+    }
223 223
 
224 224
     /**
225
-	 * Returns the payment form.
226
-	 *
227
-	 * @since 1.0.19
228
-	 * @return GetPaid_Payment_Form
229
-	 */
230
-	public function get_payment_form() {
231
-		return $this->payment_form;
232
-	}
225
+     * Returns the payment form.
226
+     *
227
+     * @since 1.0.19
228
+     * @return GetPaid_Payment_Form
229
+     */
230
+    public function get_payment_form() {
231
+        return $this->payment_form;
232
+    }
233 233
 
234
-	/*
234
+    /*
235 235
 	|--------------------------------------------------------------------------
236 236
 	| Invoices.
237 237
 	|--------------------------------------------------------------------------
@@ -240,84 +240,84 @@  discard block
 block discarded – undo
240 240
 	| might be for an existing invoice.
241 241
 	*/
242 242
 
243
-	/**
244
-	 * Prepares the submission's invoice.
245
-	 *
246
-	 * @since 1.0.19
247
-	 */
248
-	public function process_invoice() {
243
+    /**
244
+     * Prepares the submission's invoice.
245
+     *
246
+     * @since 1.0.19
247
+     */
248
+    public function process_invoice() {
249 249
 
250
-		// Abort if there is no invoice.
251
-		if ( empty( $this->data['invoice_id'] ) ) {
252
-			return;
253
-		}
250
+        // Abort if there is no invoice.
251
+        if ( empty( $this->data['invoice_id'] ) ) {
252
+            return;
253
+        }
254 254
 
255
-		// If the submission is for an existing invoice, ensure that it exists
256
-		// and that it is not paid for.
257
-		$invoice = wpinv_get_invoice( $this->data['invoice_id'] );
255
+        // If the submission is for an existing invoice, ensure that it exists
256
+        // and that it is not paid for.
257
+        $invoice = wpinv_get_invoice( $this->data['invoice_id'] );
258 258
 
259 259
         if ( empty( $invoice ) ) {
260
-			throw new Exception( __( 'Invalid invoice', 'invoicing' ) );
261
-		}
260
+            throw new Exception( __( 'Invalid invoice', 'invoicing' ) );
261
+        }
262 262
 
263
-		if ( $invoice->is_paid() ) {
264
-			throw new Exception( __( 'This invoice is already paid for.', 'invoicing' ) );
265
-		}
263
+        if ( $invoice->is_paid() ) {
264
+            throw new Exception( __( 'This invoice is already paid for.', 'invoicing' ) );
265
+        }
266 266
 
267
-		$this->payment_form->invoice = $invoice;
268
-		if ( ! $this->payment_form->is_default() ) {
267
+        $this->payment_form->invoice = $invoice;
268
+        if ( ! $this->payment_form->is_default() ) {
269 269
 
270
-			$items    = array();
271
-			$item_ids = array();
270
+            $items    = array();
271
+            $item_ids = array();
272 272
 	
273
-			foreach ( $invoice->get_items() as $item ) {
274
-				if ( ! in_array( $item->get_id(), $item_ids ) ) {
275
-					$item_ids[] = $item->get_id();
276
-					$items[]    = $item;
277
-				}
278
-			}
273
+            foreach ( $invoice->get_items() as $item ) {
274
+                if ( ! in_array( $item->get_id(), $item_ids ) ) {
275
+                    $item_ids[] = $item->get_id();
276
+                    $items[]    = $item;
277
+                }
278
+            }
279 279
 	
280
-			foreach ( $this->payment_form->get_items() as $item ) {
281
-				if ( ! in_array( $item->get_id(), $item_ids ) ) {
282
-					$item_ids[] = $item->get_id();
283
-					$items[]    = $item;
284
-				}
285
-			}
280
+            foreach ( $this->payment_form->get_items() as $item ) {
281
+                if ( ! in_array( $item->get_id(), $item_ids ) ) {
282
+                    $item_ids[] = $item->get_id();
283
+                    $items[]    = $item;
284
+                }
285
+            }
286 286
 	
287
-			$this->payment_form->set_items( $items );
287
+            $this->payment_form->set_items( $items );
288 288
 	
289
-		} else {
290
-			$this->payment_form->set_items( $invoice->get_items() );
291
-		}
292
-
293
-		$this->country = $invoice->get_country();
294
-		$this->state   = $invoice->get_state();
295
-		$this->invoice = $invoice;
296
-
297
-		do_action_ref_array( 'getpaid_submissions_process_invoice', array( &$this ) );
298
-	}
299
-
300
-	/**
301
-	 * Returns the associated invoice.
302
-	 *
303
-	 * @since 1.0.19
304
-	 * @return WPInv_Invoice
305
-	 */
306
-	public function get_invoice() {
307
-		return $this->invoice;
308
-	}
309
-
310
-	/**
311
-	 * Checks whether there is an invoice associated with this submission.
312
-	 *
313
-	 * @since 1.0.19
314
-	 * @return bool
315
-	 */
316
-	public function has_invoice() {
317
-		return ! empty( $this->invoice );
318
-	}
319
-
320
-	/*
289
+        } else {
290
+            $this->payment_form->set_items( $invoice->get_items() );
291
+        }
292
+
293
+        $this->country = $invoice->get_country();
294
+        $this->state   = $invoice->get_state();
295
+        $this->invoice = $invoice;
296
+
297
+        do_action_ref_array( 'getpaid_submissions_process_invoice', array( &$this ) );
298
+    }
299
+
300
+    /**
301
+     * Returns the associated invoice.
302
+     *
303
+     * @since 1.0.19
304
+     * @return WPInv_Invoice
305
+     */
306
+    public function get_invoice() {
307
+        return $this->invoice;
308
+    }
309
+
310
+    /**
311
+     * Checks whether there is an invoice associated with this submission.
312
+     *
313
+     * @since 1.0.19
314
+     * @return bool
315
+     */
316
+    public function has_invoice() {
317
+        return ! empty( $this->invoice );
318
+    }
319
+
320
+    /*
321 321
 	|--------------------------------------------------------------------------
322 322
 	| Items.
323 323
 	|--------------------------------------------------------------------------
@@ -326,115 +326,115 @@  discard block
 block discarded – undo
326 326
 	| recurring item. But can have an unlimited number of non-recurring items.
327 327
 	*/
328 328
 
329
-	/**
330
-	 * Prepares the submission's items.
331
-	 *
332
-	 * @since 1.0.19
333
-	 */
334
-	public function process_items() {
335
-
336
-		$processor = new GetPaid_Payment_Form_Submission_Items( $this );
337
-
338
-		foreach ( $processor->items as $item ) {
339
-			$this->add_item( $item );
340
-		}
341
-
342
-		do_action_ref_array( 'getpaid_submissions_process_items', array( &$this ) );
343
-	}
344
-
345
-	/**
346
-	 * Adds an item to the submission.
347
-	 *
348
-	 * @since 1.0.19
349
-	 * @param GetPaid_Form_Item $item
350
-	 */
351
-	public function add_item( $item ) {
352
-
353
-		// Make sure that it is available for purchase.
354
-		if ( ! $item->can_purchase() || isset( $this->items[ $item->get_id() ] ) ) {
355
-			return;
356
-		}
357
-
358
-		// Each submission can only contain one recurring item.
359
-		if ( $item->is_recurring() ) {
360
-
361
-			if ( $this->has_recurring != 0 ) {
362
-				throw new Exception( __( 'You can only buy one recurring item at a time.', 'invoicing' ) );
363
-			}
364
-
365
-			$this->has_recurring = $item->get_id();
366
-
367
-		}
368
-
369
-		// Update the items and totals.
370
-		$this->items[ $item->get_id() ]         = $item;
371
-		$this->totals['subtotal']['initial']   += $item->get_sub_total();
372
-		$this->totals['subtotal']['recurring'] += $item->get_recurring_sub_total();
373
-
374
-	}
375
-
376
-	/**
377
-	 * Removes a specific item.
378
-	 * 
379
-	 * You should not call this method after the discounts and taxes
380
-	 * have been calculated.
381
-	 *
382
-	 * @since 1.0.19
383
-	 */
384
-	public function remove_item( $item_id ) {
385
-
386
-		if ( isset( $this->items[ $item_id ] ) ) {
387
-			$this->totals['subtotal']['initial']   -= $this->items[ $item_id ]->get_sub_total();
388
-			$this->totals['subtotal']['recurring'] -= $this->items[ $item_id ]->get_recurring_sub_total();
389
-
390
-			if ( $this->items[ $item_id ]->is_recurring() ) {
391
-				$this->has_recurring = 0;
392
-			}
393
-
394
-			unset( $this->items[ $item_id ] );
395
-		}
396
-
397
-	}
398
-
399
-	/**
400
-	 * Returns the subtotal.
401
-	 *
402
-	 * @since 1.0.19
403
-	 */
404
-	public function get_subtotal() {
405
-
406
-		if ( wpinv_prices_include_tax() ) {
407
-			return $this->totals['subtotal']['initial'] - $this->totals['taxes']['initial'];
408
-		}
409
-
410
-		return $this->totals['subtotal']['initial'];
411
-	}
412
-
413
-	/**
414
-	 * Returns the recurring subtotal.
415
-	 *
416
-	 * @since 1.0.19
417
-	 */
418
-	public function get_recurring_subtotal() {
419
-
420
-		if ( wpinv_prices_include_tax() ) {
421
-			return $this->totals['subtotal']['recurring'] - $this->totals['taxes']['recurring'];
422
-		}
423
-
424
-		return $this->totals['subtotal']['recurring'];
425
-	}
426
-
427
-	/**
428
-	 * Returns all items.
429
-	 *
430
-	 * @since 1.0.19
431
-	 * @return GetPaid_Form_Item[]
432
-	 */
433
-	public function get_items() {
434
-		return $this->items;
435
-	}
436
-
437
-	/*
329
+    /**
330
+     * Prepares the submission's items.
331
+     *
332
+     * @since 1.0.19
333
+     */
334
+    public function process_items() {
335
+
336
+        $processor = new GetPaid_Payment_Form_Submission_Items( $this );
337
+
338
+        foreach ( $processor->items as $item ) {
339
+            $this->add_item( $item );
340
+        }
341
+
342
+        do_action_ref_array( 'getpaid_submissions_process_items', array( &$this ) );
343
+    }
344
+
345
+    /**
346
+     * Adds an item to the submission.
347
+     *
348
+     * @since 1.0.19
349
+     * @param GetPaid_Form_Item $item
350
+     */
351
+    public function add_item( $item ) {
352
+
353
+        // Make sure that it is available for purchase.
354
+        if ( ! $item->can_purchase() || isset( $this->items[ $item->get_id() ] ) ) {
355
+            return;
356
+        }
357
+
358
+        // Each submission can only contain one recurring item.
359
+        if ( $item->is_recurring() ) {
360
+
361
+            if ( $this->has_recurring != 0 ) {
362
+                throw new Exception( __( 'You can only buy one recurring item at a time.', 'invoicing' ) );
363
+            }
364
+
365
+            $this->has_recurring = $item->get_id();
366
+
367
+        }
368
+
369
+        // Update the items and totals.
370
+        $this->items[ $item->get_id() ]         = $item;
371
+        $this->totals['subtotal']['initial']   += $item->get_sub_total();
372
+        $this->totals['subtotal']['recurring'] += $item->get_recurring_sub_total();
373
+
374
+    }
375
+
376
+    /**
377
+     * Removes a specific item.
378
+     * 
379
+     * You should not call this method after the discounts and taxes
380
+     * have been calculated.
381
+     *
382
+     * @since 1.0.19
383
+     */
384
+    public function remove_item( $item_id ) {
385
+
386
+        if ( isset( $this->items[ $item_id ] ) ) {
387
+            $this->totals['subtotal']['initial']   -= $this->items[ $item_id ]->get_sub_total();
388
+            $this->totals['subtotal']['recurring'] -= $this->items[ $item_id ]->get_recurring_sub_total();
389
+
390
+            if ( $this->items[ $item_id ]->is_recurring() ) {
391
+                $this->has_recurring = 0;
392
+            }
393
+
394
+            unset( $this->items[ $item_id ] );
395
+        }
396
+
397
+    }
398
+
399
+    /**
400
+     * Returns the subtotal.
401
+     *
402
+     * @since 1.0.19
403
+     */
404
+    public function get_subtotal() {
405
+
406
+        if ( wpinv_prices_include_tax() ) {
407
+            return $this->totals['subtotal']['initial'] - $this->totals['taxes']['initial'];
408
+        }
409
+
410
+        return $this->totals['subtotal']['initial'];
411
+    }
412
+
413
+    /**
414
+     * Returns the recurring subtotal.
415
+     *
416
+     * @since 1.0.19
417
+     */
418
+    public function get_recurring_subtotal() {
419
+
420
+        if ( wpinv_prices_include_tax() ) {
421
+            return $this->totals['subtotal']['recurring'] - $this->totals['taxes']['recurring'];
422
+        }
423
+
424
+        return $this->totals['subtotal']['recurring'];
425
+    }
426
+
427
+    /**
428
+     * Returns all items.
429
+     *
430
+     * @since 1.0.19
431
+     * @return GetPaid_Form_Item[]
432
+     */
433
+    public function get_items() {
434
+        return $this->items;
435
+    }
436
+
437
+    /*
438 438
 	|--------------------------------------------------------------------------
439 439
 	| Taxes
440 440
 	|--------------------------------------------------------------------------
@@ -443,128 +443,128 @@  discard block
 block discarded – undo
443 443
 	| or only one-time.
444 444
     */
445 445
 
446
-	/**
447
-	 * Prepares the submission's taxes.
448
-	 *
449
-	 * @since 1.0.19
450
-	 */
451
-	public function process_taxes() {
452
-
453
-		// Abort if we're not using taxes.
454
-		if ( ! $this->use_taxes() ) {
455
-			return;
456
-		}
457
-
458
-		// If a custom country && state has been passed in, use it to calculate taxes.
459
-		$country = $this->get_field( 'wpinv_country', 'billing' );
460
-		if ( ! empty( $country ) ) {
461
-			$this->country = $country;
462
-		}
463
-
464
-		$state = $this->get_field( 'wpinv_state', 'billing' );
465
-		if ( ! empty( $state ) ) {
466
-			$this->state = $state;
467
-		}
468
-
469
-		// Confirm if the provided country and the ip country are similar.
470
-		$address_confirmed = $this->get_field( 'confirm-address' );
471
-		if ( wpinv_should_validate_vat_number() && getpaid_get_ip_country() != $this->country && empty( $address_confirmed ) ) {
472
-			throw new Exception( __( 'The country of your current location must be the same as the country of your billing location or you must confirm the billing address is your home country.', 'invoicing' ) );
473
-		}
474
-
475
-		// Abort if the country is not taxable.
476
-		if ( ! wpinv_is_country_taxable( $this->country ) ) {
477
-			return;
478
-		}
479
-
480
-		$processor = new GetPaid_Payment_Form_Submission_Taxes( $this );
481
-
482
-		foreach ( $processor->taxes as $tax ) {
483
-			$this->add_tax( $tax );
484
-		}
485
-
486
-		do_action_ref_array( 'getpaid_submissions_process_taxes', array( &$this ) );
487
-	}
488
-
489
-	/**
490
-	 * Adds a tax to the submission.
491
-	 *
492
-	 * @param array $tax An array of tax details. name, initial_tax, and recurring_tax are required.
493
-	 * @since 1.0.19
494
-	 */
495
-	public function add_tax( $tax ) {
496
-
497
-		if ( wpinv_round_tax_per_tax_rate() ) {
498
-			$tax['initial_tax']   = wpinv_round_amount( $tax['initial_tax'] );
499
-			$tax['recurring_tax'] = wpinv_round_amount( $tax['recurring_tax'] );
500
-		}
501
-
502
-		$this->taxes[ $tax['name'] ]         = $tax;
503
-		$this->totals['taxes']['initial']   += wpinv_sanitize_amount( $tax['initial_tax'] );
504
-		$this->totals['taxes']['recurring'] += wpinv_sanitize_amount( $tax['recurring_tax'] );
505
-
506
-	}
507
-
508
-	/**
509
-	 * Removes a specific tax.
510
-	 *
511
-	 * @since 1.0.19
512
-	 */
513
-	public function remove_tax( $tax_name ) {
514
-
515
-		if ( isset( $this->taxes[ $tax_name ] ) ) {
516
-			$this->totals['taxes']['initial']   -= $this->taxes[ $tax_name ]['initial_tax'];
517
-			$this->totals['taxes']['recurring'] -= $this->taxes[ $tax_name ]['recurring_tax'];
518
-			unset( $this->taxes[ $tax_name ] );
519
-		}
520
-
521
-	}
522
-
523
-	/**
524
-	 * Whether or not we'll use taxes for the submission.
525
-	 *
526
-	 * @since 1.0.19
527
-	 */
528
-	public function use_taxes() {
529
-
530
-		$use_taxes = wpinv_use_taxes();
531
-
532
-		if ( $this->has_invoice() && ! $this->invoice->is_taxable() ) {
533
-			$use_taxes = false;
534
-		}
535
-
536
-		return apply_filters( 'getpaid_submission_use_taxes', $use_taxes, $this );
537
-
538
-	}
539
-
540
-	/**
541
-	 * Returns the tax.
542
-	 *
543
-	 * @since 1.0.19
544
-	 */
545
-	public function get_tax() {
546
-		return $this->totals['taxes']['initial'];
547
-	}
548
-
549
-	/**
550
-	 * Returns the recurring tax.
551
-	 *
552
-	 * @since 1.0.19
553
-	 */
554
-	public function get_recurring_tax() {
555
-		return $this->totals['taxes']['recurring'];
556
-	}
557
-
558
-	/**
559
-	 * Returns all taxes.
560
-	 *
561
-	 * @since 1.0.19
562
-	 */
563
-	public function get_taxes() {
564
-		return $this->taxes;
565
-	}
566
-
567
-	/*
446
+    /**
447
+     * Prepares the submission's taxes.
448
+     *
449
+     * @since 1.0.19
450
+     */
451
+    public function process_taxes() {
452
+
453
+        // Abort if we're not using taxes.
454
+        if ( ! $this->use_taxes() ) {
455
+            return;
456
+        }
457
+
458
+        // If a custom country && state has been passed in, use it to calculate taxes.
459
+        $country = $this->get_field( 'wpinv_country', 'billing' );
460
+        if ( ! empty( $country ) ) {
461
+            $this->country = $country;
462
+        }
463
+
464
+        $state = $this->get_field( 'wpinv_state', 'billing' );
465
+        if ( ! empty( $state ) ) {
466
+            $this->state = $state;
467
+        }
468
+
469
+        // Confirm if the provided country and the ip country are similar.
470
+        $address_confirmed = $this->get_field( 'confirm-address' );
471
+        if ( wpinv_should_validate_vat_number() && getpaid_get_ip_country() != $this->country && empty( $address_confirmed ) ) {
472
+            throw new Exception( __( 'The country of your current location must be the same as the country of your billing location or you must confirm the billing address is your home country.', 'invoicing' ) );
473
+        }
474
+
475
+        // Abort if the country is not taxable.
476
+        if ( ! wpinv_is_country_taxable( $this->country ) ) {
477
+            return;
478
+        }
479
+
480
+        $processor = new GetPaid_Payment_Form_Submission_Taxes( $this );
481
+
482
+        foreach ( $processor->taxes as $tax ) {
483
+            $this->add_tax( $tax );
484
+        }
485
+
486
+        do_action_ref_array( 'getpaid_submissions_process_taxes', array( &$this ) );
487
+    }
488
+
489
+    /**
490
+     * Adds a tax to the submission.
491
+     *
492
+     * @param array $tax An array of tax details. name, initial_tax, and recurring_tax are required.
493
+     * @since 1.0.19
494
+     */
495
+    public function add_tax( $tax ) {
496
+
497
+        if ( wpinv_round_tax_per_tax_rate() ) {
498
+            $tax['initial_tax']   = wpinv_round_amount( $tax['initial_tax'] );
499
+            $tax['recurring_tax'] = wpinv_round_amount( $tax['recurring_tax'] );
500
+        }
501
+
502
+        $this->taxes[ $tax['name'] ]         = $tax;
503
+        $this->totals['taxes']['initial']   += wpinv_sanitize_amount( $tax['initial_tax'] );
504
+        $this->totals['taxes']['recurring'] += wpinv_sanitize_amount( $tax['recurring_tax'] );
505
+
506
+    }
507
+
508
+    /**
509
+     * Removes a specific tax.
510
+     *
511
+     * @since 1.0.19
512
+     */
513
+    public function remove_tax( $tax_name ) {
514
+
515
+        if ( isset( $this->taxes[ $tax_name ] ) ) {
516
+            $this->totals['taxes']['initial']   -= $this->taxes[ $tax_name ]['initial_tax'];
517
+            $this->totals['taxes']['recurring'] -= $this->taxes[ $tax_name ]['recurring_tax'];
518
+            unset( $this->taxes[ $tax_name ] );
519
+        }
520
+
521
+    }
522
+
523
+    /**
524
+     * Whether or not we'll use taxes for the submission.
525
+     *
526
+     * @since 1.0.19
527
+     */
528
+    public function use_taxes() {
529
+
530
+        $use_taxes = wpinv_use_taxes();
531
+
532
+        if ( $this->has_invoice() && ! $this->invoice->is_taxable() ) {
533
+            $use_taxes = false;
534
+        }
535
+
536
+        return apply_filters( 'getpaid_submission_use_taxes', $use_taxes, $this );
537
+
538
+    }
539
+
540
+    /**
541
+     * Returns the tax.
542
+     *
543
+     * @since 1.0.19
544
+     */
545
+    public function get_tax() {
546
+        return $this->totals['taxes']['initial'];
547
+    }
548
+
549
+    /**
550
+     * Returns the recurring tax.
551
+     *
552
+     * @since 1.0.19
553
+     */
554
+    public function get_recurring_tax() {
555
+        return $this->totals['taxes']['recurring'];
556
+    }
557
+
558
+    /**
559
+     * Returns all taxes.
560
+     *
561
+     * @since 1.0.19
562
+     */
563
+    public function get_taxes() {
564
+        return $this->taxes;
565
+    }
566
+
567
+    /*
568 568
 	|--------------------------------------------------------------------------
569 569
 	| Discounts
570 570
 	|--------------------------------------------------------------------------
@@ -573,99 +573,99 @@  discard block
 block discarded – undo
573 573
 	| or only one-time. They also do not have to come from a discount code.
574 574
     */
575 575
 
576
-	/**
577
-	 * Prepares the submission's discount.
578
-	 *
579
-	 * @since 1.0.19
580
-	 */
581
-	public function process_discount() {
582
-
583
-		$initial_total    = $this->get_subtotal() + $this->get_fee() + $this->get_tax();
584
-		$recurring_total  = $this->get_recurring_subtotal() + $this->get_recurring_fee() + $this->get_recurring_tax();
585
-		$processor        = new GetPaid_Payment_Form_Submission_Discount( $this, $initial_total, $recurring_total );
586
-
587
-		foreach ( $processor->discounts as $discount ) {
588
-			$this->add_discount( $discount );
589
-		}
590
-
591
-		do_action_ref_array( 'getpaid_submissions_process_discounts', array( &$this ) );
592
-	}
593
-
594
-	/**
595
-	 * Adds a discount to the submission.
596
-	 *
597
-	 * @param array $discount An array of discount details. name, initial_discount, and recurring_discount are required. Include discount_code if the discount is from a discount code.
598
-	 * @since 1.0.19
599
-	 */
600
-	public function add_discount( $discount ) {
601
-		$this->discounts[ $discount['name'] ]   = $discount;
602
-		$this->totals['discount']['initial']   += wpinv_sanitize_amount( $discount['initial_discount'] );
603
-		$this->totals['discount']['recurring'] += wpinv_sanitize_amount( $discount['recurring_discount'] );
604
-	}
605
-
606
-	/**
607
-	 * Removes a discount from the submission.
608
-	 *
609
-	 * @since 1.0.19
610
-	 */
611
-	public function remove_discount( $name ) {
612
-
613
-		if ( isset( $this->discounts[ $name ] ) ) {
614
-			$this->totals['discount']['initial']   -= $this->discounts[ $name ]['initial_discount'];
615
-			$this->totals['discount']['recurring'] -= $this->discounts[ $name ]['recurring_discount'];
616
-			unset( $this->discounts[ $name ] );
617
-		}
618
-
619
-	}
620
-
621
-	/**
622
-	 * Checks whether there is a discount code associated with this submission.
623
-	 *
624
-	 * @since 1.0.19
625
-	 * @return bool
626
-	 */
627
-	public function has_discount_code() {
628
-		return ! empty( $this->discounts['discount_code'] );
629
-	}
630
-
631
-	/**
632
-	 * Returns the discount code.
633
-	 *
634
-	 * @since 1.0.19
635
-	 * @return string
636
-	 */
637
-	public function get_discount_code() {
638
-		return $this->has_discount_code() ? $this->discounts['discount_code']['discount_code'] : '';
639
-	}
640
-
641
-	/**
642
-	 * Returns the discount.
643
-	 *
644
-	 * @since 1.0.19
645
-	 */
646
-	public function get_discount() {
647
-		return $this->totals['discount']['initial'];
648
-	}
649
-
650
-	/**
651
-	 * Returns the recurring discount.
652
-	 *
653
-	 * @since 1.0.19
654
-	 */
655
-	public function get_recurring_discount() {
656
-		return $this->totals['discount']['recurring'];
657
-	}
658
-
659
-	/**
660
-	 * Returns all discounts.
661
-	 *
662
-	 * @since 1.0.19
663
-	 */
664
-	public function get_discounts() {
665
-		return $this->discounts;
666
-	}
667
-
668
-	/*
576
+    /**
577
+     * Prepares the submission's discount.
578
+     *
579
+     * @since 1.0.19
580
+     */
581
+    public function process_discount() {
582
+
583
+        $initial_total    = $this->get_subtotal() + $this->get_fee() + $this->get_tax();
584
+        $recurring_total  = $this->get_recurring_subtotal() + $this->get_recurring_fee() + $this->get_recurring_tax();
585
+        $processor        = new GetPaid_Payment_Form_Submission_Discount( $this, $initial_total, $recurring_total );
586
+
587
+        foreach ( $processor->discounts as $discount ) {
588
+            $this->add_discount( $discount );
589
+        }
590
+
591
+        do_action_ref_array( 'getpaid_submissions_process_discounts', array( &$this ) );
592
+    }
593
+
594
+    /**
595
+     * Adds a discount to the submission.
596
+     *
597
+     * @param array $discount An array of discount details. name, initial_discount, and recurring_discount are required. Include discount_code if the discount is from a discount code.
598
+     * @since 1.0.19
599
+     */
600
+    public function add_discount( $discount ) {
601
+        $this->discounts[ $discount['name'] ]   = $discount;
602
+        $this->totals['discount']['initial']   += wpinv_sanitize_amount( $discount['initial_discount'] );
603
+        $this->totals['discount']['recurring'] += wpinv_sanitize_amount( $discount['recurring_discount'] );
604
+    }
605
+
606
+    /**
607
+     * Removes a discount from the submission.
608
+     *
609
+     * @since 1.0.19
610
+     */
611
+    public function remove_discount( $name ) {
612
+
613
+        if ( isset( $this->discounts[ $name ] ) ) {
614
+            $this->totals['discount']['initial']   -= $this->discounts[ $name ]['initial_discount'];
615
+            $this->totals['discount']['recurring'] -= $this->discounts[ $name ]['recurring_discount'];
616
+            unset( $this->discounts[ $name ] );
617
+        }
618
+
619
+    }
620
+
621
+    /**
622
+     * Checks whether there is a discount code associated with this submission.
623
+     *
624
+     * @since 1.0.19
625
+     * @return bool
626
+     */
627
+    public function has_discount_code() {
628
+        return ! empty( $this->discounts['discount_code'] );
629
+    }
630
+
631
+    /**
632
+     * Returns the discount code.
633
+     *
634
+     * @since 1.0.19
635
+     * @return string
636
+     */
637
+    public function get_discount_code() {
638
+        return $this->has_discount_code() ? $this->discounts['discount_code']['discount_code'] : '';
639
+    }
640
+
641
+    /**
642
+     * Returns the discount.
643
+     *
644
+     * @since 1.0.19
645
+     */
646
+    public function get_discount() {
647
+        return $this->totals['discount']['initial'];
648
+    }
649
+
650
+    /**
651
+     * Returns the recurring discount.
652
+     *
653
+     * @since 1.0.19
654
+     */
655
+    public function get_recurring_discount() {
656
+        return $this->totals['discount']['recurring'];
657
+    }
658
+
659
+    /**
660
+     * Returns all discounts.
661
+     *
662
+     * @since 1.0.19
663
+     */
664
+    public function get_discounts() {
665
+        return $this->discounts;
666
+    }
667
+
668
+    /*
669 669
 	|--------------------------------------------------------------------------
670 670
 	| Fees
671 671
 	|--------------------------------------------------------------------------
@@ -675,89 +675,89 @@  discard block
 block discarded – undo
675 675
 	| fees.
676 676
     */
677 677
 
678
-	/**
679
-	 * Prepares the submission's fees.
680
-	 *
681
-	 * @since 1.0.19
682
-	 */
683
-	public function process_fees() {
684
-
685
-		$fees_processor = new GetPaid_Payment_Form_Submission_Fees( $this );
686
-
687
-		foreach ( $fees_processor->fees as $fee ) {
688
-			$this->add_fee( $fee );
689
-		}
690
-
691
-		do_action_ref_array( 'getpaid_submissions_process_fees', array( &$this ) );
692
-	}
693
-
694
-	/**
695
-	 * Adds a fee to the submission.
696
-	 *
697
-	 * @param array $fee An array of fee details. name, initial_fee, and recurring_fee are required.
698
-	 * @since 1.0.19
699
-	 */
700
-	public function add_fee( $fee ) {
701
-
702
-		$this->fees[ $fee['name'] ]         = $fee;
703
-		$this->totals['fees']['initial']   += wpinv_sanitize_amount( $fee['initial_fee'] );
704
-		$this->totals['fees']['recurring'] += wpinv_sanitize_amount( $fee['recurring_fee'] );
705
-
706
-	}
707
-
708
-	/**
709
-	 * Removes a fee from the submission.
710
-	 *
711
-	 * @since 1.0.19
712
-	 */
713
-	public function remove_fee( $name ) {
714
-
715
-		if ( isset( $this->fees[ $name ] ) ) {
716
-			$this->totals['fees']['initial']   -= $this->fees[ $name ]['initial_fee'];
717
-			$this->totals['fees']['recurring'] -= $this->fees[ $name ]['recurring_fee'];
718
-			unset( $this->fees[ $name ] );
719
-		}
720
-
721
-	}
722
-
723
-	/**
724
-	 * Returns the fees.
725
-	 *
726
-	 * @since 1.0.19
727
-	 */
728
-	public function get_fee() {
729
-		return $this->totals['fees']['initial'];
730
-	}
731
-
732
-	/**
733
-	 * Returns the recurring fees.
734
-	 *
735
-	 * @since 1.0.19
736
-	 */
737
-	public function get_recurring_fee() {
738
-		return $this->totals['fees']['recurring'];
739
-	}
740
-
741
-	/**
742
-	 * Returns all fees.
743
-	 *
744
-	 * @since 1.0.19
745
-	 */
746
-	public function get_fees() {
747
-		return $this->fees;
748
-	}
749
-
750
-	/**
751
-	 * Checks if there are any fees for the form.
752
-	 *
753
-	 * @return bool
754
-	 * @since 1.0.19
755
-	 */
756
-	public function has_fees() {
757
-		return count( $this->fees ) !== 0;
758
-	}
759
-
760
-	/*
678
+    /**
679
+     * Prepares the submission's fees.
680
+     *
681
+     * @since 1.0.19
682
+     */
683
+    public function process_fees() {
684
+
685
+        $fees_processor = new GetPaid_Payment_Form_Submission_Fees( $this );
686
+
687
+        foreach ( $fees_processor->fees as $fee ) {
688
+            $this->add_fee( $fee );
689
+        }
690
+
691
+        do_action_ref_array( 'getpaid_submissions_process_fees', array( &$this ) );
692
+    }
693
+
694
+    /**
695
+     * Adds a fee to the submission.
696
+     *
697
+     * @param array $fee An array of fee details. name, initial_fee, and recurring_fee are required.
698
+     * @since 1.0.19
699
+     */
700
+    public function add_fee( $fee ) {
701
+
702
+        $this->fees[ $fee['name'] ]         = $fee;
703
+        $this->totals['fees']['initial']   += wpinv_sanitize_amount( $fee['initial_fee'] );
704
+        $this->totals['fees']['recurring'] += wpinv_sanitize_amount( $fee['recurring_fee'] );
705
+
706
+    }
707
+
708
+    /**
709
+     * Removes a fee from the submission.
710
+     *
711
+     * @since 1.0.19
712
+     */
713
+    public function remove_fee( $name ) {
714
+
715
+        if ( isset( $this->fees[ $name ] ) ) {
716
+            $this->totals['fees']['initial']   -= $this->fees[ $name ]['initial_fee'];
717
+            $this->totals['fees']['recurring'] -= $this->fees[ $name ]['recurring_fee'];
718
+            unset( $this->fees[ $name ] );
719
+        }
720
+
721
+    }
722
+
723
+    /**
724
+     * Returns the fees.
725
+     *
726
+     * @since 1.0.19
727
+     */
728
+    public function get_fee() {
729
+        return $this->totals['fees']['initial'];
730
+    }
731
+
732
+    /**
733
+     * Returns the recurring fees.
734
+     *
735
+     * @since 1.0.19
736
+     */
737
+    public function get_recurring_fee() {
738
+        return $this->totals['fees']['recurring'];
739
+    }
740
+
741
+    /**
742
+     * Returns all fees.
743
+     *
744
+     * @since 1.0.19
745
+     */
746
+    public function get_fees() {
747
+        return $this->fees;
748
+    }
749
+
750
+    /**
751
+     * Checks if there are any fees for the form.
752
+     *
753
+     * @return bool
754
+     * @since 1.0.19
755
+     */
756
+    public function has_fees() {
757
+        return count( $this->fees ) !== 0;
758
+    }
759
+
760
+    /*
761 761
 	|--------------------------------------------------------------------------
762 762
 	| MISC
763 763
 	|--------------------------------------------------------------------------
@@ -765,119 +765,119 @@  discard block
 block discarded – undo
765 765
 	| Extra submission functions.
766 766
     */
767 767
 
768
-	/**
769
-	 * Checks if this is the initial fetch.
770
-	 *
771
-	 * @return bool
772
-	 * @since 1.0.19
773
-	 */
774
-	public function is_initial_fetch() {
775
-		return empty( $this->data['initial_state'] );
776
-	}
777
-
778
-	/**
779
-	 * Returns the total amount to collect for this submission.
780
-	 *
781
-	 * @since 1.0.19
782
-	 */
783
-	public function get_total() {
784
-		$total = $this->get_subtotal() + $this->get_fee() + $this->get_tax() - $this->get_discount();
785
-		return max( $total, 0 );
786
-	}
787
-
788
-	/**
789
-	 * Returns the recurring total amount to collect for this submission.
790
-	 *
791
-	 * @since 1.0.19
792
-	 */
793
-	public function get_recurring_total() {
794
-		$total = $this->get_recurring_subtotal() + $this->get_recurring_fee() + $this->get_recurring_tax() - $this->get_recurring_discount();
795
-		return max( $total, 0 );
796
-	}
797
-
798
-	/**
799
-	 * Whether payment details should be collected for this submission.
800
-	 *
801
-	 * @since 1.0.19
802
-	 */
803
-	public function should_collect_payment_details() {
804
-		$initial   = $this->get_total();
805
-		$recurring = $this->get_recurring_total();
806
-
807
-		if ( $this->has_recurring == 0 ) {
808
-			$recurring = 0;
809
-		}
810
-
811
-		$collect = $initial > 0 || $recurring > 0;
812
-		return apply_filters( 'getpaid_submission_should_collect_payment_details', $collect, $this  );
813
-	}
814
-
815
-	/**
816
-	 * Returns the billing email of the user.
817
-	 *
818
-	 * @since 1.0.19
819
-	 */
820
-	public function get_billing_email() {
821
-		return apply_filters( 'getpaid_get_submission_billing_email', $this->get_field( 'billing_email' ), $this  );
822
-	}
823
-
824
-	/**
825
-	 * Checks if the submitter has a billing email.
826
-	 *
827
-	 * @since 1.0.19
828
-	 */
829
-	public function has_billing_email() {
830
-		$billing_email = $this->get_billing_email();
831
-		return ! empty( $billing_email ) && is_email( $billing_email );
832
-	}
833
-
834
-	/**
835
-	 * Returns the appropriate currency for the submission.
836
-	 *
837
-	 * @since 1.0.19
838
-	 * @return string
839
-	 */
840
-	public function get_currency() {
841
-		return $this->has_invoice() ? $this->invoice->get_currency() : wpinv_get_currency();
842
-    }
843
-
844
-    /**
845
-	 * Returns the raw submission data.
846
-	 *
847
-	 * @since 1.0.19
848
-	 * @return array
849
-	 */
850
-	public function get_data() {
851
-		return $this->data;
852
-	}
853
-
854
-	/**
855
-	 * Returns a field from the submission data
856
-	 *
857
-	 * @param string $field
858
-	 * @since 1.0.19
859
-	 * @return mixed|null
860
-	 */
861
-	public function get_field( $field, $sub_array_key = null ) {
862
-		return getpaid_get_array_field( $this->data, $field, $sub_array_key );
863
-	}
864
-
865
-	/**
866
-	 * Checks if a required field is set.
867
-	 *
868
-	 * @since 1.0.19
869
-	 */
870
-	public function is_required_field_set( $field ) {
871
-		return empty( $field['required'] ) || ! empty( $this->data[ $field['id'] ] );
872
-	}
873
-
874
-	/**
875
-	 * Formats an amount
876
-	 *
877
-	 * @since 1.0.19
878
-	 */
879
-	public function format_amount( $amount ) {
880
-		return wpinv_price( $amount, $this->get_currency() );
881
-	}
768
+    /**
769
+     * Checks if this is the initial fetch.
770
+     *
771
+     * @return bool
772
+     * @since 1.0.19
773
+     */
774
+    public function is_initial_fetch() {
775
+        return empty( $this->data['initial_state'] );
776
+    }
777
+
778
+    /**
779
+     * Returns the total amount to collect for this submission.
780
+     *
781
+     * @since 1.0.19
782
+     */
783
+    public function get_total() {
784
+        $total = $this->get_subtotal() + $this->get_fee() + $this->get_tax() - $this->get_discount();
785
+        return max( $total, 0 );
786
+    }
787
+
788
+    /**
789
+     * Returns the recurring total amount to collect for this submission.
790
+     *
791
+     * @since 1.0.19
792
+     */
793
+    public function get_recurring_total() {
794
+        $total = $this->get_recurring_subtotal() + $this->get_recurring_fee() + $this->get_recurring_tax() - $this->get_recurring_discount();
795
+        return max( $total, 0 );
796
+    }
797
+
798
+    /**
799
+     * Whether payment details should be collected for this submission.
800
+     *
801
+     * @since 1.0.19
802
+     */
803
+    public function should_collect_payment_details() {
804
+        $initial   = $this->get_total();
805
+        $recurring = $this->get_recurring_total();
806
+
807
+        if ( $this->has_recurring == 0 ) {
808
+            $recurring = 0;
809
+        }
810
+
811
+        $collect = $initial > 0 || $recurring > 0;
812
+        return apply_filters( 'getpaid_submission_should_collect_payment_details', $collect, $this  );
813
+    }
814
+
815
+    /**
816
+     * Returns the billing email of the user.
817
+     *
818
+     * @since 1.0.19
819
+     */
820
+    public function get_billing_email() {
821
+        return apply_filters( 'getpaid_get_submission_billing_email', $this->get_field( 'billing_email' ), $this  );
822
+    }
823
+
824
+    /**
825
+     * Checks if the submitter has a billing email.
826
+     *
827
+     * @since 1.0.19
828
+     */
829
+    public function has_billing_email() {
830
+        $billing_email = $this->get_billing_email();
831
+        return ! empty( $billing_email ) && is_email( $billing_email );
832
+    }
833
+
834
+    /**
835
+     * Returns the appropriate currency for the submission.
836
+     *
837
+     * @since 1.0.19
838
+     * @return string
839
+     */
840
+    public function get_currency() {
841
+        return $this->has_invoice() ? $this->invoice->get_currency() : wpinv_get_currency();
842
+    }
843
+
844
+    /**
845
+     * Returns the raw submission data.
846
+     *
847
+     * @since 1.0.19
848
+     * @return array
849
+     */
850
+    public function get_data() {
851
+        return $this->data;
852
+    }
853
+
854
+    /**
855
+     * Returns a field from the submission data
856
+     *
857
+     * @param string $field
858
+     * @since 1.0.19
859
+     * @return mixed|null
860
+     */
861
+    public function get_field( $field, $sub_array_key = null ) {
862
+        return getpaid_get_array_field( $this->data, $field, $sub_array_key );
863
+    }
864
+
865
+    /**
866
+     * Checks if a required field is set.
867
+     *
868
+     * @since 1.0.19
869
+     */
870
+    public function is_required_field_set( $field ) {
871
+        return empty( $field['required'] ) || ! empty( $this->data[ $field['id'] ] );
872
+    }
873
+
874
+    /**
875
+     * Formats an amount
876
+     *
877
+     * @since 1.0.19
878
+     */
879
+    public function format_amount( $amount ) {
880
+        return wpinv_price( $amount, $this->get_currency() );
881
+    }
882 882
 
883 883
 }
Please login to merge, or discard this patch.