-
Notifications
You must be signed in to change notification settings - Fork 212
Expand file tree
/
Copy pathvariations.class.php
More file actions
executable file
·371 lines (297 loc) · 11.1 KB
/
variations.class.php
File metadata and controls
executable file
·371 lines (297 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
<?php
/**
* wp- e-Commerce Variations class
*
* This is the code that handles adding, editing and displaying variations on Products
*/
class wpsc_variations {
// variation groups: i.e. colour, size
var $variation_groups;
var $variation_group_count = 0;
var $current_variation_group = -1;
var $variation_group;
// for getting the product price
var $first_variations;
//variations inside variation groups: i.e. ( red, green, blue ) or ( S, M, L, XL )
var $variations;
var $variation_count = 0;
var $current_variation = -1;
var $variation;
const VARIATIONS_BEING_USED_OPTION_NAME = 'wpsc_variations_are_being_used';
static function variations_are_being_used() {
// variations are always enabled on the back-end (admin), for the user facing site we only enable variations
// if there are variation terms saved by the administrator
if ( is_admin() ) {
$variations_are_being_used = true;
} else {
$variations_are_being_used = intval( get_option( self::VARIATIONS_BEING_USED_OPTION_NAME, 1 ) );
}
return (bool) $variations_are_being_used;
}
function __construct( $product_id ) {
global $wpdb;
if ( self::variations_are_being_used() ) {
$product_terms = wpsc_get_product_terms( $product_id, 'wpsc-variation' );
$product_terms = wpsc_get_terms_variation_sort_filter( $product_terms );
} else {
$product_terms = array();
}
$this->variation_groups = array();
$this->first_variations = array();
$this->all_associated_variations = array();
foreach ( $product_terms as $product_term ) {
if ( $product_term->parent > 0 )
$this->all_associated_variations[$product_term->parent][] = $product_term;
else
$this->variation_groups[] = $product_term;
}
// Sort variation orders
foreach ( $this->all_associated_variations as $variation_set => &$terms ) {
$terms = wpsc_get_terms_variation_sort_filter( $terms );
array_unshift(
$this->all_associated_variations[$variation_set], (object) array(
'term_id' => 0,
'name' => __( '-- Please Select --', 'wpsc' ),
)
);
}
// Filters to hook into variations to sort etc.
$this->variation_groups = apply_filters( 'wpsc_variation_groups', $this->variation_groups, $product_id );
$this->all_associated_variations = apply_filters( 'wpsc_all_associated_variations', $this->all_associated_variations, $this->variation_groups, $product_id );
//the parent_id is the variation group id we need to use this to alter the object ( variants )
// inside each of these arrays
$parent_ids = array_keys( $this->all_associated_variations );
foreach ( (array) $parent_ids as $parent_id ) {
//sort the variants by their term_order which is the array key
ksort( $this->all_associated_variations[$parent_id] );
//once sorted renumber the array keys back from 0
$this->all_associated_variations[$parent_id] = array_values( $this->all_associated_variations[$parent_id] );
}
foreach ( (array) $this->variation_groups as $variation_group ) {
$variation_id = $variation_group->term_id;
$this->first_variations[] = $this->all_associated_variations[$variation_id][0]->term_id;
}
$this->variation_group_count = count( $this->variation_groups );
}
/*
* ( Variation Group and Variation ) Loop Code Starts here
*/
function get_variation_groups() {
global $wpdb;
$this->variation_group_count = count( $this->variation_groups );
$this->get_first_variations();
}
function next_variation_group() {
$this->current_variation_group++;
// make sure we don't walk off the end of the variation group array
if ( $this->current_variation_group < count( $this->variation_groups ) ) {
$this->variation_group = $this->variation_groups[ $this->current_variation_group ];
} else {
$this->variation_group = array();
}
return $this->variation_group;
}
function the_variation_group() {
$this->variation_group = $this->next_variation_group();
$this->get_variations();
}
function have_variation_groups() {
if ( self::variations_are_being_used() ) {
if ( $this->current_variation_group + 1 < $this->variation_group_count ) {
return true;
} else if ( $this->current_variation_group + 1 == $this->variation_group_count && $this->variation_group_count > 0 ) {
$this->rewind_variation_groups();
}
}
return false;
}
function rewind_variation_groups() {
$this->current_variation_group = -1;
if ( $this->variation_group_count > 0 ) {
$this->variation_group = $this->variation_groups[0];
}
}
function get_first_variations() {
return null;
}
function get_variations() {
// check to be sure the variations we are accessing exist in the variations array
if ( isset( $this->all_associated_variations[$this->variation_group->term_id] ) ) {
$this->variations = $this->all_associated_variations[ $this->variation_group->term_id ];
} else {
$this->variations = array();
}
$this->variation_count = count( $this->variations );
}
function next_variation() {
$this->current_variation++;
// check to make sure we don't access off the end of the variation array
if ( $this->current_variation < $this->variation_count ) {
$this->variation = $this->variations[ $this->current_variation ];
} else {
$this->variation = false;
}
return $this->variation;
}
function the_variation() {
$this->variation = $this->next_variation();
}
function have_variations() {
if ( self::variations_are_being_used() ) {
if ( $this->current_variation + 1 < $this->variation_count ) {
return true;
} else if ( $this->current_variation + 1 == $this->variation_count && $this->variation_count > 0 ) {
// Do some cleaning up after the loop,
$this->rewind_variations();
}
}
return false;
}
function rewind_variations() {
$this->current_variation = -1;
if ( $this->variation_count > 0 ) {
$this->variation = $this->variations[0];
}
}
}
function wpsc_get_child_object_in_select_terms( $parent_id, $terms, $taxonomy ) {
global $wpdb;
$sql = $wpdb->prepare(
'SELECT tr.`object_id`
FROM `'.$wpdb->term_relationships.'` AS tr
LEFT JOIN `'.$wpdb->posts.'` AS posts
ON posts.`ID` = tr.`object_id`
WHERE tr.`term_taxonomy_id` IN ( '.implode( ',', esc_sql( $terms ) ).' ) and posts.`post_parent` = %d', $parent_id
);
$products = $wpdb->get_col( $sql );
return $products;
}
/**
* wpsc_get_child_objects_in_term function.
* gets the
*
* @access public
* @param int $parent_id
* @param int|array of int $terms
* @param int|array taxonomiy id(s) ti look for
* @param array $args additional arguments to query against
* @return boolean|int|array result false if product not found, a single product id when
* one id found, or an array of product ids if more than one found
*/
function wpsc_get_child_object_in_terms( $parent_id, $terms, $taxonomies = 'wpsc-variation', $args = array() ) {
$parent_id = absint( $parent_id );
if ( ! is_array( $terms ) )
$terms = array( $terms );
if ( ! is_array( $taxonomies ) )
$taxonomies = array( $taxonomies );
foreach ( $taxonomies as $taxonomy ) {
if ( ! taxonomy_exists( $taxonomy ) )
return new WP_Error( 'invalid_taxonomy', __( 'Invalid Taxonomy', 'wpsc' ) );
}
$defaults = array(
'post_type' => 'wpsc-product',
'post_status' => 'inherit',
'posts_per_page' => 1,
'post_parent' => $parent_id,
);
$args = wp_parse_args( $args, $defaults );
$terms = array_map( 'intval', $terms );
$tax_query = array( 'relation' => 'AND' );
foreach ( $terms as $term_index => $term_id ) {
$taxonomy = isset( $taxonomies[ $term_index ] ) ? $taxonomies[ $term_index ] : 'wpsc-variation';
$tax_query[] = array( 'taxonomy' => $taxonomy, 'field' => 'id', 'terms' => array( $term_id ), 'operator' => 'IN' );
}
$args['tax_query'] = $tax_query;
$children = get_posts( $args );
$child_id = ! empty( $children ) ? $children[0]->ID : false;
// return false if product not found, a single product id if one id found, or an array of ids if many found
if ( empty( $children ) ) {
$result = false;
} elseif ( count( $children ) == 1 ) {
$result = $children[0]->ID;
} else {
$result = array();
foreach ( $children as $child ) {
$result[] = $child->ID;
}
}
return $result;
}
/**
* wpsc_get_child_objects_in_term function.
* gets the
*
* @access public
* @param mixed $parent_id
* @param mixed $terms
* @param mixed $taxonomies
* @param array $args. ( default: array() )
* @return void
*/
function wpsc_get_child_object_in_terms_var( $parent_id, $terms, $taxonomies, $args = array() ) {
global $wpdb, $current_version_number;
$wpdb->show_errors = true;
$parent_id = absint( $parent_id );
if ( !is_array( $terms ) )
$terms = array( $terms );
if ( !is_array( $taxonomies ) )
$taxonomies = array( $taxonomies );
foreach ( ( array ) $taxonomies as $taxonomy ) {
if ( $current_version_number < 3.8 ) {
if ( ! taxonomy_exists( $taxonomy ) )
return new WP_Error( 'invalid_taxonomy', __( 'Invalid Taxonomy', 'wpsc' ) );
} else {
if ( !taxonomy_exists( $taxonomy ) )
return new WP_Error( 'invalid_taxonomy', __( 'Invalid Taxonomy', 'wpsc' ) );
}
}
$defaults = array( 'order' => 'ASC' );
$args = wp_parse_args( $args, $defaults );
extract( $args, EXTR_SKIP );
$order = ( 'desc' == strtolower( $order ) ) ? 'DESC' : 'ASC';
$terms = array_map( 'intval', $terms );
$taxonomies = "'" . implode( "', '", $taxonomies ) . "'";
$terms = "'" . implode( "', '", $terms ) . "'";
// This SQL statement finds the item associated with all variations in the selected combination that is a child of the target product
$object_sql = "SELECT tr.object_id
FROM {$wpdb->term_relationships} AS tr
INNER JOIN {$wpdb->posts} AS posts
ON posts.ID = tr.object_id
INNER JOIN {$wpdb->term_taxonomy} AS tt
ON tr.term_taxonomy_id = tt.term_taxonomy_id
WHERE posts.post_parent = {$parent_id}
AND tt.taxonomy IN ( {$taxonomies} )
AND tt.term_id IN ( {$terms} )
AND tt.parent > 0
GROUP BY tr.object_id";
$object_ids = $wpdb->get_results( $object_sql, ARRAY_A );
if ( count( $object_ids ) > 0 ) {
return $object_ids;
} else {
return false;
}
}
/*
* Remember if variations are being used for products. If not the variation class can skip many requests
* to the database when servicing user requests. Although the transactions are fast when there aren't
* any variation, the number of requests is significant, and the results are not cached.
*/
if ( is_admin() ) {
function _wpsc_remember_if_taxonomy_terms_are_being_used() {
// we are going to look for variations that are assigned to products, if they exist we remember that
// variations are being used
$terms = get_terms( 'wpsc-variation' );
$new_variations_are_being_used = false;
if ( ! is_wp_error( $terms ) ) {
if ( ! empty( $terms ) ) {
$new_variations_are_being_used = true;
}
}
$old_variations_being_used = (bool) intval( get_option( wpsc_variations::VARIATIONS_BEING_USED_OPTION_NAME, true ) );
if ( $old_variations_being_used != $new_variations_are_being_used ) {
delete_option( wpsc_variations::VARIATIONS_BEING_USED_OPTION_NAME );
add_option( wpsc_variations::VARIATIONS_BEING_USED_OPTION_NAME, $new_variations_are_being_used, null, true );
}
}
add_action( 'shutdown', '_wpsc_remember_if_taxonomy_terms_are_being_used' );
}