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
|
<?php /** * Traits for handling custom product attributes and their terms. */
namespace Automattic\WooCommerce\Admin\API;
defined( 'ABSPATH' ) || exit;
/** * CustomAttributeTraits class. * * @internal */ trait CustomAttributeTraits { /** * Get a single attribute by its slug. * * @internal * @param string $slug The attribute slug. * @return WP_Error|object The matching attribute object or WP_Error if not found. */ public function get_custom_attribute_by_slug( $slug ) { $matching_attributes = $this->get_custom_attributes( array( 'slug' => $slug ) );
if ( empty( $matching_attributes ) ) { return new \WP_Error( 'woocommerce_rest_product_attribute_not_found', __( 'No product attribute with that slug was found.', 'woocommerce' ), array( 'status' => 404 ) ); }
foreach ( $matching_attributes as $attribute_key => $attribute_value ) { return array( $attribute_key => $attribute_value ); } }
/** * Query custom attributes by name or slug. * * @param string $args Search arguments, either name or slug. * @return array Matching attributes, formatted for response. */ protected function get_custom_attributes( $args ) { global $wpdb;
$args = wp_parse_args( $args, array( 'name' => '', 'slug' => '', ) );
if ( empty( $args['name'] ) && empty( $args['slug'] ) ) { return array(); }
$mode = $args['name'] ? 'name' : 'slug';
if ( 'name' === $mode ) { $name = $args['name']; // Get as close as we can to matching the name property of custom attributes using SQL. $like = '%"name";s:%:"%' . $wpdb->esc_like( $name ) . '%"%'; } else { $slug = sanitize_title_for_query( $args['slug'] ); // Get as close as we can to matching the slug property of custom attributes using SQL. $like = '%s:' . strlen( $slug ) . ':"' . $slug . '";a:6:{%'; }
// Find all serialized product attributes with names like the search string. $query_results = $wpdb->get_results( $wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_product_attributes' AND meta_value LIKE %s LIMIT 100", $like ), ARRAY_A );
$custom_attributes = array();
foreach ( $query_results as $raw_product_attributes ) {
$meta_attributes = maybe_unserialize( $raw_product_attributes['meta_value'] );
if ( empty( $meta_attributes ) || ! is_array( $meta_attributes ) ) { continue; }
foreach ( $meta_attributes as $meta_attribute_key => $meta_attribute_value ) { $meta_value = array_merge( array( 'name' => '', 'is_taxonomy' => 0, ), (array) $meta_attribute_value );
// Skip non-custom attributes. if ( ! empty( $meta_value['is_taxonomy'] ) ) { continue; }
// Skip custom attributes that didn't match the query. // (There can be any number of attributes in the meta value). if ( ( 'name' === $mode ) && ( false === stripos( $meta_value['name'], $name ) ) ) { continue; }
if ( ( 'slug' === $mode ) && ( $meta_attribute_key !== $slug ) ) { continue; }
// Combine all values when there are multiple matching custom attributes. if ( isset( $custom_attributes[ $meta_attribute_key ] ) ) { $custom_attributes[ $meta_attribute_key ]['value'] .= ' ' . WC_DELIMITER . ' ' . $meta_value['value']; } else { $custom_attributes[ $meta_attribute_key ] = $meta_attribute_value; } } }
return $custom_attributes; } }
|