-
Notifications
You must be signed in to change notification settings - Fork 4
/
uc_varprice.module
501 lines (440 loc) · 18.3 KB
/
uc_varprice.module
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
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
<?php
/**
* @file
* Defines a product feature to turn any product into a variable priced product.
*/
/**
* Implements hook_theme().
*/
function uc_varprice_theme() {
return array(
'varprice_qty' => array(
'render element' => 'form',
),
);
}
/**
* Implements hook_config_info().
*/
function uc_varprice_config_info() {
$prefixes['uc_varprice.settings'] = array(
'label' => t('Variable Price settings'),
'group' => t('Configuration'),
);
return $prefixes;
}
/**
* Implements hook_form_alter().
*
* Summary of alterations:
* 1) Alters the product feature add form to restrict multiple Variable Price
* features from being added to a single product.
* 2) Alters the add to cart form for variable priced products.
* 3) Disable the appropriate Qty. fields on the cart view form.
* 4) Alter the product class form to set default donations.
*/
function uc_varprice_form_alter(&$form, &$form_state, $form_id) {
// 1) Alter the product feature add form.
if ($form_id == 'uc_product_feature_add_form') {
// If a Variable Price feature has already been added to this product...
if (db_query("SELECT COUNT(*) FROM {uc_product_features} WHERE nid = :nid AND fid = :fid", array(':nid' => arg(1), ':fid' => 'varprice'))->fetchField()) {
// Remove Variable Price from the available list of features to add.
unset($form['feature']['#options']['varprice']);
}
}
// 2) Alter the add to cart form.
if (strpos($form_id, 'uc_product_add_to_cart_form_') === 0) {
$data = uc_varprice_product_load($form['nid']['#value']);
if ($data) {
$description = array();
if (!empty($data->price_minimum)) {
$description[] = t('Minimum: @price', array('@price' => uc_currency_format($data->price_minimum)));
}
if (!empty($data->price_maximum)) {
$description[] = t('Maximum: @price', array('@price' => uc_currency_format($data->price_maximum)));
}
// Add the amount textfield to the add to cart form.
$config_store = config('uc_store.settings');
$form['varprice'] = array(
'#type' => 'textfield',
'#title' => $data && !empty($data->amount_title) ? $data->amount_title : t('Amount'),
'#description' => implode('<br />', $description),
'#default_value' => $data ? $data->price_default : config_get('uc_varprice.settings', 'uc_varprice_global_default'),
'#size' => 8,
'#weight' => -5,
'#field_prefix' => $config_store->get('uc_sign_after_amount') ? '' : $config_store->get('uc_currency_sign'),
'#field_suffix' => $config_store->get('uc_sign_after_amount') ?$config_store->get('uc_currency_sign') : '',
);
if (!empty($data->add_to_cart_title)) {
$form['actions']['submit']['#value'] = $data->add_to_cart_title;
}
}
}
// 3) Disable the appropriate Qty. fields on the cart view form.
if ($form_id == 'uc_cart_view_form') {
for ($i = 0, $j = count(uc_cart_get_contents()); $i < $j; $i++) {
$data = unserialize($form['items'][$i]['data']['#value']);
// If this item has a quantity restriction on it...
if (isset($data['varprice']) && $data['varprice'] > 0) {
$form['items'][$i]['qty']['#type'] = 'value';
$form['items'][$i]['qty']['#theme'] = 'varprice_qty';
}
}
}
// 4) Alter the product class form to set default donations.
if ($form_id == 'uc_product_class_form') {
// Add some helper JS to the form.
backdrop_add_js(backdrop_get_path('module', 'uc_varprice') . '/uc_varprice.js');
$data = FALSE;
if (!empty($form['pcid']['#value'])) {
$class_defaults = config_get('uc_varprice.settings', 'class_definitions.' . $form['pcid']['#value']);
if (!empty($class_defaults)) {
$data = (object) $class_defaults;
}
}
$form['varprice'] = array(
'#type' => 'fieldset',
'#title' => t('Default Variable Price product feature'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 5,
);
$form['varprice']['default_varprice'] = array(
'#type' => 'checkbox',
'#title' => t('Check this box to add a default product feature to every product of this class using these settings.'),
'#default_value' => $data === FALSE?FALSE : TRUE,
);
$form['varprice'] += _uc_varprice_feature_form($data);
$form['#submit'][] = 'uc_varprice_product_class_submit';
$form['submit']['#weight'] = 10;
}
}
/**
* Submit handler for the product class form for default Variable Price features.
*/
function uc_varprice_product_class_submit($form, &$form_state) {
if ($form_state['values']['default_varprice']) {
$data = array(
'price_default' => $form_state['values']['price_default'],
'price_minimum' => $form_state['values']['price_minimum'],
'price_maximum' => $form_state['values']['price_maximum'],
'override_add_to_cart_title' => $form_state['values']['override_add_to_cart_title'],
'add_to_cart_title' => $form_state['values']['override_add_to_cart_title'] ? $form_state['values']['add_to_cart_title'] : '',
'override_amount_title' => $form_state['values']['override_amount_title'],
'amount_title' => $form_state['values']['override_amount_title'] ? $form_state['values']['amount_title'] : '',
);
config_set('uc_varprice.settings', 'class_definitions.' . $form_state['values']['pcid'], $data);
}
else {
config_clear('uc_varprice.settings', 'class_definitions.' . $form_state['values']['pcid']);
}
}
/**
* Implements hook_node_view().
*
* Summary of alterations:
* 1) Removes price displays from variable priced product nodes.
* 2) Inserts Variable Price product feature on product node creation.
*/
function uc_varprice_node_view($node, $view_mode = 'full') {
// If this node has a variable price product feature...
if (db_query("SELECT pfid FROM {uc_product_features} WHERE fid = :fid AND nid = :nid", array(':fid' => 'varprice', ':nid' => $node->nid))->fetchField()) {
// Hide all the prices from display.
$node->content['cost']['#access'] = FALSE;
$node->content['list_price']['#access'] = FALSE;
$node->content['sell_price']['#access'] = FALSE;
$node->content['display_price']['#access'] = FALSE;
}
}
/**
* Implements hook_node_insert().
*/
function uc_varprice_node_insert($node) {
if (uc_product_is_product($node)) {
$data = config_get('uc_varprice.settings', 'class_definitions.' . $node->type);
// If the product class has a default Variable Price product feature...
if ($data) {
// Prepare the data as if it were from a form submission.
$data['nid'] = $node->nid;
$data['pfid'] = '';
$form_state = array('values' => $data);
// Add the feature to the product by spoofing the normal form submission.
uc_varprice_feature_form_submit(array(), $form_state);
}
}
}
/**
* Implements hook_uc_add_to_cart_data().
*/
function uc_varprice_uc_add_to_cart_data($form_values) {
// Store the customer entered price in the product's data array.
if (!empty($form_values['varprice'])) {
return array('varprice' => $form_values['varprice'], 'uniqid' => uniqid());
}
}
/**
* Implements hook_uc_add_to_cart().
*/
function uc_varprice_uc_add_to_cart($nid, $qty, $data) {
$result = array();
// If there is Variable Price data for this product...
if (isset($data['varprice'])) {
$message = '';
// Load the product feature data.
$vp_data = uc_varprice_product_load($nid);
// Fail if the customer failed to enter a price.
if (empty($data['varprice']) || $data['varprice'] == 0) {
$message = t('You must specify a price.');
}
// Fail if the customer entered a price lower than the minimum.
elseif (!empty($vp_data->price_minimum) && $data['varprice'] < $vp_data->price_minimum) {
$message = t('You must specify an amount greater than or equal to @price.', array('@price' => uc_currency_format($vp_data->price_minimum)));
}
// Fail if the customer entered a price above the maximum.
elseif (!empty($vp_data->price_maximum) && $data['varprice'] > $vp_data->price_maximum) {
$message = t('You must specify an amount less than or equal to @price.', array('@price' => uc_currency_format($vp_data->price_maximum)));
}
// If an error message was set, return the failure notification.
if (!empty($message)) {
return array(array('success' => FALSE, 'message' => $message, 'silent' => FALSE));
}
}
}
/**
* Implements hook_uc_product_alter().
*/
function uc_varprice_uc_product_alter($item) {
// If the product has a variable price set...
if (!empty($item->data['varprice'])) {
// Update the cart item's price to the entered price value.
$item->display_price = $item->price = $item->data['varprice'];
}
}
/**
* Implements hook_uc_product_feature().
*/
function uc_varprice_uc_product_feature() {
$features = array();
$features[] = array(
'id' => 'varprice',
'title' => t('Variable price'),
'callback' => 'uc_varprice_feature_form',
'delete' => 'uc_varprice_feature_delete',
'settings' => 'uc_varprice_settings',
'multiple' => FALSE,
);
return $features;
}
/**
* Adds settings to the product features form for UC Variable Price.
*/
function uc_varprice_settings() {
$form = array();
$config_store = config('uc_store.settings');
$form['uc_varprice_global_default'] = array(
'#title' => t('Global default price'),
'#type' => 'textfield',
'#size' => 8,
'#description' => t('The global default price for variable priced products; may be overridden at the product class or product level.'),
'#default_value' => config_get('uc_varprice.settings', 'uc_varprice_global_default'),
'#field_prefix' => $config_store->get('uc_sign_after_amount') ? '' : $config_store->get('uc_currency_sign'),
'#field_suffix' => $config_store->get('uc_sign_after_amount') ?$config_store->get('uc_currency_sign') : '',
);
return $form;
}
/**
* Settings form for individual Variable Price product features.
*/
function uc_varprice_feature_form($form, &$form_state, $node, $feature) {
// Add some helper JS to the form.
backdrop_add_js(backdrop_get_path('module', 'uc_varprice') . '/uc_varprice.js');
// Load the Variable Price data specific to this product.
if (!empty($feature)) {
$varprice_feature = db_query('SELECT * FROM {uc_varprice_products} WHERE pfid = :pfid', array(':pfid' => $feature['pfid']))->fetchObject();
}
else {
$varprice_feature = new stdClass();
$varprice_feature->pfid = NULL;
$varprice_feature->price_default = config_get('uc_varprice.settings', 'uc_varprice_global_default');
$varprice_feature->price_minimum = '';
$varprice_feature->price_maximum = '';
$varprice_feature->add_to_cart_title = t('Add to cart');
$varprice_feature->amount_title = t('Amount');
}
$form['nid'] = array(
'#type' => 'value',
'#value' => $node->nid,
);
$form['pfid'] = array(
'#type' => 'value',
'#value' => $varprice_feature ? $varprice_feature->pfid : '',
);
$form += _uc_varprice_feature_form($varprice_feature);
return $form;
}
/**
* Feature form
*
* @param object|false $varprice_feature
*/
function _uc_varprice_feature_form($varprice_feature = FALSE) {
$form = array();
$form['prices'] = array(
'#type' => 'fieldset',
'#title' => t('Price settings'),
);
$config_store = config('uc_store.settings');
$form['prices']['price_default'] = array(
'#type' => 'textfield',
'#title' => t('Default price'),
'#size' => 8,
'#description' => t('The default price for this variable priced products.'),
'#default_value' => $varprice_feature ? $varprice_feature->price_default : config_get('uc_varprice.settings', 'uc_varprice_global_default'),
'#field_prefix' => $config_store->get('uc_sign_after_amount') ? '' : $config_store->get('uc_currency_sign'),
'#field_suffix' => $config_store->get('uc_sign_after_amount') ?$config_store->get('uc_currency_sign') : '',
);
$form['prices']['price_minimum'] = array(
'#type' => 'textfield',
'#title' => t('Minimum price'),
'#size' => 8,
'#description' => t('The minimum price required for this product to be added to the cart.<br />Leave blank for no minimum.'),
'#default_value' => $varprice_feature ? $varprice_feature->price_minimum : '',
'#field_prefix' => $config_store->get('uc_sign_after_amount') ? '' : $config_store->get('uc_currency_sign'),
'#field_suffix' => $config_store->get('uc_sign_after_amount') ?$config_store->get('uc_currency_sign') : '',
);
$form['prices']['price_maximum'] = array(
'#type' => 'textfield',
'#title' => t('Maximum price'),
'#size' => 8,
'#description' => t('The maximum price allowed for this product to be added to the cart.<br />Leave blank for no maximum.'),
'#default_value' => $varprice_feature ? $varprice_feature->price_maximum : '',
'#field_prefix' => $config_store->get('uc_sign_after_amount') ? '' : $config_store->get('uc_currency_sign'),
'#field_suffix' => $config_store->get('uc_sign_after_amount') ?$config_store->get('uc_currency_sign') : '',
);
$form['titles'] = array(
'#type' => 'fieldset',
'#title' => t('Add to cart form element titles'),
'#description' => t('Use these settings to adjust the normal titles of add to cart form elements for variable priced products.'),
);
$form['titles']['override_add_to_cart_title'] = array(
'#type' => 'checkbox',
'#title' => t('Override the title of the add to cart button.'),
'#description' => t('Defaults to <em>Add to cart</em>. For multilingual sites, use <a href="!url">String Overrides</a> instead.', array('!url' => url('http://drupal.org/project/stringoverrides', array('absolute' => TRUE)))),
'#default_value' => $varprice_feature ? !empty($varprice_feature->add_to_cart_title) : FALSE,
'#attributes' => array('class' => array('override-checkbox')),
);
$form['titles']['add_to_cart_title'] = array(
'#type' => 'textfield',
'#title' => t('Add to cart button title'),
'#default_value' => $varprice_feature && !empty($varprice_feature->add_to_cart_title) ? $varprice_feature->add_to_cart_title : t('Add to cart'),
);
$form['titles']['override_amount_title'] = array(
'#type' => 'checkbox',
'#title' => t('Override the title of the amount field for the price on the add to cart form.'),
'#description' => t('Defaults to <em>Amount</em>. For multilingual sites, use <a href="!url">String Overrides</a> instead.', array('!url' => url('http://drupal.org/project/stringoverrides', array('absolute' => TRUE)))),
'#default_value' => $varprice_feature ? !empty($varprice_feature->amount_title) : FALSE,
'#attributes' => array('class' => array('override-checkbox')),
);
$form['titles']['amount_title'] = array(
'#type' => 'textfield',
'#title' => t('Amount field title'),
'#default_value' => $varprice_feature && !empty($varprice_feature->amount_title) ? $varprice_feature->amount_title : t('Amount'),
);
return $form;
}
/**
* Creates the varprice feature in the database.
*/
function uc_varprice_feature_form_submit($form, &$form_state) {
// Build an array of Variable Price data from the form submission.
$vp_data = array(
'pfid' => $form_state['values']['pfid'],
'price_default' => $form_state['values']['price_default'],
'price_minimum' => $form_state['values']['price_minimum'],
'price_maximum' => $form_state['values']['price_maximum'],
'add_to_cart_title' => $form_state['values']['override_add_to_cart_title'] ? $form_state['values']['add_to_cart_title'] : '',
'amount_title' => $form_state['values']['override_amount_title'] ? $form_state['values']['amount_title'] : '',
);
// Build the product feature description.
$description = array(
t('Customers can specify a price for this product.'),
t('<b>Default price:</b> @price', array('@price' => uc_currency_format($vp_data['price_default']))),
);
if (!empty($vp_data['price_minimum'])) {
$description[] = t('<b>Minimum price:</b> @price', array('@price' => uc_currency_format($vp_data['price_minimum'])));
}
if (!empty($vp_data['price_maximum'])) {
$description[] = t('<b>Maximum price:</b> @price', array('@price' => uc_currency_format($vp_data['price_maximum'])));
}
if (!empty($vp_data['add_to_cart_title'])) {
$description[] = t('<b>Add to cart title:</b> @title', array('@title' => $vp_data['add_to_cart_title']));
}
if (!empty($vp_data['amount_title'])) {
$description[] = t('<b>Amount field title:</b> @title', array('@title' => $vp_data['amount_title']));
}
// Save the basic product feature data.
$data = array(
'pfid' => $vp_data['pfid'],
'nid' => $form_state['values']['nid'],
'fid' => 'varprice',
'description' => implode('<br />', $description),
);
$form_state['redirect'] = uc_product_feature_save($data);
$vp_data['pfid'] = $data['pfid'];
// Insert or update the data in the Variable Price products table.
$key = array();
if ($vpid = _uc_varprice_get_vpid($vp_data['pfid'])) {
$key = 'vpid';
$vp_data['vpid'] = $vpid;
}
backdrop_write_record('uc_varprice_products', $vp_data, $key);
}
/**
* Variable Price product feature delete function.
*
* @param array $feature
*/
function uc_varprice_feature_delete($feature) {
if (is_array($feature) && isset($feature['pfid'])) {
db_delete('uc_varprice_products')
->condition('pfid', $feature['pfid'])
->execute();
}
else {
watchdog('uc_varprice', 'Invalid data passed to uc_varprice_feature_delete(). Expected array with key "pfid".', array(), WATCHDOG_ERROR);
}
}
/**
* Load the product feature data for a given node.
*
* @param int $nid
*
* @return DatabaseStatementInterface
*/
function uc_varprice_product_load($nid) {
return db_query('SELECT vp.* FROM {uc_product_features} AS pf
LEFT JOIN {uc_varprice_products} AS vp ON pf.pfid = vp.pfid
WHERE pf.fid = :pf_fid AND pf.nid = :pf_nid',
array(':pf_fid' => 'varprice', ':pf_nid' => $nid))->fetchObject();
}
/**
* Theme the Qty. field for products in the shopping cart with variable prices.
*
* @param array $variables
*
* @return string
*/
function theme_varprice_qty($variables) {
$element = $variables['form'];
return $element['#default_value'];
}
/**
* Gets a uc_varprice id from a product feature id.
*
* @param int $pfid
*
* @return DatabaseStatementInterface
*/
function _uc_varprice_get_vpid($pfid) {
return db_query('SELECT vpid FROM {uc_varprice_products} WHERE pfid = :pfid', array(':pfid' => $pfid))->fetchField();
}