-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathgpi-inventory-shortcode.php
234 lines (187 loc) · 7.77 KB
/
gpi-inventory-shortcode.php
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
<?php
/**
* Gravity Perks // Inventory // Inventory Shortcode
* https://gravitywiz.com/documentation/gravity-forms-inventory/
*
* Instruction Video: https://www.loom.com/share/9d1897075b7b435389479d4f17fc6807
*
* Update "123" to your form ID and "4" to your field ID with inventory.
*
* `[gravityforms action="inventory" id="123" field="4"]`
*
* If using a field with scopes, you may provide the scope values in a comma-delimited list:
*
* `[gravityforms action="inventory" id="123" field="4" scope_values="Scope Value,Another Scope Value"]`
*
* This snippet requires GP Inventory 1.0-beta-1.7 or newer.
*
* @todo
* - Add support for excluding field parameter and showing a consolidated list of all inventories.
*/
add_filter( 'gform_shortcode_inventory', 'gpi_inventory_shortcode', 10, 3 );
function gpi_inventory_shortcode( $output, $atts, $content ) {
if ( ! is_callable( 'gp_inventory' ) ) {
return $output;
}
$atts = shortcode_atts( array(
'id' => false,
'field' => false,
'scope_values' => false,
), $atts, 'gpi_inventory' );
if ( empty( $atts['id'] ) || empty( $atts['field'] ) ) {
return $content;
}
$form = GFAPI::get_form( $atts['id'] );
/* Ensure choices populated by Populate Anything are loaded in. */
if ( function_exists( 'gp_populate_anything' ) && is_callable( array( gp_populate_anything(), 'modify_admin_field_choices' ) ) ) {
$form = gp_populate_anything()->modify_admin_field_choices( $form );
}
$field = GFAPI::get_field( $form, $atts['field'] );
if ( ! $field ) {
return $content;
}
/**
* Some scopes have infinite values (i.e. Date fields). Use the * scope value to look up submitted scope values and
* display the content template for each. Default template when using the * scope is:
*
* {scope}: {count}
*
* NOTE: This only works with inventories with a single scope. Will continue exploring this in the future.
*/
if ( $atts['scope_values'] && $atts['scope_values'] === '*' ) {
global $wpdb;
$resource_field_id = reset( $field->gpiResourcePropertyMap );
$sql = gf_apply_filters( array( 'gpis_scopes_sql', $form['id'], $resource_field_id ), $wpdb->prepare( "SELECT DISTINCT meta_value FROM {$wpdb->prefix}gf_entry_meta WHERE form_id = %d AND meta_key = %d", $form['id'], $resource_field_id ), $form, $field, $resource_field_id );
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$items = $wpdb->get_results( $sql );
if ( empty( $items ) ) {
return $content;
}
$output = array();
$is_choice_field = ! empty( $field->choices );
if ( ! $content ) {
if ( $is_choice_field ) {
$content = '{label}: {count}';
} else {
$content = '{scope}: {count}';
}
}
foreach ( $items as $item ) {
$atts['scope_values'] = $item->meta_value;
$scope_display_value = gf_apply_filters( array( 'gpis_scope_display_value', $form['id'], $resource_field_id ), $item->meta_value, $field, $resource_field_id, $atts );
$item_output = '';
if ( $is_choice_field ) {
$item_output = $scope_display_value;
}
$item_output .= str_replace( '{scope}', $scope_display_value, gpi_inventory_shortcode( null, $atts, $content ) );
$output[] = $item_output;
}
$label = $field->get_field_label( false, '' );
$output = sprintf(
'<ul class="gpi-inventory-list gpi-inventory-list-%d-%d"><li>%s</li></ul>',
$form['id'], $field->id, implode( '</li><li>', $output )
);
return $output;
}
/**
* Callback for mapping property values from the scope_values attribute to the gpi_property_map_values filter to
* get the current inventory for scoped inventory fields.
*
* @param $property_values
*
* @return mixed
*/
$map_property_values = function ( $property_values ) use ( $atts ) {
$scope_values = explode( ',', $atts['scope_values'] );
if ( empty( $scope_values ) || empty( array_filter( $scope_values ) ) ) {
return $property_values;
}
/* Take the order of property value keys and map them according to the order of the values in scope_values
as the order of the properties should never change. */
$property_value_keys = array_keys( $property_values );
foreach ( $scope_values as $scope_value_index => $scope_value ) {
if ( ! isset( $property_value_keys [ $scope_value_index ] ) ) {
continue;
}
$property_id = $property_value_keys [ $scope_value_index ];
$property_values [ $property_id ] = $scope_value;
}
return $property_values;
};
$items = array();
add_filter( 'gpi_property_map_values_' . $form['id'] . '_' . $field->id, $map_property_values );
if ( is_array( $field->choices ) ) {
$field->gpiShowAvailableInventory = true;
// Delete choice count cache before and after getting choice counts to prevent scopes from interfering.
$cache_key = 'gpi_choice_counts_' . $form['id'] . '_' . $field->id;
GFCache::delete( $cache_key );
if ( $content ) {
$counts = gp_inventory_type_choices()->get_choice_counts( $form['id'], $field );
foreach ( $field->choices as $choice ) {
$limit = (int) $choice['inventory_limit'];
$count = (int) rgar( $counts, $choice['value'] );
$available = $limit - $count;
$items[] = gpis_get_item_markup( $content, array(
'limit' => $limit,
'count' => $count,
'available' => $available,
'label' => $choice['text'],
'value' => $choice['value'],
) );
}
} else {
$choices = gp_inventory_type_choices()->apply_choice_limits( $field->choices, $field, $form );
foreach ( $choices as $choice ) {
$items[] = $choice['text'];
}
}
GFCache::delete( $cache_key );
$output = sprintf(
'<ul class="gpi-inventory-list gpi-inventory-list-%d-%d"><li>%s</li></ul>',
$form['id'], $field->id, implode( '</li><li>', $items )
);
} else {
if ( gp_inventory_type_advanced()->is_applicable_field( $field ) ) {
$available = gp_inventory_type_advanced()->get_available_stock( $field );
$limit = gp_inventory_type_advanced()->get_stock_quantity( $field );
$count = gp_inventory_type_advanced()->get_claimed_inventory( $field );
/**
* Temporarily remove filter for resources to get the inventory count specific to the field rather than the
* count of all fields using the same resource.
*/
remove_filter( 'gpi_query', array( gp_inventory_type_advanced(), 'resource_and_properties' ), 9 );
$count_current_field = gp_inventory_type_simple()->get_claimed_inventory( $field );
add_filter( 'gpi_query', array( gp_inventory_type_advanced(), 'resource_and_properties' ), 9, 2 );
} else {
$available = gp_inventory_type_simple()->get_available_stock( $field );
$limit = gp_inventory_type_simple()->get_stock_quantity( $field );
$count = gp_inventory_type_simple()->get_claimed_inventory( $field );
$count_current_field = $count;
}
$label = $field->get_field_label( false, '' );
if ( $content ) {
$output .= gpis_get_item_markup( $content, array(
'limit' => $limit,
'count' => $count,
'count_current_field' => $count_current_field,
'available' => $available,
'label' => $label,
'value' => '',
) );
} else {
$output .= $label . ': ' . $available;
}
}
remove_filter( 'gpi_property_map_values_' . $form['id'] . '_' . $field->id, $map_property_values );
return $output;
}
function gpis_get_item_markup( $template, $args ) {
$markup = $template;
$markup = str_replace( '{limit}', $args['limit'], $markup );
$markup = str_replace( '{count}', $args['count'], $markup );
$markup = str_replace( '{count_current_field}', $args['count_current_field'], $markup );
$markup = str_replace( '{available}', $args['available'], $markup );
$markup = str_replace( '{label}', $args['label'], $markup );
$markup = str_replace( '{value}', $args['value'], $markup );
return $markup;
}