Completed
Push — master ( a85a3b...a9e055 )
by Justin
11:13
created

tablerate::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 6
rs 9.4285
cc 1
eloc 5
nc 1
nop 0
1
<?php
2
/**
3
 * shipping/tablerate.php
4
 *
5
 * @package WP e-Commerce
6
 */
7
8
9
class tablerate {
0 ignored issues
show
Coding Style introduced by
Class name "tablerate" is not in camel caps format
Loading history...
10
11
	var $internal_name, $name;
12
13
	/**
14
	 * Constructor
15
	 *
16
	 * @return boolean Always returns true.
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
17
	 */
18
	public function __construct() {
19
		$this->internal_name = "tablerate";
20
		$this->name = __( "Table Rate", 'wp-e-commerce' );
21
		$this->is_external=false;
0 ignored issues
show
Bug introduced by
The property is_external does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
22
		return true;
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
23
	}
24
25
	/**
26
	 * Returns i18n-ized name of shipping module.
27
	 *
28
	 * @return string
29
	 */
30
	function getName() {
31
		return $this->name;
32
	}
33
34
	/**
35
	 * Returns internal name of shipping module.
36
	 *
37
	 * @return string
38
	 */
39
	function getInternalName() {
40
		return $this->internal_name;
41
	}
42
43
	/**
44
	 * generates row of table rate fields
45
	 */
46
	private function output_row( $key = '', $shipping = '' ) {
47
		$currency = wpsc_get_currency_symbol();
48
		$class = ( $this->alt ) ? 'class="alternate"' : '';
0 ignored issues
show
Bug introduced by
The property alt does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
49
		$this->alt = ! $this->alt;
50
		?>
51
			<tr>
52
				<td <?php echo $class; ?>>
53
					<div class="cell-wrapper">
54
						<small><?php echo esc_html( $currency ); ?></small>
55
						<input type="text" name="wpsc_shipping_tablerate_layer[]" value="<?php echo esc_attr( $key ); ?>" size="4" />
56
						<small><?php _e( ' and above', 'wp-e-commerce' ); ?></small>
57
					</div>
58
				</td>
59
				<td <?php echo $class; ?>>
60
					<div class="cell-wrapper">
61
						<small><?php echo esc_html( $currency ); ?></small>
62
						<input type="text" name="wpsc_shipping_tablerate_shipping[]" value="<?php echo esc_attr( $shipping ); ?>" size="4" />
63
						<span class="actions">
64
							<a tabindex="-1" title="<?php _e( 'Delete Layer', 'wp-e-commerce' ); ?>" class="button-secondary wpsc-button-round wpsc-button-minus" href="#"><?php echo _x( '&ndash;', 'delete item', 'wp-e-commerce' ); ?></a>
65
							<a tabindex="-1" title="<?php _e( 'Add Layer', 'wp-e-commerce' ); ?>" class="button-secondary wpsc-button-round wpsc-button-plus" href="#"><?php echo _x( '+', 'add item', 'wp-e-commerce' ); ?></a>
66
						</span>
67
					</div>
68
				</td>
69
			</tr>
70
		<?php
71
	}
72
73
	/**
74
	 * Returns HTML settings form. Should be a collection of <tr> elements containing two columns.
75
	 *
76
	 * @return string HTML snippet.
77
	 */
78
	function getForm() {
79
		$layers = get_option( 'table_rate_layers', array() );
80
		$this->alt = false;
81
		ob_start();
82
		?>
83
		<tr>
84
			<td colspan='2'>
85
				<table>
86
					<thead>
87
						<tr>
88
							<th class="total"><?php _e('Total Price', 'wp-e-commerce' ); ?></th>
89
							<th class="shipping"><?php _e( 'Shipping Price', 'wp-e-commerce' ); ?></th>
90
						</tr>
91
					</thead>
92
					<tbody class="table-rate">
93
						<tr class="js-warning">
94
							<td colspan="2">
95
								<small><?php echo sprintf( __( 'To remove a rate layer, simply leave the values on that row blank. By the way, <a href="%s">enable JavaScript</a> for a better user experience.', 'wp-e-commerce'), 'http://www.google.com/support/bin/answer.py?answer=23852' ); ?></small>
96
							</td>
97
						</tr>
98
						<?php if ( ! empty( $layers ) ): ?>
99
							<?php
100
								foreach( $layers as $key => $shipping ){
101
									$this->output_row( $key, $shipping );
102
								}
103
							?>
104
						<?php else: ?>
105
							<?php $this->output_row(); ?>
106
						<?php endif ?>
107
					</tbody>
108
				</table>
109
			</td>
110
		</tr>
111
		<?php
112
		return ob_get_clean();
113
	}
114
115
	/**
116
	 * Saves shipping module settings.
117
	 *
118
	 * @return boolean Always returns true.
119
	 */
120
	function submit_form() {
121
		if ( ! isset( $_POST['wpsc_shipping_tablerate_layer'] ) || ! isset( $_POST['wpsc_shipping_tablerate_shipping'] ) )
122
			return false;
123
124
		$layers    = (array) $_POST['wpsc_shipping_tablerate_layer'];
125
		$shippings = (array) $_POST['wpsc_shipping_tablerate_shipping'];
126
		$new_layer = array();
127
128
		if ( $shippings != '' ) {
129
			foreach ( $shippings as $key => $price ) {
130
131
				if ( ! is_numeric( $key ) || ! is_numeric( $price ) ) {
132
					continue;
133
				}
134
135
				$new_layer[ sanitize_text_field( $layers[ $key ] ) ] = sanitize_text_field( $price );
136
			}
137
		}
138
139
		// Sort the data before it goes into the database. Makes the UI make more sense
140
		krsort( $new_layer );
141
		update_option( 'table_rate_layers', $new_layer );
142
		return true;
143
	}
144
145
	/**
146
	 * returns shipping quotes using this shipping module.
147
	 *
148
	 * @return array collection of rates applicable.
149
	 */
150
	function getQuote() {
151
152
		global $wpdb, $wpsc_cart;
153
		if ( wpsc_get_customer_meta( 'nzshpcart' ) ) {
154
			$shopping_cart = wpsc_get_customer_meta( 'nzshpcart' );
155
		}
156
		if ( is_object( $wpsc_cart ) ) {
157
			$price = $wpsc_cart->calculate_subtotal( true );
158
		}
159
160
		$layers = get_option( 'table_rate_layers' );
161
162
		if ($layers != '') {
163
164
			// At some point we should probably remove this as the sorting should be
165
			// done when we save the data to the database. But need to leave it here
166
			// for people who have non-sorted settings in their database
167
			krsort( $layers );
168
169
			foreach ( $layers as $key => $shipping ) {
170
171
				if ( $price >= (float) $key ) {
172
173
					if ( stristr( $shipping, '%' ) ) {
174
175
						// Shipping should be a % of the cart total
176
						$shipping = str_replace( '%', '', $shipping );
177
						$shipping_amount = $price * ( $shipping / 100 );
0 ignored issues
show
Bug introduced by
The variable $price does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
178
179
					} else {
180
181
						// Shipping is an absolute value
182
						$shipping_amount = $shipping;
183
184
					}
185
186
					return array( __( "Table Rate", 'wp-e-commerce' ) => $shipping_amount );
187
188
				}
0 ignored issues
show
introduced by
Blank line found after control structure
Loading history...
189
190
			}
191
192
			$shipping = array_shift( $layers );
193
194
			if ( stristr( $shipping, '%' ) ) {
195
				$shipping = str_replace( '%', '', $shipping );
196
				$shipping_amount = $price * ( $shipping / 100 );
197
			} else {
198
				$shipping_amount = $shipping;
199
			}
200
201
			return array( __( "Table Rate", 'wp-e-commerce' ) => $shipping_amount );
202
203
		}
204
	}
205
206
	/**
207
	 * calculates shipping price for an individual cart item.
208
	 *
209
	 * @param object $cart_item (reference)
210
	 * @return float price of shipping for the item.
211
	 */
212
	function get_item_shipping( &$cart_item ) {
213
214
		global $wpdb, $wpsc_cart;
215
216
		$unit_price = $cart_item->unit_price;
217
		$quantity = $cart_item->quantity;
218
		$weight = $cart_item->weight;
219
		$product_id = $cart_item->product_id;
220
221
		$uses_billing_address = false;
222
		foreach ( $cart_item->category_id_list as $category_id ) {
223
			$uses_billing_address = (bool) wpsc_get_categorymeta( $category_id, 'uses_billing_address' );
224
			if ( $uses_billing_address === true ) {
225
				break; /// just one true value is sufficient
226
			}
227
		}
228
229
		if ( is_numeric( $product_id ) && ( get_option( 'do_not_use_shipping' ) != 1 ) ) {
230
			if ( $uses_billing_address == true ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
231
				$country_code = $wpsc_cart->selected_country;
232
			} else {
233
				$country_code = $wpsc_cart->delivery_country;
234
			}
235
236
			if ( $cart_item->uses_shipping == true ) {
237
				//if the item has shipping
238
				$additional_shipping = '';
239
				if ( isset( $cart_item->meta[0]['shipping'] ) ) {
240
					$shipping_values = $cart_item->meta[0]['shipping'];
241
				}
242
				if ( isset( $shipping_values['local'] ) && $country_code == get_option( 'base_country' ) ) {
243
					$additional_shipping = $shipping_values['local'];
244
				} else {
245
					if ( isset( $shipping_values['international'] ) ) {
246
						$additional_shipping = $shipping_values['international'];
247
					}
248
				}
249
				$shipping = $quantity * $additional_shipping;
250
			} else {
251
				//if the item does not have shipping
252
				$shipping = 0;
253
			}
254
		} else {
255
			//if the item is invalid or all items do not have shipping
256
			$shipping = 0;
257
		}
258
		return $shipping;
259
	}
260
261
}
262
263
264
$tablerate = new tablerate();
265
$wpsc_shipping_modules[$tablerate->getInternalName()] = $tablerate;
266
?>
267