Completed
Push — master ( 09c0c8...f70f12 )
by Justin
14:47 queued 05:47
created

product-template.php ➔ wpsc_product_is_variation()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 7
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 13
rs 9.2
1
<?php
2
3
/**
4
 * WP eCommerce product functions and product utility function.
5
 *
6
 * This is the wpsc equivalent of post-template.php
7
 *
8
 * @package wp-e-commerce
9
 * @since 3.8
10
 * @subpackage wpsc-template-functions
11
 */
12
13
/**
14
 * Get The Product Excerpt
15
 *
16
 * WPEC uses the excerpt field in the database to store additional product details.
17
 * This means that where themes output the excerpt (like in search results) the product's
18
 * additional details are displayed which is not the expected behaviour.
19
 *
20
 * This function filters the excerpt early and returns an empty string which forces the default
21
 * WordPress behaviour to use a truncated version of the content instead.
22
 *
23
 * Always use wpsc_the_product_additional_description() to return the addition product description.
24
 *
25
 * @since  3.8.13
26
 *
27
 * @param   string  $excerpt  The post excerpt (which for products is the additional description).
28
 * @return  string            The empty excerpt.
29
 */
30
function wpsc_get_the_excerpt( $excerpt ) {
31
	if ( 'wpsc-product' == get_post_type() )
32
		return '';
33
	return $excerpt;
34
}
35
36
add_filter( 'get_the_excerpt', 'wpsc_get_the_excerpt', 2 );
37
38
/**
39
 * WPSC Product Variation Price From
40
 * Gets the formatted lowest price of a product's variations.
41
 *
42
 * @since  3.8.10
43
 *
44
 * @param  $product_id  (int)       Product ID
45
 * @param  $args        (array)     Array of options
46
 * @return              (string)    Number formatted price
47
 *
48
 * @uses   apply_filters()          Calls 'wpsc_do_convert_price' passing price and product ID.
49
 * @uses   wpsc_currency_display()  Passing price and args.
50
 */
51
function wpsc_product_variation_price_from( $product_id, $args = null ) {
52
	global $wpdb;
53
54
	$args = wp_parse_args( $args, array(
55
		'from_text'         => false,
56
		'no_decimals'       => false,
57
		'only_normal_price' => false,
58
		'only_in_stock'     => false
59
	) );
60
61
	static $price_data = array();
62
63
	/* @todo: Rewrite using proper WP_Query */
64
	if ( isset( $price_data[ $product_id ] ) ) {
65
		$results = $price_data[ $product_id ];
66
	} else {
67
68
		$stock_sql = '';
69
70
		if ( $args['only_in_stock'] ) {
71
			$stock_sql = "INNER JOIN {$wpdb->postmeta} AS pm3 ON pm3.post_id = p.id AND pm3.meta_key = '_wpsc_stock' AND pm3.meta_value != '0'";
72
		}
73
74
		$sql = $wpdb->prepare( "
75
			SELECT pm.meta_value AS price, pm2.meta_value AS special_price
76
			FROM {$wpdb->posts} AS p
77
			INNER JOIN {$wpdb->postmeta} AS pm ON pm.post_id = p.id AND pm.meta_key = '_wpsc_price'
78
			LEFT JOIN {$wpdb->postmeta} AS pm2 ON pm2.post_id = p.id AND pm2.meta_key = '_wpsc_special_price'
79
			$stock_sql
80
			WHERE p.post_type = 'wpsc-product' AND p.post_parent = %d AND p.post_status IN ( 'publish', 'inherit' )
81
		", $product_id );
82
83
		$results                   = $wpdb->get_results( $sql );
84
		$price_data[ $product_id ] = $results;
85
	}
86
87
	$prices = array();
88
89
	foreach ( $results as $row ) {
90
91
		$price = (float) $row->price;
92
93
		if ( ! $args['only_normal_price'] ) {
94
95
			$special_price = (float) $row->special_price;
96
97
			if ( $special_price != 0 && $special_price < $price ) {
98
				$price = $special_price;
99
			}
100
		}
101
102
		if ( $args['no_decimals'] ) {
103
			$price = explode( '.', $price );
104
			$price = array_shift( $price );
105
		}
106
107
		$prices[] = $price;
108
	}
109
110
	sort( $prices );
111
112
	if ( empty( $prices ) ) {
113
		$prices[] = 0;
114
	}
115
116
	$price = apply_filters( 'wpsc_do_convert_price', $prices[0], $product_id );
117
118
	$price_args = array(
119
		'display_as_html'       => false,
120
		'display_decimal_point' => ! $args['no_decimals']
121
	);
122
123
	$price = wpsc_currency_display( $price, $price_args );
124
125
	if ( isset( $prices[0] ) && $prices[0] == $prices[count( $prices ) - 1] ) {
126
		$args['from_text'] = false;
127
	}
128
129
	if ( $args['from_text'] ){
130
		$price = sprintf( $args['from_text'], $price );
131
	}
132
133
	return $price;
134
}
135
136
/**
137
 * wpsc normal product price function
138
 * TODO determine why this function is here
139
 * @return string - returns some form of product price
140
 */
141
function wpsc_product_normal_price() {
142
	return wpsc_the_product_price( false, true );
143
}
144
145
function wpsc_calculate_price( $product_id, $variations = false, $special = true ) {
146
	global $wpdb;
147
148
	$p_id = $product_id;
149
	if ( ! empty( $variations ) )
150
		$product_id = wpsc_get_child_object_in_terms( $product_id, $variations, 'wpsc-variation' );
151
	elseif ( !$product_id )
152
		$product_id = get_the_ID();
153
154
	if( ! $product_id && ! empty( $variations ) ){
155
		$product_ids = wpsc_get_child_object_in_select_terms( $p_id, $variations, 'wpsc_variation' );
156
		$sql = "SELECT `post_id` FROM ".$wpdb->postmeta." WHERE `meta_key` = '_wpsc_stock' AND `meta_value` != '0' AND `post_id` IN (".implode(',' , $product_ids).")";
157
		$stock_available = $wpdb->get_col($sql);
158
		$sql = "SELECT `post_id` FROM ".$wpdb->postmeta." WHERE `meta_key` = '_wpsc_price' AND `post_id` IN (".implode(',',$stock_available).") ORDER BY `meta_value` ASC LIMIT 1";
159
		$product_id = $wpdb->get_var($sql);
160
	}
161
162
	if ( $special ) {
163
		$full_price = get_post_meta( $product_id, '_wpsc_price', true );
164
		$special_price = get_post_meta( $product_id, '_wpsc_special_price', true );
165
166
		$price = $full_price;
167
		if ( ($full_price > $special_price) && ($special_price > 0) ) {
168
			$price = $special_price;
169
		}
170
	} else {
171
		$price = get_post_meta( $product_id, '_wpsc_price', true );
172
	}
173
	$price = apply_filters( 'wpsc_price', $price, $product_id );
174
175
	return $price;
176
}
177
178
/**
179
 * Get The Product Thumbnail ID
180
 *
181
 * If no post thumbnail is set, this will return the ID of the first image
182
 * associated with a product.
183
 *
184
 * @param  int  $product_id  Product ID
185
 * @return int               Product thumbnail ID
186
 */
187
/**
188
 * Get The Product Thumbnail ID
189
 *
190
 * If no post thumbnail is set, this will return the ID of the first image
191
 * associated with a product. If no image is found and the product is a variation it will
192
 * then try getting the parent product's image instead.
193
 *
194
 * @param  int  $product_id  Product ID
195
 * @return int               Product thumbnail ID
196
 */
197
function wpsc_the_product_thumbnail_id( $product_id ) {
198
	$thumbnail_id = null;
199
200
	// Use product thumbnail...
201
	if ( has_post_thumbnail( $product_id ) ) {
202
		$thumbnail_id = get_post_thumbnail_id( $product_id  );
203
	} else {
204
		// ... or get first image in the product gallery
205
		$attached_images = wpsc_get_product_gallery( $product_id );
206
		if ( ! empty( $attached_images ) )
207
			$thumbnail_id = $attached_images[0]->ID;
208
	}
209
	return apply_filters( 'wpsc_the_product_thumbnail_id', $thumbnail_id, $product_id );
210
}
211
212
/**
213
* Regenerate size metadata of a thumbnail in case it's missing.
214
*
215
* @since  3.8.9
216
* @access private
217
*/
218
function _wpsc_regenerate_thumbnail_size( $thumbnail_id, $size ) {
219
	// regenerate size metadata in case it's missing
220
	require_once( ABSPATH . 'wp-admin/includes/image.php' );
221
222
	if ( ! $metadata = wp_get_attachment_metadata( $thumbnail_id ) ) {
223
		$metadata = array();
224
	}
225
226
	if ( empty( $metadata['sizes'] ) ) {
227
		$metadata['sizes'] = array();
228
	}
229
230
	$file      = get_attached_file( $thumbnail_id );
231
	$generated = wp_generate_attachment_metadata( $thumbnail_id, $file );
232
233
	if ( empty( $generated ) ) {
234
		return false;
235
	}
236
237
	if ( empty( $generated['sizes'] ) ) {
238
		$generated['sizes'] = array();
239
	}
240
241
	$metadata['sizes'] = array_merge( $metadata['sizes'], $generated['sizes'] );
242
	wp_update_attachment_metadata( $thumbnail_id, $metadata );
243
244
	return true;
245
}
246
247
function wpsc_get_downloadable_file( $file_id ) {
248
	return get_post( $file_id );
249
}
250
251
/**
252
* wpsc_product_has_children function
253
* Checks whether a product has variations or not
254
*
255
* @return boolean true if product does have variations, false otherwise
256
*/
257
function wpsc_product_has_children( $id, $exclude_unpublished = true ){
0 ignored issues
show
Unused Code introduced by
The parameter $exclude_unpublished is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
258
	return wpsc_product_has_variations( $id );
259
}
260
261
/**
262
 * Check whether a product has variations or not.
263
 *
264
 * @since  3.8.9
265
 * @access public
266
 * @param  int  $id Product ID. Defaults to 0 for current post in the loop.
267
 * @return bool     true if product has variations.
268
 */
269
function wpsc_product_has_variations( $id = 0 ) {
270
	static $has_variations = array();
271
272
	if ( ! $id )
273
		$id = get_the_ID();
274
275
	if ( ! isset( $has_variations[ $id ] ) ) {
276
		$args = array(
277
			'post_parent' => $id,
278
			'post_type'   => 'wpsc-product',
279
			'post_status' => array( 'inherit', 'publish' ),
280
		);
281
		$children = get_children( $args );
282
283
		$has_variations[$id] = ! empty( $children );
284
	}
285
286
	return $has_variations[$id];
287
}
288
289
/**
290
* Check whether or not a product is a variation.
291
*
292
* @param int $product_id Product ID to check.
293
* @since 4.0.0
294
* @return mixed Returns parent product ID if product is a variation, false otherwise.
295
*/
296
function wpsc_product_is_variation( $product_id ) {
297
    $product = get_post( $product_id );
298
    
299
    if ( ! is_a( $product, 'WP_Post' ) ) {
300
        return false;
301
    }
302
    
303
    if ( 'wpsc-product' !== $product->post_type || ! $product->post_parent ) {
304
        return false;
305
    }
306
    
307
    return $product->post_parent;
308
}
309
310
/**
311
 * Maybe Get The Parent Product Thumbnail ID
312
 *
313
 * If no thumbnail is found and the product is a variation it will
314
 * then try getting the parent product's image instead.
315
 *
316
 * @param  int  $thumbnail_id  Thumbnail ID
317
 * @param  int  $product_id    Product ID
318
 * @return int                 Product thumbnail ID
319
 *
320
 * @uses   wpsc_the_product_thumbnail_id()  Get the product thumbnail ID
321
 */
322
function wpsc_maybe_get_the_parent_product_thumbnail_id( $thumbnail_id, $product_id ) {
323
324
	if ( ! $thumbnail_id ) {
325
		$product = get_post( $product_id );
326
327
		if ( is_a( $product, 'WP_Post' ) && $product->post_parent > 0 ) {
328
			$thumbnail_id = wpsc_the_product_thumbnail_id( $product->post_parent );
329
		}
330
	}
331
332
	return $thumbnail_id;
333
}
334
335
add_filter( 'wpsc_the_product_thumbnail_id', 'wpsc_maybe_get_the_parent_product_thumbnail_id', 10, 2 );
336
337
function wpsc_get_product_gallery( $id ) {
338
	$ids = get_post_meta( $id, '_wpsc_product_gallery', true );
339
340
	$args = array(
341
		'nopaging' => true,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set nopaging to true ever.
Loading history...
342
		'post_status' => 'all',
343
		'post_type' => 'attachment'
344
	);
345
346
	// By default, when the user took no action to select product gallery, all the
347
	// images attached to a product are treated as gallery images. If $ids is not
348
	// empty, however, it means the user has made some selection for the product
349
	// gallery, we should respect that selection.
350
	if ( empty( $ids ) ) {
351
		$args['post_parent'] = $id;
352
		$args['orderby'] = 'menu_order';
353
		$args['order'] = 'ASC';
354
	} else {
355
		if ( ! is_array( $ids ) )
356
			$ids = array();
357
358
		if ( has_post_thumbnail( $id ) ) {
359
			$thumb_id = get_post_thumbnail_id( $id );
360
			if ( ! in_array( $thumb_id, $ids ) )
361
				array_unshift( $ids, $thumb_id );
362
		}
363
364
		if ( ! is_array( $ids ) || empty( $ids ) )
365
			return array();
366
367
		$args['post__in'] = $ids;
368
		$args['orderby'] = 'post__in';
369
	}
370
371
	return get_posts( $args );
372
}
373
374
function wpsc_set_product_gallery( $id, $attachments ) {
375
	$attachment_ids = array();
376
	foreach ( $attachments as $attachment ) {
377
		if ( is_object( $attachment ) )
378
			$attachment_ids[] = $attachment->ID;
379
		elseif ( is_numeric( $attachment ) )
380
			$attachment_ids[] = absint( $attachment );
381
	}
382
383
	return update_post_meta( $id, '_wpsc_product_gallery', $attachment_ids );
384
}
385