PluginProbe ʕ •ᴥ•ʔ
Weight Based Shipping Table Rate for WooCommerce – Flexible Shipping / 6.12.0
Weight Based Shipping Table Rate for WooCommerce – Flexible Shipping v6.12.0
6.12.1 6.12.0 6.11.0 6.10.0 6.9.1 6.9.0 6.8.1 6.8.0 6.7.4 6.7.3 6.7.2 6.7.0 4.21.7 4.22.0 4.22.1 4.23.0 4.23.1 4.23.2 4.23.3 4.24.0 4.24.1 4.24.10 4.24.11 4.24.12 4.24.13 4.24.14 4.24.15 4.24.16 4.24.17 4.24.18 4.24.19 4.24.2 4.24.4 4.24.6 4.24.7 4.24.8 4.24.9 4.25.0 4.25.1 4.25.2 4.25.4 4.25.5 4.25.6 4.25.7 4.25.8 4.3.0 4.3.1 4.4.0 4.4.1 4.5.0 4.5.1 4.6.0 4.6.1 4.7.0 4.7.1 4.7.2 4.8.0 4.8.1 4.8.3 4.8.4 4.8.5 4.9.0 5.0.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.0.9 5.1.0 5.1.1 5.1.2 5.1.3 5.2.0 5.3.0 5.3.1 5.3.3 5.3.4 5.3.5 6.0.0 6.1.0 6.1.1 6.1.2 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.3.0 trunk 6.4.0 1.4 6.4.1 1.4.1 6.4.2 1.5 6.4.3 1.6 6.4.5 1.6.1 6.5.0 1.6.2 6.5.1 1.7 6.5.2 1.8 6.5.3 1.9 6.5.4 1.9.1 6.5.5 1.9.10 6.5.6 1.9.11 6.5.7 1.9.12 6.5.8 1.9.2 6.6.0 1.9.3 6.6.1 1.9.4 6.6.2 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0 2.0.1 2.1 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.6 3.0.7 3.1 3.1.1 3.1.10 3.1.11 3.1.12 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.10.0 3.11.0 3.11.1 3.11.2 3.11.3 3.11.4 3.12.0 3.13.0 3.14.0 3.14.1 3.14.2 3.14.3 3.14.4 3.15.0 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.2.0 3.3.1 3.3.10 3.3.11 3.3.12 3.3.13 3.3.14 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.8.0 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.15 3.9.16 3.9.17 3.9.18 3.9.19 3.9.2 3.9.20 3.9.21 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.9 4.0.0 4.0.1 4.0.10 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.10.0 4.10.1 4.11.0 4.11.1 4.11.2 4.11.3 4.11.4 4.11.5 4.11.6 4.11.7 4.11.8 4.11.9 4.12.0 4.13.0 4.13.1 4.13.2 4.13.3 4.14.0 4.14.1 4.14.2 4.15.0 4.16.0 4.16.1 4.16.2 4.17.0 4.18.0 4.18.1 4.18.2 4.18.3 4.18.4 4.18.5 4.18.6 4.19.0 4.19.1 4.2.0 4.20.0 4.20.1 4.20.2 4.20.3 4.21.0 4.21.1 4.21.2 4.21.3 4.21.4 4.21.5
flexible-shipping / src / WPDesk / FS / TableRate / ImporterExporter / Importer / CSV.php
flexible-shipping / src / WPDesk / FS / TableRate / ImporterExporter / Importer Last commit date
Exception 1 week ago AbstractImporter.php 1 week ago CSV.php 1 week ago Importer.php 1 week ago ImporterFactory.php 1 week ago JSON.php 1 week ago
CSV.php
339 lines
1 <?php
2 /**
3 * Import shipping methods and rules from CSV.
4 *
5 * @package WPDesk\FS\TableRate\Importer
6 */
7
8 namespace WPDesk\FS\TableRate\ImporterExporter\Importer;
9
10 use WC_Admin_Settings;
11 use WPDesk\FS\TableRate\ImporterExporter\Importer\Exception\ImportCSVException;
12 use WPDesk\FS\TableRate\Rule\Condition\ConditionsFactory;
13 use WPDesk\FS\TableRate\ShippingMethod\CommonMethodSettings;
14 use WPDesk_Flexible_Shipping;
15
16 /**
17 * Class CSV
18 *
19 * @package WPDesk\FS\TableRate\Importer
20 */
21 class CSV extends AbstractImporter {
22 const CSV_DELIMITER = ';';
23
24 /**
25 * Delimiter used in CSV file.
26 *
27 * @return string
28 */
29 public static function get_csv_delimiter() {
30 return apply_filters( 'flexible_shipping_csv_delimiter', self::CSV_DELIMITER );
31 }
32
33 /**
34 * Load CSV from file.
35 *
36 * @param string $tmp_name File name.
37 *
38 * @return array
39 */
40 private function load_csv_from_file( $tmp_name ) {
41 return array_map(
42 function ( $v ) {
43 return str_getcsv( $v, self::get_csv_delimiter() );
44 },
45 file( $tmp_name )
46 );
47 }
48
49 /**
50 * Add columns to row.
51 *
52 * @param array $row Row.
53 * @param array $columns Columns.
54 *
55 * @return array
56 */
57 private function add_columns_to_row( array $row, array $columns ) {
58 foreach ( $columns as $col_key => $col ) {
59 $row[ $col ] = $row[ $col_key ];
60 }
61
62 return $row;
63 }
64
65 /**
66 * Convert rows to named values.
67 *
68 * @param array $csv_array CSV.
69 *
70 * @return array
71 */
72 private function convert_rows_to_named_values( array $csv_array ) {
73 $first = true;
74 $columns = [];
75 foreach ( $csv_array as $row_key => $csv_row ) {
76 if ( $first ) {
77 $columns = $csv_row;
78 } else {
79 $csv_array[ $row_key ] = $this->add_columns_to_row( $csv_array[ $row_key ], $columns );
80 }
81 $first = false;
82 }
83
84 return $csv_array;
85 }
86
87
88 /**
89 * Create new shipping method.
90 *
91 * @param array $csv_row CSV row.
92 * @param int $import_row_count Rows count.
93 *
94 * @return array
95 * @throws ImportCSVException Exception.
96 */
97 private function new_shipping_method( array $csv_row, $import_row_count ) {
98 $new_shipping_method = [ 'method_enabled' => 'no' ];
99 if ( ! isset( $csv_row['Method Title'] ) || '' === trim( $csv_row['Method Title'] ) ) {
100 throw new ImportCSVException(
101 __(
102 'Sorry, there has been an error. The CSV is invalid or incorrect file type.',
103 'flexible-shipping'
104 )
105 );
106 }
107
108 $new_shipping_method['id'] = $this->flexible_shipping_method->shipping_method_next_id( $this->shipping_methods );
109 $new_shipping_method['id_for_shipping'] = $this->flexible_shipping_method->id . '_' . $this->flexible_shipping_method->instance_id . '_' . $new_shipping_method['id'];
110 $new_shipping_method['method_title'] = $this->get_new_method_title( $csv_row['Method Title'] );
111 $new_shipping_method['instance_id'] = $this->flexible_shipping_method->instance_id;
112 $new_shipping_method['method_description'] = $csv_row['Method Description'];
113 $new_shipping_method[ CommonMethodSettings::METHOD_LOGO_ID ] = isset( $csv_row['Method Logo ID'] ) ? absint( $csv_row['Method Logo ID'] ) : 0;
114
115 if ( '' !== trim( $csv_row['Free Shipping'] ) && ! is_numeric( str_replace( ',', '.', $csv_row['Free Shipping'] ) ) ) {
116 throw new ImportCSVException(
117 sprintf(
118 // Translators: free shipping value and row number.
119 __( 'Free Shipping value %1$s is not valid number. Row number %2$d.', 'flexible-shipping' ),
120 $csv_row['Free Shipping'],
121 $import_row_count
122 )
123 );
124 }
125 $new_shipping_method[ WPDesk_Flexible_Shipping::FIELD_METHOD_FREE_SHIPPING ] = str_replace( ',', '.', $csv_row['Free Shipping'] );
126 if ( trim( $csv_row['Maximum Cost'] ) !== '' && ! is_numeric( str_replace( ',', '.', $csv_row['Maximum Cost'] ) ) ) {
127 throw new ImportCSVException(
128 sprintf(
129 // Translators: maximum cost value and row number.
130 __( 'Maximum Cost value %1$s is not valid number. Row number %2$d.', 'flexible-shipping' ),
131 $csv_row['Maximum Cost'],
132 $import_row_count
133 )
134 );
135 }
136 $new_shipping_method['method_max_cost'] = str_replace( ',', '.', $csv_row['Maximum Cost'] );
137 $new_shipping_method['method_calculation_method'] = $csv_row['Calculation Method'];
138 $new_shipping_method['cart_calculation'] = isset( $csv_row['Cart Calculation'] ) ? $csv_row['Cart Calculation'] : '';
139 if ( ! in_array(
140 $new_shipping_method['method_calculation_method'],
141 [ 'sum', 'lowest', 'highest' ],
142 true
143 ) ) {
144 throw new ImportCSVException(
145 sprintf(
146 // Translators: row number.
147 __( 'Invalid value for Calculation Method in row number %d.', 'flexible-shipping' ),
148 $import_row_count
149 )
150 );
151 }
152 $new_shipping_method['method_visibility'] = $csv_row['Visibility'];
153 if ( 'yes' !== $new_shipping_method['method_visibility'] ) {
154 $new_shipping_method['method_visibility'] = 'no';
155 }
156 $new_shipping_method['method_default'] = $csv_row['Default'];
157 if ( 'yes' !== $new_shipping_method['method_default'] ) {
158 $new_shipping_method['method_default'] = 'no';
159 }
160 $new_shipping_method['method_rules'] = [];
161
162 return $new_shipping_method;
163 }
164
165 /**
166 * Get numeric value from row.
167 *
168 * @param array $csv_row CSV row.
169 * @param string $column Column.
170 * @param int $import_row_count Row count.
171 *
172 * @return string
173 * @throws ImportCSVException Exception.
174 */
175 private function get_numeric_value_from_row( array $csv_row, $column, $import_row_count ) {
176 if ( '' !== trim( $csv_row[ $column ] ) && ! is_numeric( str_replace( ',', '.', $csv_row[ $column ] ) ) ) {
177 throw new ImportCSVException(
178 sprintf(
179 // Translators: column name, value and row number.
180 __( '%1$s value %2$s is not valid number. Row number %3$d.', 'flexible-shipping' ),
181 $column,
182 $csv_row['Min'],
183 $import_row_count
184 )
185 );
186 }
187
188 return str_replace( ',', '.', $csv_row[ $column ] );
189 }
190
191 /**
192 * Maybe populate and create shipping classes.
193 *
194 * @param string $shipping_classes Shipping Classes.
195 *
196 * @return array
197 * @throws ImportCSVException Exception.
198 */
199 private function maybe_populate_and_create_shipping_classes( $shipping_classes ) {
200 $data = [];
201
202 $rule_shipping_classes = explode( ',', trim( $shipping_classes ) );
203
204 foreach ( $rule_shipping_classes as $rule_shipping_class ) {
205 if ( ! in_array( $rule_shipping_class, [ 'all', 'any', 'none' ], true ) ) {
206 $term_id = $this->find_shipping_class_by_name( $rule_shipping_class );
207 if ( null === $term_id ) {
208 $term_id = $this->create_shipping_class( $rule_shipping_class, $rule_shipping_class );
209 }
210 $data[] = $term_id;
211 } else {
212 $data[] = $rule_shipping_class;
213 }
214 }
215
216 return $data;
217 }
218
219 /**
220 * New shipping method rule.
221 *
222 * @param array $csv_row CSV row.
223 * @param int $import_row_count Row count.
224 *
225 * @return array
226 * @throws ImportCSVException Exception.
227 */
228 private function new_rule( array $csv_row, $import_row_count ) {
229 $rule = [];
230 $rule['based_on'] = $csv_row['Based on'];
231
232 $conditions = array_keys( ( new ConditionsFactory() )->get_conditions() );
233
234 if ( ! in_array( $rule['based_on'], $conditions, true ) ) {
235 throw new ImportCSVException(
236 sprintf(
237 // Translators: row number.
238 __( 'Invalid value for Based On in row number %d.', 'flexible-shipping' ),
239 $import_row_count
240 )
241 );
242 }
243
244 $rule['cost_per_order'] = $this->get_numeric_value_from_row( $csv_row, 'Cost per order', $import_row_count );
245
246 // Conditions.
247 $rule['conditions'] = [];
248
249 $condition = [
250 'condition_id' => $csv_row['Based on'],
251 'min' => $this->get_numeric_value_from_row( $csv_row, 'Min', $import_row_count ),
252 'max' => $this->get_numeric_value_from_row( $csv_row, 'Max', $import_row_count ),
253 ];
254
255 if ( ! empty( $condition['min'] ) || ! empty( $condition['max'] ) ) {
256 $rule['conditions'][] = $condition;
257 }
258
259 // Shipping Classes.
260 $rule['shipping_class'] = trim( $csv_row['Shipping Class'] );
261
262 if ( ! empty( $rule['shipping_class'] ) && 'all' !== $rule['shipping_class'] ) {
263 $rule['conditions'][] = [
264 'condition_id' => 'shipping_class',
265 'shipping_class' => $this->maybe_populate_and_create_shipping_classes( $rule['shipping_class'] ),
266 ];
267 }
268
269 // Special Actions.
270 if ( 'yes' === $csv_row['Cancel'] ) {
271 $rule['special_action'] = 'cancel';
272 } elseif ( 'yes' === $csv_row['Stop'] ) {
273 $rule['special_action'] = 'stop';
274 } else {
275 $rule['special_action'] = 'none';
276 }
277
278 // Additional Costs.
279 $cost_additional = $this->get_numeric_value_from_row( $csv_row, 'Additional cost', $import_row_count );
280
281 if ( ! empty( $cost_additional ) ) {
282 $rule['additional_costs'][] = [
283 'additional_cost' => $cost_additional,
284 'per_value' => $this->get_numeric_value_from_row( $csv_row, 'Value', $import_row_count ),
285 'based_on' => $rule['based_on'],
286 ];
287 }
288
289 return $rule;
290 }
291
292 /**
293 * Import file.
294 *
295 * @throws ImportCSVException Exception.
296 */
297 public function import() {
298 $csv_array = $this->load_csv_from_file( $this->file['tmp_name'] );
299 $csv_array = $this->convert_rows_to_named_values( $csv_array );
300
301 $first = true;
302 $current_method_title = '';
303 $method_title = '';
304 $imported_shipping_method = [];
305 $import_row_count = 0;
306 foreach ( $csv_array as $row_key => $csv_row ) {
307 ++$import_row_count;
308 $new_method = false;
309 if ( ! $first ) {
310 if ( ! isset( $csv_row['Method Title'] ) || $current_method_title !== $csv_row['Method Title'] || ! isset( $csv_row['Based on'] ) || '' === $csv_row['Based on'] ) {
311 $new_method = true;
312
313 $imported_shipping_method = $this->new_shipping_method( $csv_row, $import_row_count );
314
315 $current_method_title = $csv_row['Method Title'];
316 $method_title = $imported_shipping_method['method_title'];
317
318 } else {
319 $imported_shipping_method['method_rules'][] = $this->new_rule( $csv_row, $import_row_count );
320 }
321 }
322 if ( ! $first ) {
323 $this->shipping_methods[ $imported_shipping_method['id'] ] = $imported_shipping_method;
324 if ( $new_method ) {
325 WC_Admin_Settings::add_message(
326 sprintf(
327 // Translators: imported method title and method title.
328 __( 'Shipping method %1$s imported as %2$s.', 'flexible-shipping' ),
329 $current_method_title,
330 $method_title
331 )
332 );
333 }
334 }
335 $first = false;
336 }
337 }
338 }
339