This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
1 | <?php |
||||
2 | /** |
||||
3 | * Contains the main tax class. |
||||
4 | * |
||||
5 | * |
||||
6 | */ |
||||
7 | |||||
8 | defined( 'ABSPATH' ) || exit; |
||||
9 | |||||
10 | /** |
||||
11 | * Class GetPaid_Tax |
||||
12 | * |
||||
13 | */ |
||||
14 | class GetPaid_Tax { |
||||
15 | |||||
16 | /** |
||||
17 | * Calculates tax for a line item. |
||||
18 | * |
||||
19 | * @param float $price The price to calc tax on. |
||||
20 | * @param array $rates The rates to apply. |
||||
21 | * @param boolean $price_includes_tax Whether the passed price has taxes included. |
||||
22 | * @return array Array of tax name => tax amount. |
||||
23 | */ |
||||
24 | public static function calc_tax( $price, $rates, $price_includes_tax = false ) { |
||||
25 | |||||
26 | if ( $price_includes_tax ) { |
||||
27 | $taxes = self::calc_inclusive_tax( $price, $rates ); |
||||
28 | } else { |
||||
29 | $taxes = self::calc_exclusive_tax( $price, $rates ); |
||||
30 | } |
||||
31 | |||||
32 | return apply_filters( 'getpaid_calc_tax', $taxes, $price, $rates, $price_includes_tax ); |
||||
33 | |||||
34 | } |
||||
35 | |||||
36 | /** |
||||
37 | * Calc tax from inclusive price. |
||||
38 | * |
||||
39 | * @param float $price Price to calculate tax for. |
||||
40 | * @param array $rates Array of tax rates. |
||||
41 | * @return array |
||||
42 | */ |
||||
43 | public static function calc_inclusive_tax( $price, $rates ) { |
||||
44 | $taxes = array(); |
||||
45 | $tax_rates = wp_list_pluck( $rates, 'rate', 'name' ); |
||||
46 | |||||
47 | // Add tax rates. |
||||
48 | $tax_rate = 1 + ( array_sum( $tax_rates ) / 100 ); |
||||
49 | |||||
50 | foreach ( $tax_rates as $name => $rate ) { |
||||
51 | $the_rate = ( $rate / 100 ) / $tax_rate; |
||||
52 | $net_price = $price - ( $the_rate * $price ); |
||||
53 | $tax_amount = apply_filters( 'getpaid_price_inc_tax_amount', $price - $net_price, $name, $rate, $price ); |
||||
54 | $taxes[ $name ] = $tax_amount; |
||||
55 | } |
||||
56 | |||||
57 | // Round all taxes to precision (4DP) before passing them back. |
||||
58 | $taxes = array_map( array( __CLASS__, 'round' ), $taxes ); |
||||
59 | |||||
60 | return $taxes; |
||||
61 | } |
||||
62 | |||||
63 | /** |
||||
64 | * Calc tax from exclusive price. |
||||
65 | * |
||||
66 | * @param float $price Price to calculate tax for. |
||||
67 | * @param array $rates Array of tax rates. |
||||
68 | * @return array |
||||
69 | */ |
||||
70 | public static function calc_exclusive_tax( $price, $rates ) { |
||||
71 | $taxes = array(); |
||||
72 | $tax_rates = wp_list_pluck( $rates, 'rate', 'name' ); |
||||
73 | |||||
74 | foreach ( $tax_rates as $name => $rate ) { |
||||
75 | |||||
76 | $tax_amount = $price * ( $rate / 100 ); |
||||
77 | $taxes[ $name ] = apply_filters( 'getpaid_price_ex_tax_amount', $tax_amount, $name, $rate, $price ); |
||||
78 | |||||
79 | } |
||||
80 | |||||
81 | // Round all taxes to precision (4DP) before passing them back. |
||||
82 | $taxes = array_map( array( __CLASS__, 'round' ), $taxes ); |
||||
83 | |||||
84 | return $taxes; |
||||
85 | } |
||||
86 | |||||
87 | /** |
||||
88 | * Get's an array of all tax rates. |
||||
89 | * |
||||
90 | * @return array |
||||
91 | */ |
||||
92 | public static function get_all_tax_rates() { |
||||
93 | |||||
94 | $rates = get_option( 'wpinv_tax_rates', array() ); |
||||
95 | |||||
96 | return apply_filters( |
||||
97 | 'getpaid_get_all_tax_rates', |
||||
98 | array_filter( wpinv_parse_list( $rates ) ) |
||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
99 | ); |
||||
100 | |||||
101 | } |
||||
102 | |||||
103 | /** |
||||
104 | * Get's an array of default tax rates. |
||||
105 | * |
||||
106 | * @return array |
||||
107 | */ |
||||
108 | public static function get_default_tax_rates() { |
||||
109 | |||||
110 | return apply_filters( |
||||
111 | 'getpaid_get_default_tax_rates', |
||||
112 | array( |
||||
113 | array( |
||||
114 | 'country' => wpinv_get_default_country(), |
||||
115 | 'state' => wpinv_get_default_state(), |
||||
116 | 'global' => true, |
||||
117 | 'rate' => wpinv_get_default_tax_rate(), |
||||
118 | 'name' => __( 'Tax', 'invoicing' ), |
||||
119 | ), |
||||
120 | ) |
||||
121 | ); |
||||
122 | |||||
123 | } |
||||
124 | |||||
125 | /** |
||||
126 | * Get's an array of all tax rules. |
||||
127 | * |
||||
128 | * @return array |
||||
129 | */ |
||||
130 | public static function get_all_tax_rules() { |
||||
131 | |||||
132 | $rules = get_option( |
||||
133 | 'wpinv_tax_rules', |
||||
134 | array( |
||||
135 | array( |
||||
136 | 'key' => 'physical', |
||||
137 | 'label' => __( 'Physical Item', 'invoicing' ), |
||||
138 | 'tax_base' => wpinv_get_option( 'tax_base', 'billing' ), |
||||
139 | 'same_country_rule' => wpinv_get_option( 'vat_same_country_rule', 'vat_too' ), |
||||
140 | ), |
||||
141 | array( |
||||
142 | 'key' => 'digital', |
||||
143 | 'label' => __( 'Digital Item', 'invoicing' ), |
||||
144 | 'tax_base' => wpinv_get_option( 'tax_base', 'billing' ), |
||||
145 | 'same_country_rule' => wpinv_get_option( 'vat_same_country_rule', 'vat_too' ), |
||||
146 | ), |
||||
147 | ) |
||||
148 | ); |
||||
149 | |||||
150 | return apply_filters( |
||||
151 | 'getpaid_tax_rules', |
||||
152 | array_filter( array_values( wpinv_parse_list( $rules ) ) ) |
||||
0 ignored issues
–
show
It seems like
$rules can also be of type false ; however, parameter $list of wpinv_parse_list() does only seem to accept array|string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
153 | ); |
||||
154 | |||||
155 | } |
||||
156 | |||||
157 | /** |
||||
158 | * Get's an array of tax rates for a given address. |
||||
159 | * |
||||
160 | * @param string $country |
||||
161 | * @param string $state |
||||
162 | * @return array |
||||
163 | */ |
||||
164 | public static function get_address_tax_rates( $country, $state ) { |
||||
165 | |||||
166 | $all_tax_rates = self::get_all_tax_rates(); |
||||
167 | $matching_rates = array_merge( |
||||
168 | wp_list_filter( $all_tax_rates, array( 'country' => $country ) ), |
||||
169 | wp_list_filter( $all_tax_rates, array( 'country' => '' ) ) |
||||
170 | ); |
||||
171 | |||||
172 | foreach ( $matching_rates as $i => $rate ) { |
||||
173 | |||||
174 | $states = array_filter( wpinv_clean( explode( ',', strtolower( $rate['state'] ) ) ) ); |
||||
175 | if ( empty( $rate['global'] ) && ! in_array( strtolower( $state ), $states ) ) { |
||||
176 | unset( $matching_rates[ $i ] ); |
||||
177 | } |
||||
178 | } |
||||
179 | |||||
180 | return apply_filters( 'getpaid_get_address_tax_rates', $matching_rates, $country, $state ); |
||||
181 | |||||
182 | } |
||||
183 | |||||
184 | /** |
||||
185 | * Sums a set of taxes to form a single total. Result is rounded to precision. |
||||
186 | * |
||||
187 | * @param array $taxes Array of taxes. |
||||
188 | * @return float |
||||
189 | */ |
||||
190 | public static function get_tax_total( $taxes ) { |
||||
191 | return self::round( array_sum( $taxes ) ); |
||||
192 | } |
||||
193 | |||||
194 | /** |
||||
195 | * Round to precision. |
||||
196 | * |
||||
197 | * Filter example: to return rounding to .5 cents you'd use: |
||||
198 | * |
||||
199 | * function euro_5cent_rounding( $in ) { |
||||
200 | * return round( $in / 5, 2 ) * 5; |
||||
201 | * } |
||||
202 | * add_filter( 'getpaid_tax_round', 'euro_5cent_rounding' ); |
||||
203 | * |
||||
204 | * @param float|int $in Value to round. |
||||
205 | * @return float |
||||
206 | */ |
||||
207 | public static function round( $in ) { |
||||
208 | return apply_filters( 'getpaid_tax_round', round( $in, 4 ), $in ); |
||||
209 | } |
||||
210 | |||||
211 | } |
||||
212 |