Passed
Pull Request — master (#281)
by Kiran
04:07
created
widgets/subscriptions.php 1 patch
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -46,25 +46,25 @@
 block discarded – undo
46 46
         parent::__construct( $options );
47 47
     }
48 48
 
49
-	/**
50
-	 * The Super block output function.
51
-	 *
52
-	 * @param array $args
53
-	 * @param array $widget_args
54
-	 * @param string $content
55
-	 *
56
-	 * @return mixed|string|bool
57
-	 */
49
+    /**
50
+     * The Super block output function.
51
+     *
52
+     * @param array $args
53
+     * @param array $widget_args
54
+     * @param string $content
55
+     *
56
+     * @return mixed|string|bool
57
+     */
58 58
     public function output( $args = array(), $widget_args = array(), $content = '' ) {
59 59
 
60
-	    ob_start();
60
+        ob_start();
61 61
 
62
-	    do_action( 'wpinv_before_user_subscriptions' );
63
-	    wpinv_get_template_part( 'wpinv-subscriptions-history' );
64
-	    do_action( 'wpinv_after_user_subscriptions' );
62
+        do_action( 'wpinv_before_user_subscriptions' );
63
+        wpinv_get_template_part( 'wpinv-subscriptions-history' );
64
+        do_action( 'wpinv_after_user_subscriptions' );
65 65
 
66
-	    $output = ob_get_clean();
67
-	    return trim($output);
66
+        $output = ob_get_clean();
67
+        return trim($output);
68 68
 
69 69
     }
70 70
 
Please login to merge, or discard this patch.
widgets/invoice-receipt.php 1 patch
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -44,25 +44,25 @@
 block discarded – undo
44 44
         parent::__construct( $options );
45 45
     }
46 46
 
47
-	/**
48
-	 * The Super block output function.
49
-	 *
50
-	 * @param array $args
51
-	 * @param array $widget_args
52
-	 * @param string $content
53
-	 *
54
-	 * @return mixed|string|bool
55
-	 */
47
+    /**
48
+     * The Super block output function.
49
+     *
50
+     * @param array $args
51
+     * @param array $widget_args
52
+     * @param string $content
53
+     *
54
+     * @return mixed|string|bool
55
+     */
56 56
     public function output( $args = array(), $widget_args = array(), $content = '' ) {
57 57
 
58
-	    ob_start();
58
+        ob_start();
59 59
 
60
-	    do_action( 'wpinv_success_content_before' );
61
-	    echo wpinv_payment_receipt( $args );
62
-	    do_action( 'wpinv_success_content_after' );
60
+        do_action( 'wpinv_success_content_before' );
61
+        echo wpinv_payment_receipt( $args );
62
+        do_action( 'wpinv_success_content_after' );
63 63
 
64
-	    $output = ob_get_clean();
65
-	    return trim($output);
64
+        $output = ob_get_clean();
65
+        return trim($output);
66 66
 
67 67
     }
68 68
 
Please login to merge, or discard this patch.
includes/class-wpinv.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -139,12 +139,12 @@  discard block
 block discarded – undo
139 139
         require_once( WPINV_PLUGIN_DIR . 'includes/class-wpinv-privacy.php' );
140 140
         require_once( WPINV_PLUGIN_DIR . 'includes/libraries/class-ayecode-addons.php' );
141 141
         require_once( WPINV_PLUGIN_DIR . 'includes/class-wpinv-addons.php' );
142
-	    require_once( WPINV_PLUGIN_DIR . 'widgets/checkout.php' );
143
-	    require_once( WPINV_PLUGIN_DIR . 'widgets/invoice-history.php' );
144
-	    require_once( WPINV_PLUGIN_DIR . 'widgets/invoice-receipt.php' );
145
-	    require_once( WPINV_PLUGIN_DIR . 'widgets/invoice-messages.php' );
146
-	    require_once( WPINV_PLUGIN_DIR . 'widgets/subscriptions.php' );
147
-	    require_once( WPINV_PLUGIN_DIR . 'widgets/buy-item.php' );
142
+        require_once( WPINV_PLUGIN_DIR . 'widgets/checkout.php' );
143
+        require_once( WPINV_PLUGIN_DIR . 'widgets/invoice-history.php' );
144
+        require_once( WPINV_PLUGIN_DIR . 'widgets/invoice-receipt.php' );
145
+        require_once( WPINV_PLUGIN_DIR . 'widgets/invoice-messages.php' );
146
+        require_once( WPINV_PLUGIN_DIR . 'widgets/subscriptions.php' );
147
+        require_once( WPINV_PLUGIN_DIR . 'widgets/buy-item.php' );
148 148
 
149 149
         if ( !class_exists( 'WPInv_EUVat' ) ) {
150 150
             require_once( WPINV_PLUGIN_DIR . 'includes/libraries/wpinv-euvat/class-wpinv-euvat.php' );
@@ -420,16 +420,16 @@  discard block
 block discarded – undo
420 420
         require_once( WPINV_PLUGIN_DIR . 'includes/class-wpinv-bp-core.php' );
421 421
     }
422 422
 
423
-	/**
424
-	 * Register widgets
425
-	 *
426
-	 */
427
-	public function register_widgets() {
428
-		register_widget( "WPInv_Checkout_Widget" );
429
-		register_widget( "WPInv_History_Widget" );
430
-		register_widget( "WPInv_Receipt_Widget" );
431
-		register_widget( "WPInv_Subscriptions_Widget" );
432
-		register_widget( "WPInv_Buy_Item_Widget" );
433
-		register_widget( "WPInv_Messages_Widget" );
434
-	}
423
+    /**
424
+     * Register widgets
425
+     *
426
+     */
427
+    public function register_widgets() {
428
+        register_widget( "WPInv_Checkout_Widget" );
429
+        register_widget( "WPInv_History_Widget" );
430
+        register_widget( "WPInv_Receipt_Widget" );
431
+        register_widget( "WPInv_Subscriptions_Widget" );
432
+        register_widget( "WPInv_Buy_Item_Widget" );
433
+        register_widget( "WPInv_Messages_Widget" );
434
+    }
435 435
 }
436 436
\ No newline at end of file
Please login to merge, or discard this patch.
includes/admin/register-settings.php 1 patch
Indentation   +328 added lines, -328 removed lines patch added patch discarded remove patch
@@ -984,326 +984,326 @@  discard block
 block discarded – undo
984 984
 }
985 985
 
986 986
 function wpinv_get_pages( $with_slug = false, $default_label = NULL ) {
987
-	$pages_options = array();
987
+    $pages_options = array();
988 988
 
989
-	if( $default_label !== NULL && $default_label !== false ) {
990
-		$pages_options = array( '' => $default_label ); // Blank option
991
-	}
989
+    if( $default_label !== NULL && $default_label !== false ) {
990
+        $pages_options = array( '' => $default_label ); // Blank option
991
+    }
992 992
 
993
-	$pages = get_pages();
994
-	if ( $pages ) {
995
-		foreach ( $pages as $page ) {
996
-			$title = $with_slug ? $page->post_title . ' (' . $page->post_name . ')' : $page->post_title;
993
+    $pages = get_pages();
994
+    if ( $pages ) {
995
+        foreach ( $pages as $page ) {
996
+            $title = $with_slug ? $page->post_title . ' (' . $page->post_name . ')' : $page->post_title;
997 997
             $pages_options[ $page->ID ] = $title;
998
-		}
999
-	}
998
+        }
999
+    }
1000 1000
 
1001
-	return $pages_options;
1001
+    return $pages_options;
1002 1002
 }
1003 1003
 
1004 1004
 function wpinv_header_callback( $args ) {
1005
-	if ( !empty( $args['desc'] ) ) {
1005
+    if ( !empty( $args['desc'] ) ) {
1006 1006
         echo $args['desc'];
1007 1007
     }
1008 1008
 }
1009 1009
 
1010 1010
 function wpinv_hidden_callback( $args ) {
1011
-	global $wpinv_options;
1012
-
1013
-	if ( isset( $args['set_value'] ) ) {
1014
-		$value = $args['set_value'];
1015
-	} elseif ( isset( $wpinv_options[ $args['id'] ] ) ) {
1016
-		$value = $wpinv_options[ $args['id'] ];
1017
-	} else {
1018
-		$value = isset( $args['std'] ) ? $args['std'] : '';
1019
-	}
1020
-
1021
-	if ( isset( $args['faux'] ) && true === $args['faux'] ) {
1022
-		$args['readonly'] = true;
1023
-		$value = isset( $args['std'] ) ? $args['std'] : '';
1024
-		$name  = '';
1025
-	} else {
1026
-		$name = 'name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"';
1027
-	}
1028
-
1029
-	$html = '<input type="hidden" id="wpinv_settings[' . wpinv_sanitize_key( $args['id'] ) . ']" ' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '" />';
1011
+    global $wpinv_options;
1012
+
1013
+    if ( isset( $args['set_value'] ) ) {
1014
+        $value = $args['set_value'];
1015
+    } elseif ( isset( $wpinv_options[ $args['id'] ] ) ) {
1016
+        $value = $wpinv_options[ $args['id'] ];
1017
+    } else {
1018
+        $value = isset( $args['std'] ) ? $args['std'] : '';
1019
+    }
1020
+
1021
+    if ( isset( $args['faux'] ) && true === $args['faux'] ) {
1022
+        $args['readonly'] = true;
1023
+        $value = isset( $args['std'] ) ? $args['std'] : '';
1024
+        $name  = '';
1025
+    } else {
1026
+        $name = 'name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"';
1027
+    }
1028
+
1029
+    $html = '<input type="hidden" id="wpinv_settings[' . wpinv_sanitize_key( $args['id'] ) . ']" ' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '" />';
1030 1030
     
1031
-	echo $html;
1031
+    echo $html;
1032 1032
 }
1033 1033
 
1034 1034
 function wpinv_checkbox_callback( $args ) {
1035
-	global $wpinv_options;
1035
+    global $wpinv_options;
1036 1036
     
1037 1037
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1038 1038
 
1039
-	if ( isset( $args['faux'] ) && true === $args['faux'] ) {
1040
-		$name = '';
1041
-	} else {
1042
-		$name = 'name="wpinv_settings[' . $sanitize_id . ']"';
1043
-	}
1039
+    if ( isset( $args['faux'] ) && true === $args['faux'] ) {
1040
+        $name = '';
1041
+    } else {
1042
+        $name = 'name="wpinv_settings[' . $sanitize_id . ']"';
1043
+    }
1044 1044
 
1045
-	$checked = isset( $wpinv_options[ $args['id'] ] ) ? checked( 1, $wpinv_options[ $args['id'] ], false ) : '';
1046
-	$html = '<input type="checkbox" id="wpinv_settings[' . $sanitize_id . ']"' . $name . ' value="1" ' . $checked . '/>';
1047
-	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1045
+    $checked = isset( $wpinv_options[ $args['id'] ] ) ? checked( 1, $wpinv_options[ $args['id'] ], false ) : '';
1046
+    $html = '<input type="checkbox" id="wpinv_settings[' . $sanitize_id . ']"' . $name . ' value="1" ' . $checked . '/>';
1047
+    $html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1048 1048
 
1049
-	echo $html;
1049
+    echo $html;
1050 1050
 }
1051 1051
 
1052 1052
 function wpinv_multicheck_callback( $args ) {
1053
-	global $wpinv_options;
1053
+    global $wpinv_options;
1054 1054
 
1055
-	$sanitize_id = wpinv_sanitize_key( $args['id'] );
1056
-	$class = !empty( $args['class'] ) ? ' ' . esc_attr( $args['class'] ) : '';
1055
+    $sanitize_id = wpinv_sanitize_key( $args['id'] );
1056
+    $class = !empty( $args['class'] ) ? ' ' . esc_attr( $args['class'] ) : '';
1057 1057
 
1058
-	if ( ! empty( $args['options'] ) ) {
1059
-		echo '<div class="wpi-mcheck-rows wpi-mcheck-' . $sanitize_id . $class . '">';
1058
+    if ( ! empty( $args['options'] ) ) {
1059
+        echo '<div class="wpi-mcheck-rows wpi-mcheck-' . $sanitize_id . $class . '">';
1060 1060
         foreach( $args['options'] as $key => $option ):
1061
-			$sanitize_key = wpinv_sanitize_key( $key );
1062
-			if ( isset( $wpinv_options[$args['id']][$sanitize_key] ) ) { 
1063
-				$enabled = $sanitize_key;
1064
-			} else { 
1065
-				$enabled = NULL; 
1066
-			}
1067
-			echo '<div class="wpi-mcheck-row"><input name="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" id="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" type="checkbox" value="' . esc_attr( $sanitize_key ) . '" ' . checked( $sanitize_key, $enabled, false ) . '/>&nbsp;';
1068
-			echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']">' . wp_kses_post( $option ) . '</label></div>';
1069
-		endforeach;
1070
-		echo '</div>';
1071
-		echo '<p class="description">' . $args['desc'] . '</p>';
1072
-	}
1061
+            $sanitize_key = wpinv_sanitize_key( $key );
1062
+            if ( isset( $wpinv_options[$args['id']][$sanitize_key] ) ) { 
1063
+                $enabled = $sanitize_key;
1064
+            } else { 
1065
+                $enabled = NULL; 
1066
+            }
1067
+            echo '<div class="wpi-mcheck-row"><input name="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" id="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" type="checkbox" value="' . esc_attr( $sanitize_key ) . '" ' . checked( $sanitize_key, $enabled, false ) . '/>&nbsp;';
1068
+            echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']">' . wp_kses_post( $option ) . '</label></div>';
1069
+        endforeach;
1070
+        echo '</div>';
1071
+        echo '<p class="description">' . $args['desc'] . '</p>';
1072
+    }
1073 1073
 }
1074 1074
 
1075 1075
 function wpinv_payment_icons_callback( $args ) {
1076
-	global $wpinv_options;
1076
+    global $wpinv_options;
1077 1077
     
1078 1078
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1079 1079
 
1080
-	if ( ! empty( $args['options'] ) ) {
1081
-		foreach( $args['options'] as $key => $option ) {
1080
+    if ( ! empty( $args['options'] ) ) {
1081
+        foreach( $args['options'] as $key => $option ) {
1082 1082
             $sanitize_key = wpinv_sanitize_key( $key );
1083 1083
             
1084
-			if( isset( $wpinv_options[$args['id']][$key] ) ) {
1085
-				$enabled = $option;
1086
-			} else {
1087
-				$enabled = NULL;
1088
-			}
1089
-
1090
-			echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" style="margin-right:10px;line-height:16px;height:16px;display:inline-block;">';
1091
-
1092
-				echo '<input name="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" id="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" type="checkbox" value="' . esc_attr( $option ) . '" ' . checked( $option, $enabled, false ) . '/>&nbsp;';
1093
-
1094
-				if ( wpinv_string_is_image_url( $key ) ) {
1095
-					echo '<img class="payment-icon" src="' . esc_url( $key ) . '" style="width:32px;height:24px;position:relative;top:6px;margin-right:5px;"/>';
1096
-				} else {
1097
-					$card = strtolower( str_replace( ' ', '', $option ) );
1098
-
1099
-					if ( has_filter( 'wpinv_accepted_payment_' . $card . '_image' ) ) {
1100
-						$image = apply_filters( 'wpinv_accepted_payment_' . $card . '_image', '' );
1101
-					} else {
1102
-						$image       = wpinv_locate_template( 'images' . DIRECTORY_SEPARATOR . 'icons' . DIRECTORY_SEPARATOR . $card . '.gif', false );
1103
-						$content_dir = WP_CONTENT_DIR;
1104
-
1105
-						if ( function_exists( 'wp_normalize_path' ) ) {
1106
-							// Replaces backslashes with forward slashes for Windows systems
1107
-							$image = wp_normalize_path( $image );
1108
-							$content_dir = wp_normalize_path( $content_dir );
1109
-						}
1110
-
1111
-						$image = str_replace( $content_dir, content_url(), $image );
1112
-					}
1113
-
1114
-					echo '<img class="payment-icon" src="' . esc_url( $image ) . '" style="width:32px;height:24px;position:relative;top:6px;margin-right:5px;"/>';
1115
-				}
1116
-			echo $option . '</label>';
1117
-		}
1118
-		echo '<p class="description" style="margin-top:16px;">' . wp_kses_post( $args['desc'] ) . '</p>';
1119
-	}
1084
+            if( isset( $wpinv_options[$args['id']][$key] ) ) {
1085
+                $enabled = $option;
1086
+            } else {
1087
+                $enabled = NULL;
1088
+            }
1089
+
1090
+            echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" style="margin-right:10px;line-height:16px;height:16px;display:inline-block;">';
1091
+
1092
+                echo '<input name="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" id="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" type="checkbox" value="' . esc_attr( $option ) . '" ' . checked( $option, $enabled, false ) . '/>&nbsp;';
1093
+
1094
+                if ( wpinv_string_is_image_url( $key ) ) {
1095
+                    echo '<img class="payment-icon" src="' . esc_url( $key ) . '" style="width:32px;height:24px;position:relative;top:6px;margin-right:5px;"/>';
1096
+                } else {
1097
+                    $card = strtolower( str_replace( ' ', '', $option ) );
1098
+
1099
+                    if ( has_filter( 'wpinv_accepted_payment_' . $card . '_image' ) ) {
1100
+                        $image = apply_filters( 'wpinv_accepted_payment_' . $card . '_image', '' );
1101
+                    } else {
1102
+                        $image       = wpinv_locate_template( 'images' . DIRECTORY_SEPARATOR . 'icons' . DIRECTORY_SEPARATOR . $card . '.gif', false );
1103
+                        $content_dir = WP_CONTENT_DIR;
1104
+
1105
+                        if ( function_exists( 'wp_normalize_path' ) ) {
1106
+                            // Replaces backslashes with forward slashes for Windows systems
1107
+                            $image = wp_normalize_path( $image );
1108
+                            $content_dir = wp_normalize_path( $content_dir );
1109
+                        }
1110
+
1111
+                        $image = str_replace( $content_dir, content_url(), $image );
1112
+                    }
1113
+
1114
+                    echo '<img class="payment-icon" src="' . esc_url( $image ) . '" style="width:32px;height:24px;position:relative;top:6px;margin-right:5px;"/>';
1115
+                }
1116
+            echo $option . '</label>';
1117
+        }
1118
+        echo '<p class="description" style="margin-top:16px;">' . wp_kses_post( $args['desc'] ) . '</p>';
1119
+    }
1120 1120
 }
1121 1121
 
1122 1122
 function wpinv_radio_callback( $args ) {
1123
-	global $wpinv_options;
1123
+    global $wpinv_options;
1124 1124
     
1125 1125
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1126 1126
     
1127 1127
     foreach ( $args['options'] as $key => $option ) :
1128
-		$sanitize_key = wpinv_sanitize_key( $key );
1128
+        $sanitize_key = wpinv_sanitize_key( $key );
1129 1129
         
1130 1130
         $checked = false;
1131 1131
 
1132
-		if ( isset( $wpinv_options[ $args['id'] ] ) && $wpinv_options[ $args['id'] ] == $key )
1133
-			$checked = true;
1134
-		elseif( isset( $args['std'] ) && $args['std'] == $key && ! isset( $wpinv_options[ $args['id'] ] ) )
1135
-			$checked = true;
1132
+        if ( isset( $wpinv_options[ $args['id'] ] ) && $wpinv_options[ $args['id'] ] == $key )
1133
+            $checked = true;
1134
+        elseif( isset( $args['std'] ) && $args['std'] == $key && ! isset( $wpinv_options[ $args['id'] ] ) )
1135
+            $checked = true;
1136 1136
 
1137
-		echo '<input name="wpinv_settings[' . $sanitize_id . ']" id="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" type="radio" value="' . $sanitize_key . '" ' . checked(true, $checked, false) . '/>&nbsp;';
1138
-		echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']">' . esc_html( $option ) . '</label><br/>';
1139
-	endforeach;
1137
+        echo '<input name="wpinv_settings[' . $sanitize_id . ']" id="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" type="radio" value="' . $sanitize_key . '" ' . checked(true, $checked, false) . '/>&nbsp;';
1138
+        echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']">' . esc_html( $option ) . '</label><br/>';
1139
+    endforeach;
1140 1140
 
1141
-	echo '<p class="description">' . wp_kses_post( $args['desc'] ) . '</p>';
1141
+    echo '<p class="description">' . wp_kses_post( $args['desc'] ) . '</p>';
1142 1142
 }
1143 1143
 
1144 1144
 function wpinv_gateways_callback( $args ) {
1145
-	global $wpinv_options;
1145
+    global $wpinv_options;
1146 1146
     
1147 1147
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1148 1148
 
1149
-	foreach ( $args['options'] as $key => $option ) :
1150
-		$sanitize_key = wpinv_sanitize_key( $key );
1149
+    foreach ( $args['options'] as $key => $option ) :
1150
+        $sanitize_key = wpinv_sanitize_key( $key );
1151 1151
         
1152 1152
         if ( isset( $wpinv_options['gateways'][ $key ] ) )
1153
-			$enabled = '1';
1154
-		else
1155
-			$enabled = null;
1153
+            $enabled = '1';
1154
+        else
1155
+            $enabled = null;
1156 1156
 
1157
-		echo '<input name="wpinv_settings[' . esc_attr( $args['id'] ) . '][' . $sanitize_key . ']" id="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" type="checkbox" value="1" ' . checked('1', $enabled, false) . '/>&nbsp;';
1158
-		echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']">' . esc_html( $option['admin_label'] ) . '</label><br/>';
1159
-	endforeach;
1157
+        echo '<input name="wpinv_settings[' . esc_attr( $args['id'] ) . '][' . $sanitize_key . ']" id="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']" type="checkbox" value="1" ' . checked('1', $enabled, false) . '/>&nbsp;';
1158
+        echo '<label for="wpinv_settings[' . $sanitize_id . '][' . $sanitize_key . ']">' . esc_html( $option['admin_label'] ) . '</label><br/>';
1159
+    endforeach;
1160 1160
 }
1161 1161
 
1162 1162
 function wpinv_gateway_select_callback($args) {
1163
-	global $wpinv_options;
1163
+    global $wpinv_options;
1164 1164
     
1165 1165
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1166 1166
     $class = !empty( $args['class'] ) ? ' ' . esc_attr( $args['class'] ) : '';
1167 1167
 
1168
-	echo '<select name="wpinv_settings[' . $sanitize_id . ']"" id="wpinv_settings[' . $sanitize_id . ']" class="'.$class.'" >';
1168
+    echo '<select name="wpinv_settings[' . $sanitize_id . ']"" id="wpinv_settings[' . $sanitize_id . ']" class="'.$class.'" >';
1169 1169
 
1170
-	foreach ( $args['options'] as $key => $option ) :
1171
-		if ( isset( $args['selected'] ) && $args['selected'] !== null && $args['selected'] !== false ) {
1170
+    foreach ( $args['options'] as $key => $option ) :
1171
+        if ( isset( $args['selected'] ) && $args['selected'] !== null && $args['selected'] !== false ) {
1172 1172
             $selected = selected( $key, $args['selected'], false );
1173 1173
         } else {
1174 1174
             $selected = isset( $wpinv_options[ $args['id'] ] ) ? selected( $key, $wpinv_options[$args['id']], false ) : '';
1175 1175
         }
1176
-		echo '<option value="' . wpinv_sanitize_key( $key ) . '"' . $selected . '>' . esc_html( $option['admin_label'] ) . '</option>';
1177
-	endforeach;
1176
+        echo '<option value="' . wpinv_sanitize_key( $key ) . '"' . $selected . '>' . esc_html( $option['admin_label'] ) . '</option>';
1177
+    endforeach;
1178 1178
 
1179
-	echo '</select>';
1180
-	echo '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1179
+    echo '</select>';
1180
+    echo '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1181 1181
 }
1182 1182
 
1183 1183
 function wpinv_text_callback( $args ) {
1184
-	global $wpinv_options;
1184
+    global $wpinv_options;
1185 1185
     
1186 1186
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1187 1187
 
1188
-	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1189
-		$value = $wpinv_options[ $args['id'] ];
1190
-	} else {
1191
-		$value = isset( $args['std'] ) ? $args['std'] : '';
1192
-	}
1193
-
1194
-	if ( isset( $args['faux'] ) && true === $args['faux'] ) {
1195
-		$args['readonly'] = true;
1196
-		$value = isset( $args['std'] ) ? $args['std'] : '';
1197
-		$name  = '';
1198
-	} else {
1199
-		$name = 'name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"';
1200
-	}
1201
-	$class = !empty( $args['class'] ) ? sanitize_html_class( $args['class'] ) : '';
1202
-
1203
-	$readonly = $args['readonly'] === true ? ' readonly="readonly"' : '';
1204
-	$size     = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
1205
-	$html     = '<input type="text" class="' . sanitize_html_class( $size ) . '-text ' . $class . '" id="wpinv_settings[' . $sanitize_id . ']" ' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '"' . $readonly . '/>';
1206
-	$html    .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1207
-
1208
-	echo $html;
1188
+    if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1189
+        $value = $wpinv_options[ $args['id'] ];
1190
+    } else {
1191
+        $value = isset( $args['std'] ) ? $args['std'] : '';
1192
+    }
1193
+
1194
+    if ( isset( $args['faux'] ) && true === $args['faux'] ) {
1195
+        $args['readonly'] = true;
1196
+        $value = isset( $args['std'] ) ? $args['std'] : '';
1197
+        $name  = '';
1198
+    } else {
1199
+        $name = 'name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"';
1200
+    }
1201
+    $class = !empty( $args['class'] ) ? sanitize_html_class( $args['class'] ) : '';
1202
+
1203
+    $readonly = $args['readonly'] === true ? ' readonly="readonly"' : '';
1204
+    $size     = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
1205
+    $html     = '<input type="text" class="' . sanitize_html_class( $size ) . '-text ' . $class . '" id="wpinv_settings[' . $sanitize_id . ']" ' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '"' . $readonly . '/>';
1206
+    $html    .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1207
+
1208
+    echo $html;
1209 1209
 }
1210 1210
 
1211 1211
 function wpinv_number_callback( $args ) {
1212
-	global $wpinv_options;
1212
+    global $wpinv_options;
1213 1213
     
1214 1214
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1215 1215
 
1216
-	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1217
-		$value = $wpinv_options[ $args['id'] ];
1218
-	} else {
1219
-		$value = isset( $args['std'] ) ? $args['std'] : '';
1220
-	}
1221
-
1222
-	if ( isset( $args['faux'] ) && true === $args['faux'] ) {
1223
-		$args['readonly'] = true;
1224
-		$value = isset( $args['std'] ) ? $args['std'] : '';
1225
-		$name  = '';
1226
-	} else {
1227
-		$name = 'name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"';
1228
-	}
1229
-
1230
-	$max  = isset( $args['max'] ) ? $args['max'] : 999999;
1231
-	$min  = isset( $args['min'] ) ? $args['min'] : 0;
1232
-	$step = isset( $args['step'] ) ? $args['step'] : 1;
1233
-	$class = !empty( $args['class'] ) ? sanitize_html_class( $args['class'] ) : '';
1234
-
1235
-	$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
1236
-	$html = '<input type="number" step="' . esc_attr( $step ) . '" max="' . esc_attr( $max ) . '" min="' . esc_attr( $min ) . '" class="' . sanitize_html_class( $size ) . '-text ' . $class . '" id="wpinv_settings[' . $sanitize_id . ']" ' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '"/>';
1237
-	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1238
-
1239
-	echo $html;
1216
+    if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1217
+        $value = $wpinv_options[ $args['id'] ];
1218
+    } else {
1219
+        $value = isset( $args['std'] ) ? $args['std'] : '';
1220
+    }
1221
+
1222
+    if ( isset( $args['faux'] ) && true === $args['faux'] ) {
1223
+        $args['readonly'] = true;
1224
+        $value = isset( $args['std'] ) ? $args['std'] : '';
1225
+        $name  = '';
1226
+    } else {
1227
+        $name = 'name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"';
1228
+    }
1229
+
1230
+    $max  = isset( $args['max'] ) ? $args['max'] : 999999;
1231
+    $min  = isset( $args['min'] ) ? $args['min'] : 0;
1232
+    $step = isset( $args['step'] ) ? $args['step'] : 1;
1233
+    $class = !empty( $args['class'] ) ? sanitize_html_class( $args['class'] ) : '';
1234
+
1235
+    $size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
1236
+    $html = '<input type="number" step="' . esc_attr( $step ) . '" max="' . esc_attr( $max ) . '" min="' . esc_attr( $min ) . '" class="' . sanitize_html_class( $size ) . '-text ' . $class . '" id="wpinv_settings[' . $sanitize_id . ']" ' . $name . ' value="' . esc_attr( stripslashes( $value ) ) . '"/>';
1237
+    $html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1238
+
1239
+    echo $html;
1240 1240
 }
1241 1241
 
1242 1242
 function wpinv_textarea_callback( $args ) {
1243
-	global $wpinv_options;
1243
+    global $wpinv_options;
1244 1244
     
1245 1245
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1246 1246
 
1247
-	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1248
-		$value = $wpinv_options[ $args['id'] ];
1249
-	} else {
1250
-		$value = isset( $args['std'] ) ? $args['std'] : '';
1251
-	}
1247
+    if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1248
+        $value = $wpinv_options[ $args['id'] ];
1249
+    } else {
1250
+        $value = isset( $args['std'] ) ? $args['std'] : '';
1251
+    }
1252 1252
     
1253 1253
     $size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
1254 1254
     $class = ( isset( $args['class'] ) && ! is_null( $args['class'] ) ) ? $args['class'] : 'large-text';
1255 1255
 
1256
-	$html = '<textarea class="' . sanitize_html_class( $class ) . ' txtarea-' . sanitize_html_class( $size ) . ' wpi-' . esc_attr( sanitize_html_class( $sanitize_id ) ) . ' " cols="' . $args['cols'] . '" rows="' . $args['rows'] . '" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']">' . esc_textarea( stripslashes( $value ) ) . '</textarea>';
1257
-	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1256
+    $html = '<textarea class="' . sanitize_html_class( $class ) . ' txtarea-' . sanitize_html_class( $size ) . ' wpi-' . esc_attr( sanitize_html_class( $sanitize_id ) ) . ' " cols="' . $args['cols'] . '" rows="' . $args['rows'] . '" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']">' . esc_textarea( stripslashes( $value ) ) . '</textarea>';
1257
+    $html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1258 1258
 
1259
-	echo $html;
1259
+    echo $html;
1260 1260
 }
1261 1261
 
1262 1262
 function wpinv_password_callback( $args ) {
1263
-	global $wpinv_options;
1263
+    global $wpinv_options;
1264 1264
     
1265 1265
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1266 1266
 
1267
-	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1268
-		$value = $wpinv_options[ $args['id'] ];
1269
-	} else {
1270
-		$value = isset( $args['std'] ) ? $args['std'] : '';
1271
-	}
1267
+    if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1268
+        $value = $wpinv_options[ $args['id'] ];
1269
+    } else {
1270
+        $value = isset( $args['std'] ) ? $args['std'] : '';
1271
+    }
1272 1272
 
1273
-	$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
1274
-	$html = '<input type="password" class="' . sanitize_html_class( $size ) . '-text" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( $value ) . '"/>';
1275
-	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
1273
+    $size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
1274
+    $html = '<input type="password" class="' . sanitize_html_class( $size ) . '-text" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( $value ) . '"/>';
1275
+    $html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
1276 1276
 
1277
-	echo $html;
1277
+    echo $html;
1278 1278
 }
1279 1279
 
1280 1280
 function wpinv_missing_callback($args) {
1281
-	printf(
1282
-		__( 'The callback function used for the %s setting is missing.', 'invoicing' ),
1283
-		'<strong>' . $args['id'] . '</strong>'
1284
-	);
1281
+    printf(
1282
+        __( 'The callback function used for the %s setting is missing.', 'invoicing' ),
1283
+        '<strong>' . $args['id'] . '</strong>'
1284
+    );
1285 1285
 }
1286 1286
 
1287 1287
 function wpinv_select_callback($args) {
1288
-	global $wpinv_options;
1288
+    global $wpinv_options;
1289 1289
     
1290 1290
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1291 1291
 
1292
-	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1293
-		$value = $wpinv_options[ $args['id'] ];
1294
-	} else {
1295
-		$value = isset( $args['std'] ) ? $args['std'] : '';
1296
-	}
1292
+    if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1293
+        $value = $wpinv_options[ $args['id'] ];
1294
+    } else {
1295
+        $value = isset( $args['std'] ) ? $args['std'] : '';
1296
+    }
1297 1297
     
1298 1298
     if ( isset( $args['selected'] ) && $args['selected'] !== null && $args['selected'] !== false ) {
1299 1299
         $value = $args['selected'];
1300 1300
     }
1301 1301
 
1302
-	if ( isset( $args['placeholder'] ) ) {
1303
-		$placeholder = $args['placeholder'];
1304
-	} else {
1305
-		$placeholder = '';
1306
-	}
1302
+    if ( isset( $args['placeholder'] ) ) {
1303
+        $placeholder = $args['placeholder'];
1304
+    } else {
1305
+        $placeholder = '';
1306
+    }
1307 1307
     
1308 1308
     if( !empty( $args['onchange'] ) ) {
1309 1309
         $onchange = ' onchange="' . esc_attr( $args['onchange'] ) . '"';
@@ -1313,142 +1313,142 @@  discard block
 block discarded – undo
1313 1313
 
1314 1314
     $class = !empty( $args['class'] ) ? ' ' . esc_attr( $args['class'] ) : '';
1315 1315
 
1316
-	$html = '<select id="wpinv_settings[' . $sanitize_id . ']" class="'.$class.'"  name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" data-placeholder="' . esc_html( $placeholder ) . '"' . $onchange . ' />';
1316
+    $html = '<select id="wpinv_settings[' . $sanitize_id . ']" class="'.$class.'"  name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" data-placeholder="' . esc_html( $placeholder ) . '"' . $onchange . ' />';
1317 1317
 
1318
-	foreach ( $args['options'] as $option => $name ) {
1319
-		$selected = selected( $option, $value, false );
1320
-		$html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $name ) . '</option>';
1321
-	}
1318
+    foreach ( $args['options'] as $option => $name ) {
1319
+        $selected = selected( $option, $value, false );
1320
+        $html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $name ) . '</option>';
1321
+    }
1322 1322
 
1323
-	$html .= '</select>';
1324
-	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
1323
+    $html .= '</select>';
1324
+    $html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
1325 1325
 
1326
-	echo $html;
1326
+    echo $html;
1327 1327
 }
1328 1328
 
1329 1329
 function wpinv_color_select_callback( $args ) {
1330
-	global $wpinv_options;
1330
+    global $wpinv_options;
1331 1331
     
1332 1332
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1333 1333
 
1334
-	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1335
-		$value = $wpinv_options[ $args['id'] ];
1336
-	} else {
1337
-		$value = isset( $args['std'] ) ? $args['std'] : '';
1338
-	}
1334
+    if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1335
+        $value = $wpinv_options[ $args['id'] ];
1336
+    } else {
1337
+        $value = isset( $args['std'] ) ? $args['std'] : '';
1338
+    }
1339 1339
 
1340
-	$html = '<select id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"/>';
1340
+    $html = '<select id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"/>';
1341 1341
 
1342
-	foreach ( $args['options'] as $option => $color ) {
1343
-		$selected = selected( $option, $value, false );
1344
-		$html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $color['label'] ) . '</option>';
1345
-	}
1342
+    foreach ( $args['options'] as $option => $color ) {
1343
+        $selected = selected( $option, $value, false );
1344
+        $html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $color['label'] ) . '</option>';
1345
+    }
1346 1346
 
1347
-	$html .= '</select>';
1348
-	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1347
+    $html .= '</select>';
1348
+    $html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1349 1349
 
1350
-	echo $html;
1350
+    echo $html;
1351 1351
 }
1352 1352
 
1353 1353
 function wpinv_rich_editor_callback( $args ) {
1354
-	global $wpinv_options, $wp_version;
1354
+    global $wpinv_options, $wp_version;
1355 1355
     
1356 1356
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1357 1357
 
1358
-	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1359
-		$value = $wpinv_options[ $args['id'] ];
1358
+    if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1359
+        $value = $wpinv_options[ $args['id'] ];
1360 1360
 
1361
-		if( empty( $args['allow_blank'] ) && empty( $value ) ) {
1362
-			$value = isset( $args['std'] ) ? $args['std'] : '';
1363
-		}
1364
-	} else {
1365
-		$value = isset( $args['std'] ) ? $args['std'] : '';
1366
-	}
1361
+        if( empty( $args['allow_blank'] ) && empty( $value ) ) {
1362
+            $value = isset( $args['std'] ) ? $args['std'] : '';
1363
+        }
1364
+    } else {
1365
+        $value = isset( $args['std'] ) ? $args['std'] : '';
1366
+    }
1367 1367
 
1368
-	$rows = isset( $args['size'] ) ? $args['size'] : 20;
1368
+    $rows = isset( $args['size'] ) ? $args['size'] : 20;
1369 1369
 
1370
-	if ( $wp_version >= 3.3 && function_exists( 'wp_editor' ) ) {
1371
-		ob_start();
1372
-		wp_editor( stripslashes( $value ), 'wpinv_settings_' . esc_attr( $args['id'] ), array( 'textarea_name' => 'wpinv_settings[' . esc_attr( $args['id'] ) . ']', 'textarea_rows' => absint( $rows ), 'media_buttons' => false ) );
1373
-		$html = ob_get_clean();
1374
-	} else {
1375
-		$html = '<textarea class="large-text" rows="10" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" class="wpi-' . esc_attr( sanitize_html_class( $args['id'] ) ) . '">' . esc_textarea( stripslashes( $value ) ) . '</textarea>';
1376
-	}
1370
+    if ( $wp_version >= 3.3 && function_exists( 'wp_editor' ) ) {
1371
+        ob_start();
1372
+        wp_editor( stripslashes( $value ), 'wpinv_settings_' . esc_attr( $args['id'] ), array( 'textarea_name' => 'wpinv_settings[' . esc_attr( $args['id'] ) . ']', 'textarea_rows' => absint( $rows ), 'media_buttons' => false ) );
1373
+        $html = ob_get_clean();
1374
+    } else {
1375
+        $html = '<textarea class="large-text" rows="10" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" class="wpi-' . esc_attr( sanitize_html_class( $args['id'] ) ) . '">' . esc_textarea( stripslashes( $value ) ) . '</textarea>';
1376
+    }
1377 1377
 
1378
-	$html .= '<br/><label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
1378
+    $html .= '<br/><label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
1379 1379
 
1380
-	echo $html;
1380
+    echo $html;
1381 1381
 }
1382 1382
 
1383 1383
 function wpinv_upload_callback( $args ) {
1384
-	global $wpinv_options;
1384
+    global $wpinv_options;
1385 1385
     
1386 1386
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1387 1387
 
1388
-	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1389
-		$value = $wpinv_options[$args['id']];
1390
-	} else {
1391
-		$value = isset($args['std']) ? $args['std'] : '';
1392
-	}
1388
+    if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1389
+        $value = $wpinv_options[$args['id']];
1390
+    } else {
1391
+        $value = isset($args['std']) ? $args['std'] : '';
1392
+    }
1393 1393
 
1394
-	$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
1395
-	$html = '<input type="text" class="' . sanitize_html_class( $size ) . '-text" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( stripslashes( $value ) ) . '"/>';
1396
-	$html .= '<span>&nbsp;<input type="button" class="wpinv_settings_upload_button button-secondary" value="' . __( 'Upload File', 'invoicing' ) . '"/></span>';
1397
-	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
1394
+    $size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
1395
+    $html = '<input type="text" class="' . sanitize_html_class( $size ) . '-text" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( stripslashes( $value ) ) . '"/>';
1396
+    $html .= '<span>&nbsp;<input type="button" class="wpinv_settings_upload_button button-secondary" value="' . __( 'Upload File', 'invoicing' ) . '"/></span>';
1397
+    $html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
1398 1398
 
1399
-	echo $html;
1399
+    echo $html;
1400 1400
 }
1401 1401
 
1402 1402
 function wpinv_color_callback( $args ) {
1403
-	global $wpinv_options;
1403
+    global $wpinv_options;
1404 1404
     
1405 1405
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1406 1406
 
1407
-	if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1408
-		$value = $wpinv_options[ $args['id'] ];
1409
-	} else {
1410
-		$value = isset( $args['std'] ) ? $args['std'] : '';
1411
-	}
1407
+    if ( isset( $wpinv_options[ $args['id'] ] ) ) {
1408
+        $value = $wpinv_options[ $args['id'] ];
1409
+    } else {
1410
+        $value = isset( $args['std'] ) ? $args['std'] : '';
1411
+    }
1412 1412
 
1413
-	$default = isset( $args['std'] ) ? $args['std'] : '';
1413
+    $default = isset( $args['std'] ) ? $args['std'] : '';
1414 1414
 
1415
-	$html = '<input type="text" class="wpinv-color-picker" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( $value ) . '" data-default-color="' . esc_attr( $default ) . '" />';
1416
-	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1415
+    $html = '<input type="text" class="wpinv-color-picker" id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( $value ) . '" data-default-color="' . esc_attr( $default ) . '" />';
1416
+    $html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1417 1417
 
1418
-	echo $html;
1418
+    echo $html;
1419 1419
 }
1420 1420
 
1421 1421
 function wpinv_country_states_callback($args) {
1422
-	global $wpinv_options;
1422
+    global $wpinv_options;
1423 1423
     
1424 1424
     $sanitize_id = wpinv_sanitize_key( $args['id'] );
1425 1425
 
1426
-	if ( isset( $args['placeholder'] ) ) {
1427
-		$placeholder = $args['placeholder'];
1428
-	} else {
1429
-		$placeholder = '';
1430
-	}
1426
+    if ( isset( $args['placeholder'] ) ) {
1427
+        $placeholder = $args['placeholder'];
1428
+    } else {
1429
+        $placeholder = '';
1430
+    }
1431 1431
 
1432
-	$states = wpinv_get_country_states();
1432
+    $states = wpinv_get_country_states();
1433 1433
 
1434
-	$class = empty( $states ) ? ' class="wpinv-no-states"' : ' class="wpi_select2"';
1435
-	$html = '<select id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"' . $class . 'data-placeholder="' . esc_html( $placeholder ) . '"/>';
1434
+    $class = empty( $states ) ? ' class="wpinv-no-states"' : ' class="wpi_select2"';
1435
+    $html = '<select id="wpinv_settings[' . $sanitize_id . ']" name="wpinv_settings[' . esc_attr( $args['id'] ) . ']"' . $class . 'data-placeholder="' . esc_html( $placeholder ) . '"/>';
1436 1436
 
1437
-	foreach ( $states as $option => $name ) {
1438
-		$selected = isset( $wpinv_options[ $args['id'] ] ) ? selected( $option, $wpinv_options[$args['id']], false ) : '';
1439
-		$html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $name ) . '</option>';
1440
-	}
1437
+    foreach ( $states as $option => $name ) {
1438
+        $selected = isset( $wpinv_options[ $args['id'] ] ) ? selected( $option, $wpinv_options[$args['id']], false ) : '';
1439
+        $html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $name ) . '</option>';
1440
+    }
1441 1441
 
1442
-	$html .= '</select>';
1443
-	$html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1442
+    $html .= '</select>';
1443
+    $html .= '<label for="wpinv_settings[' . $sanitize_id . ']"> '  . wp_kses_post( $args['desc'] ) . '</label>';
1444 1444
 
1445
-	echo $html;
1445
+    echo $html;
1446 1446
 }
1447 1447
 
1448 1448
 function wpinv_tax_rates_callback($args) {
1449
-	global $wpinv_options;
1450
-	$rates = wpinv_get_tax_rates();
1451
-	ob_start(); ?>
1449
+    global $wpinv_options;
1450
+    $rates = wpinv_get_tax_rates();
1451
+    ob_start(); ?>
1452 1452
     </td><tr>
1453 1453
     <td colspan="2" class="wpinv_tax_tdbox">
1454 1454
 	<p><?php echo $args['desc']; ?></p>
@@ -1472,40 +1472,40 @@  discard block
 block discarded – undo
1472 1472
 			<tr>
1473 1473
 				<td class="wpinv_tax_country">
1474 1474
 					<?php
1475
-					echo wpinv_html_select( array(
1476
-						'options'          => wpinv_get_country_list( true ),
1477
-						'name'             => 'tax_rates[' . $sanitized_key . '][country]',
1475
+                    echo wpinv_html_select( array(
1476
+                        'options'          => wpinv_get_country_list( true ),
1477
+                        'name'             => 'tax_rates[' . $sanitized_key . '][country]',
1478 1478
                         'id'               => 'tax_rates[' . $sanitized_key . '][country]',
1479
-						'selected'         => $rate['country'],
1480
-						'show_option_all'  => false,
1481
-						'show_option_none' => false,
1482
-						'class'            => 'wpinv-tax-country wpi_select2',
1483
-						'placeholder'      => __( 'Choose a country', 'invoicing' )
1484
-					) );
1485
-					?>
1479
+                        'selected'         => $rate['country'],
1480
+                        'show_option_all'  => false,
1481
+                        'show_option_none' => false,
1482
+                        'class'            => 'wpinv-tax-country wpi_select2',
1483
+                        'placeholder'      => __( 'Choose a country', 'invoicing' )
1484
+                    ) );
1485
+                    ?>
1486 1486
 				</td>
1487 1487
 				<td class="wpinv_tax_state">
1488 1488
 					<?php
1489
-					$states = wpinv_get_country_states( $rate['country'] );
1490
-					if( !empty( $states ) ) {
1491
-						echo wpinv_html_select( array(
1492
-							'options'          => array_merge( array( '' => '' ), $states ),
1493
-							'name'             => 'tax_rates[' . $sanitized_key . '][state]',
1489
+                    $states = wpinv_get_country_states( $rate['country'] );
1490
+                    if( !empty( $states ) ) {
1491
+                        echo wpinv_html_select( array(
1492
+                            'options'          => array_merge( array( '' => '' ), $states ),
1493
+                            'name'             => 'tax_rates[' . $sanitized_key . '][state]',
1494 1494
                             'id'               => 'tax_rates[' . $sanitized_key . '][state]',
1495
-							'selected'         => $rate['state'],
1496
-							'show_option_all'  => false,
1497
-							'show_option_none' => false,
1495
+                            'selected'         => $rate['state'],
1496
+                            'show_option_all'  => false,
1497
+                            'show_option_none' => false,
1498 1498
                             'class'            => 'wpi_select2',
1499
-							'placeholder'      => __( 'Choose a state', 'invoicing' )
1500
-						) );
1501
-					} else {
1502
-						echo wpinv_html_text( array(
1503
-							'name'  => 'tax_rates[' . $sanitized_key . '][state]', $rate['state'],
1504
-							'value' => ! empty( $rate['state'] ) ? $rate['state'] : '',
1499
+                            'placeholder'      => __( 'Choose a state', 'invoicing' )
1500
+                        ) );
1501
+                    } else {
1502
+                        echo wpinv_html_text( array(
1503
+                            'name'  => 'tax_rates[' . $sanitized_key . '][state]', $rate['state'],
1504
+                            'value' => ! empty( $rate['state'] ) ? $rate['state'] : '',
1505 1505
                             'id'    => 'tax_rates[' . $sanitized_key . '][state]',
1506
-						) );
1507
-					}
1508
-					?>
1506
+                        ) );
1507
+                    }
1508
+                    ?>
1509 1509
 				</td>
1510 1510
 				<td class="wpinv_tax_global">
1511 1511
 					<input type="checkbox" name="tax_rates[<?php echo $sanitized_key; ?>][global]" id="tax_rates[<?php echo $sanitized_key; ?>][global]" value="1"<?php checked( true, ! empty( $rate['global'] ) ); ?>/>
@@ -1520,19 +1520,19 @@  discard block
 block discarded – undo
1520 1520
 			<tr>
1521 1521
 				<td class="wpinv_tax_country">
1522 1522
 					<?php
1523
-					echo wpinv_html_select( array(
1524
-						'options'          => wpinv_get_country_list( true ),
1525
-						'name'             => 'tax_rates[0][country]',
1526
-						'show_option_all'  => false,
1527
-						'show_option_none' => false,
1528
-						'class'            => 'wpinv-tax-country wpi_select2',
1529
-						'placeholder'      => __( 'Choose a country', 'invoicing' )
1530
-					) ); ?>
1523
+                    echo wpinv_html_select( array(
1524
+                        'options'          => wpinv_get_country_list( true ),
1525
+                        'name'             => 'tax_rates[0][country]',
1526
+                        'show_option_all'  => false,
1527
+                        'show_option_none' => false,
1528
+                        'class'            => 'wpinv-tax-country wpi_select2',
1529
+                        'placeholder'      => __( 'Choose a country', 'invoicing' )
1530
+                    ) ); ?>
1531 1531
 				</td>
1532 1532
 				<td class="wpinv_tax_state">
1533 1533
 					<?php echo wpinv_html_text( array(
1534
-						'name' => 'tax_rates[0][state]'
1535
-					) ); ?>
1534
+                        'name' => 'tax_rates[0][state]'
1535
+                    ) ); ?>
1536 1536
 				</td>
1537 1537
 				<td class="wpinv_tax_global">
1538 1538
 					<input type="checkbox" name="tax_rates[0][global]" id="tax_rates[0][global]" value="1"/>
@@ -1547,7 +1547,7 @@  discard block
 block discarded – undo
1547 1547
         <tfoot><tr><td colspan="5"></td><td class="wpinv_tax_action"><span class="button-secondary" id="wpinv_add_tax_rate"><?php _e( 'Add Tax Rate', 'invoicing' ); ?></span></td></tr></tfoot>
1548 1548
 	</table>
1549 1549
 	<?php
1550
-	echo ob_get_clean();
1550
+    echo ob_get_clean();
1551 1551
 }
1552 1552
 
1553 1553
 function wpinv_tools_callback($args) {
@@ -1575,15 +1575,15 @@  discard block
 block discarded – undo
1575 1575
 }
1576 1576
 
1577 1577
 function wpinv_descriptive_text_callback( $args ) {
1578
-	echo wp_kses_post( $args['desc'] );
1578
+    echo wp_kses_post( $args['desc'] );
1579 1579
 }
1580 1580
 
1581 1581
 function wpinv_hook_callback( $args ) {
1582
-	do_action( 'wpinv_' . $args['id'], $args );
1582
+    do_action( 'wpinv_' . $args['id'], $args );
1583 1583
 }
1584 1584
 
1585 1585
 function wpinv_set_settings_cap() {
1586
-	return wpinv_get_capability();
1586
+    return wpinv_get_capability();
1587 1587
 }
1588 1588
 add_filter( 'option_page_capability_wpinv_settings', 'wpinv_set_settings_cap' );
1589 1589
 
Please login to merge, or discard this patch.
includes/admin/wpinv-admin-functions.php 1 patch
Indentation   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -101,9 +101,9 @@  discard block
 block discarded – undo
101 101
         case 'status' :
102 102
             $value   = $wpi_invoice->get_status( true ) . ( $wpi_invoice->is_recurring() && $wpi_invoice->is_parent() ? ' <span class="wpi-suffix">' . __( '(r)', 'invoicing' ) . '</span>' : '' );
103 103
             $is_viewed = wpinv_is_invoice_viewed( $wpi_invoice->ID );
104
-	        $gateway_title = wpinv_get_gateway_admin_label( $wpi_invoice->get_gateway() );
105
-	        $offline_gateways = apply_filters('wpinv_offline_payments', array('bank_transfer', 'cheque', 'cod'));
106
-	        $is_offline_payment = in_array($wpi_invoice->get_gateway(), $offline_gateways) ? true : false;
104
+            $gateway_title = wpinv_get_gateway_admin_label( $wpi_invoice->get_gateway() );
105
+            $offline_gateways = apply_filters('wpinv_offline_payments', array('bank_transfer', 'cheque', 'cod'));
106
+            $is_offline_payment = in_array($wpi_invoice->get_gateway(), $offline_gateways) ? true : false;
107 107
 
108 108
             if ( 1 == $is_viewed ) {
109 109
                 $value .= '&nbsp;&nbsp;<i class="fa fa-eye" title="'.__( 'Viewed by Customer', 'invoicing' ).'"></i>';
@@ -174,69 +174,69 @@  discard block
 block discarded – undo
174 174
 }
175 175
 
176 176
 function wpinv_admin_messages() {
177
-	global $wpinv_options, $pagenow, $post;
177
+    global $wpinv_options, $pagenow, $post;
178 178
 
179
-	if ( isset( $_GET['wpinv-message'] ) && 'discount_added' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
180
-		 add_settings_error( 'wpinv-notices', 'wpinv-discount-added', __( 'Discount code added.', 'invoicing' ), 'updated' );
181
-	}
179
+    if ( isset( $_GET['wpinv-message'] ) && 'discount_added' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
180
+            add_settings_error( 'wpinv-notices', 'wpinv-discount-added', __( 'Discount code added.', 'invoicing' ), 'updated' );
181
+    }
182 182
 
183
-	if ( isset( $_GET['wpinv-message'] ) && 'discount_add_failed' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
184
-		add_settings_error( 'wpinv-notices', 'wpinv-discount-add-fail', __( 'There was a problem adding your discount code, please try again.', 'invoicing' ), 'error' );
185
-	}
183
+    if ( isset( $_GET['wpinv-message'] ) && 'discount_add_failed' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
184
+        add_settings_error( 'wpinv-notices', 'wpinv-discount-add-fail', __( 'There was a problem adding your discount code, please try again.', 'invoicing' ), 'error' );
185
+    }
186 186
 
187
-	if ( isset( $_GET['wpinv-message'] ) && 'discount_exists' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
188
-		add_settings_error( 'wpinv-notices', 'wpinv-discount-exists', __( 'A discount with that code already exists, please use a different code.', 'invoicing' ), 'error' );
189
-	}
187
+    if ( isset( $_GET['wpinv-message'] ) && 'discount_exists' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
188
+        add_settings_error( 'wpinv-notices', 'wpinv-discount-exists', __( 'A discount with that code already exists, please use a different code.', 'invoicing' ), 'error' );
189
+    }
190 190
 
191
-	if ( isset( $_GET['wpinv-message'] ) && 'discount_updated' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
192
-		 add_settings_error( 'wpinv-notices', 'wpinv-discount-updated', __( 'Discount code updated.', 'invoicing' ), 'updated' );
193
-	}
191
+    if ( isset( $_GET['wpinv-message'] ) && 'discount_updated' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
192
+            add_settings_error( 'wpinv-notices', 'wpinv-discount-updated', __( 'Discount code updated.', 'invoicing' ), 'updated' );
193
+    }
194 194
 
195
-	if ( isset( $_GET['wpinv-message'] ) && 'discount_update_failed' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
196
-		add_settings_error( 'wpinv-notices', 'wpinv-discount-updated-fail', __( 'There was a problem updating your discount code, please try again.', 'invoicing' ), 'error' );
197
-	}
195
+    if ( isset( $_GET['wpinv-message'] ) && 'discount_update_failed' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
196
+        add_settings_error( 'wpinv-notices', 'wpinv-discount-updated-fail', __( 'There was a problem updating your discount code, please try again.', 'invoicing' ), 'error' );
197
+    }
198 198
 
199
-	if ( isset( $_GET['wpinv-message'] ) && 'invoice_deleted' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
200
-		add_settings_error( 'wpinv-notices', 'wpinv-deleted', __( 'The invoice has been deleted.', 'invoicing' ), 'updated' );
201
-	}
199
+    if ( isset( $_GET['wpinv-message'] ) && 'invoice_deleted' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
200
+        add_settings_error( 'wpinv-notices', 'wpinv-deleted', __( 'The invoice has been deleted.', 'invoicing' ), 'updated' );
201
+    }
202 202
 
203
-	if ( isset( $_GET['wpinv-message'] ) && 'email_disabled' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
204
-		add_settings_error( 'wpinv-notices', 'wpinv-sent-fail', __( 'Email notification is disabled. Please check settings.', 'invoicing' ), 'error' );
205
-	}
203
+    if ( isset( $_GET['wpinv-message'] ) && 'email_disabled' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
204
+        add_settings_error( 'wpinv-notices', 'wpinv-sent-fail', __( 'Email notification is disabled. Please check settings.', 'invoicing' ), 'error' );
205
+    }
206 206
 
207
-	if ( isset( $_GET['wpinv-message'] ) && 'email_sent' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
208
-		add_settings_error( 'wpinv-notices', 'wpinv-sent', __( 'The email has been sent to customer.', 'invoicing' ), 'updated' );
207
+    if ( isset( $_GET['wpinv-message'] ) && 'email_sent' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
208
+        add_settings_error( 'wpinv-notices', 'wpinv-sent', __( 'The email has been sent to customer.', 'invoicing' ), 'updated' );
209 209
     }
210 210
     
211 211
     if ( isset( $_GET['wpinv-message'] ) && 'email_fail' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
212
-		add_settings_error( 'wpinv-notices', 'wpinv-sent-fail', __( 'Fail to send email to the customer.', 'invoicing' ), 'error' );
212
+        add_settings_error( 'wpinv-notices', 'wpinv-sent-fail', __( 'Fail to send email to the customer.', 'invoicing' ), 'error' );
213 213
     }
214 214
 
215 215
     if ( isset( $_GET['wpinv-message'] ) && 'invoice-note-deleted' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
216 216
         add_settings_error( 'wpinv-notices', 'wpinv-note-deleted', __( 'The invoice note has been deleted.', 'invoicing' ), 'updated' );
217 217
     }
218 218
 
219
-	if ( isset( $_GET['wpinv-message'] ) && 'settings-imported' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
220
-		add_settings_error( 'wpinv-notices', 'wpinv-settings-imported', __( 'The settings have been imported.', 'invoicing' ), 'updated' );
221
-	}
219
+    if ( isset( $_GET['wpinv-message'] ) && 'settings-imported' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
220
+        add_settings_error( 'wpinv-notices', 'wpinv-settings-imported', __( 'The settings have been imported.', 'invoicing' ), 'updated' );
221
+    }
222 222
 
223
-	if ( isset( $_GET['wpinv-message'] ) && 'note-added' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
224
-		add_settings_error( 'wpinv-notices', 'wpinv-note-added', __( 'The invoice note has been added successfully.', 'invoicing' ), 'updated' );
225
-	}
223
+    if ( isset( $_GET['wpinv-message'] ) && 'note-added' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
224
+        add_settings_error( 'wpinv-notices', 'wpinv-note-added', __( 'The invoice note has been added successfully.', 'invoicing' ), 'updated' );
225
+    }
226 226
 
227
-	if ( isset( $_GET['wpinv-message'] ) && 'invoice-updated' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
228
-		add_settings_error( 'wpinv-notices', 'wpinv-updated', __( 'The invoice has been successfully updated.', 'invoicing' ), 'updated' );
229
-	}
227
+    if ( isset( $_GET['wpinv-message'] ) && 'invoice-updated' == $_GET['wpinv-message'] && wpinv_current_user_can_manage_invoicing() ) {
228
+        add_settings_error( 'wpinv-notices', 'wpinv-updated', __( 'The invoice has been successfully updated.', 'invoicing' ), 'updated' );
229
+    }
230 230
     
231
-	if ( $pagenow == 'post.php' && !empty( $post->post_type ) && $post->post_type == 'wpi_item' && !wpinv_item_is_editable( $post ) ) {
232
-		$message = apply_filters( 'wpinv_item_non_editable_message', __( 'This item in not editable.', 'invoicing' ), $post->ID );
231
+    if ( $pagenow == 'post.php' && !empty( $post->post_type ) && $post->post_type == 'wpi_item' && !wpinv_item_is_editable( $post ) ) {
232
+        $message = apply_filters( 'wpinv_item_non_editable_message', __( 'This item in not editable.', 'invoicing' ), $post->ID );
233 233
 
234
-		if ( !empty( $message ) ) {
235
-			add_settings_error( 'wpinv-notices', 'wpinv-edit-n', $message, 'updated' );
236
-		}
237
-	}
234
+        if ( !empty( $message ) ) {
235
+            add_settings_error( 'wpinv-notices', 'wpinv-edit-n', $message, 'updated' );
236
+        }
237
+    }
238 238
 
239
-	settings_errors( 'wpinv-notices' );
239
+    settings_errors( 'wpinv-notices' );
240 240
 }
241 241
 add_action( 'admin_notices', 'wpinv_admin_messages' );
242 242
 
@@ -326,7 +326,7 @@  discard block
 block discarded – undo
326 326
         break;
327 327
         case 'id' :
328 328
            echo $post->ID;
329
-           echo '<div class="hidden" id="wpinv_inline-' . $post->ID . '">
329
+            echo '<div class="hidden" id="wpinv_inline-' . $post->ID . '">
330 330
                     <div class="price">' . wpinv_get_item_price( $post->ID ) . '</div>';
331 331
                     if ( $wpinv_euvat->allow_vat_rules() ) {
332 332
                         echo '<div class="vat_rule">' . $wpinv_euvat->get_item_rule( $post->ID ) . '</div>';
Please login to merge, or discard this patch.
includes/wpinv-user-functions.php 1 patch
Indentation   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -159,11 +159,11 @@
 block discarded – undo
159 159
  */
160 160
 function wpinv_get_capability( $capalibilty = 'manage_invoicing' ) {
161 161
 
162
-	if ( current_user_can( 'manage_options' ) ) {
163
-		return 'manage_options';
164
-	};
162
+    if ( current_user_can( 'manage_options' ) ) {
163
+        return 'manage_options';
164
+    };
165 165
 
166
-	return $capalibilty;
166
+    return $capalibilty;
167 167
 }
168 168
 
169 169
 /**
Please login to merge, or discard this patch.
includes/api/class-wpinv-rest-items-controller.php 1 patch
Indentation   +987 added lines, -987 removed lines patch added patch discarded remove patch
@@ -20,91 +20,91 @@  discard block
 block discarded – undo
20 20
 class WPInv_REST_Items_Controller extends WP_REST_Posts_Controller {
21 21
 
22 22
     /**
23
-	 * Post type.
24
-	 *
25
-	 * @var string
26
-	 */
27
-	protected $post_type = 'wpi_item';
23
+     * Post type.
24
+     *
25
+     * @var string
26
+     */
27
+    protected $post_type = 'wpi_item';
28 28
 	
29
-	/**
30
-	 * Cached results of get_item_schema.
31
-	 *
32
-	 * @since 1.0.13
33
-	 * @var array
34
-	 */
35
-	protected $schema;
29
+    /**
30
+     * Cached results of get_item_schema.
31
+     *
32
+     * @since 1.0.13
33
+     * @var array
34
+     */
35
+    protected $schema;
36 36
 
37 37
     /**
38
-	 * Constructor.
39
-	 *
40
-	 * @since 1.0.13
41
-	 *
42
-	 * @param string $namespace Api Namespace
43
-	 */
44
-	public function __construct( $namespace ) {
38
+     * Constructor.
39
+     *
40
+     * @since 1.0.13
41
+     *
42
+     * @param string $namespace Api Namespace
43
+     */
44
+    public function __construct( $namespace ) {
45 45
         
46 46
         // Set api namespace...
47
-		$this->namespace = $namespace;
47
+        $this->namespace = $namespace;
48 48
 
49 49
         // ... and the rest base
50 50
         $this->rest_base = 'items';
51 51
 		
52 52
     }
53 53
 	
54
-	/**
55
-	 * Registers the routes for the objects of the controller.
56
-	 *
57
-	 * @since 1.0.13
58
-	 *
59
-	 * @see register_rest_route()
60
-	 */
61
-	public function register_routes() {
62
-
63
-		parent::register_routes();
64
-
65
-		register_rest_route(
66
-			$this->namespace,
67
-			'/' . $this->rest_base . '/item-types',
68
-			array(
69
-				array(
70
-					'methods'             => WP_REST_Server::READABLE,
71
-					'callback'            => array( $this, 'get_item_types' ),
72
-				),
73
-			)
74
-		);
75
-
76
-	}
54
+    /**
55
+     * Registers the routes for the objects of the controller.
56
+     *
57
+     * @since 1.0.13
58
+     *
59
+     * @see register_rest_route()
60
+     */
61
+    public function register_routes() {
62
+
63
+        parent::register_routes();
64
+
65
+        register_rest_route(
66
+            $this->namespace,
67
+            '/' . $this->rest_base . '/item-types',
68
+            array(
69
+                array(
70
+                    'methods'             => WP_REST_Server::READABLE,
71
+                    'callback'            => array( $this, 'get_item_types' ),
72
+                ),
73
+            )
74
+        );
75
+
76
+    }
77 77
 
78 78
     /**
79
-	 * Checks if a given request has access to read items.
79
+     * Checks if a given request has access to read items.
80 80
      * 
81
-	 *
82
-	 * @since 1.0.13
83
-	 *
84
-	 * @param WP_REST_Request $request Full details about the request.
85
-	 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
86
-	 */
87
-	public function get_items_permissions_check( $request ) {
81
+     *
82
+     * @since 1.0.13
83
+     *
84
+     * @param WP_REST_Request $request Full details about the request.
85
+     * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
86
+     */
87
+    public function get_items_permissions_check( $request ) {
88 88
 	
89
-		if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
90
-			return true;
91
-		}
89
+        if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
90
+            return true;
91
+        }
92 92
 
93
-		return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to view invoice items.', 'invoicing' ), array( 'status' => rest_authorization_required_code() ) );
93
+        return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to view invoice items.', 'invoicing' ), array( 'status' => rest_authorization_required_code() ) );
94 94
 
95 95
     }
96 96
     
97 97
     /**
98
-	 * Retrieves a collection of invoice items.
99
-	 *
100
-	 * @since 1.0.13
101
-	 *
102
-	 * @param WP_REST_Request $request Full details about the request.
103
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
104
-	 */
105
-	public function get_items( $request ) {
98
+     * Retrieves a collection of invoice items.
99
+     *
100
+     * @since 1.0.13
101
+     *
102
+     * @param WP_REST_Request $request Full details about the request.
103
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
104
+     */
105
+    public function get_items( $request ) {
106 106
 		
107
-		// Retrieve the list of registered item query parameters.
107
+        // Retrieve the list of registered item query parameters.
108 108
         $registered = $this->get_collection_params();
109 109
         
110 110
         $args       = array();
@@ -117,54 +117,54 @@  discard block
 block discarded – undo
117 117
 
118 118
         }
119 119
 
120
-		/**
121
-		 * Filters the wpinv_get_items arguments for items rest requests.
122
-		 *
123
-		 *
124
-		 * @since 1.0.13
125
-		 *
126
-		 *
127
-		 * @param array           $args    Key value array of query var to query value.
128
-		 * @param WP_REST_Request $request The request used.
129
-		 */
120
+        /**
121
+         * Filters the wpinv_get_items arguments for items rest requests.
122
+         *
123
+         *
124
+         * @since 1.0.13
125
+         *
126
+         *
127
+         * @param array           $args    Key value array of query var to query value.
128
+         * @param WP_REST_Request $request The request used.
129
+         */
130 130
         $args       = apply_filters( "wpinv_rest_get_items_arguments", $args, $request, $this );
131 131
 		
132
-		// Special args
133
-		$args[ 'return' ]   = 'objects';
134
-		$args[ 'paginate' ] = true;
132
+        // Special args
133
+        $args[ 'return' ]   = 'objects';
134
+        $args[ 'paginate' ] = true;
135 135
 
136 136
         // Run the query.
137
-		$query = wpinv_get_all_items( $args );
137
+        $query = wpinv_get_all_items( $args );
138 138
 		
139
-		// Prepare the retrieved items
140
-		$items = array();
141
-		foreach( $query->items as $item ) {
142
-
143
-			if ( ! $this->check_read_permission( $item ) ) {
144
-				continue;
145
-			}
146
-
147
-			$data       = $this->prepare_item_for_response( $item, $request );
148
-			$items[]    = $this->prepare_response_for_collection( $data );
149
-
150
-		}
151
-
152
-		// Prepare the response.
153
-		$response = rest_ensure_response( $items );
154
-		$response->header( 'X-WP-Total', (int) $query->total );
155
-		$response->header( 'X-WP-TotalPages', (int) $query->max_num_pages );
156
-
157
-		/**
158
-		 * Filters the responses for item requests.
159
-		 *
160
-		 *
161
-		 * @since 1.0.13
162
-		 *
163
-		 *
164
-		 * @param arrWP_REST_Response $response    Response object.
165
-		 * @param WP_REST_Request     $request The request used.
139
+        // Prepare the retrieved items
140
+        $items = array();
141
+        foreach( $query->items as $item ) {
142
+
143
+            if ( ! $this->check_read_permission( $item ) ) {
144
+                continue;
145
+            }
146
+
147
+            $data       = $this->prepare_item_for_response( $item, $request );
148
+            $items[]    = $this->prepare_response_for_collection( $data );
149
+
150
+        }
151
+
152
+        // Prepare the response.
153
+        $response = rest_ensure_response( $items );
154
+        $response->header( 'X-WP-Total', (int) $query->total );
155
+        $response->header( 'X-WP-TotalPages', (int) $query->max_num_pages );
156
+
157
+        /**
158
+         * Filters the responses for item requests.
159
+         *
160
+         *
161
+         * @since 1.0.13
162
+         *
163
+         *
164
+         * @param arrWP_REST_Response $response    Response object.
165
+         * @param WP_REST_Request     $request The request used.
166 166
          * @param array               $args Array of args used to retrieve the items
167
-		 */
167
+         */
168 168
         $response       = apply_filters( "wpinv_rest_items_response", $response, $request, $args );
169 169
 
170 170
         return rest_ensure_response( $response );
@@ -172,25 +172,25 @@  discard block
 block discarded – undo
172 172
     }
173 173
 
174 174
     /**
175
-	 * Get the post, if the ID is valid.
176
-	 *
177
-	 * @since 1.0.13
178
-	 *
179
-	 * @param int $item_id Supplied ID.
180
-	 * @return WPInv_Item|WP_Error Item object if ID is valid, WP_Error otherwise.
181
-	 */
182
-	protected function get_post( $item_id ) {
175
+     * Get the post, if the ID is valid.
176
+     *
177
+     * @since 1.0.13
178
+     *
179
+     * @param int $item_id Supplied ID.
180
+     * @return WPInv_Item|WP_Error Item object if ID is valid, WP_Error otherwise.
181
+     */
182
+    protected function get_post( $item_id ) {
183 183
 		
184
-		$error     = new WP_Error( 'rest_item_invalid_id', __( 'Invalid item ID.', 'invoicing' ), array( 'status' => 404 ) );
184
+        $error     = new WP_Error( 'rest_item_invalid_id', __( 'Invalid item ID.', 'invoicing' ), array( 'status' => 404 ) );
185 185
 
186 186
         // Ids start from 1
187 187
         if ( (int) $item_id <= 0 ) {
188
-			return $error;
189
-		}
188
+            return $error;
189
+        }
190 190
 
191
-		$item = wpinv_get_item_by( 'id', (int) $item_id );
192
-		if ( empty( $item ) ) {
193
-			return $error;
191
+        $item = wpinv_get_item_by( 'id', (int) $item_id );
192
+        if ( empty( $item ) ) {
193
+            return $error;
194 194
         }
195 195
 
196 196
         return $item;
@@ -198,27 +198,27 @@  discard block
 block discarded – undo
198 198
     }
199 199
 
200 200
     /**
201
-	 * Checks if a given request has access to read an invoice item.
202
-	 *
203
-	 * @since 1.0.13
204
-	 *
205
-	 * @param WP_REST_Request $request Full details about the request.
206
-	 * @return bool|WP_Error True if the request has read access for the invoice item, WP_Error object otherwise.
207
-	 */
208
-	public function get_item_permissions_check( $request ) {
201
+     * Checks if a given request has access to read an invoice item.
202
+     *
203
+     * @since 1.0.13
204
+     *
205
+     * @param WP_REST_Request $request Full details about the request.
206
+     * @return bool|WP_Error True if the request has read access for the invoice item, WP_Error object otherwise.
207
+     */
208
+    public function get_item_permissions_check( $request ) {
209 209
 
210 210
         // Retrieve the item object.
211 211
         $item = $this->get_post( $request['id'] );
212 212
         
213 213
         // Ensure it is valid.
214
-		if ( is_wp_error( $item ) ) {
215
-			return $item;
216
-		}
214
+        if ( is_wp_error( $item ) ) {
215
+            return $item;
216
+        }
217 217
 
218
-		$post_type = get_post_type_object( $this->post_type );
218
+        $post_type = get_post_type_object( $this->post_type );
219 219
 
220
-		if ( ! current_user_can(  $post_type->cap->read_post, $item->ID  ) ) {
221
-			return new WP_Error( 
220
+        if ( ! current_user_can(  $post_type->cap->read_post, $item->ID  ) ) {
221
+            return new WP_Error( 
222 222
                 'rest_cannot_edit', 
223 223
                 __( 'Sorry, you are not allowed to view this item.', 'invoicing' ), 
224 224
                 array( 
@@ -227,61 +227,61 @@  discard block
 block discarded – undo
227 227
             );
228 228
         }
229 229
 
230
-		return $this->check_read_permission( $item );
230
+        return $this->check_read_permission( $item );
231 231
     }
232 232
     
233 233
     /**
234
-	 * Checks if an item can be read.
235
-	 * 
236
-	 * An item can be read by site admins.
237
-	 *
238
-	 *
239
-	 * @since 1.0.13
240
-	 *
241
-	 * @param WPInv_Item $item WPInv_Item object.
242
-	 * @return bool Whether the post can be read.
243
-	 */
244
-	public function check_read_permission( $item ) {
245
-
246
-		// An item can be read by an admin...
247
-		if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
248
-			return true;
249
-		}
250
-
251
-		return false;
234
+     * Checks if an item can be read.
235
+     * 
236
+     * An item can be read by site admins.
237
+     *
238
+     *
239
+     * @since 1.0.13
240
+     *
241
+     * @param WPInv_Item $item WPInv_Item object.
242
+     * @return bool Whether the post can be read.
243
+     */
244
+    public function check_read_permission( $item ) {
245
+
246
+        // An item can be read by an admin...
247
+        if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
248
+            return true;
249
+        }
250
+
251
+        return false;
252 252
     }
253 253
     
254 254
     /**
255
-	 * Retrieves a single invoice item.
256
-	 *
257
-	 * @since 1.0.13
258
-	 *
259
-	 * @param WP_REST_Request $request Full details about the request.
260
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
261
-	 */
262
-	public function get_item( $request ) {
255
+     * Retrieves a single invoice item.
256
+     *
257
+     * @since 1.0.13
258
+     *
259
+     * @param WP_REST_Request $request Full details about the request.
260
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
261
+     */
262
+    public function get_item( $request ) {
263 263
 
264 264
         // Fetch the item.
265 265
         $item = $this->get_post( $request['id'] );
266 266
         
267 267
         // Abort early if it does not exist
268
-		if ( is_wp_error( $item ) ) {
269
-			return $item;
270
-		}
271
-
272
-		// Prepare the response
273
-		$response = $this->prepare_item_for_response( $item, $request );
274
-
275
-		/**
276
-		 * Filters the responses for single invoice item requests.
277
-		 *
278
-		 *
279
-		 * @since 1.0.13
280
-		 * @var WP_HTTP_Response
281
-		 *
282
-		 * @param WP_HTTP_Response $response Response.
283
-		 * @param WP_REST_Request  $request The request used.
284
-		 */
268
+        if ( is_wp_error( $item ) ) {
269
+            return $item;
270
+        }
271
+
272
+        // Prepare the response
273
+        $response = $this->prepare_item_for_response( $item, $request );
274
+
275
+        /**
276
+         * Filters the responses for single invoice item requests.
277
+         *
278
+         *
279
+         * @since 1.0.13
280
+         * @var WP_HTTP_Response
281
+         *
282
+         * @param WP_HTTP_Response $response Response.
283
+         * @param WP_REST_Request  $request The request used.
284
+         */
285 285
         $response       = apply_filters( "wpinv_rest_get_item_response", $response, $request );
286 286
 
287 287
         return rest_ensure_response( $response );
@@ -289,26 +289,26 @@  discard block
 block discarded – undo
289 289
     }
290 290
     
291 291
     /**
292
-	 * Checks if a given request has access to create an invoice item.
293
-	 *
294
-	 * @since 1.0.13
295
-	 *
296
-	 * @param WP_REST_Request $request Full details about the request.
297
-	 * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
298
-	 */
299
-	public function create_item_permissions_check( $request ) {
292
+     * Checks if a given request has access to create an invoice item.
293
+     *
294
+     * @since 1.0.13
295
+     *
296
+     * @param WP_REST_Request $request Full details about the request.
297
+     * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
298
+     */
299
+    public function create_item_permissions_check( $request ) {
300 300
 	
301
-		if ( ! empty( $request['id'] ) ) {
302
-			return new WP_Error( 'rest_item_exists', __( 'Cannot create existing item.', 'invoicing' ), array( 'status' => 400 ) );
303
-		}
301
+        if ( ! empty( $request['id'] ) ) {
302
+            return new WP_Error( 'rest_item_exists', __( 'Cannot create existing item.', 'invoicing' ), array( 'status' => 400 ) );
303
+        }
304 304
 
305
-		if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
306
-			return true;
307
-		}
305
+        if ( current_user_can( 'manage_options' ) ||  current_user_can( 'manage_invoicing' ) ) {
306
+            return true;
307
+        }
308 308
 
309
-		$post_type = get_post_type_object( $this->post_type );
310
-		if ( ! current_user_can( $post_type->cap->create_posts ) ) {
311
-			return new WP_Error( 
309
+        $post_type = get_post_type_object( $this->post_type );
310
+        if ( ! current_user_can( $post_type->cap->create_posts ) ) {
311
+            return new WP_Error( 
312 312
                 'rest_cannot_create', 
313 313
                 __( 'Sorry, you are not allowed to create invoice items as this user.', 'invoicing' ), 
314 314
                 array( 
@@ -317,253 +317,253 @@  discard block
 block discarded – undo
317 317
             );
318 318
         }
319 319
 
320
-		return true;
320
+        return true;
321 321
     }
322 322
     
323 323
     /**
324
-	 * Creates a single invoice item.
325
-	 *
326
-	 * @since 1.0.13
327
-	 *
328
-	 * @param WP_REST_Request $request Full details about the request.
329
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
330
-	 */
331
-	public function create_item( $request ) {
332
-
333
-		if ( ! empty( $request['id'] ) ) {
334
-			return new WP_Error( 'rest_item_exists', __( 'Cannot create existing invoice item.', 'invoicing' ), array( 'status' => 400 ) );
335
-		}
324
+     * Creates a single invoice item.
325
+     *
326
+     * @since 1.0.13
327
+     *
328
+     * @param WP_REST_Request $request Full details about the request.
329
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
330
+     */
331
+    public function create_item( $request ) {
332
+
333
+        if ( ! empty( $request['id'] ) ) {
334
+            return new WP_Error( 'rest_item_exists', __( 'Cannot create existing invoice item.', 'invoicing' ), array( 'status' => 400 ) );
335
+        }
336 336
 
337
-		$request->set_param( 'context', 'edit' );
337
+        $request->set_param( 'context', 'edit' );
338 338
 
339
-		// Prepare the updated data.
340
-		$item_data = $this->prepare_item_for_database( $request );
339
+        // Prepare the updated data.
340
+        $item_data = $this->prepare_item_for_database( $request );
341 341
 
342
-		if ( is_wp_error( $item_data ) ) {
343
-			return $item_data;
344
-		}
342
+        if ( is_wp_error( $item_data ) ) {
343
+            return $item_data;
344
+        }
345 345
 
346
-		// Try creating the item.
346
+        // Try creating the item.
347 347
         $item = wpinv_create_item( $item_data, true );
348 348
 
349
-		if ( is_wp_error( $item ) ) {
349
+        if ( is_wp_error( $item ) ) {
350 350
             return $item;
351
-		}
352
-
353
-		// Prepare the response
354
-		$response = $this->prepare_item_for_response( $item, $request );
355
-
356
-		/**
357
-		 * Fires after a single invoice item is created or updated via the REST API.
358
-		 *
359
-		 * @since 1.0.13
360
-		 *
361
-		 * @param WPinv_Item   $item  Inserted or updated item object.
362
-		 * @param WP_REST_Request $request  Request object.
363
-		 * @param bool            $creating True when creating a post, false when updating.
364
-		 */
365
-		do_action( "wpinv_rest_insert_item", $item, $request, true );
366
-
367
-		/**
368
-		 * Filters the responses for creating single item requests.
369
-		 *
370
-		 *
371
-		 * @since 1.0.13
372
-		 *
373
-		 *
374
-		 * @param array           $item_data Invoice properties.
375
-		 * @param WP_REST_Request $request The request used.
376
-		 */
351
+        }
352
+
353
+        // Prepare the response
354
+        $response = $this->prepare_item_for_response( $item, $request );
355
+
356
+        /**
357
+         * Fires after a single invoice item is created or updated via the REST API.
358
+         *
359
+         * @since 1.0.13
360
+         *
361
+         * @param WPinv_Item   $item  Inserted or updated item object.
362
+         * @param WP_REST_Request $request  Request object.
363
+         * @param bool            $creating True when creating a post, false when updating.
364
+         */
365
+        do_action( "wpinv_rest_insert_item", $item, $request, true );
366
+
367
+        /**
368
+         * Filters the responses for creating single item requests.
369
+         *
370
+         *
371
+         * @since 1.0.13
372
+         *
373
+         *
374
+         * @param array           $item_data Invoice properties.
375
+         * @param WP_REST_Request $request The request used.
376
+         */
377 377
         $response       = apply_filters( "wpinv_rest_create_item_response", $response, $request );
378 378
 
379 379
         return rest_ensure_response( $response );
380
-	}
381
-
382
-	/**
383
-	 * Checks if a given request has access to update an item.
384
-	 *
385
-	 * @since 1.0.13
386
-	 *
387
-	 * @param WP_REST_Request $request Full details about the request.
388
-	 * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
389
-	 */
390
-	public function update_item_permissions_check( $request ) {
391
-
392
-		// Retrieve the item.
393
-		$item = $this->get_post( $request['id'] );
394
-		if ( is_wp_error( $item ) ) {
395
-			return $item;
396
-		}
397
-
398
-		if ( wpinv_current_user_can_manage_invoicing() ) {
399
-			return true;
400
-		}
401
-
402
-		return new WP_Error( 
403
-			'rest_cannot_edit', 
404
-			__( 'Sorry, you are not allowed to update this item.', 'invoicing' ), 
405
-			array( 
406
-				'status' => rest_authorization_required_code(),
407
-			)
408
-		);
409
-
410
-	}
411
-
412
-	/**
413
-	 * Updates a single item.
414
-	 *
415
-	 * @since 1.0.13
416
-	 *
417
-	 * @param WP_REST_Request $request Full details about the request.
418
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
419
-	 */
420
-	public function update_item( $request ) {
380
+    }
381
+
382
+    /**
383
+     * Checks if a given request has access to update an item.
384
+     *
385
+     * @since 1.0.13
386
+     *
387
+     * @param WP_REST_Request $request Full details about the request.
388
+     * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
389
+     */
390
+    public function update_item_permissions_check( $request ) {
391
+
392
+        // Retrieve the item.
393
+        $item = $this->get_post( $request['id'] );
394
+        if ( is_wp_error( $item ) ) {
395
+            return $item;
396
+        }
397
+
398
+        if ( wpinv_current_user_can_manage_invoicing() ) {
399
+            return true;
400
+        }
401
+
402
+        return new WP_Error( 
403
+            'rest_cannot_edit', 
404
+            __( 'Sorry, you are not allowed to update this item.', 'invoicing' ), 
405
+            array( 
406
+                'status' => rest_authorization_required_code(),
407
+            )
408
+        );
409
+
410
+    }
411
+
412
+    /**
413
+     * Updates a single item.
414
+     *
415
+     * @since 1.0.13
416
+     *
417
+     * @param WP_REST_Request $request Full details about the request.
418
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
419
+     */
420
+    public function update_item( $request ) {
421 421
 		
422
-		// Ensure the item exists.
422
+        // Ensure the item exists.
423 423
         $valid_check = $this->get_post( $request['id'] );
424 424
         
425 425
         // Abort early if it does not exist
426
-		if ( is_wp_error( $valid_check ) ) {
427
-			return $valid_check;
428
-		}
426
+        if ( is_wp_error( $valid_check ) ) {
427
+            return $valid_check;
428
+        }
429 429
 
430
-		$request->set_param( 'context', 'edit' );
430
+        $request->set_param( 'context', 'edit' );
431 431
 
432
-		// Prepare the updated data.
433
-		$data_to_update = $this->prepare_item_for_database( $request );
432
+        // Prepare the updated data.
433
+        $data_to_update = $this->prepare_item_for_database( $request );
434 434
 
435
-		if ( is_wp_error( $data_to_update ) ) {
436
-			return $data_to_update;
437
-		}
435
+        if ( is_wp_error( $data_to_update ) ) {
436
+            return $data_to_update;
437
+        }
438 438
 
439
-		// Abort if no item data is provided
439
+        // Abort if no item data is provided
440 440
         if( empty( $data_to_update ) ) {
441 441
             return new WP_Error( 'missing_data', __( 'An update request cannot be empty.', 'invoicing' ) );
442 442
         }
443 443
 
444
-		// Include the item ID
445
-		$data_to_update['ID'] = $request['id'];
446
-
447
-		// Update the item
448
-		$updated_item = wpinv_update_item( $data_to_update, true );
449
-
450
-		// Incase the update operation failed...
451
-		if ( is_wp_error( $updated_item ) ) {
452
-			return $updated_item;
453
-		}
454
-
455
-		// Prepare the response
456
-		$response = $this->prepare_item_for_response( $updated_item, $request );
457
-
458
-		/** This action is documented in includes/class-wpinv-rest-item-controller.php */
459
-		do_action( "wpinv_rest_insert_item", $updated_item, $request, false );
460
-
461
-		/**
462
-		 * Filters the responses for updating single item requests.
463
-		 *
464
-		 *
465
-		 * @since 1.0.13
466
-		 *
467
-		 *
468
-		 * @param array           $data_to_update Item properties.
469
-		 * @param WP_REST_Request $request The request used.
470
-		 */
444
+        // Include the item ID
445
+        $data_to_update['ID'] = $request['id'];
446
+
447
+        // Update the item
448
+        $updated_item = wpinv_update_item( $data_to_update, true );
449
+
450
+        // Incase the update operation failed...
451
+        if ( is_wp_error( $updated_item ) ) {
452
+            return $updated_item;
453
+        }
454
+
455
+        // Prepare the response
456
+        $response = $this->prepare_item_for_response( $updated_item, $request );
457
+
458
+        /** This action is documented in includes/class-wpinv-rest-item-controller.php */
459
+        do_action( "wpinv_rest_insert_item", $updated_item, $request, false );
460
+
461
+        /**
462
+         * Filters the responses for updating single item requests.
463
+         *
464
+         *
465
+         * @since 1.0.13
466
+         *
467
+         *
468
+         * @param array           $data_to_update Item properties.
469
+         * @param WP_REST_Request $request The request used.
470
+         */
471 471
         $response       = apply_filters( "wpinv_rest_update_item_response", $response,  $data_to_update, $request );
472 472
 
473 473
         return rest_ensure_response( $response );
474
-	}
475
-
476
-	/**
477
-	 * Checks if a given request has access to delete an item.
478
-	 *
479
-	 * @since 1.0.13
480
-	 *
481
-	 * @param WP_REST_Request $request Full details about the request.
482
-	 * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
483
-	 */
484
-	public function delete_item_permissions_check( $request ) {
485
-
486
-		// Retrieve the item.
487
-		$item = $this->get_post( $request['id'] );
488
-		if ( is_wp_error( $item ) ) {
489
-			return $item;
490
-		}
491
-
492
-		// 
493
-
494
-		// Ensure the current user can delete the item
495
-		if (! wpinv_can_delete_item( $request['id'] ) ) {
496
-			return new WP_Error( 
474
+    }
475
+
476
+    /**
477
+     * Checks if a given request has access to delete an item.
478
+     *
479
+     * @since 1.0.13
480
+     *
481
+     * @param WP_REST_Request $request Full details about the request.
482
+     * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
483
+     */
484
+    public function delete_item_permissions_check( $request ) {
485
+
486
+        // Retrieve the item.
487
+        $item = $this->get_post( $request['id'] );
488
+        if ( is_wp_error( $item ) ) {
489
+            return $item;
490
+        }
491
+
492
+        // 
493
+
494
+        // Ensure the current user can delete the item
495
+        if (! wpinv_can_delete_item( $request['id'] ) ) {
496
+            return new WP_Error( 
497 497
                 'rest_cannot_delete', 
498 498
                 __( 'Sorry, you are not allowed to delete this item.', 'invoicing' ), 
499 499
                 array( 
500 500
                     'status' => rest_authorization_required_code(),
501 501
                 )
502 502
             );
503
-		}
504
-
505
-		return true;
506
-	}
507
-
508
-	/**
509
-	 * Deletes a single item.
510
-	 *
511
-	 * @since 1.0.13
512
-	 *
513
-	 * @param WP_REST_Request $request Full details about the request.
514
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
515
-	 */
516
-	public function delete_item( $request ) {
503
+        }
504
+
505
+        return true;
506
+    }
507
+
508
+    /**
509
+     * Deletes a single item.
510
+     *
511
+     * @since 1.0.13
512
+     *
513
+     * @param WP_REST_Request $request Full details about the request.
514
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
515
+     */
516
+    public function delete_item( $request ) {
517 517
 		
518
-		// Retrieve the item.
519
-		$item = $this->get_post( $request['id'] );
520
-		if ( is_wp_error( $item ) ) {
521
-			return $item;
522
-		}
518
+        // Retrieve the item.
519
+        $item = $this->get_post( $request['id'] );
520
+        if ( is_wp_error( $item ) ) {
521
+            return $item;
522
+        }
523 523
 
524
-		$request->set_param( 'context', 'edit' );
524
+        $request->set_param( 'context', 'edit' );
525 525
 
526
-		// Prepare the item id
527
-		$id    = $item->ID;
526
+        // Prepare the item id
527
+        $id    = $item->ID;
528 528
 
529
-		// Prepare the response
530
-		$response = $this->prepare_item_for_response( $item, $request );
529
+        // Prepare the response
530
+        $response = $this->prepare_item_for_response( $item, $request );
531 531
 
532
-		// Check if the user wants to bypass the trash...
533
-		$force_delete = (bool) $request['force'];
532
+        // Check if the user wants to bypass the trash...
533
+        $force_delete = (bool) $request['force'];
534 534
 
535
-		// Try deleting the item.
536
-		$deleted = wp_delete_post( $id, $force_delete );
535
+        // Try deleting the item.
536
+        $deleted = wp_delete_post( $id, $force_delete );
537 537
 
538
-		// Abort early if we can't delete the item.
539
-		if ( ! $deleted ) {
540
-			return new WP_Error( 'rest_cannot_delete', __( 'The item cannot be deleted.', 'invoicing' ), array( 'status' => 500 ) );
541
-		}
538
+        // Abort early if we can't delete the item.
539
+        if ( ! $deleted ) {
540
+            return new WP_Error( 'rest_cannot_delete', __( 'The item cannot be deleted.', 'invoicing' ), array( 'status' => 500 ) );
541
+        }
542 542
 
543
-		/**
544
-		 * Fires immediately after a single item is deleted or trashed via the REST API.
545
-		 *
546
-		 *
547
-		 * @since 1.0.13
548
-		 *
549
-		 * @param WPInv_Item    $item  The deleted or trashed item.
550
-		 * @param WP_REST_Request  $request  The request sent to the API.
551
-		 */
552
-		do_action( "wpinv_rest_delete_item", $item, $request );
543
+        /**
544
+         * Fires immediately after a single item is deleted or trashed via the REST API.
545
+         *
546
+         *
547
+         * @since 1.0.13
548
+         *
549
+         * @param WPInv_Item    $item  The deleted or trashed item.
550
+         * @param WP_REST_Request  $request  The request sent to the API.
551
+         */
552
+        do_action( "wpinv_rest_delete_item", $item, $request );
553 553
 
554
-		return $response;
554
+        return $response;
555 555
 
556
-	}
556
+    }
557 557
     
558 558
     
559 559
     /**
560
-	 * Retrieves the query params for the items collection.
561
-	 *
562
-	 * @since 1.0.13
563
-	 *
564
-	 * @return array Collection parameters.
565
-	 */
566
-	public function get_collection_params() {
560
+     * Retrieves the query params for the items collection.
561
+     *
562
+     * @since 1.0.13
563
+     *
564
+     * @return array Collection parameters.
565
+     */
566
+    public function get_collection_params() {
567 567
         
568 568
         $query_params               = array(
569 569
 
@@ -577,27 +577,27 @@  discard block
 block discarded – undo
577 577
             
578 578
             // Item types
579 579
             'type'                  => array(
580
-				'description'       => __( 'Type of items to fetch.', 'invoicing' ),
581
-				'type'              => 'array',
582
-				'default'           => wpinv_item_types(),
583
-				'items'             => array(
580
+                'description'       => __( 'Type of items to fetch.', 'invoicing' ),
581
+                'type'              => 'array',
582
+                'default'           => wpinv_item_types(),
583
+                'items'             => array(
584 584
                     'enum'          => wpinv_item_types(),
585 585
                     'type'          => 'string',
586 586
                 ),
587
-			),
587
+            ),
588 588
 			
589
-			// Number of results per page
589
+            // Number of results per page
590 590
             'limit'                 => array(
591
-				'description'       => __( 'Number of items to fetch.', 'invoicing' ),
592
-				'type'              => 'integer',
593
-				'default'           => (int) get_option( 'posts_per_page' ),
591
+                'description'       => __( 'Number of items to fetch.', 'invoicing' ),
592
+                'type'              => 'integer',
593
+                'default'           => (int) get_option( 'posts_per_page' ),
594 594
             ),
595 595
 
596 596
             // Pagination
597 597
             'page'     => array(
598
-				'description'       => __( 'Current page to fetch.', 'invoicing' ),
599
-				'type'              => 'integer',
600
-				'default'           => 1,
598
+                'description'       => __( 'Current page to fetch.', 'invoicing' ),
599
+                'type'              => 'integer',
600
+                'default'           => 1,
601 601
             ),
602 602
 
603 603
             // Exclude certain items
@@ -620,9 +620,9 @@  discard block
 block discarded – undo
620 620
                     'date',
621 621
                     'ID',
622 622
                     'modified',
623
-					'title',
624
-					'relevance',
625
-					'rand'
623
+                    'title',
624
+                    'relevance',
625
+                    'rand'
626 626
                 ),
627 627
             ),
628 628
 
@@ -632,617 +632,617 @@  discard block
 block discarded – undo
632 632
                 'type'        => 'string',
633 633
                 'default'     => 'DESC',
634 634
                 'enum'        => array( 'ASC', 'DESC' ),
635
-			),
635
+            ),
636 636
 			
637
-			// Search term
637
+            // Search term
638 638
             'search'                => array(
639
-				'description'       => __( 'Return items that match the search term.', 'invoicing' ),
640
-				'type'              => 'string',
639
+                'description'       => __( 'Return items that match the search term.', 'invoicing' ),
640
+                'type'              => 'string',
641 641
             ),
642 642
         );
643 643
 
644
-		/**
645
-		 * Filter collection parameters for the items controller.
646
-		 *
647
-		 *
648
-		 * @since 1.0.13
649
-		 *
650
-		 * @param array        $query_params JSON Schema-formatted collection parameters.
651
-		 */
652
-		return apply_filters( "wpinv_rest_items_collection_params", $query_params );
644
+        /**
645
+         * Filter collection parameters for the items controller.
646
+         *
647
+         *
648
+         * @since 1.0.13
649
+         *
650
+         * @param array        $query_params JSON Schema-formatted collection parameters.
651
+         */
652
+        return apply_filters( "wpinv_rest_items_collection_params", $query_params );
653 653
     }
654 654
     
655 655
     /**
656
-	 * Checks if a given post type can be viewed or managed.
657
-	 *
658
-	 * @since 1.0.13
659
-	 *
660
-	 * @param object|string $post_type Post type name or object.
661
-	 * @return bool Whether the post type is allowed in REST.
662
-	 */
663
-	protected function check_is_post_type_allowed( $post_type ) {
664
-		return true;
665
-	}
666
-
667
-	/**
668
-	 * Prepares a single item for create or update.
669
-	 *
670
-	 * @since 1.0.13
671
-	 *
672
-	 * @param WP_REST_Request $request Request object.
673
-	 * @return array|WP_Error Invoice Properties or WP_Error.
674
-	 */
675
-	protected function prepare_item_for_database( $request ) {
676
-		$prepared_item = new stdClass();
677
-
678
-		// Post ID.
679
-		if ( isset( $request['id'] ) ) {
680
-			$existing_item = $this->get_post( $request['id'] );
681
-			if ( is_wp_error( $existing_item ) ) {
682
-				return $existing_item;
683
-			}
684
-
685
-			$prepared_item->ID 		  = $existing_item->ID;
686
-		}
687
-
688
-		$schema = $this->get_item_schema();
689
-
690
-		// item title.
691
-		if ( ! empty( $schema['properties']['name'] ) && isset( $request['name'] ) ) {
692
-			$prepared_item->title = sanitize_text_field( $request['name'] );
693
-		}
694
-
695
-		// item summary.
696
-		if ( ! empty( $schema['properties']['summary'] ) && isset( $request['summary'] ) ) {
697
-			$prepared_item->excerpt = wp_kses_post( $request['summary'] );
698
-		}
699
-
700
-		// item price.
701
-		if ( ! empty( $schema['properties']['price'] ) && isset( $request['price'] ) ) {
702
-			$prepared_item->price = floatval( $request['price'] );
703
-		}
704
-
705
-		// minimum price (for dynamc items).
706
-		if ( ! empty( $schema['properties']['minimum_price'] ) && isset( $request['minimum_price'] ) ) {
707
-			$prepared_item->minimum_price = floatval( $request['minimum_price'] );
708
-		}
709
-
710
-		// item status.
711
-		if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) ) {
712
-			$prepared_item->status = 'publish' === $request['status'] ? 'publish' : 'pending';
713
-		}
714
-
715
-		// item type.
716
-		if ( ! empty( $schema['properties']['type'] ) && isset( $request['type'] ) ) {
717
-			$prepared_item->type = in_array( $request['type'], wpinv_item_types() ) ? trim( strtolower( $request['type'] ) ) : 'custom';
718
-		}
719
-
720
-		// VAT rule.
721
-		if ( ! empty( $schema['properties']['vat_rule'] ) && isset( $request['vat_rule'] ) ) {
722
-			$prepared_item->vat_rule = 'digital' === $request['vat_rule'] ? 'digital' : 'physical';
723
-		}
724
-
725
-		// Simple strings.
726
-		foreach( array( 'custom_id', 'custom_name', 'custom_singular_name' ) as $property ) {
727
-
728
-			if ( ! empty( $schema['properties'][$property] ) && isset( $request[$property] ) ) {
729
-				$prepared_item->$property = sanitize_text_field( $request[$property] );
730
-			}
731
-
732
-		}
733
-
734
-		// Simple integers.
735
-		foreach( array( 'is_recurring', 'recurring_interval', 'recurring_limit', 'free_trial', 'trial_interval', 'dynamic_pricing', 'editable' ) as $property ) {
736
-
737
-			if ( ! empty( $schema['properties'][$property] ) && isset( $request[$property] ) ) {
738
-				$prepared_item->$property = intval( $request[$property] );
739
-			}
740
-
741
-		}
742
-
743
-		// Time periods.
744
-		foreach( array( 'recurring_period',  'trial_period' ) as $property ) {
745
-
746
-			if ( ! empty( $schema['properties'][$property] ) && isset( $request[$property] ) ) {
747
-				$prepared_item->$property = in_array( $request[$property], array( 'D', 'W', 'M', 'Y' ) ) ? trim( strtoupper( $request[$property] ) ) : 'D';
748
-			}
749
-
750
-		}
751
-
752
-		$item_data = (array) wp_unslash( $prepared_item );
753
-
754
-		/**
755
-		 * Filters an item before it is inserted via the REST API.
756
-		 *
757
-		 * @since 1.0.13
758
-		 *
759
-		 * @param array        $item_data An array of item data
760
-		 * @param WP_REST_Request $request       Request object.
761
-		 */
762
-		return apply_filters( "wpinv_rest_pre_insert_item", $item_data, $request );
763
-
764
-	}
765
-
766
-	/**
767
-	 * Prepares a single item output for response.
768
-	 *
769
-	 * @since 1.0.13
770
-	 *
771
-	 * @param WPInv_Item   $item    item object.
772
-	 * @param WP_REST_Request $request Request object.
773
-	 * @return WP_REST_Response Response object.
774
-	 */
775
-	public function prepare_item_for_response( $item, $request ) {
656
+     * Checks if a given post type can be viewed or managed.
657
+     *
658
+     * @since 1.0.13
659
+     *
660
+     * @param object|string $post_type Post type name or object.
661
+     * @return bool Whether the post type is allowed in REST.
662
+     */
663
+    protected function check_is_post_type_allowed( $post_type ) {
664
+        return true;
665
+    }
776 666
 
777
-		$GLOBALS['post'] = get_post( $item->get_ID() );
667
+    /**
668
+     * Prepares a single item for create or update.
669
+     *
670
+     * @since 1.0.13
671
+     *
672
+     * @param WP_REST_Request $request Request object.
673
+     * @return array|WP_Error Invoice Properties or WP_Error.
674
+     */
675
+    protected function prepare_item_for_database( $request ) {
676
+        $prepared_item = new stdClass();
677
+
678
+        // Post ID.
679
+        if ( isset( $request['id'] ) ) {
680
+            $existing_item = $this->get_post( $request['id'] );
681
+            if ( is_wp_error( $existing_item ) ) {
682
+                return $existing_item;
683
+            }
778 684
 
779
-		setup_postdata( $item->get_ID() );
685
+            $prepared_item->ID 		  = $existing_item->ID;
686
+        }
780 687
 
781
-		// Fetch the fields to include in this response.
782
-		$fields = $this->get_fields_for_response( $request );
688
+        $schema = $this->get_item_schema();
783 689
 
784
-		// Base fields for every item.
785
-		$data = array();
690
+        // item title.
691
+        if ( ! empty( $schema['properties']['name'] ) && isset( $request['name'] ) ) {
692
+            $prepared_item->title = sanitize_text_field( $request['name'] );
693
+        }
786 694
 
787
-		// Set up ID
788
-		if ( rest_is_field_included( 'id', $fields ) ) {
789
-			$data['id'] = $item->get_ID();
790
-		}
695
+        // item summary.
696
+        if ( ! empty( $schema['properties']['summary'] ) && isset( $request['summary'] ) ) {
697
+            $prepared_item->excerpt = wp_kses_post( $request['summary'] );
698
+        }
791 699
 
700
+        // item price.
701
+        if ( ! empty( $schema['properties']['price'] ) && isset( $request['price'] ) ) {
702
+            $prepared_item->price = floatval( $request['price'] );
703
+        }
792 704
 
793
-		// Item properties
794
-		$item_properties = array(
795
-			'name', 'summary', 'price', 'status', 'type',
796
-			'vat_rule', 'vat_class',
797
-			'custom_id', 'custom_name', 'custom_singular_name', 
798
-			'editable'
799
-		);
705
+        // minimum price (for dynamc items).
706
+        if ( ! empty( $schema['properties']['minimum_price'] ) && isset( $request['minimum_price'] ) ) {
707
+            $prepared_item->minimum_price = floatval( $request['minimum_price'] );
708
+        }
709
+
710
+        // item status.
711
+        if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) ) {
712
+            $prepared_item->status = 'publish' === $request['status'] ? 'publish' : 'pending';
713
+        }
800 714
 
801
-		foreach( $item_properties as $property ) {
715
+        // item type.
716
+        if ( ! empty( $schema['properties']['type'] ) && isset( $request['type'] ) ) {
717
+            $prepared_item->type = in_array( $request['type'], wpinv_item_types() ) ? trim( strtolower( $request['type'] ) ) : 'custom';
718
+        }
802 719
 
803
-			if ( rest_is_field_included( $property, $fields ) && method_exists( $item, 'get_' . $property ) ) {
804
-				$data[$property] = call_user_func( array( $item, 'get_' . $property ) );
805
-			}
720
+        // VAT rule.
721
+        if ( ! empty( $schema['properties']['vat_rule'] ) && isset( $request['vat_rule'] ) ) {
722
+            $prepared_item->vat_rule = 'digital' === $request['vat_rule'] ? 'digital' : 'physical';
723
+        }
806 724
 
807
-		}
725
+        // Simple strings.
726
+        foreach( array( 'custom_id', 'custom_name', 'custom_singular_name' ) as $property ) {
808 727
 
809
-		// Dynamic pricing.
810
-		if( $item->supports_dynamic_pricing() ) {
728
+            if ( ! empty( $schema['properties'][$property] ) && isset( $request[$property] ) ) {
729
+                $prepared_item->$property = sanitize_text_field( $request[$property] );
730
+            }
811 731
 
812
-			if( rest_is_field_included( 'dynamic_pricing', $fields ) ) {
813
-				$data['dynamic_pricing'] = $item->get_is_dynamic_pricing();
814
-			}
732
+        }
815 733
 
816
-			if( rest_is_field_included( 'minimum_price', $fields ) ) {
817
-				$data['minimum_price'] = $item->get_minimum_price();
818
-			}
819
-		}
734
+        // Simple integers.
735
+        foreach( array( 'is_recurring', 'recurring_interval', 'recurring_limit', 'free_trial', 'trial_interval', 'dynamic_pricing', 'editable' ) as $property ) {
820 736
 
821
-		// Subscriptions.
822
-		if( rest_is_field_included( 'is_recurring', $fields ) ) {
823
-			$data['is_recurring'] = $item->get_is_recurring();
824
-		}
737
+            if ( ! empty( $schema['properties'][$property] ) && isset( $request[$property] ) ) {
738
+                $prepared_item->$property = intval( $request[$property] );
739
+            }
825 740
 
826
-		if( $item->is_recurring() ) {
741
+        }
827 742
 
828
-			$recurring_fields = array( 'is_recurring', 'recurring_period', 'recurring_interval', 'recurring_limit', 'free_trial' );
829
-			foreach( $recurring_fields as $field ) {
743
+        // Time periods.
744
+        foreach( array( 'recurring_period',  'trial_period' ) as $property ) {
830 745
 
831
-				if ( rest_is_field_included( $field, $fields ) && method_exists( $item, 'get_' . $field ) ) {
832
-					$data[$field] = call_user_func( array( $item, 'get_' . $field ) );
833
-				}
746
+            if ( ! empty( $schema['properties'][$property] ) && isset( $request[$property] ) ) {
747
+                $prepared_item->$property = in_array( $request[$property], array( 'D', 'W', 'M', 'Y' ) ) ? trim( strtoupper( $request[$property] ) ) : 'D';
748
+            }
749
+
750
+        }
751
+
752
+        $item_data = (array) wp_unslash( $prepared_item );
753
+
754
+        /**
755
+         * Filters an item before it is inserted via the REST API.
756
+         *
757
+         * @since 1.0.13
758
+         *
759
+         * @param array        $item_data An array of item data
760
+         * @param WP_REST_Request $request       Request object.
761
+         */
762
+        return apply_filters( "wpinv_rest_pre_insert_item", $item_data, $request );
763
+
764
+    }
765
+
766
+    /**
767
+     * Prepares a single item output for response.
768
+     *
769
+     * @since 1.0.13
770
+     *
771
+     * @param WPInv_Item   $item    item object.
772
+     * @param WP_REST_Request $request Request object.
773
+     * @return WP_REST_Response Response object.
774
+     */
775
+    public function prepare_item_for_response( $item, $request ) {
776
+
777
+        $GLOBALS['post'] = get_post( $item->get_ID() );
778
+
779
+        setup_postdata( $item->get_ID() );
780
+
781
+        // Fetch the fields to include in this response.
782
+        $fields = $this->get_fields_for_response( $request );
783
+
784
+        // Base fields for every item.
785
+        $data = array();
786
+
787
+        // Set up ID
788
+        if ( rest_is_field_included( 'id', $fields ) ) {
789
+            $data['id'] = $item->get_ID();
790
+        }
791
+
792
+
793
+        // Item properties
794
+        $item_properties = array(
795
+            'name', 'summary', 'price', 'status', 'type',
796
+            'vat_rule', 'vat_class',
797
+            'custom_id', 'custom_name', 'custom_singular_name', 
798
+            'editable'
799
+        );
800
+
801
+        foreach( $item_properties as $property ) {
802
+
803
+            if ( rest_is_field_included( $property, $fields ) && method_exists( $item, 'get_' . $property ) ) {
804
+                $data[$property] = call_user_func( array( $item, 'get_' . $property ) );
805
+            }
806
+
807
+        }
808
+
809
+        // Dynamic pricing.
810
+        if( $item->supports_dynamic_pricing() ) {
811
+
812
+            if( rest_is_field_included( 'dynamic_pricing', $fields ) ) {
813
+                $data['dynamic_pricing'] = $item->get_is_dynamic_pricing();
814
+            }
815
+
816
+            if( rest_is_field_included( 'minimum_price', $fields ) ) {
817
+                $data['minimum_price'] = $item->get_minimum_price();
818
+            }
819
+        }
820
+
821
+        // Subscriptions.
822
+        if( rest_is_field_included( 'is_recurring', $fields ) ) {
823
+            $data['is_recurring'] = $item->get_is_recurring();
824
+        }
825
+
826
+        if( $item->is_recurring() ) {
827
+
828
+            $recurring_fields = array( 'is_recurring', 'recurring_period', 'recurring_interval', 'recurring_limit', 'free_trial' );
829
+            foreach( $recurring_fields as $field ) {
830
+
831
+                if ( rest_is_field_included( $field, $fields ) && method_exists( $item, 'get_' . $field ) ) {
832
+                    $data[$field] = call_user_func( array( $item, 'get_' . $field ) );
833
+                }
834 834
 	
835
-			}
835
+            }
836 836
 
837
-			if( $item->has_free_trial() ) {
837
+            if( $item->has_free_trial() ) {
838 838
 
839
-				$trial_fields = array( 'trial_period', 'trial_interval' );
840
-				foreach( $trial_fields as $field ) {
839
+                $trial_fields = array( 'trial_period', 'trial_interval' );
840
+                foreach( $trial_fields as $field ) {
841 841
 
842
-					if ( rest_is_field_included( $field, $fields ) && method_exists( $item, 'get_' . $field ) ) {
843
-						$data[$field] = call_user_func( array( $item, 'get_' . $field ) );
844
-					}
842
+                    if ( rest_is_field_included( $field, $fields ) && method_exists( $item, 'get_' . $field ) ) {
843
+                        $data[$field] = call_user_func( array( $item, 'get_' . $field ) );
844
+                    }
845 845
 	
846
-				}
847
-
848
-			}
849
-
850
-		}
851
-
852
-		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
853
-		$data    = $this->add_additional_fields_to_object( $data, $request );
854
-		$data    = $this->filter_response_by_context( $data, $context );
855
-
856
-		// Wrap the data in a response object.
857
-		$response = rest_ensure_response( $data );
858
-
859
-		$links = $this->prepare_links( $item );
860
-		$response->add_links( $links );
861
-
862
-		if ( ! empty( $links['self']['href'] ) ) {
863
-			$actions = $this->get_available_actions( $item, $request );
864
-
865
-			$self = $links['self']['href'];
866
-
867
-			foreach ( $actions as $rel ) {
868
-				$response->add_link( $rel, $self );
869
-			}
870
-		}
871
-
872
-		/**
873
-		 * Filters the item data for a response.
874
-		 *
875
-		 * @since 1.0.13
876
-		 *
877
-		 * @param WP_REST_Response $response The response object.
878
-		 * @param WPInv_Item    $item  The item object.
879
-		 * @param WP_REST_Request  $request  Request object.
880
-		 */
881
-		return apply_filters( "wpinv_rest_prepare_item", $response, $item, $request );
882
-	}
883
-
884
-	/**
885
-	 * Gets an array of fields to be included on the response.
886
-	 *
887
-	 * Included fields are based on item schema and `_fields=` request argument.
888
-	 *
889
-	 * @since 1.0.13
890
-	 *
891
-	 * @param WP_REST_Request $request Full details about the request.
892
-	 * @return array Fields to be included in the response.
893
-	 */
894
-	public function get_fields_for_response( $request ) {
895
-		$schema     = $this->get_item_schema();
896
-		$properties = isset( $schema['properties'] ) ? $schema['properties'] : array();
897
-
898
-		$additional_fields = $this->get_additional_fields();
899
-		foreach ( $additional_fields as $field_name => $field_options ) {
900
-			// For back-compat, include any field with an empty schema
901
-			// because it won't be present in $this->get_item_schema().
902
-			if ( is_null( $field_options['schema'] ) ) {
903
-				$properties[ $field_name ] = $field_options;
904
-			}
905
-		}
906
-
907
-		// Exclude fields that specify a different context than the request context.
908
-		$context = $request['context'];
909
-		if ( $context ) {
910
-			foreach ( $properties as $name => $options ) {
911
-				if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) {
912
-					unset( $properties[ $name ] );
913
-				}
914
-			}
915
-		}
916
-
917
-		$fields = array_keys( $properties );
918
-
919
-		if ( ! isset( $request['_fields'] ) ) {
920
-			return $fields;
921
-		}
922
-		$requested_fields = wpinv_parse_list( $request['_fields'] );
923
-		if ( 0 === count( $requested_fields ) ) {
924
-			return $fields;
925
-		}
926
-		// Trim off outside whitespace from the comma delimited list.
927
-		$requested_fields = array_map( 'trim', $requested_fields );
928
-		// Always persist 'id', because it can be needed for add_additional_fields_to_object().
929
-		if ( in_array( 'id', $fields, true ) ) {
930
-			$requested_fields[] = 'id';
931
-		}
932
-		// Return the list of all requested fields which appear in the schema.
933
-		return array_reduce(
934
-			$requested_fields,
935
-			function( $response_fields, $field ) use ( $fields ) {
936
-				if ( in_array( $field, $fields, true ) ) {
937
-					$response_fields[] = $field;
938
-					return $response_fields;
939
-				}
940
-				// Check for nested fields if $field is not a direct match.
941
-				$nested_fields = explode( '.', $field );
942
-				// A nested field is included so long as its top-level property is
943
-				// present in the schema.
944
-				if ( in_array( $nested_fields[0], $fields, true ) ) {
945
-					$response_fields[] = $field;
946
-				}
947
-				return $response_fields;
948
-			},
949
-			array()
950
-		);
951
-	}
952
-
953
-	/**
954
-	 * Retrieves the item's schema, conforming to JSON Schema.
955
-	 *
956
-	 * @since 1.0.13
957
-	 *
958
-	 * @return array Item schema data.
959
-	 */
960
-	public function get_item_schema() {
961
-
962
-		// Maybe retrieve the schema from cache.
963
-		if ( $this->schema ) {
964
-			return $this->add_additional_fields_schema( $this->schema );
965
-		}
966
-
967
-		$schema = array(
968
-			'$schema'    => 'http://json-schema.org/draft-04/schema#',
969
-			'title'      => $this->post_type,
970
-			'type'       => 'object',
971
-
972
-			// Base properties for every Item.
973
-			'properties' 		  => array(
974
-
975
-				'id'           => array(
976
-					'description' => __( 'Unique identifier for the item.', 'invoicing' ),
977
-					'type'        => 'integer',
978
-					'context'     => array( 'view', 'edit', 'embed' ),
979
-					'readonly'    => true,
980
-				),
981
-
982
-				'name'			  => array(
983
-					'description' => __( 'The name for the item.', 'invoicing' ),
984
-					'type'        => 'string',
985
-					'context'     => array( 'view', 'edit', 'embed' ),
986
-				),
987
-
988
-				'summary'        => array(
989
-					'description' => __( 'A summary for the item.', 'invoicing' ),
990
-					'type'        => 'string',
991
-					'context'     => array( 'view', 'edit', 'embed' ),
992
-				),
993
-
994
-				'price'        => array(
995
-					'description' => __( 'The price for the item.', 'invoicing' ),
996
-					'type'        => 'number',
997
-					'context'     => array( 'view', 'edit', 'embed' ),
998
-				),
999
-
1000
-				'status'       => array(
1001
-					'description' => __( 'A named status for the item.', 'invoicing' ),
1002
-					'type'        => 'string',
1003
-					'enum'        => array_keys( get_post_stati( array( 'internal' => false ) ) ),
1004
-					'context'     => array( 'view', 'edit' ),
1005
-				),
1006
-
1007
-				'type'       => array(
1008
-					'description' => __( 'The item type.', 'invoicing' ),
1009
-					'type'        => 'string',
1010
-					'enum'        => wpinv_item_types(),
1011
-					'context'     => array( 'view', 'edit', 'embed' ),
1012
-				),
1013
-
1014
-				'vat_rule'       => array(
1015
-					'description' => __( 'VAT rule applied to the item.', 'invoicing' ),
1016
-					'type'        => 'string',
1017
-					'enum'        => array( 'digital', 'physical' ),
1018
-					'context'     => array( 'view', 'edit' ),
1019
-				),
1020
-
1021
-				'vat_class'       => array(
1022
-					'description' => __( 'VAT class for the item.', 'invoicing' ),
1023
-					'type'        => 'string',
1024
-					'context'     => array( 'view', 'edit' ),
1025
-					'readonly'    => true,
1026
-				),
1027
-
1028
-				'custom_id'       => array(
1029
-					'description' => __( 'Custom id for the item.', 'invoicing' ),
1030
-					'type'        => 'string',
1031
-					'context'     => array( 'view', 'edit', 'embed' ),
1032
-				),
846
+                }
847
+
848
+            }
849
+
850
+        }
851
+
852
+        $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
853
+        $data    = $this->add_additional_fields_to_object( $data, $request );
854
+        $data    = $this->filter_response_by_context( $data, $context );
855
+
856
+        // Wrap the data in a response object.
857
+        $response = rest_ensure_response( $data );
858
+
859
+        $links = $this->prepare_links( $item );
860
+        $response->add_links( $links );
861
+
862
+        if ( ! empty( $links['self']['href'] ) ) {
863
+            $actions = $this->get_available_actions( $item, $request );
864
+
865
+            $self = $links['self']['href'];
866
+
867
+            foreach ( $actions as $rel ) {
868
+                $response->add_link( $rel, $self );
869
+            }
870
+        }
871
+
872
+        /**
873
+         * Filters the item data for a response.
874
+         *
875
+         * @since 1.0.13
876
+         *
877
+         * @param WP_REST_Response $response The response object.
878
+         * @param WPInv_Item    $item  The item object.
879
+         * @param WP_REST_Request  $request  Request object.
880
+         */
881
+        return apply_filters( "wpinv_rest_prepare_item", $response, $item, $request );
882
+    }
883
+
884
+    /**
885
+     * Gets an array of fields to be included on the response.
886
+     *
887
+     * Included fields are based on item schema and `_fields=` request argument.
888
+     *
889
+     * @since 1.0.13
890
+     *
891
+     * @param WP_REST_Request $request Full details about the request.
892
+     * @return array Fields to be included in the response.
893
+     */
894
+    public function get_fields_for_response( $request ) {
895
+        $schema     = $this->get_item_schema();
896
+        $properties = isset( $schema['properties'] ) ? $schema['properties'] : array();
897
+
898
+        $additional_fields = $this->get_additional_fields();
899
+        foreach ( $additional_fields as $field_name => $field_options ) {
900
+            // For back-compat, include any field with an empty schema
901
+            // because it won't be present in $this->get_item_schema().
902
+            if ( is_null( $field_options['schema'] ) ) {
903
+                $properties[ $field_name ] = $field_options;
904
+            }
905
+        }
906
+
907
+        // Exclude fields that specify a different context than the request context.
908
+        $context = $request['context'];
909
+        if ( $context ) {
910
+            foreach ( $properties as $name => $options ) {
911
+                if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) {
912
+                    unset( $properties[ $name ] );
913
+                }
914
+            }
915
+        }
916
+
917
+        $fields = array_keys( $properties );
918
+
919
+        if ( ! isset( $request['_fields'] ) ) {
920
+            return $fields;
921
+        }
922
+        $requested_fields = wpinv_parse_list( $request['_fields'] );
923
+        if ( 0 === count( $requested_fields ) ) {
924
+            return $fields;
925
+        }
926
+        // Trim off outside whitespace from the comma delimited list.
927
+        $requested_fields = array_map( 'trim', $requested_fields );
928
+        // Always persist 'id', because it can be needed for add_additional_fields_to_object().
929
+        if ( in_array( 'id', $fields, true ) ) {
930
+            $requested_fields[] = 'id';
931
+        }
932
+        // Return the list of all requested fields which appear in the schema.
933
+        return array_reduce(
934
+            $requested_fields,
935
+            function( $response_fields, $field ) use ( $fields ) {
936
+                if ( in_array( $field, $fields, true ) ) {
937
+                    $response_fields[] = $field;
938
+                    return $response_fields;
939
+                }
940
+                // Check for nested fields if $field is not a direct match.
941
+                $nested_fields = explode( '.', $field );
942
+                // A nested field is included so long as its top-level property is
943
+                // present in the schema.
944
+                if ( in_array( $nested_fields[0], $fields, true ) ) {
945
+                    $response_fields[] = $field;
946
+                }
947
+                return $response_fields;
948
+            },
949
+            array()
950
+        );
951
+    }
952
+
953
+    /**
954
+     * Retrieves the item's schema, conforming to JSON Schema.
955
+     *
956
+     * @since 1.0.13
957
+     *
958
+     * @return array Item schema data.
959
+     */
960
+    public function get_item_schema() {
961
+
962
+        // Maybe retrieve the schema from cache.
963
+        if ( $this->schema ) {
964
+            return $this->add_additional_fields_schema( $this->schema );
965
+        }
966
+
967
+        $schema = array(
968
+            '$schema'    => 'http://json-schema.org/draft-04/schema#',
969
+            'title'      => $this->post_type,
970
+            'type'       => 'object',
971
+
972
+            // Base properties for every Item.
973
+            'properties' 		  => array(
974
+
975
+                'id'           => array(
976
+                    'description' => __( 'Unique identifier for the item.', 'invoicing' ),
977
+                    'type'        => 'integer',
978
+                    'context'     => array( 'view', 'edit', 'embed' ),
979
+                    'readonly'    => true,
980
+                ),
981
+
982
+                'name'			  => array(
983
+                    'description' => __( 'The name for the item.', 'invoicing' ),
984
+                    'type'        => 'string',
985
+                    'context'     => array( 'view', 'edit', 'embed' ),
986
+                ),
987
+
988
+                'summary'        => array(
989
+                    'description' => __( 'A summary for the item.', 'invoicing' ),
990
+                    'type'        => 'string',
991
+                    'context'     => array( 'view', 'edit', 'embed' ),
992
+                ),
993
+
994
+                'price'        => array(
995
+                    'description' => __( 'The price for the item.', 'invoicing' ),
996
+                    'type'        => 'number',
997
+                    'context'     => array( 'view', 'edit', 'embed' ),
998
+                ),
999
+
1000
+                'status'       => array(
1001
+                    'description' => __( 'A named status for the item.', 'invoicing' ),
1002
+                    'type'        => 'string',
1003
+                    'enum'        => array_keys( get_post_stati( array( 'internal' => false ) ) ),
1004
+                    'context'     => array( 'view', 'edit' ),
1005
+                ),
1006
+
1007
+                'type'       => array(
1008
+                    'description' => __( 'The item type.', 'invoicing' ),
1009
+                    'type'        => 'string',
1010
+                    'enum'        => wpinv_item_types(),
1011
+                    'context'     => array( 'view', 'edit', 'embed' ),
1012
+                ),
1013
+
1014
+                'vat_rule'       => array(
1015
+                    'description' => __( 'VAT rule applied to the item.', 'invoicing' ),
1016
+                    'type'        => 'string',
1017
+                    'enum'        => array( 'digital', 'physical' ),
1018
+                    'context'     => array( 'view', 'edit' ),
1019
+                ),
1020
+
1021
+                'vat_class'       => array(
1022
+                    'description' => __( 'VAT class for the item.', 'invoicing' ),
1023
+                    'type'        => 'string',
1024
+                    'context'     => array( 'view', 'edit' ),
1025
+                    'readonly'    => true,
1026
+                ),
1027
+
1028
+                'custom_id'       => array(
1029
+                    'description' => __( 'Custom id for the item.', 'invoicing' ),
1030
+                    'type'        => 'string',
1031
+                    'context'     => array( 'view', 'edit', 'embed' ),
1032
+                ),
1033 1033
 				
1034
-				'custom_name'       => array(
1035
-					'description' => __( 'Custom name for the item.', 'invoicing' ),
1036
-					'type'        => 'string',
1037
-					'context'     => array( 'view', 'edit', 'embed' ),
1038
-				),
1039
-
1040
-				'custom_singular_name'       => array(
1041
-					'description' => __( 'Custom singular name for the item.', 'invoicing' ),
1042
-					'type'        => 'string',
1043
-					'context'     => array( 'view', 'edit', 'embed' ),
1044
-				),
1045
-
1046
-				'dynamic_pricing'        => array(
1047
-					'description' => __( 'Whether the item allows a user to set their own price.', 'invoicing' ),
1048
-					'type'        => 'integer',
1049
-					'context'     => array( 'view', 'edit', 'embed' ),
1050
-				),
1051
-
1052
-				'minimum_price'        => array(
1053
-					'description' => __( 'For dynamic prices, this is the minimum price that a user can set.', 'invoicing' ),
1054
-					'type'        => 'number',
1055
-					'context'     => array( 'view', 'edit', 'embed' ),
1056
-				),
1057
-
1058
-				'is_recurring'        => array(
1059
-					'description' => __( 'Whether the item is a subscription item.', 'invoicing' ),
1060
-					'type'        => 'integer',
1061
-					'context'     => array( 'view', 'edit', 'embed' ),
1062
-				),
1063
-
1064
-				'recurring_period'        => array(
1065
-					'description' => __( 'The recurring period for a recurring item.', 'invoicing' ),
1066
-					'type'        => 'string',
1067
-					'context'     => array( 'view', 'edit', 'embed' ),
1068
-					'enum'        => array( 'D', 'W', 'M', 'Y' ),
1069
-				),
1070
-
1071
-				'recurring_interval'        => array(
1072
-					'description' => __( 'The recurring interval for a subscription item.', 'invoicing' ),
1073
-					'type'        => 'integer',
1074
-					'context'     => array( 'view', 'edit', 'embed' ),
1075
-				),
1076
-
1077
-				'recurring_limit'        => array(
1078
-					'description' => __( 'The maximum number of renewals for a subscription item.', 'invoicing' ),
1079
-					'type'        => 'integer',
1080
-					'context'     => array( 'view', 'edit', 'embed' ),
1081
-				),
1082
-
1083
-				'free_trial'        => array(
1084
-					'description' => __( 'Whether the item has a free trial period.', 'invoicing' ),
1085
-					'type'        => 'integer',
1086
-					'context'     => array( 'view', 'edit', 'embed' ),
1087
-				),
1088
-
1089
-				'trial_period'        => array(
1090
-					'description' => __( 'The trial period of a recurring item.', 'invoicing' ),
1091
-					'type'        => 'string',
1092
-					'context'     => array( 'view', 'edit', 'embed' ),
1093
-					'enum'        => array( 'D', 'W', 'M', 'Y' ),
1094
-				),
1095
-
1096
-				'trial_interval'        => array(
1097
-					'description' => __( 'The trial interval for a subscription item.', 'invoicing' ),
1098
-					'type'        => 'integer',
1099
-					'context'     => array( 'view', 'edit', 'embed' ),
1100
-				),
1101
-
1102
-				'editable'        => array(
1103
-					'description' => __( 'Whether or not the item is editable.', 'invoicing' ),
1104
-					'type'        => 'integer',
1105
-					'context'     => array( 'view', 'edit' ),
1106
-				),
1107
-
1108
-			),
1109
-		);
1110
-
1111
-		// Add helpful links to the item schem.
1112
-		$schema['links'] = $this->get_schema_links();
1113
-
1114
-		/**
1115
-		 * Filters the item schema for the REST API.
1116
-		 *
1117
-		 * Enables adding extra properties to items.
1118
-		 *
1119
-		 * @since 1.0.13
1120
-		 *
1121
-		 * @param array   $schema    The item schema.
1122
-		 */
1034
+                'custom_name'       => array(
1035
+                    'description' => __( 'Custom name for the item.', 'invoicing' ),
1036
+                    'type'        => 'string',
1037
+                    'context'     => array( 'view', 'edit', 'embed' ),
1038
+                ),
1039
+
1040
+                'custom_singular_name'       => array(
1041
+                    'description' => __( 'Custom singular name for the item.', 'invoicing' ),
1042
+                    'type'        => 'string',
1043
+                    'context'     => array( 'view', 'edit', 'embed' ),
1044
+                ),
1045
+
1046
+                'dynamic_pricing'        => array(
1047
+                    'description' => __( 'Whether the item allows a user to set their own price.', 'invoicing' ),
1048
+                    'type'        => 'integer',
1049
+                    'context'     => array( 'view', 'edit', 'embed' ),
1050
+                ),
1051
+
1052
+                'minimum_price'        => array(
1053
+                    'description' => __( 'For dynamic prices, this is the minimum price that a user can set.', 'invoicing' ),
1054
+                    'type'        => 'number',
1055
+                    'context'     => array( 'view', 'edit', 'embed' ),
1056
+                ),
1057
+
1058
+                'is_recurring'        => array(
1059
+                    'description' => __( 'Whether the item is a subscription item.', 'invoicing' ),
1060
+                    'type'        => 'integer',
1061
+                    'context'     => array( 'view', 'edit', 'embed' ),
1062
+                ),
1063
+
1064
+                'recurring_period'        => array(
1065
+                    'description' => __( 'The recurring period for a recurring item.', 'invoicing' ),
1066
+                    'type'        => 'string',
1067
+                    'context'     => array( 'view', 'edit', 'embed' ),
1068
+                    'enum'        => array( 'D', 'W', 'M', 'Y' ),
1069
+                ),
1070
+
1071
+                'recurring_interval'        => array(
1072
+                    'description' => __( 'The recurring interval for a subscription item.', 'invoicing' ),
1073
+                    'type'        => 'integer',
1074
+                    'context'     => array( 'view', 'edit', 'embed' ),
1075
+                ),
1076
+
1077
+                'recurring_limit'        => array(
1078
+                    'description' => __( 'The maximum number of renewals for a subscription item.', 'invoicing' ),
1079
+                    'type'        => 'integer',
1080
+                    'context'     => array( 'view', 'edit', 'embed' ),
1081
+                ),
1082
+
1083
+                'free_trial'        => array(
1084
+                    'description' => __( 'Whether the item has a free trial period.', 'invoicing' ),
1085
+                    'type'        => 'integer',
1086
+                    'context'     => array( 'view', 'edit', 'embed' ),
1087
+                ),
1088
+
1089
+                'trial_period'        => array(
1090
+                    'description' => __( 'The trial period of a recurring item.', 'invoicing' ),
1091
+                    'type'        => 'string',
1092
+                    'context'     => array( 'view', 'edit', 'embed' ),
1093
+                    'enum'        => array( 'D', 'W', 'M', 'Y' ),
1094
+                ),
1095
+
1096
+                'trial_interval'        => array(
1097
+                    'description' => __( 'The trial interval for a subscription item.', 'invoicing' ),
1098
+                    'type'        => 'integer',
1099
+                    'context'     => array( 'view', 'edit', 'embed' ),
1100
+                ),
1101
+
1102
+                'editable'        => array(
1103
+                    'description' => __( 'Whether or not the item is editable.', 'invoicing' ),
1104
+                    'type'        => 'integer',
1105
+                    'context'     => array( 'view', 'edit' ),
1106
+                ),
1107
+
1108
+            ),
1109
+        );
1110
+
1111
+        // Add helpful links to the item schem.
1112
+        $schema['links'] = $this->get_schema_links();
1113
+
1114
+        /**
1115
+         * Filters the item schema for the REST API.
1116
+         *
1117
+         * Enables adding extra properties to items.
1118
+         *
1119
+         * @since 1.0.13
1120
+         *
1121
+         * @param array   $schema    The item schema.
1122
+         */
1123 1123
         $schema = apply_filters( "wpinv_rest_item_schema", $schema );
1124 1124
 
1125
-		//  Cache the item schema.
1126
-		$this->schema = $schema;
1125
+        //  Cache the item schema.
1126
+        $this->schema = $schema;
1127 1127
 		
1128
-		return $this->add_additional_fields_schema( $this->schema );
1129
-	}
1130
-
1131
-	/**
1132
-	 * Retrieve Link Description Objects that should be added to the Schema for the invoices collection.
1133
-	 *
1134
-	 * @since 1.0.13
1135
-	 *
1136
-	 * @return array
1137
-	 */
1138
-	protected function get_schema_links() {
1139
-
1140
-		$href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" );
1141
-
1142
-		$links = array();
1143
-
1144
-		$links[] = array(
1145
-			'rel'          => 'https://api.w.org/action-publish',
1146
-			'title'        => __( 'The current user can publish this item.' ),
1147
-			'href'         => $href,
1148
-			'targetSchema' => array(
1149
-				'type'       => 'object',
1150
-				'properties' => array(
1151
-					'status' => array(
1152
-						'type' => 'string',
1153
-						'enum' => array( 'publish', 'future' ),
1154
-					),
1155
-				),
1156
-			),
1157
-		);
1158
-
1159
-		return $links;
1160
-	}
1161
-
1162
-	/**
1163
-	 * Prepares links for the request.
1164
-	 *
1165
-	 * @since 1.0.13
1166
-	 *
1167
-	 * @param WPInv_Item $item Item Object.
1168
-	 * @return array Links for the given item.
1169
-	 */
1170
-	protected function prepare_links( $item ) {
1171
-
1172
-		// Prepare the base REST API endpoint for items.
1173
-		$base = sprintf( '%s/%s', $this->namespace, $this->rest_base );
1174
-
1175
-		// Entity meta.
1176
-		$links = array(
1177
-			'self'       => array(
1178
-				'href' => rest_url( trailingslashit( $base ) . $item->ID ),
1179
-			),
1180
-			'collection' => array(
1181
-				'href' => rest_url( $base ),
1182
-			),
1183
-		);
1184
-
1185
-		/**
1186
-		 * Filters the returned item links for the REST API.
1187
-		 *
1188
-		 * Enables adding extra links to item API responses.
1189
-		 *
1190
-		 * @since 1.0.13
1191
-		 *
1192
-		 * @param array   $links    Rest links.
1193
-		 */
1194
-		return apply_filters( "wpinv_rest_item_links", $links );
1195
-
1196
-	}
1197
-
1198
-	/**
1199
-	 * Get the link relations available for the post and current user.
1200
-	 *
1201
-	 * @since 1.0.13
1202
-	 *
1203
-	 * @param WPInv_Item   $item    Item object.
1204
-	 * @param WP_REST_Request $request Request object.
1205
-	 * @return array List of link relations.
1206
-	 */
1207
-	protected function get_available_actions( $item, $request ) {
1208
-
1209
-		if ( 'edit' !== $request['context'] ) {
1210
-			return array();
1211
-		}
1212
-
1213
-		$rels = array();
1214
-
1215
-		// Retrieve the post type object.
1216
-		$post_type = get_post_type_object( $item->post_type );
1217
-
1218
-		// Mark item as published.
1219
-		if ( current_user_can( $post_type->cap->publish_posts ) ) {
1220
-			$rels[] = 'https://api.w.org/action-publish';
1221
-		}
1222
-
1223
-		/**
1224
-		 * Filters the available item link relations for the REST API.
1225
-		 *
1226
-		 * Enables adding extra link relation for the current user and request to item responses.
1227
-		 *
1228
-		 * @since 1.0.13
1229
-		 *
1230
-		 * @param array   $rels    Available link relations.
1231
-		 */
1232
-		return apply_filters( "wpinv_rest_item_link_relations", $rels );
1233
-	}
1234
-
1235
-	/**
1236
-	 * Handles rest requests for item types.
1237
-	 *
1238
-	 * @since 1.0.13
1239
-	 * 
1240
-	 * 
1241
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
1242
-	 */
1243
-	public function get_item_types() {
1244
-		return rest_ensure_response( wpinv_get_item_types() );
1245
-	}
1128
+        return $this->add_additional_fields_schema( $this->schema );
1129
+    }
1130
+
1131
+    /**
1132
+     * Retrieve Link Description Objects that should be added to the Schema for the invoices collection.
1133
+     *
1134
+     * @since 1.0.13
1135
+     *
1136
+     * @return array
1137
+     */
1138
+    protected function get_schema_links() {
1139
+
1140
+        $href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" );
1141
+
1142
+        $links = array();
1143
+
1144
+        $links[] = array(
1145
+            'rel'          => 'https://api.w.org/action-publish',
1146
+            'title'        => __( 'The current user can publish this item.' ),
1147
+            'href'         => $href,
1148
+            'targetSchema' => array(
1149
+                'type'       => 'object',
1150
+                'properties' => array(
1151
+                    'status' => array(
1152
+                        'type' => 'string',
1153
+                        'enum' => array( 'publish', 'future' ),
1154
+                    ),
1155
+                ),
1156
+            ),
1157
+        );
1158
+
1159
+        return $links;
1160
+    }
1161
+
1162
+    /**
1163
+     * Prepares links for the request.
1164
+     *
1165
+     * @since 1.0.13
1166
+     *
1167
+     * @param WPInv_Item $item Item Object.
1168
+     * @return array Links for the given item.
1169
+     */
1170
+    protected function prepare_links( $item ) {
1171
+
1172
+        // Prepare the base REST API endpoint for items.
1173
+        $base = sprintf( '%s/%s', $this->namespace, $this->rest_base );
1174
+
1175
+        // Entity meta.
1176
+        $links = array(
1177
+            'self'       => array(
1178
+                'href' => rest_url( trailingslashit( $base ) . $item->ID ),
1179
+            ),
1180
+            'collection' => array(
1181
+                'href' => rest_url( $base ),
1182
+            ),
1183
+        );
1184
+
1185
+        /**
1186
+         * Filters the returned item links for the REST API.
1187
+         *
1188
+         * Enables adding extra links to item API responses.
1189
+         *
1190
+         * @since 1.0.13
1191
+         *
1192
+         * @param array   $links    Rest links.
1193
+         */
1194
+        return apply_filters( "wpinv_rest_item_links", $links );
1195
+
1196
+    }
1197
+
1198
+    /**
1199
+     * Get the link relations available for the post and current user.
1200
+     *
1201
+     * @since 1.0.13
1202
+     *
1203
+     * @param WPInv_Item   $item    Item object.
1204
+     * @param WP_REST_Request $request Request object.
1205
+     * @return array List of link relations.
1206
+     */
1207
+    protected function get_available_actions( $item, $request ) {
1208
+
1209
+        if ( 'edit' !== $request['context'] ) {
1210
+            return array();
1211
+        }
1212
+
1213
+        $rels = array();
1214
+
1215
+        // Retrieve the post type object.
1216
+        $post_type = get_post_type_object( $item->post_type );
1217
+
1218
+        // Mark item as published.
1219
+        if ( current_user_can( $post_type->cap->publish_posts ) ) {
1220
+            $rels[] = 'https://api.w.org/action-publish';
1221
+        }
1222
+
1223
+        /**
1224
+         * Filters the available item link relations for the REST API.
1225
+         *
1226
+         * Enables adding extra link relation for the current user and request to item responses.
1227
+         *
1228
+         * @since 1.0.13
1229
+         *
1230
+         * @param array   $rels    Available link relations.
1231
+         */
1232
+        return apply_filters( "wpinv_rest_item_link_relations", $rels );
1233
+    }
1234
+
1235
+    /**
1236
+     * Handles rest requests for item types.
1237
+     *
1238
+     * @since 1.0.13
1239
+     * 
1240
+     * 
1241
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
1242
+     */
1243
+    public function get_item_types() {
1244
+        return rest_ensure_response( wpinv_get_item_types() );
1245
+    }
1246 1246
 
1247 1247
     
1248 1248
 }
1249 1249
\ No newline at end of file
Please login to merge, or discard this patch.
includes/gateways/paypal.php 1 patch
Indentation   +255 added lines, -255 removed lines patch added patch discarded remove patch
@@ -219,262 +219,262 @@  discard block
 block discarded – undo
219 219
 add_filter( 'wpinv_paypal_args', 'wpinv_get_paypal_recurring_args', 10, 3 );
220 220
 
221 221
 function wpinv_process_paypal_ipn() {
222
-	// Check the request method is POST
223
-	if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] != 'POST' ) {
224
-		return;
225
-	}
226
-
227
-	// Set initial post data to empty string
228
-	$post_data = '';
229
-
230
-	// Fallback just in case post_max_size is lower than needed
231
-	if ( ini_get( 'allow_url_fopen' ) ) {
232
-		$post_data = file_get_contents( 'php://input' );
233
-	} else {
234
-		// If allow_url_fopen is not enabled, then make sure that post_max_size is large enough
235
-		ini_set( 'post_max_size', '12M' );
236
-	}
237
-	// Start the encoded data collection with notification command
238
-	$encoded_data = 'cmd=_notify-validate';
239
-
240
-	// Get current arg separator
241
-	$arg_separator = wpinv_get_php_arg_separator_output();
242
-
243
-	// Verify there is a post_data
244
-	if ( $post_data || strlen( $post_data ) > 0 ) {
245
-		// Append the data
246
-		$encoded_data .= $arg_separator.$post_data;
247
-	} else {
248
-		// Check if POST is empty
249
-		if ( empty( $_POST ) ) {
250
-			// Nothing to do
251
-			return;
252
-		} else {
253
-			// Loop through each POST
254
-			foreach ( $_POST as $key => $value ) {
255
-				// Encode the value and append the data
256
-				$encoded_data .= $arg_separator."$key=" . urlencode( $value );
257
-			}
258
-		}
259
-	}
260
-
261
-	// Convert collected post data to an array
262
-	wp_parse_str( $encoded_data, $encoded_data_array );
263
-
264
-	foreach ( $encoded_data_array as $key => $value ) {
265
-		if ( false !== strpos( $key, 'amp;' ) ) {
266
-			$new_key = str_replace( '&amp;', '&', $key );
267
-			$new_key = str_replace( 'amp;', '&' , $new_key );
268
-
269
-			unset( $encoded_data_array[ $key ] );
270
-			$encoded_data_array[ $new_key ] = $value;
271
-		}
272
-	}
273
-
274
-	// Get the PayPal redirect uri
275
-	$paypal_redirect = wpinv_get_paypal_redirect( true );
276
-
277
-	if ( !wpinv_get_option( 'disable_paypal_verification', false ) ) {
278
-		// Validate the IPN
279
-
280
-		$remote_post_vars      = array(
281
-			'method'           => 'POST',
282
-			'timeout'          => 45,
283
-			'redirection'      => 5,
284
-			'httpversion'      => '1.1',
285
-			'blocking'         => true,
286
-			'headers'          => array(
287
-				'host'         => 'www.paypal.com',
288
-				'connection'   => 'close',
289
-				'content-type' => 'application/x-www-form-urlencoded',
290
-				'post'         => '/cgi-bin/webscr HTTP/1.1',
291
-
292
-			),
293
-			'sslverify'        => false,
294
-			'body'             => $encoded_data_array
295
-		);
296
-
297
-		// Get response
298
-		$api_response = wp_remote_post( wpinv_get_paypal_redirect(), $remote_post_vars );
299
-
300
-		if ( is_wp_error( $api_response ) ) {
301
-			wpinv_record_gateway_error( __( 'IPN Error', 'invoicing' ), sprintf( __( 'Invalid IPN verification response. IPN data: %s', 'invoicing' ), json_encode( $api_response ) ) );
302
-			return; // Something went wrong
303
-		}
304
-
305
-		if ( $api_response['body'] !== 'VERIFIED' && wpinv_get_option( 'disable_paypal_verification', false ) ) {
306
-			wpinv_record_gateway_error( __( 'IPN Error', 'invoicing' ), sprintf( __( 'Invalid IPN verification response. IPN data: %s', 'invoicing' ), json_encode( $api_response ) ) );
307
-			return; // Response not okay
308
-		}
309
-	}
310
-
311
-	// Check if $post_data_array has been populated
312
-	if ( !is_array( $encoded_data_array ) && !empty( $encoded_data_array ) )
313
-		return;
314
-
315
-	$defaults = array(
316
-		'txn_type'       => '',
317
-		'payment_status' => ''
318
-	);
319
-
320
-	$encoded_data_array = wp_parse_args( $encoded_data_array, $defaults );
321
-
322
-	$invoice_id = isset( $encoded_data_array['custom'] ) ? absint( $encoded_data_array['custom'] ) : 0;
222
+    // Check the request method is POST
223
+    if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] != 'POST' ) {
224
+        return;
225
+    }
226
+
227
+    // Set initial post data to empty string
228
+    $post_data = '';
229
+
230
+    // Fallback just in case post_max_size is lower than needed
231
+    if ( ini_get( 'allow_url_fopen' ) ) {
232
+        $post_data = file_get_contents( 'php://input' );
233
+    } else {
234
+        // If allow_url_fopen is not enabled, then make sure that post_max_size is large enough
235
+        ini_set( 'post_max_size', '12M' );
236
+    }
237
+    // Start the encoded data collection with notification command
238
+    $encoded_data = 'cmd=_notify-validate';
239
+
240
+    // Get current arg separator
241
+    $arg_separator = wpinv_get_php_arg_separator_output();
242
+
243
+    // Verify there is a post_data
244
+    if ( $post_data || strlen( $post_data ) > 0 ) {
245
+        // Append the data
246
+        $encoded_data .= $arg_separator.$post_data;
247
+    } else {
248
+        // Check if POST is empty
249
+        if ( empty( $_POST ) ) {
250
+            // Nothing to do
251
+            return;
252
+        } else {
253
+            // Loop through each POST
254
+            foreach ( $_POST as $key => $value ) {
255
+                // Encode the value and append the data
256
+                $encoded_data .= $arg_separator."$key=" . urlencode( $value );
257
+            }
258
+        }
259
+    }
260
+
261
+    // Convert collected post data to an array
262
+    wp_parse_str( $encoded_data, $encoded_data_array );
263
+
264
+    foreach ( $encoded_data_array as $key => $value ) {
265
+        if ( false !== strpos( $key, 'amp;' ) ) {
266
+            $new_key = str_replace( '&amp;', '&', $key );
267
+            $new_key = str_replace( 'amp;', '&' , $new_key );
268
+
269
+            unset( $encoded_data_array[ $key ] );
270
+            $encoded_data_array[ $new_key ] = $value;
271
+        }
272
+    }
273
+
274
+    // Get the PayPal redirect uri
275
+    $paypal_redirect = wpinv_get_paypal_redirect( true );
276
+
277
+    if ( !wpinv_get_option( 'disable_paypal_verification', false ) ) {
278
+        // Validate the IPN
279
+
280
+        $remote_post_vars      = array(
281
+            'method'           => 'POST',
282
+            'timeout'          => 45,
283
+            'redirection'      => 5,
284
+            'httpversion'      => '1.1',
285
+            'blocking'         => true,
286
+            'headers'          => array(
287
+                'host'         => 'www.paypal.com',
288
+                'connection'   => 'close',
289
+                'content-type' => 'application/x-www-form-urlencoded',
290
+                'post'         => '/cgi-bin/webscr HTTP/1.1',
291
+
292
+            ),
293
+            'sslverify'        => false,
294
+            'body'             => $encoded_data_array
295
+        );
296
+
297
+        // Get response
298
+        $api_response = wp_remote_post( wpinv_get_paypal_redirect(), $remote_post_vars );
299
+
300
+        if ( is_wp_error( $api_response ) ) {
301
+            wpinv_record_gateway_error( __( 'IPN Error', 'invoicing' ), sprintf( __( 'Invalid IPN verification response. IPN data: %s', 'invoicing' ), json_encode( $api_response ) ) );
302
+            return; // Something went wrong
303
+        }
304
+
305
+        if ( $api_response['body'] !== 'VERIFIED' && wpinv_get_option( 'disable_paypal_verification', false ) ) {
306
+            wpinv_record_gateway_error( __( 'IPN Error', 'invoicing' ), sprintf( __( 'Invalid IPN verification response. IPN data: %s', 'invoicing' ), json_encode( $api_response ) ) );
307
+            return; // Response not okay
308
+        }
309
+    }
310
+
311
+    // Check if $post_data_array has been populated
312
+    if ( !is_array( $encoded_data_array ) && !empty( $encoded_data_array ) )
313
+        return;
314
+
315
+    $defaults = array(
316
+        'txn_type'       => '',
317
+        'payment_status' => ''
318
+    );
319
+
320
+    $encoded_data_array = wp_parse_args( $encoded_data_array, $defaults );
321
+
322
+    $invoice_id = isset( $encoded_data_array['custom'] ) ? absint( $encoded_data_array['custom'] ) : 0;
323 323
     
324
-	wpinv_error_log( $encoded_data_array['txn_type'], 'PayPal txn_type', __FILE__, __LINE__ );
325
-	wpinv_error_log( $encoded_data_array, 'PayPal IPN response', __FILE__, __LINE__ );
326
-
327
-	if ( has_action( 'wpinv_paypal_' . $encoded_data_array['txn_type'] ) ) {
328
-		// Allow PayPal IPN types to be processed separately
329
-		do_action( 'wpinv_paypal_' . $encoded_data_array['txn_type'], $encoded_data_array, $invoice_id );
330
-	} else {
331
-		// Fallback to web accept just in case the txn_type isn't present
332
-		do_action( 'wpinv_paypal_web_accept', $encoded_data_array, $invoice_id );
333
-	}
334
-	exit;
324
+    wpinv_error_log( $encoded_data_array['txn_type'], 'PayPal txn_type', __FILE__, __LINE__ );
325
+    wpinv_error_log( $encoded_data_array, 'PayPal IPN response', __FILE__, __LINE__ );
326
+
327
+    if ( has_action( 'wpinv_paypal_' . $encoded_data_array['txn_type'] ) ) {
328
+        // Allow PayPal IPN types to be processed separately
329
+        do_action( 'wpinv_paypal_' . $encoded_data_array['txn_type'], $encoded_data_array, $invoice_id );
330
+    } else {
331
+        // Fallback to web accept just in case the txn_type isn't present
332
+        do_action( 'wpinv_paypal_web_accept', $encoded_data_array, $invoice_id );
333
+    }
334
+    exit;
335 335
 }
336 336
 add_action( 'wpinv_verify_paypal_ipn', 'wpinv_process_paypal_ipn' );
337 337
 
338 338
 function wpinv_process_paypal_web_accept_and_cart( $data, $invoice_id ) {
339
-	if ( $data['txn_type'] != 'web_accept' && $data['txn_type'] != 'cart' && $data['payment_status'] != 'Refunded' ) {
340
-		return;
341
-	}
342
-
343
-	if( empty( $invoice_id ) ) {
344
-		return;
345
-	}
346
-
347
-	// Collect payment details
348
-	$purchase_key   = isset( $data['invoice'] ) ? $data['invoice'] : $data['item_number'];
349
-	$paypal_amount  = $data['mc_gross'];
350
-	$payment_status = strtolower( $data['payment_status'] );
351
-	$currency_code  = strtolower( $data['mc_currency'] );
352
-	$business_email = isset( $data['business'] ) && is_email( $data['business'] ) ? trim( $data['business'] ) : trim( $data['receiver_email'] );
353
-	$payment_meta   = wpinv_get_invoice_meta( $invoice_id );
354
-
355
-	if ( wpinv_get_payment_gateway( $invoice_id ) != 'paypal' ) {
356
-		return; // this isn't a PayPal standard IPN
357
-	}
358
-
359
-	// Verify payment recipient
360
-	if ( strcasecmp( $business_email, trim( wpinv_get_option( 'paypal_email', false ) ) ) != 0 ) {
361
-		wpinv_record_gateway_error( __( 'IPN Error', 'invoicing' ), sprintf( __( 'Invalid business email in IPN response. IPN data: %s', 'invoicing' ), json_encode( $data ) ), $invoice_id );
362
-		wpinv_update_payment_status( $invoice_id, 'wpi-failed' );
363
-		wpinv_insert_payment_note( $invoice_id, __( 'Payment failed due to invalid PayPal business email.', 'invoicing' ), '', '', true );
364
-		return;
365
-	}
366
-
367
-	// Verify payment currency
368
-	if ( $currency_code != strtolower( $payment_meta['currency'] ) ) {
369
-		wpinv_record_gateway_error( __( 'IPN Error', 'invoicing' ), sprintf( __( 'Invalid currency in IPN response. IPN data: %s', 'invoicing' ), json_encode( $data ) ), $invoice_id );
370
-		wpinv_update_payment_status( $invoice_id, 'wpi-failed' );
371
-		wpinv_insert_payment_note( $invoice_id, __( 'Payment failed due to invalid currency in PayPal IPN.', 'invoicing' ), '', '', true );
372
-		return;
373
-	}
374
-
375
-	if ( !wpinv_get_payment_user_email( $invoice_id ) ) {
376
-		// This runs when a Buy Now purchase was made. It bypasses checkout so no personal info is collected until PayPal
377
-		// No email associated with purchase, so store from PayPal
378
-		wpinv_update_invoice_meta( $invoice_id, '_wpinv_email', $data['payer_email'] );
379
-
380
-		// Setup and store the customer's details
381
-		$user_info = array(
382
-			'user_id'    => '-1',
383
-			'email'      => sanitize_text_field( $data['payer_email'] ),
384
-			'first_name' => sanitize_text_field( $data['first_name'] ),
385
-			'last_name'  => sanitize_text_field( $data['last_name'] ),
386
-			'discount'   => '',
387
-		);
388
-		$user_info['address'] = ! empty( $data['address_street']       ) ? sanitize_text_field( $data['address_street'] )       : false;
389
-		$user_info['city']    = ! empty( $data['address_city']         ) ? sanitize_text_field( $data['address_city'] )         : false;
390
-		$user_info['state']   = ! empty( $data['address_state']        ) ? sanitize_text_field( $data['address_state'] )        : false;
391
-		$user_info['country'] = ! empty( $data['address_country_code'] ) ? sanitize_text_field( $data['address_country_code'] ) : false;
392
-		$user_info['zip']     = ! empty( $data['address_zip']          ) ? sanitize_text_field( $data['address_zip'] )          : false;
393
-
394
-		$payment_meta['user_info'] = $user_info;
395
-		wpinv_update_invoice_meta( $invoice_id, '_wpinv_payment_meta', $payment_meta );
396
-	}
397
-
398
-	if ( $payment_status == 'refunded' || $payment_status == 'reversed' ) {
399
-		// Process a refund
400
-		wpinv_process_paypal_refund( $data, $invoice_id );
401
-	} else {
402
-		if ( get_post_status( $invoice_id ) == 'publish' ) {
403
-			return; // Only paid payments once
404
-		}
405
-
406
-		// Retrieve the total purchase amount (before PayPal)
407
-		$payment_amount = wpinv_payment_total( $invoice_id );
408
-
409
-		if ( number_format( (float) $paypal_amount, 2 ) < number_format( (float) $payment_amount, 2 ) ) {
410
-			// The prices don't match
411
-			wpinv_record_gateway_error( __( 'IPN Error', 'invoicing' ), sprintf( __( 'Invalid payment amount in IPN response. IPN data: %s', 'invoicing' ), json_encode( $data ) ), $invoice_id );
412
-			wpinv_update_payment_status( $invoice_id, 'wpi-failed' );
413
-			wpinv_insert_payment_note( $invoice_id, __( 'Payment failed due to invalid amount in PayPal IPN.', 'invoicing' ), '', '', true );
414
-			return;
415
-		}
416
-		if ( $purchase_key != wpinv_get_payment_key( $invoice_id ) ) {
417
-			// Purchase keys don't match
418
-			wpinv_record_gateway_error( __( 'IPN Error', 'invoicing' ), sprintf( __( 'Invalid purchase key in IPN response. IPN data: %s', 'invoicing' ), json_encode( $data ) ), $invoice_id );
419
-			wpinv_update_payment_status( $invoice_id, 'wpi-failed' );
420
-			wpinv_insert_payment_note( $invoice_id, __( 'Payment failed due to invalid purchase key in PayPal IPN.', 'invoicing' ), '', '', true );
421
-			return;
422
-		}
423
-
424
-		if ( 'complete' == $payment_status || 'completed' == $payment_status || 'processed' == $payment_status || wpinv_is_test_mode( 'paypal' ) ) {
425
-			wpinv_insert_payment_note( $invoice_id, sprintf( __( 'PayPal Transaction ID: %s', 'invoicing' ) , $data['txn_id'] ), '', '', true );
426
-			wpinv_set_payment_transaction_id( $invoice_id, $data['txn_id'] );
427
-			wpinv_update_payment_status( $invoice_id, 'publish' );
428
-		} else if ( 'pending' == $payment_status && isset( $data['pending_reason'] ) ) {
429
-			// Look for possible pending reasons, such as an echeck
430
-			$note = '';
431
-
432
-			switch( strtolower( $data['pending_reason'] ) ) {
433
-				case 'echeck' :
434
-					$note = __( 'Payment made via eCheck and will clear automatically in 5-8 days', 'invoicing' );
435
-					break;
339
+    if ( $data['txn_type'] != 'web_accept' && $data['txn_type'] != 'cart' && $data['payment_status'] != 'Refunded' ) {
340
+        return;
341
+    }
342
+
343
+    if( empty( $invoice_id ) ) {
344
+        return;
345
+    }
346
+
347
+    // Collect payment details
348
+    $purchase_key   = isset( $data['invoice'] ) ? $data['invoice'] : $data['item_number'];
349
+    $paypal_amount  = $data['mc_gross'];
350
+    $payment_status = strtolower( $data['payment_status'] );
351
+    $currency_code  = strtolower( $data['mc_currency'] );
352
+    $business_email = isset( $data['business'] ) && is_email( $data['business'] ) ? trim( $data['business'] ) : trim( $data['receiver_email'] );
353
+    $payment_meta   = wpinv_get_invoice_meta( $invoice_id );
354
+
355
+    if ( wpinv_get_payment_gateway( $invoice_id ) != 'paypal' ) {
356
+        return; // this isn't a PayPal standard IPN
357
+    }
358
+
359
+    // Verify payment recipient
360
+    if ( strcasecmp( $business_email, trim( wpinv_get_option( 'paypal_email', false ) ) ) != 0 ) {
361
+        wpinv_record_gateway_error( __( 'IPN Error', 'invoicing' ), sprintf( __( 'Invalid business email in IPN response. IPN data: %s', 'invoicing' ), json_encode( $data ) ), $invoice_id );
362
+        wpinv_update_payment_status( $invoice_id, 'wpi-failed' );
363
+        wpinv_insert_payment_note( $invoice_id, __( 'Payment failed due to invalid PayPal business email.', 'invoicing' ), '', '', true );
364
+        return;
365
+    }
366
+
367
+    // Verify payment currency
368
+    if ( $currency_code != strtolower( $payment_meta['currency'] ) ) {
369
+        wpinv_record_gateway_error( __( 'IPN Error', 'invoicing' ), sprintf( __( 'Invalid currency in IPN response. IPN data: %s', 'invoicing' ), json_encode( $data ) ), $invoice_id );
370
+        wpinv_update_payment_status( $invoice_id, 'wpi-failed' );
371
+        wpinv_insert_payment_note( $invoice_id, __( 'Payment failed due to invalid currency in PayPal IPN.', 'invoicing' ), '', '', true );
372
+        return;
373
+    }
374
+
375
+    if ( !wpinv_get_payment_user_email( $invoice_id ) ) {
376
+        // This runs when a Buy Now purchase was made. It bypasses checkout so no personal info is collected until PayPal
377
+        // No email associated with purchase, so store from PayPal
378
+        wpinv_update_invoice_meta( $invoice_id, '_wpinv_email', $data['payer_email'] );
379
+
380
+        // Setup and store the customer's details
381
+        $user_info = array(
382
+            'user_id'    => '-1',
383
+            'email'      => sanitize_text_field( $data['payer_email'] ),
384
+            'first_name' => sanitize_text_field( $data['first_name'] ),
385
+            'last_name'  => sanitize_text_field( $data['last_name'] ),
386
+            'discount'   => '',
387
+        );
388
+        $user_info['address'] = ! empty( $data['address_street']       ) ? sanitize_text_field( $data['address_street'] )       : false;
389
+        $user_info['city']    = ! empty( $data['address_city']         ) ? sanitize_text_field( $data['address_city'] )         : false;
390
+        $user_info['state']   = ! empty( $data['address_state']        ) ? sanitize_text_field( $data['address_state'] )        : false;
391
+        $user_info['country'] = ! empty( $data['address_country_code'] ) ? sanitize_text_field( $data['address_country_code'] ) : false;
392
+        $user_info['zip']     = ! empty( $data['address_zip']          ) ? sanitize_text_field( $data['address_zip'] )          : false;
393
+
394
+        $payment_meta['user_info'] = $user_info;
395
+        wpinv_update_invoice_meta( $invoice_id, '_wpinv_payment_meta', $payment_meta );
396
+    }
397
+
398
+    if ( $payment_status == 'refunded' || $payment_status == 'reversed' ) {
399
+        // Process a refund
400
+        wpinv_process_paypal_refund( $data, $invoice_id );
401
+    } else {
402
+        if ( get_post_status( $invoice_id ) == 'publish' ) {
403
+            return; // Only paid payments once
404
+        }
405
+
406
+        // Retrieve the total purchase amount (before PayPal)
407
+        $payment_amount = wpinv_payment_total( $invoice_id );
408
+
409
+        if ( number_format( (float) $paypal_amount, 2 ) < number_format( (float) $payment_amount, 2 ) ) {
410
+            // The prices don't match
411
+            wpinv_record_gateway_error( __( 'IPN Error', 'invoicing' ), sprintf( __( 'Invalid payment amount in IPN response. IPN data: %s', 'invoicing' ), json_encode( $data ) ), $invoice_id );
412
+            wpinv_update_payment_status( $invoice_id, 'wpi-failed' );
413
+            wpinv_insert_payment_note( $invoice_id, __( 'Payment failed due to invalid amount in PayPal IPN.', 'invoicing' ), '', '', true );
414
+            return;
415
+        }
416
+        if ( $purchase_key != wpinv_get_payment_key( $invoice_id ) ) {
417
+            // Purchase keys don't match
418
+            wpinv_record_gateway_error( __( 'IPN Error', 'invoicing' ), sprintf( __( 'Invalid purchase key in IPN response. IPN data: %s', 'invoicing' ), json_encode( $data ) ), $invoice_id );
419
+            wpinv_update_payment_status( $invoice_id, 'wpi-failed' );
420
+            wpinv_insert_payment_note( $invoice_id, __( 'Payment failed due to invalid purchase key in PayPal IPN.', 'invoicing' ), '', '', true );
421
+            return;
422
+        }
423
+
424
+        if ( 'complete' == $payment_status || 'completed' == $payment_status || 'processed' == $payment_status || wpinv_is_test_mode( 'paypal' ) ) {
425
+            wpinv_insert_payment_note( $invoice_id, sprintf( __( 'PayPal Transaction ID: %s', 'invoicing' ) , $data['txn_id'] ), '', '', true );
426
+            wpinv_set_payment_transaction_id( $invoice_id, $data['txn_id'] );
427
+            wpinv_update_payment_status( $invoice_id, 'publish' );
428
+        } else if ( 'pending' == $payment_status && isset( $data['pending_reason'] ) ) {
429
+            // Look for possible pending reasons, such as an echeck
430
+            $note = '';
431
+
432
+            switch( strtolower( $data['pending_reason'] ) ) {
433
+                case 'echeck' :
434
+                    $note = __( 'Payment made via eCheck and will clear automatically in 5-8 days', 'invoicing' );
435
+                    break;
436 436
 				
437 437
                 case 'address' :
438
-					$note = __( 'Payment requires a confirmed customer address and must be accepted manually through PayPal', 'invoicing' );
439
-					break;
438
+                    $note = __( 'Payment requires a confirmed customer address and must be accepted manually through PayPal', 'invoicing' );
439
+                    break;
440 440
 				
441 441
                 case 'intl' :
442
-					$note = __( 'Payment must be accepted manually through PayPal due to international account regulations', 'invoicing' );
443
-					break;
442
+                    $note = __( 'Payment must be accepted manually through PayPal due to international account regulations', 'invoicing' );
443
+                    break;
444 444
 				
445 445
                 case 'multi-currency' :
446
-					$note = __( 'Payment received in non-shop currency and must be accepted manually through PayPal', 'invoicing' );
447
-					break;
446
+                    $note = __( 'Payment received in non-shop currency and must be accepted manually through PayPal', 'invoicing' );
447
+                    break;
448 448
 				
449 449
                 case 'paymentreview' :
450 450
                 case 'regulatory_review' :
451
-					$note = __( 'Payment is being reviewed by PayPal staff as high-risk or in possible violation of government regulations', 'invoicing' );
452
-					break;
451
+                    $note = __( 'Payment is being reviewed by PayPal staff as high-risk or in possible violation of government regulations', 'invoicing' );
452
+                    break;
453 453
 				
454 454
                 case 'unilateral' :
455
-					$note = __( 'Payment was sent to non-confirmed or non-registered email address.', 'invoicing' );
456
-					break;
455
+                    $note = __( 'Payment was sent to non-confirmed or non-registered email address.', 'invoicing' );
456
+                    break;
457 457
 				
458 458
                 case 'upgrade' :
459
-					$note = __( 'PayPal account must be upgraded before this payment can be accepted', 'invoicing' );
460
-					break;
459
+                    $note = __( 'PayPal account must be upgraded before this payment can be accepted', 'invoicing' );
460
+                    break;
461 461
 				
462 462
                 case 'verify' :
463
-					$note = __( 'PayPal account is not verified. Verify account in order to accept this payment', 'invoicing' );
464
-					break;
465
-
466
-				case 'other' :
467
-					$note = __( 'Payment is pending for unknown reasons. Contact PayPal support for assistance', 'invoicing' );
468
-					break;
469
-			}
470
-
471
-			if ( ! empty( $note ) ) {
472
-				wpinv_insert_payment_note( $invoice_id, $note, '', '', true );
473
-			}
474
-		} else {
475
-			wpinv_insert_payment_note( $invoice_id, wp_sprintf( __( 'PayPal IPN has been received with invalid payment status: %s', 'invoicing' ), $payment_status ), '', '', true );
476
-		}
477
-	}
463
+                    $note = __( 'PayPal account is not verified. Verify account in order to accept this payment', 'invoicing' );
464
+                    break;
465
+
466
+                case 'other' :
467
+                    $note = __( 'Payment is pending for unknown reasons. Contact PayPal support for assistance', 'invoicing' );
468
+                    break;
469
+            }
470
+
471
+            if ( ! empty( $note ) ) {
472
+                wpinv_insert_payment_note( $invoice_id, $note, '', '', true );
473
+            }
474
+        } else {
475
+            wpinv_insert_payment_note( $invoice_id, wp_sprintf( __( 'PayPal IPN has been received with invalid payment status: %s', 'invoicing' ), $payment_status ), '', '', true );
476
+        }
477
+    }
478 478
 }
479 479
 add_action( 'wpinv_paypal_web_accept', 'wpinv_process_paypal_web_accept_and_cart', 10, 2 );
480 480
 
@@ -668,34 +668,34 @@  discard block
 block discarded – undo
668 668
 }
669 669
 
670 670
 function wpinv_process_paypal_refund( $data, $invoice_id = 0 ) {
671
-	// Collect payment details
671
+    // Collect payment details
672 672
 
673
-	if( empty( $invoice_id ) ) {
674
-		return;
675
-	}
673
+    if( empty( $invoice_id ) ) {
674
+        return;
675
+    }
676 676
 
677
-	if ( get_post_status( $invoice_id ) == 'wpi-refunded' ) {
678
-		return; // Only refund payments once
679
-	}
677
+    if ( get_post_status( $invoice_id ) == 'wpi-refunded' ) {
678
+        return; // Only refund payments once
679
+    }
680 680
 
681
-	$payment_amount = wpinv_payment_total( $invoice_id );
682
-	$refund_amount  = $data['mc_gross'] * -1;
681
+    $payment_amount = wpinv_payment_total( $invoice_id );
682
+    $refund_amount  = $data['mc_gross'] * -1;
683 683
 
684
-	do_action( 'wpinv_paypal_refund_request', $data, $invoice_id );
684
+    do_action( 'wpinv_paypal_refund_request', $data, $invoice_id );
685 685
 
686
-	if ( number_format( (float) $refund_amount, 2 ) < number_format( (float) $payment_amount, 2 ) ) {
687
-		wpinv_insert_payment_note( $invoice_id, wp_sprintf( __( 'PayPal partial refund of %s processed for transaction #%s for reason: %s', 'invoicing' ), (float)$refund_amount . ' '. $data['mc_currency'], $data['parent_txn_id'], $data['reason_code'] ), '', '', true );
686
+    if ( number_format( (float) $refund_amount, 2 ) < number_format( (float) $payment_amount, 2 ) ) {
687
+        wpinv_insert_payment_note( $invoice_id, wp_sprintf( __( 'PayPal partial refund of %s processed for transaction #%s for reason: %s', 'invoicing' ), (float)$refund_amount . ' '. $data['mc_currency'], $data['parent_txn_id'], $data['reason_code'] ), '', '', true );
688 688
 
689
-		do_action( 'wpinv_paypal_invoice_partially_refunded', $data, $invoice_id, $refund_amount );
689
+        do_action( 'wpinv_paypal_invoice_partially_refunded', $data, $invoice_id, $refund_amount );
690 690
 
691
-		return; // This is a partial refund
692
-	}
691
+        return; // This is a partial refund
692
+    }
693 693
 
694
-	wpinv_insert_payment_note( $invoice_id, sprintf( __( 'PayPal Payment #%s Refunded for reason: %s', 'invoicing' ), $data['parent_txn_id'], $data['reason_code'] ), '', '', true );
695
-	wpinv_insert_payment_note( $invoice_id, sprintf( __( 'PayPal Refund Transaction ID: %s', 'invoicing' ), $data['txn_id'] ), '', '', true );
696
-	wpinv_update_payment_status( $invoice_id, 'wpi-refunded' );
694
+    wpinv_insert_payment_note( $invoice_id, sprintf( __( 'PayPal Payment #%s Refunded for reason: %s', 'invoicing' ), $data['parent_txn_id'], $data['reason_code'] ), '', '', true );
695
+    wpinv_insert_payment_note( $invoice_id, sprintf( __( 'PayPal Refund Transaction ID: %s', 'invoicing' ), $data['txn_id'] ), '', '', true );
696
+    wpinv_update_payment_status( $invoice_id, 'wpi-refunded' );
697 697
 
698
-	do_action( 'wpinv_paypal_invoice_fully_refunded', $data, $invoice_id );
698
+    do_action( 'wpinv_paypal_invoice_fully_refunded', $data, $invoice_id );
699 699
 }
700 700
 
701 701
 function wpinv_get_paypal_redirect( $ssl_check = false ) {
Please login to merge, or discard this patch.
includes/api/class-wpinv-rest-discounts-controller.php 1 patch
Indentation   +970 added lines, -970 removed lines patch added patch discarded remove patch
@@ -20,91 +20,91 @@  discard block
 block discarded – undo
20 20
 class WPInv_REST_Discounts_Controller extends WP_REST_Posts_Controller {
21 21
 
22 22
     /**
23
-	 * Post type.
24
-	 *
25
-	 * @var string
26
-	 */
27
-	protected $post_type = 'wpi_discount';
23
+     * Post type.
24
+     *
25
+     * @var string
26
+     */
27
+    protected $post_type = 'wpi_discount';
28 28
 	
29
-	/**
30
-	 * Cached results of get_item_schema.
31
-	 *
32
-	 * @since 1.0.13
33
-	 * @var array
34
-	 */
35
-	protected $schema;
29
+    /**
30
+     * Cached results of get_item_schema.
31
+     *
32
+     * @since 1.0.13
33
+     * @var array
34
+     */
35
+    protected $schema;
36 36
 
37 37
     /**
38
-	 * Constructor.
39
-	 *
40
-	 * @since 1.0.13
41
-	 *
42
-	 * @param string $namespace Api Namespace
43
-	 */
44
-	public function __construct( $namespace ) {
38
+     * Constructor.
39
+     *
40
+     * @since 1.0.13
41
+     *
42
+     * @param string $namespace Api Namespace
43
+     */
44
+    public function __construct( $namespace ) {
45 45
         
46 46
         // Set api namespace...
47
-		$this->namespace = $namespace;
47
+        $this->namespace = $namespace;
48 48
 
49 49
         // ... and the rest base
50 50
         $this->rest_base = 'discounts';
51 51
 		
52 52
     }
53 53
 	
54
-	/**
55
-	 * Registers the routes for the objects of the controller.
56
-	 *
57
-	 * @since 1.0.13
58
-	 *
59
-	 * @see register_rest_route()
60
-	 */
61
-	public function register_routes() {
62
-
63
-		parent::register_routes();
64
-
65
-		register_rest_route(
66
-			$this->namespace,
67
-			'/' . $this->rest_base . '/discount-types',
68
-			array(
69
-				array(
70
-					'methods'             => WP_REST_Server::READABLE,
71
-					'callback'            => array( $this, 'get_discount_types' ),
72
-				),
73
-			)
74
-		);
75
-
76
-	}
54
+    /**
55
+     * Registers the routes for the objects of the controller.
56
+     *
57
+     * @since 1.0.13
58
+     *
59
+     * @see register_rest_route()
60
+     */
61
+    public function register_routes() {
62
+
63
+        parent::register_routes();
64
+
65
+        register_rest_route(
66
+            $this->namespace,
67
+            '/' . $this->rest_base . '/discount-types',
68
+            array(
69
+                array(
70
+                    'methods'             => WP_REST_Server::READABLE,
71
+                    'callback'            => array( $this, 'get_discount_types' ),
72
+                ),
73
+            )
74
+        );
75
+
76
+    }
77 77
 
78 78
     /**
79
-	 * Checks if a given request has access to read discounts.
79
+     * Checks if a given request has access to read discounts.
80 80
      * 
81
-	 *
82
-	 * @since 1.0.13
83
-	 *
84
-	 * @param WP_REST_Request $request Full details about the request.
85
-	 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
86
-	 */
87
-	public function get_items_permissions_check( $request ) {
81
+     *
82
+     * @since 1.0.13
83
+     *
84
+     * @param WP_REST_Request $request Full details about the request.
85
+     * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
86
+     */
87
+    public function get_items_permissions_check( $request ) {
88 88
 	
89
-		if ( wpinv_current_user_can_manage_invoicing() ) {
90
-			return true;
91
-		}
89
+        if ( wpinv_current_user_can_manage_invoicing() ) {
90
+            return true;
91
+        }
92 92
 
93
-		return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to view invoice discounts.', 'invoicing' ), array( 'status' => rest_authorization_required_code() ) );
93
+        return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to view invoice discounts.', 'invoicing' ), array( 'status' => rest_authorization_required_code() ) );
94 94
 
95 95
     }
96 96
     
97 97
     /**
98
-	 * Retrieves a collection of discounts.
99
-	 *
100
-	 * @since 1.0.13
101
-	 *
102
-	 * @param WP_REST_Request $request Full details about the request.
103
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
104
-	 */
105
-	public function get_items( $request ) {
98
+     * Retrieves a collection of discounts.
99
+     *
100
+     * @since 1.0.13
101
+     *
102
+     * @param WP_REST_Request $request Full details about the request.
103
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
104
+     */
105
+    public function get_items( $request ) {
106 106
 		
107
-		// Retrieve the list of registered item query parameters.
107
+        // Retrieve the list of registered item query parameters.
108 108
         $registered = $this->get_collection_params();
109 109
         
110 110
         $args       = array();
@@ -115,52 +115,52 @@  discard block
 block discarded – undo
115 115
                 $args[ $key ] = $request[ $key];
116 116
             }
117 117
 
118
-		} 
119
-
120
-		/**
121
-		 * Filters the wpinv_get_all_discounts arguments for discounts rest requests.
122
-		 *
123
-		 *
124
-		 * @since 1.0.13
125
-		 *
126
-		 *
127
-		 * @param array           $args    Key value array of query var to query value.
128
-		 * @param WP_REST_Request $request The request used.
129
-		 */
118
+        } 
119
+
120
+        /**
121
+         * Filters the wpinv_get_all_discounts arguments for discounts rest requests.
122
+         *
123
+         *
124
+         * @since 1.0.13
125
+         *
126
+         *
127
+         * @param array           $args    Key value array of query var to query value.
128
+         * @param WP_REST_Request $request The request used.
129
+         */
130 130
         $args       = apply_filters( "wpinv_rest_get_discounts_arguments", $args, $request, $this );
131 131
 		
132
-		// Special args
133
-		$args[ 'return' ]   = 'objects';
134
-		$args[ 'paginate' ] = true;
132
+        // Special args
133
+        $args[ 'return' ]   = 'objects';
134
+        $args[ 'paginate' ] = true;
135 135
 
136 136
         // Run the query.
137
-		$query = wpinv_get_all_discounts( $args );
137
+        $query = wpinv_get_all_discounts( $args );
138 138
 		
139
-		// Prepare the retrieved discounts
140
-		$discounts = array();
141
-		foreach( $query->discounts as $discount ) {
142
-
143
-			$data       = $this->prepare_item_for_response( $discount, $request );
144
-			$discounts[]    = $this->prepare_response_for_collection( $data );
145
-
146
-		}
147
-
148
-		// Prepare the response.
149
-		$response = rest_ensure_response( $discounts );
150
-		$response->header( 'X-WP-Total', (int) $query->total );
151
-		$response->header( 'X-WP-TotalPages', (int) $query->max_num_pages );
152
-
153
-		/**
154
-		 * Filters the responses for discount requests.
155
-		 *
156
-		 *
157
-		 * @since 1.0.13
158
-		 *
159
-		 *
160
-		 * @param arrWP_REST_Response $response    Response object.
161
-		 * @param WP_REST_Request     $request The request used.
139
+        // Prepare the retrieved discounts
140
+        $discounts = array();
141
+        foreach( $query->discounts as $discount ) {
142
+
143
+            $data       = $this->prepare_item_for_response( $discount, $request );
144
+            $discounts[]    = $this->prepare_response_for_collection( $data );
145
+
146
+        }
147
+
148
+        // Prepare the response.
149
+        $response = rest_ensure_response( $discounts );
150
+        $response->header( 'X-WP-Total', (int) $query->total );
151
+        $response->header( 'X-WP-TotalPages', (int) $query->max_num_pages );
152
+
153
+        /**
154
+         * Filters the responses for discount requests.
155
+         *
156
+         *
157
+         * @since 1.0.13
158
+         *
159
+         *
160
+         * @param arrWP_REST_Response $response    Response object.
161
+         * @param WP_REST_Request     $request The request used.
162 162
          * @param array               $args Array of args used to retrieve the discounts
163
-		 */
163
+         */
164 164
         $response       = apply_filters( "wpinv_rest_discounts_response", $response, $request, $args );
165 165
 
166 166
         return rest_ensure_response( $response );
@@ -168,25 +168,25 @@  discard block
 block discarded – undo
168 168
     }
169 169
 
170 170
     /**
171
-	 * Get the post, if the ID is valid.
172
-	 *
173
-	 * @since 1.0.13
174
-	 *
175
-	 * @param int $discount_id Supplied ID.
176
-	 * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise.
177
-	 */
178
-	protected function get_post( $discount_id ) {
171
+     * Get the post, if the ID is valid.
172
+     *
173
+     * @since 1.0.13
174
+     *
175
+     * @param int $discount_id Supplied ID.
176
+     * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise.
177
+     */
178
+    protected function get_post( $discount_id ) {
179 179
 		
180
-		$error     = new WP_Error( 'rest_item_invalid_id', __( 'Invalid discount ID.', 'invoicing' ), array( 'status' => 404 ) );
180
+        $error     = new WP_Error( 'rest_item_invalid_id', __( 'Invalid discount ID.', 'invoicing' ), array( 'status' => 404 ) );
181 181
 
182 182
         // Ids start from 1
183 183
         if ( (int) $discount_id <= 0 ) {
184
-			return $error;
185
-		}
184
+            return $error;
185
+        }
186 186
 
187
-		$discount = wpinv_get_discount( (int) $discount_id );
188
-		if ( empty( $discount ) ) {
189
-			return $error;
187
+        $discount = wpinv_get_discount( (int) $discount_id );
188
+        if ( empty( $discount ) ) {
189
+            return $error;
190 190
         }
191 191
 
192 192
         return $discount;
@@ -194,25 +194,25 @@  discard block
 block discarded – undo
194 194
     }
195 195
 
196 196
     /**
197
-	 * Checks if a given request has access to read a discount.
198
-	 *
199
-	 * @since 1.0.13
200
-	 *
201
-	 * @param WP_REST_Request $request Full details about the request.
202
-	 * @return bool|WP_Error True if the request has read access for the invoice item, WP_Error object otherwise.
203
-	 */
204
-	public function get_item_permissions_check( $request ) {
197
+     * Checks if a given request has access to read a discount.
198
+     *
199
+     * @since 1.0.13
200
+     *
201
+     * @param WP_REST_Request $request Full details about the request.
202
+     * @return bool|WP_Error True if the request has read access for the invoice item, WP_Error object otherwise.
203
+     */
204
+    public function get_item_permissions_check( $request ) {
205 205
 
206 206
         // Retrieve the discount object.
207 207
         $discount = $this->get_post( $request['id'] );
208 208
         
209 209
         // Ensure it is valid.
210
-		if ( is_wp_error( $discount ) ) {
211
-			return $discount;
212
-		}
210
+        if ( is_wp_error( $discount ) ) {
211
+            return $discount;
212
+        }
213 213
 
214
-		if ( ! wpinv_current_user_can_manage_invoicing() ) {
215
-			return new WP_Error(
214
+        if ( ! wpinv_current_user_can_manage_invoicing() ) {
215
+            return new WP_Error(
216 216
                 'rest_cannot_view', 
217 217
                 __( 'Sorry, you are not allowed to view this discount.', 'invoicing' ), 
218 218
                 array( 
@@ -221,40 +221,40 @@  discard block
 block discarded – undo
221 221
             );
222 222
         }
223 223
 
224
-		return true;
224
+        return true;
225 225
     }
226 226
     
227 227
     /**
228
-	 * Retrieves a single invoice item.
229
-	 *
230
-	 * @since 1.0.13
231
-	 *
232
-	 * @param WP_REST_Request $request Full details about the request.
233
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
234
-	 */
235
-	public function get_item( $request ) {
228
+     * Retrieves a single invoice item.
229
+     *
230
+     * @since 1.0.13
231
+     *
232
+     * @param WP_REST_Request $request Full details about the request.
233
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
234
+     */
235
+    public function get_item( $request ) {
236 236
 
237 237
         // Fetch the discount.
238 238
         $discount = $this->get_post( $request['id'] );
239 239
         
240 240
         // Abort early if it does not exist
241
-		if ( is_wp_error( $discount ) ) {
242
-			return $discount;
243
-		}
244
-
245
-		// Prepare the response
246
-		$response = $this->prepare_item_for_response( $discount, $request );
247
-
248
-		/**
249
-		 * Filters the responses for single discount requests.
250
-		 *
251
-		 *
252
-		 * @since 1.0.13
253
-		 * @var WP_HTTP_Response
254
-		 *
255
-		 * @param WP_HTTP_Response $response Response.
256
-		 * @param WP_REST_Request  $request The request used.
257
-		 */
241
+        if ( is_wp_error( $discount ) ) {
242
+            return $discount;
243
+        }
244
+
245
+        // Prepare the response
246
+        $response = $this->prepare_item_for_response( $discount, $request );
247
+
248
+        /**
249
+         * Filters the responses for single discount requests.
250
+         *
251
+         *
252
+         * @since 1.0.13
253
+         * @var WP_HTTP_Response
254
+         *
255
+         * @param WP_HTTP_Response $response Response.
256
+         * @param WP_REST_Request  $request The request used.
257
+         */
258 258
         $response       = apply_filters( "wpinv_rest_get_discount_response", $response, $request );
259 259
 
260 260
         return rest_ensure_response( $response );
@@ -262,26 +262,26 @@  discard block
 block discarded – undo
262 262
     }
263 263
     
264 264
     /**
265
-	 * Checks if a given request has access to create an invoice item.
266
-	 *
267
-	 * @since 1.0.13
268
-	 *
269
-	 * @param WP_REST_Request $request Full details about the request.
270
-	 * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
271
-	 */
272
-	public function create_item_permissions_check( $request ) {
265
+     * Checks if a given request has access to create an invoice item.
266
+     *
267
+     * @since 1.0.13
268
+     *
269
+     * @param WP_REST_Request $request Full details about the request.
270
+     * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
271
+     */
272
+    public function create_item_permissions_check( $request ) {
273 273
 	
274
-		if ( ! empty( $request['id'] ) ) {
275
-			return new WP_Error( 'rest_item_exists', __( 'Cannot create existing item.', 'invoicing' ), array( 'status' => 400 ) );
276
-		}
274
+        if ( ! empty( $request['id'] ) ) {
275
+            return new WP_Error( 'rest_item_exists', __( 'Cannot create existing item.', 'invoicing' ), array( 'status' => 400 ) );
276
+        }
277 277
 
278
-		if ( wpinv_current_user_can_manage_invoicing() ) {
279
-			return true;
280
-		}
278
+        if ( wpinv_current_user_can_manage_invoicing() ) {
279
+            return true;
280
+        }
281 281
 
282
-		$post_type = get_post_type_object( $this->post_type );
283
-		if ( ! current_user_can( $post_type->cap->create_posts ) ) {
284
-			return new WP_Error( 
282
+        $post_type = get_post_type_object( $this->post_type );
283
+        if ( ! current_user_can( $post_type->cap->create_posts ) ) {
284
+            return new WP_Error( 
285 285
                 'rest_cannot_create', 
286 286
                 __( 'Sorry, you are not allowed to create discounts as this user.', 'invoicing' ), 
287 287
                 array( 
@@ -290,261 +290,261 @@  discard block
 block discarded – undo
290 290
             );
291 291
         }
292 292
 
293
-		return true;
293
+        return true;
294 294
     }
295 295
     
296 296
     /**
297
-	 * Creates a single discount.
298
-	 *
299
-	 * @since 1.0.13
300
-	 *
301
-	 * @param WP_REST_Request $request Full details about the request.
302
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
303
-	 */
304
-	public function create_item( $request ) {
305
-
306
-		if ( ! empty( $request['id'] ) ) {
307
-			return new WP_Error( 'rest_item_exists', __( 'Cannot create existing discount.', 'invoicing' ), array( 'status' => 400 ) );
308
-		}
297
+     * Creates a single discount.
298
+     *
299
+     * @since 1.0.13
300
+     *
301
+     * @param WP_REST_Request $request Full details about the request.
302
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
303
+     */
304
+    public function create_item( $request ) {
305
+
306
+        if ( ! empty( $request['id'] ) ) {
307
+            return new WP_Error( 'rest_item_exists', __( 'Cannot create existing discount.', 'invoicing' ), array( 'status' => 400 ) );
308
+        }
309 309
 
310
-		$request->set_param( 'context', 'edit' );
310
+        $request->set_param( 'context', 'edit' );
311 311
 
312
-		// Prepare the updated data.
313
-		$discount_data = $this->prepare_item_for_database( $request );
312
+        // Prepare the updated data.
313
+        $discount_data = $this->prepare_item_for_database( $request );
314 314
 
315
-		if ( is_wp_error( $discount_data ) ) {
316
-			return $discount_data;
317
-		}
315
+        if ( is_wp_error( $discount_data ) ) {
316
+            return $discount_data;
317
+        }
318 318
 
319
-		$discount_data['post_type'] = $this->post_type;
319
+        $discount_data['post_type'] = $this->post_type;
320 320
 
321
-		// Try creating the discount.
321
+        // Try creating the discount.
322 322
         $discount = wp_insert_post( $discount_data, true );
323 323
 
324
-		if ( is_wp_error( $discount ) ) {
324
+        if ( is_wp_error( $discount ) ) {
325 325
             return $discount;
326
-		}
327
-
328
-		// Prepare the response
329
-		$response = $this->prepare_item_for_response( $discount, $request );
330
-
331
-		/**
332
-		 * Fires after a single discount is created or updated via the REST API.
333
-		 *
334
-		 * @since 1.0.13
335
-		 *
336
-		 * @param WP_Post   $discount  Inserted or updated discount object.
337
-		 * @param WP_REST_Request $request  Request object.
338
-		 * @param bool            $creating True when creating a post, false when updating.
339
-		 */
340
-		do_action( "wpinv_rest_insert_discount", $discount, $request, true );
341
-
342
-		/**
343
-		 * Filters the responses for creating single item requests.
344
-		 *
345
-		 *
346
-		 * @since 1.0.13
347
-		 *
348
-		 *
349
-		 * @param array           $response Invoice properties.
350
-		 * @param WP_REST_Request $request The request used.
351
-		 */
326
+        }
327
+
328
+        // Prepare the response
329
+        $response = $this->prepare_item_for_response( $discount, $request );
330
+
331
+        /**
332
+         * Fires after a single discount is created or updated via the REST API.
333
+         *
334
+         * @since 1.0.13
335
+         *
336
+         * @param WP_Post   $discount  Inserted or updated discount object.
337
+         * @param WP_REST_Request $request  Request object.
338
+         * @param bool            $creating True when creating a post, false when updating.
339
+         */
340
+        do_action( "wpinv_rest_insert_discount", $discount, $request, true );
341
+
342
+        /**
343
+         * Filters the responses for creating single item requests.
344
+         *
345
+         *
346
+         * @since 1.0.13
347
+         *
348
+         *
349
+         * @param array           $response Invoice properties.
350
+         * @param WP_REST_Request $request The request used.
351
+         */
352 352
         $response       = apply_filters( "wpinv_rest_create_discount_response", $response, $request );
353 353
 
354 354
         return rest_ensure_response( $response );
355
-	}
356
-
357
-	/**
358
-	 * Checks if a given request has access to update a discount.
359
-	 *
360
-	 * @since 1.0.13
361
-	 *
362
-	 * @param WP_REST_Request $request Full details about the request.
363
-	 * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
364
-	 */
365
-	public function update_item_permissions_check( $request ) {
366
-
367
-		// Retrieve the item.
368
-		$item = $this->get_post( $request['id'] );
369
-		if ( is_wp_error( $item ) ) {
370
-			return $item;
371
-		}
372
-
373
-		if ( wpinv_current_user_can_manage_invoicing() ) {
374
-			return true;
375
-		}
376
-
377
-		return new WP_Error( 
378
-			'rest_cannot_edit', 
379
-			__( 'Sorry, you are not allowed to update this discount.', 'invoicing' ), 
380
-			array( 
381
-				'status' => rest_authorization_required_code(),
382
-			)
383
-		);
384
-
385
-	}
386
-
387
-	/**
388
-	 * Updates a single discount.
389
-	 *
390
-	 * @since 1.0.13
391
-	 *
392
-	 * @param WP_REST_Request $request Full details about the request.
393
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
394
-	 */
395
-	public function update_item( $request ) {
355
+    }
356
+
357
+    /**
358
+     * Checks if a given request has access to update a discount.
359
+     *
360
+     * @since 1.0.13
361
+     *
362
+     * @param WP_REST_Request $request Full details about the request.
363
+     * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
364
+     */
365
+    public function update_item_permissions_check( $request ) {
366
+
367
+        // Retrieve the item.
368
+        $item = $this->get_post( $request['id'] );
369
+        if ( is_wp_error( $item ) ) {
370
+            return $item;
371
+        }
372
+
373
+        if ( wpinv_current_user_can_manage_invoicing() ) {
374
+            return true;
375
+        }
376
+
377
+        return new WP_Error( 
378
+            'rest_cannot_edit', 
379
+            __( 'Sorry, you are not allowed to update this discount.', 'invoicing' ), 
380
+            array( 
381
+                'status' => rest_authorization_required_code(),
382
+            )
383
+        );
384
+
385
+    }
386
+
387
+    /**
388
+     * Updates a single discount.
389
+     *
390
+     * @since 1.0.13
391
+     *
392
+     * @param WP_REST_Request $request Full details about the request.
393
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
394
+     */
395
+    public function update_item( $request ) {
396 396
 		
397
-		// Ensure the item exists.
397
+        // Ensure the item exists.
398 398
         $valid_check = $this->get_post( $request['id'] );
399 399
         
400 400
         // Abort early if it does not exist
401
-		if ( is_wp_error( $valid_check ) ) {
402
-			return $valid_check;
403
-		}
401
+        if ( is_wp_error( $valid_check ) ) {
402
+            return $valid_check;
403
+        }
404 404
 
405
-		$request->set_param( 'context', 'edit' );
405
+        $request->set_param( 'context', 'edit' );
406 406
 
407
-		// Prepare the updated data.
408
-		$data_to_update = $this->prepare_item_for_database( $request );
407
+        // Prepare the updated data.
408
+        $data_to_update = $this->prepare_item_for_database( $request );
409 409
 
410
-		if ( is_wp_error( $data_to_update ) ) {
411
-			return $data_to_update;
412
-		}
410
+        if ( is_wp_error( $data_to_update ) ) {
411
+            return $data_to_update;
412
+        }
413 413
 
414
-		if( empty( $data_to_update['meta_input'] ) ) {
415
-			unset( $data_to_update['meta_input'] );
416
-		}
414
+        if( empty( $data_to_update['meta_input'] ) ) {
415
+            unset( $data_to_update['meta_input'] );
416
+        }
417 417
 
418
-		// Abort if no item data is provided
418
+        // Abort if no item data is provided
419 419
         if( empty( $data_to_update ) ) {
420 420
             return new WP_Error( 'missing_data', __( 'An update request cannot be empty.', 'invoicing' ) );
421
-		}
421
+        }
422 422
 		
423
-		// post_status
424
-		if( ! empty( $data_to_update['post_status'] ) ) {
425
-			wpinv_update_discount_status( $request['id'], $data_to_update['post_status'] );
426
-			unset( $data_to_update['post_status'] );
427
-		}
423
+        // post_status
424
+        if( ! empty( $data_to_update['post_status'] ) ) {
425
+            wpinv_update_discount_status( $request['id'], $data_to_update['post_status'] );
426
+            unset( $data_to_update['post_status'] );
427
+        }
428 428
 
429
-		// Update the item
430
-		if( ! empty( $data_to_update ) ) {
429
+        // Update the item
430
+        if( ! empty( $data_to_update ) ) {
431 431
 
432
-			// Include the item ID
433
-			$data_to_update['ID'] = $request['id'];
432
+            // Include the item ID
433
+            $data_to_update['ID'] = $request['id'];
434 434
 
435
-			$updated = wp_update_post( $data_to_update, true );
435
+            $updated = wp_update_post( $data_to_update, true );
436 436
 
437
-			// Incase the update operation failed...
438
-			if ( is_wp_error( $updated ) ) {
439
-				return $updated;
440
-			}
437
+            // Incase the update operation failed...
438
+            if ( is_wp_error( $updated ) ) {
439
+                return $updated;
440
+            }
441 441
 
442
-		}
442
+        }
443 443
 
444
-		$updated_discount = get_post( $request['id'] );
444
+        $updated_discount = get_post( $request['id'] );
445 445
 
446
-		// Prepare the response
447
-		$response = $this->prepare_item_for_response( $updated_discount, $request );
446
+        // Prepare the response
447
+        $response = $this->prepare_item_for_response( $updated_discount, $request );
448 448
 
449
-		/** This action is documented in includes/class-wpinv-rest-item-controller.php */
450
-		do_action( "wpinv_rest_insert_discount", $updated_discount, $request, false );
449
+        /** This action is documented in includes/class-wpinv-rest-item-controller.php */
450
+        do_action( "wpinv_rest_insert_discount", $updated_discount, $request, false );
451 451
 
452
-		/**
453
-		 * Filters the responses for updating single discount requests.
454
-		 *
455
-		 *
456
-		 * @since 1.0.13
457
-		 *
458
-		 *
459
-		 * @param array           $data_to_update Discount properties.
460
-		 * @param WP_REST_Request $request The request used.
461
-		 */
452
+        /**
453
+         * Filters the responses for updating single discount requests.
454
+         *
455
+         *
456
+         * @since 1.0.13
457
+         *
458
+         *
459
+         * @param array           $data_to_update Discount properties.
460
+         * @param WP_REST_Request $request The request used.
461
+         */
462 462
         $response       = apply_filters( "wpinv_rest_update_discount_response", $response,  $data_to_update, $request );
463 463
 
464 464
         return rest_ensure_response( $response );
465
-	}
466
-
467
-	/**
468
-	 * Checks if a given request has access to delete a discount.
469
-	 *
470
-	 * @since 1.0.13
471
-	 *
472
-	 * @param WP_REST_Request $request Full details about the request.
473
-	 * @return true|WP_Error True if the request has access to delete the discount, WP_Error object otherwise.
474
-	 */
475
-	public function delete_item_permissions_check( $request ) {
476
-
477
-		// Retrieve the discount.
478
-		$discount = $this->get_post( $request['id'] );
479
-		if ( is_wp_error( $discount ) ) {
480
-			return $discount;
481
-		} 
482
-
483
-		// Ensure the current user can delete the discount
484
-		if (! wpinv_current_user_can_manage_invoicing() ) {
485
-			return new WP_Error( 
465
+    }
466
+
467
+    /**
468
+     * Checks if a given request has access to delete a discount.
469
+     *
470
+     * @since 1.0.13
471
+     *
472
+     * @param WP_REST_Request $request Full details about the request.
473
+     * @return true|WP_Error True if the request has access to delete the discount, WP_Error object otherwise.
474
+     */
475
+    public function delete_item_permissions_check( $request ) {
476
+
477
+        // Retrieve the discount.
478
+        $discount = $this->get_post( $request['id'] );
479
+        if ( is_wp_error( $discount ) ) {
480
+            return $discount;
481
+        } 
482
+
483
+        // Ensure the current user can delete the discount
484
+        if (! wpinv_current_user_can_manage_invoicing() ) {
485
+            return new WP_Error( 
486 486
                 'rest_cannot_delete', 
487 487
                 __( 'Sorry, you are not allowed to delete this discount.', 'invoicing' ), 
488 488
                 array( 
489 489
                     'status' => rest_authorization_required_code(),
490 490
                 )
491 491
             );
492
-		}
493
-
494
-		return true;
495
-	}
496
-
497
-	/**
498
-	 * Deletes a single discount.
499
-	 *
500
-	 * @since 1.0.13
501
-	 *
502
-	 * @param WP_REST_Request $request Full details about the request.
503
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
504
-	 */
505
-	public function delete_item( $request ) {
492
+        }
493
+
494
+        return true;
495
+    }
496
+
497
+    /**
498
+     * Deletes a single discount.
499
+     *
500
+     * @since 1.0.13
501
+     *
502
+     * @param WP_REST_Request $request Full details about the request.
503
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
504
+     */
505
+    public function delete_item( $request ) {
506 506
 		
507
-		// Retrieve the discount.
508
-		$discount = $this->get_post( $request['id'] );
509
-		if ( is_wp_error( $discount ) ) {
510
-			return $discount;
511
-		}
507
+        // Retrieve the discount.
508
+        $discount = $this->get_post( $request['id'] );
509
+        if ( is_wp_error( $discount ) ) {
510
+            return $discount;
511
+        }
512 512
 
513
-		$request->set_param( 'context', 'edit' );
513
+        $request->set_param( 'context', 'edit' );
514 514
 
515
-		// Prepare the discount id
516
-		$id    = $discount->ID;
515
+        // Prepare the discount id
516
+        $id    = $discount->ID;
517 517
 
518
-		// Prepare the response
519
-		$response = $this->prepare_item_for_response( $discount, $request );
518
+        // Prepare the response
519
+        $response = $this->prepare_item_for_response( $discount, $request );
520 520
 
521
-		// Delete the discount...
522
-		wpinv_remove_discount( $id );
521
+        // Delete the discount...
522
+        wpinv_remove_discount( $id );
523 523
 
524
-		/**
525
-		 * Fires immediately after a single discount is deleted via the REST API.
526
-		 *
527
-		 *
528
-		 * @since 1.0.13
529
-		 *
530
-		 * @param WP_POST    $discount  The deleted discount.
531
-		 * @param WP_REST_Request  $request  The request sent to the API.
532
-		 */
533
-		do_action( "wpinv_rest_delete_discount", $discount, $request );
524
+        /**
525
+         * Fires immediately after a single discount is deleted via the REST API.
526
+         *
527
+         *
528
+         * @since 1.0.13
529
+         *
530
+         * @param WP_POST    $discount  The deleted discount.
531
+         * @param WP_REST_Request  $request  The request sent to the API.
532
+         */
533
+        do_action( "wpinv_rest_delete_discount", $discount, $request );
534 534
 
535
-		return $response;
535
+        return $response;
536 536
 
537
-	}
537
+    }
538 538
     
539 539
     
540 540
     /**
541
-	 * Retrieves the query params for the discount collection.
542
-	 *
543
-	 * @since 1.0.13
544
-	 *
545
-	 * @return array Collection parameters.
546
-	 */
547
-	public function get_collection_params() {
541
+     * Retrieves the query params for the discount collection.
542
+     *
543
+     * @since 1.0.13
544
+     *
545
+     * @return array Collection parameters.
546
+     */
547
+    public function get_collection_params() {
548 548
         
549 549
         $query_params               = array(
550 550
 
@@ -558,27 +558,27 @@  discard block
 block discarded – undo
558 558
             
559 559
             // Discount types
560 560
             'type'                  => array(
561
-				'description'       => __( 'Type of discounts to fetch.', 'invoicing' ),
562
-				'type'              => 'array',
563
-				'default'           => array_keys( wpinv_get_discount_types() ),
564
-				'items'             => array(
561
+                'description'       => __( 'Type of discounts to fetch.', 'invoicing' ),
562
+                'type'              => 'array',
563
+                'default'           => array_keys( wpinv_get_discount_types() ),
564
+                'items'             => array(
565 565
                     'enum'          => array_keys( wpinv_get_discount_types() ),
566 566
                     'type'          => 'string',
567 567
                 ),
568
-			),
568
+            ),
569 569
 			
570
-			// Number of results per page
570
+            // Number of results per page
571 571
             'limit'                 => array(
572
-				'description'       => __( 'Number of discounts to fetch.', 'invoicing' ),
573
-				'type'              => 'integer',
574
-				'default'           => (int) get_option( 'posts_per_page' ),
572
+                'description'       => __( 'Number of discounts to fetch.', 'invoicing' ),
573
+                'type'              => 'integer',
574
+                'default'           => (int) get_option( 'posts_per_page' ),
575 575
             ),
576 576
 
577 577
             // Pagination
578 578
             'page'     => array(
579
-				'description'       => __( 'Current page to fetch.', 'invoicing' ),
580
-				'type'              => 'integer',
581
-				'default'           => 1,
579
+                'description'       => __( 'Current page to fetch.', 'invoicing' ),
580
+                'type'              => 'integer',
581
+                'default'           => 1,
582 582
             ),
583 583
 
584 584
             // Exclude certain items
@@ -601,9 +601,9 @@  discard block
 block discarded – undo
601 601
                     'date',
602 602
                     'ID',
603 603
                     'modified',
604
-					'title',
605
-					'relevance',
606
-					'rand'
604
+                    'title',
605
+                    'relevance',
606
+                    'rand'
607 607
                 ),
608 608
             ),
609 609
 
@@ -613,598 +613,598 @@  discard block
 block discarded – undo
613 613
                 'type'        => 'string',
614 614
                 'default'     => 'DESC',
615 615
                 'enum'        => array( 'ASC', 'DESC' ),
616
-			),
616
+            ),
617 617
 			
618
-			// Search term
618
+            // Search term
619 619
             'search'                => array(
620
-				'description'       => __( 'Return discounts that match the search term.', 'invoicing' ),
621
-				'type'              => 'string',
620
+                'description'       => __( 'Return discounts that match the search term.', 'invoicing' ),
621
+                'type'              => 'string',
622 622
             ),
623 623
         );
624 624
 
625
-		/**
626
-		 * Filter collection parameters for the discounts controller.
627
-		 *
628
-		 *
629
-		 * @since 1.0.13
630
-		 *
631
-		 * @param array        $query_params JSON Schema-formatted collection parameters.
632
-		 */
633
-		return apply_filters( "wpinv_rest_discounts_collection_params", $query_params );
625
+        /**
626
+         * Filter collection parameters for the discounts controller.
627
+         *
628
+         *
629
+         * @since 1.0.13
630
+         *
631
+         * @param array        $query_params JSON Schema-formatted collection parameters.
632
+         */
633
+        return apply_filters( "wpinv_rest_discounts_collection_params", $query_params );
634 634
     }
635 635
     
636 636
     /**
637
-	 * Checks if a given post type can be viewed or managed.
638
-	 *
639
-	 * @since 1.0.13
640
-	 *
641
-	 * @param object|string $post_type Post type name or object.
642
-	 * @return bool Whether the post type is allowed in REST.
643
-	 */
644
-	protected function check_is_post_type_allowed( $post_type ) {
645
-		return true;
646
-	}
647
-
648
-	/**
649
-	 * Prepares a single item for create or update.
650
-	 *
651
-	 * @since 1.0.13
652
-	 *
653
-	 * @param WP_REST_Request $request Request object.
654
-	 * @return array|WP_Error Discount Properties or WP_Error.
655
-	 */
656
-	protected function prepare_item_for_database( $request ) {
657
-		$prepared_item 		 = new stdClass();
658
-		$prepared_item->meta_input = array();
659
-
660
-		// Post ID.
661
-		if ( isset( $request['id'] ) ) {
662
-			$existing_item = $this->get_post( $request['id'] );
663
-			if ( is_wp_error( $existing_item ) ) {
664
-				return $existing_item;
665
-			}
666
-
667
-			$prepared_item->ID 		  = $existing_item->ID;
668
-		}
669
-
670
-		$schema = $this->get_item_schema();
671
-
672
-		// item title.
673
-		if ( ! empty( $schema['properties']['title'] ) && isset( $request['title'] ) ) {
674
-			$prepared_item->post_title = sanitize_text_field( $request['title'] );
675
-		}
676
-
677
-		// item status.
678
-		if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) && in_array( $request['status'], array_keys( get_post_stati( array( 'internal' => false ) ) ) ) ) {
679
-			$prepared_item->post_status = sanitize_text_field( $request['status'] );
680
-		}
681
-
682
-		// Code.
683
-		if ( ! empty( $schema['properties']['code'] ) && isset( $request['code'] ) ) {
684
-			$prepared_item->meta_input['_wpi_discount_code'] = trim( $request['code'] );
685
-		}
686
-
687
-		// Type.
688
-		if ( ! empty( $schema['properties']['type'] ) && isset( $request['type'] )  && in_array( $request['type'], array_keys( wpinv_get_discount_types() ) ) ) {
689
-			$prepared_item->meta_input['_wpi_discount_type'] = trim( $request['type'] );
690
-		}
691
-
692
-		// Amount.
693
-		if ( ! empty( $schema['properties']['amount'] ) && isset( $request['amount'] ) ) {
694
-			$prepared_item->meta_input['_wpi_discount_amount'] = floatval( $request['amount'] );
695
-		}
696
-
697
-		// Items.
698
-		if ( ! empty( $schema['properties']['items'] ) && isset( $request['items'] ) ) {
699
-			$prepared_item->meta_input['_wpi_discount_items'] = wpinv_parse_list( $request['items'] );
700
-		}
701
-
702
-		// Excluded Items.
703
-		if ( ! empty( $schema['properties']['exclude_items'] ) && isset( $request['exclude_items'] ) ) {
704
-			$prepared_item->meta_input['_wpi_discount_excluded_items'] = wpinv_parse_list( $request['exclude_items'] );
705
-		}
706
-
707
-		// Start date.
708
-		if ( ! empty( $schema['properties']['start_date'] ) && isset( $request['start_date'] ) ) {
709
-			$prepared_item->meta_input['_wpi_discount_start'] = trim( $request['start_date'] );
710
-		}
711
-
712
-		// End date.
713
-		if ( ! empty( $schema['properties']['end_date'] ) && isset( $request['end_date'] ) ) {
714
-			$prepared_item->meta_input['_wpi_discount_expiration'] = trim( $request['end_date'] );
715
-		}
716
-
717
-		// Minimum amount.
718
-		if ( ! empty( $schema['properties']['minimum_amount'] ) && isset( $request['minimum_amount'] ) ) {
719
-			$prepared_item->meta_input['_wpi_discount_min_total'] = floatval( $request['minimum_amount'] );
720
-		}
721
-
722
-		// Maximum amount.
723
-		if ( ! empty( $schema['properties']['maximum_amount'] ) && isset( $request['maximum_amount'] ) ) {
724
-			$prepared_item->meta_input['_wpi_discount_max_total'] = floatval( $request['maximum_amount'] );
725
-		}
726
-
727
-		// Recurring.
728
-		if ( ! empty( $schema['properties']['recurring'] ) && isset( $request['recurring'] ) ) {
729
-			$prepared_item->meta_input['_wpi_discount_is_recurring'] = empty( (int) $request['recurring'] ) ? 0 : 1;
730
-		}
731
-
732
-		// Maximum uses.
733
-		if ( ! empty( $schema['properties']['max_uses'] ) && isset( $request['max_uses'] ) ) {
734
-			$prepared_item->meta_input['_wpi_discount_max_uses'] = intval( $request['max_uses'] );
735
-		}
736
-
737
-		// Single use.
738
-		if ( ! empty( $schema['properties']['single_use'] ) && isset( $request['single_use'] ) ) {
739
-			$prepared_item->meta_input['_wpi_discount_is_single_use'] = empty( (int) $request['single_use'] ) ? 0 : 1;
740
-		}
741
-
742
-		$discount_data = (array) wp_unslash( $prepared_item );
743
-
744
-		/**
745
-		 * Filters an item before it is inserted via the REST API.
746
-		 *
747
-		 * @since 1.0.13
748
-		 *
749
-		 * @param array        $discount_data An array of discount data
750
-		 * @param WP_REST_Request $request       Request object.
751
-		 */
752
-		return apply_filters( "wpinv_rest_pre_insert_discount", $discount_data, $request );
753
-
754
-	}
755
-
756
-	/**
757
-	 * Prepares a single discount output for response.
758
-	 *
759
-	 * @since 1.0.13
760
-	 *
761
-	 * @param WP_Post   $discount    WP_Post object.
762
-	 * @param WP_REST_Request $request Request object.
763
-	 * @return WP_REST_Response Response object.
764
-	 */
765
-	public function prepare_item_for_response( $discount, $request ) {
766
-
767
-		$GLOBALS['post'] = get_post( $discount->ID );
768
-
769
-		setup_postdata( $discount->ID );
770
-
771
-		// Fetch the fields to include in this response.
772
-		$fields = $this->get_fields_for_response( $request );
773
-
774
-		// Base fields for every discount.
775
-		$data = array();
776
-
777
-		// Set up ID.
778
-		if ( rest_is_field_included( 'id', $fields ) ) {
779
-			$data['id'] = $discount->ID;
780
-		}
781
-
782
-		// Title.
783
-		if ( rest_is_field_included( 'title', $fields ) ) {
784
-			$data['title'] = get_the_title( $discount->ID );
785
-		}
786
-
787
-		// Code.
788
-		if ( rest_is_field_included( 'code', $fields ) ) {
789
-			$data['code'] = wpinv_get_discount_code( $discount->ID );
790
-		}
791
-
792
-		// Type.
793
-		if ( rest_is_field_included( 'type', $fields ) ) {
794
-			$data['type'] = wpinv_get_discount_type( $discount->ID );
795
-		}
796
-
797
-		// Amount.
798
-		if ( rest_is_field_included( 'amount', $fields ) ) {
799
-			$data['amount'] = wpinv_get_discount_amount( $discount->ID );
800
-		}
801
-
802
-		// Status.
803
-		if ( rest_is_field_included( 'status', $fields ) ) {
804
-			$data['status'] = get_post_status( $discount->ID );
805
-		}
806
-
807
-		// Items.
808
-		if ( rest_is_field_included( 'items', $fields ) ) {
809
-			$data['items'] = wpinv_get_discount_item_reqs( $discount->ID );
810
-		}
811
-
812
-		// Excluded Items.
813
-		if ( rest_is_field_included( 'exclude_items', $fields ) ) {
814
-			$data['exclude_items'] = wpinv_get_discount_excluded_items( $discount->ID );
815
-		}
816
-
817
-		// Start date.
818
-		if ( rest_is_field_included( 'start_date', $fields ) ) {
819
-			$data['start_date'] = wpinv_get_discount_start_date( $discount->ID );
820
-		}
821
-
822
-		// End date.
823
-		if ( rest_is_field_included( 'end_date', $fields ) ) {
824
-			$data['end_date'] = wpinv_get_discount_expiration( $discount->ID );
825
-		}
826
-
827
-		// Minimum amount.
828
-		if ( rest_is_field_included( 'minimum_amount', $fields ) ) {
829
-			$data['minimum_amount'] = wpinv_get_discount_min_total( $discount->ID );
830
-		}
831
-
832
-		// Maximum amount.
833
-		if ( rest_is_field_included( 'maximum_amount', $fields ) ) {
834
-			$data['maximum_amount'] = wpinv_get_discount_max_total( $discount->ID );
835
-		}
836
-
837
-		// Recurring.
838
-		if ( rest_is_field_included( 'recurring', $fields ) ) {
839
-			$data['recurring'] = wpinv_discount_is_recurring( $discount->ID );
840
-		}
841
-
842
-		// Maximum uses.
843
-		if ( rest_is_field_included( 'max_uses', $fields ) ) {
844
-			$data['max_uses'] = wpinv_get_discount_max_uses( $discount->ID );
845
-		}
846
-
847
-		// Single use.
848
-		if ( rest_is_field_included( 'single_use', $fields ) ) {
849
-			$data['single_use'] = wpinv_discount_is_single_use( $discount->ID );
850
-		}
851
-
852
-		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
853
-		$data    = $this->add_additional_fields_to_object( $data, $request );
854
-		$data    = $this->filter_response_by_context( $data, $context );
855
-
856
-		// Wrap the data in a response object.
857
-		$response = rest_ensure_response( $data );
858
-
859
-		$links = $this->prepare_links( $discount );
860
-		$response->add_links( $links );
861
-
862
-		if ( ! empty( $links['self']['href'] ) ) {
863
-			$actions = $this->get_available_actions( $discount, $request );
864
-
865
-			$self = $links['self']['href'];
866
-
867
-			foreach ( $actions as $rel ) {
868
-				$response->add_link( $rel, $self );
869
-			}
870
-		}
871
-
872
-		/**
873
-		 * Filters the discount data for a response.
874
-		 *
875
-		 * @since 1.0.13
876
-		 *
877
-		 * @param WP_REST_Response $response The response object.
878
-		 * @param WP_Post    $discount  The discount post object.
879
-		 * @param WP_REST_Request  $request  Request object.
880
-		 */
881
-		return apply_filters( "wpinv_rest_prepare_discount", $response, $discount, $request );
882
-	}
883
-
884
-	/**
885
-	 * Gets an array of fields to be included on the response.
886
-	 *
887
-	 * Included fields are based on item schema and `_fields=` request argument.
888
-	 *
889
-	 * @since 1.0.13
890
-	 *
891
-	 * @param WP_REST_Request $request Full details about the request.
892
-	 * @return array Fields to be included in the response.
893
-	 */
894
-	public function get_fields_for_response( $request ) {
895
-		$schema     = $this->get_item_schema();
896
-		$properties = isset( $schema['properties'] ) ? $schema['properties'] : array();
897
-
898
-		$additional_fields = $this->get_additional_fields();
899
-		foreach ( $additional_fields as $field_name => $field_options ) {
900
-			// For back-compat, include any field with an empty schema
901
-			// because it won't be present in $this->get_item_schema().
902
-			if ( is_null( $field_options['schema'] ) ) {
903
-				$properties[ $field_name ] = $field_options;
904
-			}
905
-		}
906
-
907
-		// Exclude fields that specify a different context than the request context.
908
-		$context = $request['context'];
909
-		if ( $context ) {
910
-			foreach ( $properties as $name => $options ) {
911
-				if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) {
912
-					unset( $properties[ $name ] );
913
-				}
914
-			}
915
-		}
916
-
917
-		$fields = array_keys( $properties );
918
-
919
-		if ( ! isset( $request['_fields'] ) ) {
920
-			return $fields;
921
-		}
922
-		$requested_fields = wpinv_parse_list( $request['_fields'] );
923
-		if ( 0 === count( $requested_fields ) ) {
924
-			return $fields;
925
-		}
926
-		// Trim off outside whitespace from the comma delimited list.
927
-		$requested_fields = array_map( 'trim', $requested_fields );
928
-		// Always persist 'id', because it can be needed for add_additional_fields_to_object().
929
-		if ( in_array( 'id', $fields, true ) ) {
930
-			$requested_fields[] = 'id';
931
-		}
932
-		// Return the list of all requested fields which appear in the schema.
933
-		return array_reduce(
934
-			$requested_fields,
935
-			function( $response_fields, $field ) use ( $fields ) {
936
-				if ( in_array( $field, $fields, true ) ) {
937
-					$response_fields[] = $field;
938
-					return $response_fields;
939
-				}
940
-				// Check for nested fields if $field is not a direct match.
941
-				$nested_fields = explode( '.', $field );
942
-				// A nested field is included so long as its top-level property is
943
-				// present in the schema.
944
-				if ( in_array( $nested_fields[0], $fields, true ) ) {
945
-					$response_fields[] = $field;
946
-				}
947
-				return $response_fields;
948
-			},
949
-			array()
950
-		);
951
-	}
952
-
953
-	/**
954
-	 * Retrieves the discount's schema, conforming to JSON Schema.
955
-	 *
956
-	 * @since 1.0.13
957
-	 *
958
-	 * @return array Discount schema data.
959
-	 */
960
-	public function get_item_schema() {
961
-
962
-		// Maybe retrieve the schema from cache.
963
-		if (  empty( $this->schema ) ) {
964
-			return $this->add_additional_fields_schema( $this->schema );
965
-		}
966
-
967
-		$schema = array(
968
-			'$schema'    => 'http://json-schema.org/draft-04/schema#',
969
-			'title'      => $this->post_type,
970
-			'type'       => 'object',
971
-
972
-			// Base properties for every Item.
973
-			'properties' 		  => array(
974
-
975
-				'id'           => array(
976
-					'description' => __( 'Unique identifier for the discount.', 'invoicing' ),
977
-					'type'        => 'integer',
978
-					'context'     => array( 'view', 'edit', 'embed' ),
979
-					'readonly'    => true,
980
-				),
981
-
982
-				'title'			  => array(
983
-					'description' => __( 'The title for the discount.', 'invoicing' ),
984
-					'type'        => 'string',
985
-					'context'     => array( 'view', 'edit' ),
986
-				),
987
-
988
-				'code'        => array(
989
-					'description' => __( 'The discount code.', 'invoicing' ),
990
-					'type'        => 'string',
991
-					'context'     => array( 'view', 'edit', 'embed' ),
992
-					'required'	  => true,
993
-				),
994
-
995
-				'type'        => array(
996
-					'description' => __( 'The type of discount.', 'invoicing' ),
997
-					'type'        => 'string',
998
-					'enum'        => array_keys( wpinv_get_discount_types() ),
999
-					'context'     => array( 'view', 'edit', 'embed' ),
1000
-					'default'	  => 'percentage',
1001
-				),
1002
-
1003
-				'amount'        => array(
1004
-					'description' => __( 'The discount value.', 'invoicing' ),
1005
-					'type'        => 'number',
1006
-					'context'     => array( 'view', 'edit', 'embed' ),
1007
-					'required'	  => true,
1008
-				),
1009
-
1010
-				'status'       => array(
1011
-					'description' => __( 'A named status for the discount.', 'invoicing' ),
1012
-					'type'        => 'string',
1013
-					'enum'        => array_keys( get_post_stati( array( 'internal' => false ) ) ),
1014
-					'context'     => array( 'view', 'edit' ),
1015
-				),
1016
-
1017
-				'items'       => array(
1018
-					'description' => __( 'Items which need to be in the cart to use this discount or, for "Item Discounts", which items are discounted. If left blank, this discount will be used on any item.', 'invoicing' ),
1019
-					'type'        => 'array',
1020
-					'context'     => array( 'view', 'edit' ),
1021
-				),
1022
-
1023
-				'exclude_items'   => array(
1024
-					'description' => __( 'Items which are NOT allowed to use this discount.', 'invoicing' ),
1025
-					'type'        => 'array',
1026
-					'context'     => array( 'view', 'edit' ),
1027
-				),
1028
-
1029
-				'start_date'       => array(
1030
-					'description' => __( 'The start date for the discount in the format of yyyy-mm-dd hh:mm:ss  . If provided, the discount can only be used after or on this date.', 'invoicing' ),
1031
-					'type'        => 'string',
1032
-					'context'     => array( 'view', 'edit' ),
1033
-				),
1034
-
1035
-				'end_date'        => array(
1036
-					'description' => __( 'The expiration date for the discount.', 'invoicing' ),
1037
-					'type'        => 'string',
1038
-					'context'     => array( 'view', 'edit', 'embed' ),
1039
-				),
637
+     * Checks if a given post type can be viewed or managed.
638
+     *
639
+     * @since 1.0.13
640
+     *
641
+     * @param object|string $post_type Post type name or object.
642
+     * @return bool Whether the post type is allowed in REST.
643
+     */
644
+    protected function check_is_post_type_allowed( $post_type ) {
645
+        return true;
646
+    }
647
+
648
+    /**
649
+     * Prepares a single item for create or update.
650
+     *
651
+     * @since 1.0.13
652
+     *
653
+     * @param WP_REST_Request $request Request object.
654
+     * @return array|WP_Error Discount Properties or WP_Error.
655
+     */
656
+    protected function prepare_item_for_database( $request ) {
657
+        $prepared_item 		 = new stdClass();
658
+        $prepared_item->meta_input = array();
659
+
660
+        // Post ID.
661
+        if ( isset( $request['id'] ) ) {
662
+            $existing_item = $this->get_post( $request['id'] );
663
+            if ( is_wp_error( $existing_item ) ) {
664
+                return $existing_item;
665
+            }
666
+
667
+            $prepared_item->ID 		  = $existing_item->ID;
668
+        }
669
+
670
+        $schema = $this->get_item_schema();
671
+
672
+        // item title.
673
+        if ( ! empty( $schema['properties']['title'] ) && isset( $request['title'] ) ) {
674
+            $prepared_item->post_title = sanitize_text_field( $request['title'] );
675
+        }
676
+
677
+        // item status.
678
+        if ( ! empty( $schema['properties']['status'] ) && isset( $request['status'] ) && in_array( $request['status'], array_keys( get_post_stati( array( 'internal' => false ) ) ) ) ) {
679
+            $prepared_item->post_status = sanitize_text_field( $request['status'] );
680
+        }
681
+
682
+        // Code.
683
+        if ( ! empty( $schema['properties']['code'] ) && isset( $request['code'] ) ) {
684
+            $prepared_item->meta_input['_wpi_discount_code'] = trim( $request['code'] );
685
+        }
686
+
687
+        // Type.
688
+        if ( ! empty( $schema['properties']['type'] ) && isset( $request['type'] )  && in_array( $request['type'], array_keys( wpinv_get_discount_types() ) ) ) {
689
+            $prepared_item->meta_input['_wpi_discount_type'] = trim( $request['type'] );
690
+        }
691
+
692
+        // Amount.
693
+        if ( ! empty( $schema['properties']['amount'] ) && isset( $request['amount'] ) ) {
694
+            $prepared_item->meta_input['_wpi_discount_amount'] = floatval( $request['amount'] );
695
+        }
696
+
697
+        // Items.
698
+        if ( ! empty( $schema['properties']['items'] ) && isset( $request['items'] ) ) {
699
+            $prepared_item->meta_input['_wpi_discount_items'] = wpinv_parse_list( $request['items'] );
700
+        }
701
+
702
+        // Excluded Items.
703
+        if ( ! empty( $schema['properties']['exclude_items'] ) && isset( $request['exclude_items'] ) ) {
704
+            $prepared_item->meta_input['_wpi_discount_excluded_items'] = wpinv_parse_list( $request['exclude_items'] );
705
+        }
706
+
707
+        // Start date.
708
+        if ( ! empty( $schema['properties']['start_date'] ) && isset( $request['start_date'] ) ) {
709
+            $prepared_item->meta_input['_wpi_discount_start'] = trim( $request['start_date'] );
710
+        }
711
+
712
+        // End date.
713
+        if ( ! empty( $schema['properties']['end_date'] ) && isset( $request['end_date'] ) ) {
714
+            $prepared_item->meta_input['_wpi_discount_expiration'] = trim( $request['end_date'] );
715
+        }
716
+
717
+        // Minimum amount.
718
+        if ( ! empty( $schema['properties']['minimum_amount'] ) && isset( $request['minimum_amount'] ) ) {
719
+            $prepared_item->meta_input['_wpi_discount_min_total'] = floatval( $request['minimum_amount'] );
720
+        }
721
+
722
+        // Maximum amount.
723
+        if ( ! empty( $schema['properties']['maximum_amount'] ) && isset( $request['maximum_amount'] ) ) {
724
+            $prepared_item->meta_input['_wpi_discount_max_total'] = floatval( $request['maximum_amount'] );
725
+        }
726
+
727
+        // Recurring.
728
+        if ( ! empty( $schema['properties']['recurring'] ) && isset( $request['recurring'] ) ) {
729
+            $prepared_item->meta_input['_wpi_discount_is_recurring'] = empty( (int) $request['recurring'] ) ? 0 : 1;
730
+        }
731
+
732
+        // Maximum uses.
733
+        if ( ! empty( $schema['properties']['max_uses'] ) && isset( $request['max_uses'] ) ) {
734
+            $prepared_item->meta_input['_wpi_discount_max_uses'] = intval( $request['max_uses'] );
735
+        }
736
+
737
+        // Single use.
738
+        if ( ! empty( $schema['properties']['single_use'] ) && isset( $request['single_use'] ) ) {
739
+            $prepared_item->meta_input['_wpi_discount_is_single_use'] = empty( (int) $request['single_use'] ) ? 0 : 1;
740
+        }
741
+
742
+        $discount_data = (array) wp_unslash( $prepared_item );
743
+
744
+        /**
745
+         * Filters an item before it is inserted via the REST API.
746
+         *
747
+         * @since 1.0.13
748
+         *
749
+         * @param array        $discount_data An array of discount data
750
+         * @param WP_REST_Request $request       Request object.
751
+         */
752
+        return apply_filters( "wpinv_rest_pre_insert_discount", $discount_data, $request );
753
+
754
+    }
755
+
756
+    /**
757
+     * Prepares a single discount output for response.
758
+     *
759
+     * @since 1.0.13
760
+     *
761
+     * @param WP_Post   $discount    WP_Post object.
762
+     * @param WP_REST_Request $request Request object.
763
+     * @return WP_REST_Response Response object.
764
+     */
765
+    public function prepare_item_for_response( $discount, $request ) {
766
+
767
+        $GLOBALS['post'] = get_post( $discount->ID );
768
+
769
+        setup_postdata( $discount->ID );
770
+
771
+        // Fetch the fields to include in this response.
772
+        $fields = $this->get_fields_for_response( $request );
773
+
774
+        // Base fields for every discount.
775
+        $data = array();
776
+
777
+        // Set up ID.
778
+        if ( rest_is_field_included( 'id', $fields ) ) {
779
+            $data['id'] = $discount->ID;
780
+        }
781
+
782
+        // Title.
783
+        if ( rest_is_field_included( 'title', $fields ) ) {
784
+            $data['title'] = get_the_title( $discount->ID );
785
+        }
786
+
787
+        // Code.
788
+        if ( rest_is_field_included( 'code', $fields ) ) {
789
+            $data['code'] = wpinv_get_discount_code( $discount->ID );
790
+        }
791
+
792
+        // Type.
793
+        if ( rest_is_field_included( 'type', $fields ) ) {
794
+            $data['type'] = wpinv_get_discount_type( $discount->ID );
795
+        }
796
+
797
+        // Amount.
798
+        if ( rest_is_field_included( 'amount', $fields ) ) {
799
+            $data['amount'] = wpinv_get_discount_amount( $discount->ID );
800
+        }
801
+
802
+        // Status.
803
+        if ( rest_is_field_included( 'status', $fields ) ) {
804
+            $data['status'] = get_post_status( $discount->ID );
805
+        }
806
+
807
+        // Items.
808
+        if ( rest_is_field_included( 'items', $fields ) ) {
809
+            $data['items'] = wpinv_get_discount_item_reqs( $discount->ID );
810
+        }
811
+
812
+        // Excluded Items.
813
+        if ( rest_is_field_included( 'exclude_items', $fields ) ) {
814
+            $data['exclude_items'] = wpinv_get_discount_excluded_items( $discount->ID );
815
+        }
816
+
817
+        // Start date.
818
+        if ( rest_is_field_included( 'start_date', $fields ) ) {
819
+            $data['start_date'] = wpinv_get_discount_start_date( $discount->ID );
820
+        }
821
+
822
+        // End date.
823
+        if ( rest_is_field_included( 'end_date', $fields ) ) {
824
+            $data['end_date'] = wpinv_get_discount_expiration( $discount->ID );
825
+        }
826
+
827
+        // Minimum amount.
828
+        if ( rest_is_field_included( 'minimum_amount', $fields ) ) {
829
+            $data['minimum_amount'] = wpinv_get_discount_min_total( $discount->ID );
830
+        }
831
+
832
+        // Maximum amount.
833
+        if ( rest_is_field_included( 'maximum_amount', $fields ) ) {
834
+            $data['maximum_amount'] = wpinv_get_discount_max_total( $discount->ID );
835
+        }
836
+
837
+        // Recurring.
838
+        if ( rest_is_field_included( 'recurring', $fields ) ) {
839
+            $data['recurring'] = wpinv_discount_is_recurring( $discount->ID );
840
+        }
841
+
842
+        // Maximum uses.
843
+        if ( rest_is_field_included( 'max_uses', $fields ) ) {
844
+            $data['max_uses'] = wpinv_get_discount_max_uses( $discount->ID );
845
+        }
846
+
847
+        // Single use.
848
+        if ( rest_is_field_included( 'single_use', $fields ) ) {
849
+            $data['single_use'] = wpinv_discount_is_single_use( $discount->ID );
850
+        }
851
+
852
+        $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
853
+        $data    = $this->add_additional_fields_to_object( $data, $request );
854
+        $data    = $this->filter_response_by_context( $data, $context );
855
+
856
+        // Wrap the data in a response object.
857
+        $response = rest_ensure_response( $data );
858
+
859
+        $links = $this->prepare_links( $discount );
860
+        $response->add_links( $links );
861
+
862
+        if ( ! empty( $links['self']['href'] ) ) {
863
+            $actions = $this->get_available_actions( $discount, $request );
864
+
865
+            $self = $links['self']['href'];
866
+
867
+            foreach ( $actions as $rel ) {
868
+                $response->add_link( $rel, $self );
869
+            }
870
+        }
871
+
872
+        /**
873
+         * Filters the discount data for a response.
874
+         *
875
+         * @since 1.0.13
876
+         *
877
+         * @param WP_REST_Response $response The response object.
878
+         * @param WP_Post    $discount  The discount post object.
879
+         * @param WP_REST_Request  $request  Request object.
880
+         */
881
+        return apply_filters( "wpinv_rest_prepare_discount", $response, $discount, $request );
882
+    }
883
+
884
+    /**
885
+     * Gets an array of fields to be included on the response.
886
+     *
887
+     * Included fields are based on item schema and `_fields=` request argument.
888
+     *
889
+     * @since 1.0.13
890
+     *
891
+     * @param WP_REST_Request $request Full details about the request.
892
+     * @return array Fields to be included in the response.
893
+     */
894
+    public function get_fields_for_response( $request ) {
895
+        $schema     = $this->get_item_schema();
896
+        $properties = isset( $schema['properties'] ) ? $schema['properties'] : array();
897
+
898
+        $additional_fields = $this->get_additional_fields();
899
+        foreach ( $additional_fields as $field_name => $field_options ) {
900
+            // For back-compat, include any field with an empty schema
901
+            // because it won't be present in $this->get_item_schema().
902
+            if ( is_null( $field_options['schema'] ) ) {
903
+                $properties[ $field_name ] = $field_options;
904
+            }
905
+        }
906
+
907
+        // Exclude fields that specify a different context than the request context.
908
+        $context = $request['context'];
909
+        if ( $context ) {
910
+            foreach ( $properties as $name => $options ) {
911
+                if ( ! empty( $options['context'] ) && ! in_array( $context, $options['context'], true ) ) {
912
+                    unset( $properties[ $name ] );
913
+                }
914
+            }
915
+        }
916
+
917
+        $fields = array_keys( $properties );
918
+
919
+        if ( ! isset( $request['_fields'] ) ) {
920
+            return $fields;
921
+        }
922
+        $requested_fields = wpinv_parse_list( $request['_fields'] );
923
+        if ( 0 === count( $requested_fields ) ) {
924
+            return $fields;
925
+        }
926
+        // Trim off outside whitespace from the comma delimited list.
927
+        $requested_fields = array_map( 'trim', $requested_fields );
928
+        // Always persist 'id', because it can be needed for add_additional_fields_to_object().
929
+        if ( in_array( 'id', $fields, true ) ) {
930
+            $requested_fields[] = 'id';
931
+        }
932
+        // Return the list of all requested fields which appear in the schema.
933
+        return array_reduce(
934
+            $requested_fields,
935
+            function( $response_fields, $field ) use ( $fields ) {
936
+                if ( in_array( $field, $fields, true ) ) {
937
+                    $response_fields[] = $field;
938
+                    return $response_fields;
939
+                }
940
+                // Check for nested fields if $field is not a direct match.
941
+                $nested_fields = explode( '.', $field );
942
+                // A nested field is included so long as its top-level property is
943
+                // present in the schema.
944
+                if ( in_array( $nested_fields[0], $fields, true ) ) {
945
+                    $response_fields[] = $field;
946
+                }
947
+                return $response_fields;
948
+            },
949
+            array()
950
+        );
951
+    }
952
+
953
+    /**
954
+     * Retrieves the discount's schema, conforming to JSON Schema.
955
+     *
956
+     * @since 1.0.13
957
+     *
958
+     * @return array Discount schema data.
959
+     */
960
+    public function get_item_schema() {
961
+
962
+        // Maybe retrieve the schema from cache.
963
+        if (  empty( $this->schema ) ) {
964
+            return $this->add_additional_fields_schema( $this->schema );
965
+        }
966
+
967
+        $schema = array(
968
+            '$schema'    => 'http://json-schema.org/draft-04/schema#',
969
+            'title'      => $this->post_type,
970
+            'type'       => 'object',
971
+
972
+            // Base properties for every Item.
973
+            'properties' 		  => array(
974
+
975
+                'id'           => array(
976
+                    'description' => __( 'Unique identifier for the discount.', 'invoicing' ),
977
+                    'type'        => 'integer',
978
+                    'context'     => array( 'view', 'edit', 'embed' ),
979
+                    'readonly'    => true,
980
+                ),
981
+
982
+                'title'			  => array(
983
+                    'description' => __( 'The title for the discount.', 'invoicing' ),
984
+                    'type'        => 'string',
985
+                    'context'     => array( 'view', 'edit' ),
986
+                ),
987
+
988
+                'code'        => array(
989
+                    'description' => __( 'The discount code.', 'invoicing' ),
990
+                    'type'        => 'string',
991
+                    'context'     => array( 'view', 'edit', 'embed' ),
992
+                    'required'	  => true,
993
+                ),
994
+
995
+                'type'        => array(
996
+                    'description' => __( 'The type of discount.', 'invoicing' ),
997
+                    'type'        => 'string',
998
+                    'enum'        => array_keys( wpinv_get_discount_types() ),
999
+                    'context'     => array( 'view', 'edit', 'embed' ),
1000
+                    'default'	  => 'percentage',
1001
+                ),
1002
+
1003
+                'amount'        => array(
1004
+                    'description' => __( 'The discount value.', 'invoicing' ),
1005
+                    'type'        => 'number',
1006
+                    'context'     => array( 'view', 'edit', 'embed' ),
1007
+                    'required'	  => true,
1008
+                ),
1009
+
1010
+                'status'       => array(
1011
+                    'description' => __( 'A named status for the discount.', 'invoicing' ),
1012
+                    'type'        => 'string',
1013
+                    'enum'        => array_keys( get_post_stati( array( 'internal' => false ) ) ),
1014
+                    'context'     => array( 'view', 'edit' ),
1015
+                ),
1016
+
1017
+                'items'       => array(
1018
+                    'description' => __( 'Items which need to be in the cart to use this discount or, for "Item Discounts", which items are discounted. If left blank, this discount will be used on any item.', 'invoicing' ),
1019
+                    'type'        => 'array',
1020
+                    'context'     => array( 'view', 'edit' ),
1021
+                ),
1022
+
1023
+                'exclude_items'   => array(
1024
+                    'description' => __( 'Items which are NOT allowed to use this discount.', 'invoicing' ),
1025
+                    'type'        => 'array',
1026
+                    'context'     => array( 'view', 'edit' ),
1027
+                ),
1028
+
1029
+                'start_date'       => array(
1030
+                    'description' => __( 'The start date for the discount in the format of yyyy-mm-dd hh:mm:ss  . If provided, the discount can only be used after or on this date.', 'invoicing' ),
1031
+                    'type'        => 'string',
1032
+                    'context'     => array( 'view', 'edit' ),
1033
+                ),
1034
+
1035
+                'end_date'        => array(
1036
+                    'description' => __( 'The expiration date for the discount.', 'invoicing' ),
1037
+                    'type'        => 'string',
1038
+                    'context'     => array( 'view', 'edit', 'embed' ),
1039
+                ),
1040 1040
 				
1041
-				'minimum_amount'       => array(
1042
-					'description' => __( 'Minimum amount needed to use this invoice.', 'invoicing' ),
1043
-					'type'        => 'number',
1044
-					'context'     => array( 'view', 'edit', 'embed' ),
1045
-				),
1046
-
1047
-				'maximum_amount'       => array(
1048
-					'description' => __( 'Maximum amount needed to use this invoice.', 'invoicing' ),
1049
-					'type'        => 'number',
1050
-					'context'     => array( 'view', 'edit', 'embed' ),
1051
-				),
1052
-
1053
-				'recurring'       => array(
1054
-					'description' => __( 'Whether the discount is applied to all recurring payments or only the first recurring payment.', 'invoicing' ),
1055
-					'type'        => 'integer',
1056
-					'context'     => array( 'view', 'edit', 'embed' ),
1057
-				),
1058
-
1059
-				'max_uses'        => array(
1060
-					'description' => __( 'The maximum number of times this discount code can be used.', 'invoicing' ),
1061
-					'type'        => 'number',
1062
-					'context'     => array( 'view', 'edit', 'embed' ),
1063
-				),
1064
-
1065
-				'single_use'       => array(
1066
-					'description' => __( 'Whether or not this discount can only be used once per user.', 'invoicing' ),
1067
-					'type'        => 'integer',
1068
-					'context'     => array( 'view', 'edit', 'embed' ),
1069
-				)
1070
-
1071
-			),
1072
-		);
1073
-
1074
-		// Add helpful links to the discount schem.
1075
-		$schema['links'] = $this->get_schema_links();
1076
-
1077
-		/**
1078
-		 * Filters the discount schema for the REST API.
1079
-		 *
1080
-		 * Enables adding extra properties to discounts.
1081
-		 *
1082
-		 * @since 1.0.13
1083
-		 *
1084
-		 * @param array   $schema    The discount schema.
1085
-		 */
1041
+                'minimum_amount'       => array(
1042
+                    'description' => __( 'Minimum amount needed to use this invoice.', 'invoicing' ),
1043
+                    'type'        => 'number',
1044
+                    'context'     => array( 'view', 'edit', 'embed' ),
1045
+                ),
1046
+
1047
+                'maximum_amount'       => array(
1048
+                    'description' => __( 'Maximum amount needed to use this invoice.', 'invoicing' ),
1049
+                    'type'        => 'number',
1050
+                    'context'     => array( 'view', 'edit', 'embed' ),
1051
+                ),
1052
+
1053
+                'recurring'       => array(
1054
+                    'description' => __( 'Whether the discount is applied to all recurring payments or only the first recurring payment.', 'invoicing' ),
1055
+                    'type'        => 'integer',
1056
+                    'context'     => array( 'view', 'edit', 'embed' ),
1057
+                ),
1058
+
1059
+                'max_uses'        => array(
1060
+                    'description' => __( 'The maximum number of times this discount code can be used.', 'invoicing' ),
1061
+                    'type'        => 'number',
1062
+                    'context'     => array( 'view', 'edit', 'embed' ),
1063
+                ),
1064
+
1065
+                'single_use'       => array(
1066
+                    'description' => __( 'Whether or not this discount can only be used once per user.', 'invoicing' ),
1067
+                    'type'        => 'integer',
1068
+                    'context'     => array( 'view', 'edit', 'embed' ),
1069
+                )
1070
+
1071
+            ),
1072
+        );
1073
+
1074
+        // Add helpful links to the discount schem.
1075
+        $schema['links'] = $this->get_schema_links();
1076
+
1077
+        /**
1078
+         * Filters the discount schema for the REST API.
1079
+         *
1080
+         * Enables adding extra properties to discounts.
1081
+         *
1082
+         * @since 1.0.13
1083
+         *
1084
+         * @param array   $schema    The discount schema.
1085
+         */
1086 1086
         $schema = apply_filters( "wpinv_rest_discount_schema", $schema );
1087 1087
 
1088
-		//  Cache the discount schema.
1089
-		$this->schema = $schema;
1088
+        //  Cache the discount schema.
1089
+        $this->schema = $schema;
1090 1090
 		
1091
-		return $this->add_additional_fields_schema( $this->schema );
1092
-	}
1093
-
1094
-	/**
1095
-	 * Retrieve Link Description Objects that should be added to the Schema for the discounts collection.
1096
-	 *
1097
-	 * @since 1.0.13
1098
-	 *
1099
-	 * @return array
1100
-	 */
1101
-	protected function get_schema_links() {
1102
-
1103
-		$href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" );
1104
-
1105
-		$links = array();
1106
-
1107
-		$links[] = array(
1108
-			'rel'          => 'https://api.w.org/action-publish',
1109
-			'title'        => __( 'The current user can publish this discount.', 'invoicing' ),
1110
-			'href'         => $href,
1111
-			'targetSchema' => array(
1112
-				'type'       => 'object',
1113
-				'properties' => array(
1114
-					'status' => array(
1115
-						'type' => 'string',
1116
-						'enum' => array( 'publish', 'future' ),
1117
-					),
1118
-				),
1119
-			),
1120
-		);
1121
-
1122
-		return $links;
1123
-	}
1124
-
1125
-	/**
1126
-	 * Prepares links for the request.
1127
-	 *
1128
-	 * @since 1.0.13
1129
-	 *
1130
-	 * @param WP_Post $discount Post Object.
1131
-	 * @return array Links for the given discount.
1132
-	 */
1133
-	protected function prepare_links( $discount ) {
1134
-
1135
-		// Prepare the base REST API endpoint for discounts.
1136
-		$base = sprintf( '%s/%s', $this->namespace, $this->rest_base );
1137
-
1138
-		// Entity meta.
1139
-		$links = array(
1140
-			'self'       => array(
1141
-				'href' => rest_url( trailingslashit( $base ) . $discount->ID ),
1142
-			),
1143
-			'collection' => array(
1144
-				'href' => rest_url( $base ),
1145
-			),
1146
-		);
1147
-
1148
-		/**
1149
-		 * Filters the returned discount links for the REST API.
1150
-		 *
1151
-		 * Enables adding extra links to discount API responses.
1152
-		 *
1153
-		 * @since 1.0.13
1154
-		 *
1155
-		 * @param array   $links    Rest links.
1156
-		 */
1157
-		return apply_filters( "wpinv_rest_discount_links", $links );
1158
-
1159
-	}
1160
-
1161
-	/**
1162
-	 * Get the link relations available for the post and current user.
1163
-	 *
1164
-	 * @since 1.0.13
1165
-	 *
1166
-	 * @param WP_Post   $discount    WP_Post object.
1167
-	 * @param WP_REST_Request $request Request object.
1168
-	 * @return array List of link relations.
1169
-	 */
1170
-	protected function get_available_actions( $discount, $request ) {
1171
-
1172
-		if ( 'edit' !== $request['context'] ) {
1173
-			return array();
1174
-		}
1175
-
1176
-		$rels = array();
1177
-
1178
-		// Retrieve the post type object.
1179
-		$post_type = get_post_type_object( $discount->post_type );
1180
-
1181
-		// Mark discount as published.
1182
-		if ( current_user_can( $post_type->cap->publish_posts ) ) {
1183
-			$rels[] = 'https://api.w.org/action-publish';
1184
-		}
1185
-
1186
-		/**
1187
-		 * Filters the available discount link relations for the REST API.
1188
-		 *
1189
-		 * Enables adding extra link relation for the current user and request to discount responses.
1190
-		 *
1191
-		 * @since 1.0.13
1192
-		 *
1193
-		 * @param array   $rels    Available link relations.
1194
-		 */
1195
-		return apply_filters( "wpinv_rest_discount_link_relations", $rels );
1196
-	}
1197
-
1198
-	/**
1199
-	 * Handles rest requests for discount types.
1200
-	 *
1201
-	 * @since 1.0.13
1202
-	 * 
1203
-	 * 
1204
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
1205
-	 */
1206
-	public function get_discount_types() {
1207
-		return rest_ensure_response( wpinv_get_discount_types() );
1208
-	}
1091
+        return $this->add_additional_fields_schema( $this->schema );
1092
+    }
1093
+
1094
+    /**
1095
+     * Retrieve Link Description Objects that should be added to the Schema for the discounts collection.
1096
+     *
1097
+     * @since 1.0.13
1098
+     *
1099
+     * @return array
1100
+     */
1101
+    protected function get_schema_links() {
1102
+
1103
+        $href = rest_url( "{$this->namespace}/{$this->rest_base}/{id}" );
1104
+
1105
+        $links = array();
1106
+
1107
+        $links[] = array(
1108
+            'rel'          => 'https://api.w.org/action-publish',
1109
+            'title'        => __( 'The current user can publish this discount.', 'invoicing' ),
1110
+            'href'         => $href,
1111
+            'targetSchema' => array(
1112
+                'type'       => 'object',
1113
+                'properties' => array(
1114
+                    'status' => array(
1115
+                        'type' => 'string',
1116
+                        'enum' => array( 'publish', 'future' ),
1117
+                    ),
1118
+                ),
1119
+            ),
1120
+        );
1121
+
1122
+        return $links;
1123
+    }
1124
+
1125
+    /**
1126
+     * Prepares links for the request.
1127
+     *
1128
+     * @since 1.0.13
1129
+     *
1130
+     * @param WP_Post $discount Post Object.
1131
+     * @return array Links for the given discount.
1132
+     */
1133
+    protected function prepare_links( $discount ) {
1134
+
1135
+        // Prepare the base REST API endpoint for discounts.
1136
+        $base = sprintf( '%s/%s', $this->namespace, $this->rest_base );
1137
+
1138
+        // Entity meta.
1139
+        $links = array(
1140
+            'self'       => array(
1141
+                'href' => rest_url( trailingslashit( $base ) . $discount->ID ),
1142
+            ),
1143
+            'collection' => array(
1144
+                'href' => rest_url( $base ),
1145
+            ),
1146
+        );
1147
+
1148
+        /**
1149
+         * Filters the returned discount links for the REST API.
1150
+         *
1151
+         * Enables adding extra links to discount API responses.
1152
+         *
1153
+         * @since 1.0.13
1154
+         *
1155
+         * @param array   $links    Rest links.
1156
+         */
1157
+        return apply_filters( "wpinv_rest_discount_links", $links );
1158
+
1159
+    }
1160
+
1161
+    /**
1162
+     * Get the link relations available for the post and current user.
1163
+     *
1164
+     * @since 1.0.13
1165
+     *
1166
+     * @param WP_Post   $discount    WP_Post object.
1167
+     * @param WP_REST_Request $request Request object.
1168
+     * @return array List of link relations.
1169
+     */
1170
+    protected function get_available_actions( $discount, $request ) {
1171
+
1172
+        if ( 'edit' !== $request['context'] ) {
1173
+            return array();
1174
+        }
1175
+
1176
+        $rels = array();
1177
+
1178
+        // Retrieve the post type object.
1179
+        $post_type = get_post_type_object( $discount->post_type );
1180
+
1181
+        // Mark discount as published.
1182
+        if ( current_user_can( $post_type->cap->publish_posts ) ) {
1183
+            $rels[] = 'https://api.w.org/action-publish';
1184
+        }
1185
+
1186
+        /**
1187
+         * Filters the available discount link relations for the REST API.
1188
+         *
1189
+         * Enables adding extra link relation for the current user and request to discount responses.
1190
+         *
1191
+         * @since 1.0.13
1192
+         *
1193
+         * @param array   $rels    Available link relations.
1194
+         */
1195
+        return apply_filters( "wpinv_rest_discount_link_relations", $rels );
1196
+    }
1197
+
1198
+    /**
1199
+     * Handles rest requests for discount types.
1200
+     *
1201
+     * @since 1.0.13
1202
+     * 
1203
+     * 
1204
+     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
1205
+     */
1206
+    public function get_discount_types() {
1207
+        return rest_ensure_response( wpinv_get_discount_types() );
1208
+    }
1209 1209
     
1210 1210
 }
1211 1211
\ No newline at end of file
Please login to merge, or discard this patch.