1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* Forms for creating / editing and deleting orders.
|
6
|
*/
|
7
|
|
8
|
|
9
|
/**
|
10
|
* Form callback: create or edit an order.
|
11
|
*
|
12
|
* @param $order
|
13
|
* The order object to edit through the form.
|
14
|
*/
|
15
|
function commerce_order_order_form($form, &$form_state, $order) {
|
16
|
// Ensure this include file is loaded when the form is rebuilt from the cache.
|
17
|
$form_state['build_info']['files']['form'] = drupal_get_path('module', 'commerce_order') . '/includes/commerce_order.forms.inc';
|
18
|
|
19
|
// Ensure the owner name is accessible if the uid is set.
|
20
|
if (!empty($order->uid) && $owner = user_load($order->uid)) {
|
21
|
$order->name = $owner->name;
|
22
|
|
23
|
if (empty($order->mail)) {
|
24
|
$order->mail = $owner->mail;
|
25
|
}
|
26
|
}
|
27
|
|
28
|
if (empty($order->created)) {
|
29
|
$order->date = format_date(REQUEST_TIME, 'custom', 'Y-m-d H:i:s O');
|
30
|
}
|
31
|
|
32
|
// Add the field related form elements.
|
33
|
$form_state['commerce_order'] = $order;
|
34
|
field_attach_form('commerce_order', $order, $form, $form_state);
|
35
|
|
36
|
// Hide the order total field from direct editing.
|
37
|
$form['commerce_order_total']['#access'] = FALSE;
|
38
|
|
39
|
$form['additional_settings'] = array(
|
40
|
'#type' => 'vertical_tabs',
|
41
|
'#weight' => 99,
|
42
|
);
|
43
|
|
44
|
// Build an array of order status options grouped by order state.
|
45
|
$options = array();
|
46
|
|
47
|
foreach (commerce_order_state_get_title() as $name => $title) {
|
48
|
foreach (commerce_order_statuses(array('state' => $name)) as $order_status) {
|
49
|
$options[check_plain($title)][$order_status['name']] = check_plain($order_status['title']);
|
50
|
}
|
51
|
}
|
52
|
|
53
|
// Add a section to update the status and leave a log message.
|
54
|
$form['order_status'] = array(
|
55
|
'#type' => 'fieldset',
|
56
|
'#title' => t('Order status'),
|
57
|
'#collapsible' => TRUE,
|
58
|
'#collapsed' => FALSE,
|
59
|
'#group' => 'additional_settings',
|
60
|
'#attached' => array(
|
61
|
'js' => array(
|
62
|
drupal_get_path('module', 'commerce_order') . '/commerce_order.js',
|
63
|
array(
|
64
|
'type' => 'setting',
|
65
|
'data' => array('status_titles' => commerce_order_status_get_title()),
|
66
|
),
|
67
|
),
|
68
|
),
|
69
|
'#weight' => 20,
|
70
|
);
|
71
|
$form['order_status']['status'] = array(
|
72
|
'#type' => 'select',
|
73
|
'#title' => t('Status'),
|
74
|
'#options' => $options,
|
75
|
'#default_value' => $order->status,
|
76
|
);
|
77
|
$form['order_status']['status_original'] = array(
|
78
|
'#type' => 'hidden',
|
79
|
'#value' => $order->status,
|
80
|
'#attributes' => array('id' => 'edit-status-original'),
|
81
|
);
|
82
|
$form['order_status']['log'] = array(
|
83
|
'#type' => 'textarea',
|
84
|
'#title' => t('Update log message'),
|
85
|
'#description' => t('Provide an explanation of the changes you are making. This will provide a meaningful audit trail for updates to this order.'),
|
86
|
'#rows' => 4,
|
87
|
);
|
88
|
|
89
|
// Add the user account and e-mail fields.
|
90
|
$form['user'] = array(
|
91
|
'#type' => 'fieldset',
|
92
|
'#title' => t('User information'),
|
93
|
'#collapsible' => TRUE,
|
94
|
'#collapsed' => TRUE,
|
95
|
'#access' => user_access('administer commerce_order entities'),
|
96
|
'#group' => 'additional_settings',
|
97
|
'#attached' => array(
|
98
|
'js' => array(
|
99
|
drupal_get_path('module', 'commerce_order') . '/commerce_order.js',
|
100
|
array(
|
101
|
'type' => 'setting',
|
102
|
'data' => array('anonymous' => variable_get('anonymous', t('Anonymous'))),
|
103
|
),
|
104
|
),
|
105
|
),
|
106
|
'#weight' => 30,
|
107
|
);
|
108
|
$form['user']['name'] = array(
|
109
|
'#type' => 'textfield',
|
110
|
'#title' => t('Owned by'),
|
111
|
'#description' => t('Leave blank for %anonymous.', array('%anonymous' => variable_get('anonymous', t('Anonymous')))),
|
112
|
'#maxlength' => 60,
|
113
|
'#autocomplete_path' => 'user/autocomplete',
|
114
|
'#default_value' => !empty($order->name) ? $order->name : '',
|
115
|
'#weight' => -1,
|
116
|
);
|
117
|
$form['user']['mail'] = array(
|
118
|
'#type' => 'textfield',
|
119
|
'#title' => t('Order contact e-mail'),
|
120
|
'#description' => t('Defaults to the owner account e-mail address if left blank. Used for order communication.'),
|
121
|
'#default_value' => $order->mail,
|
122
|
);
|
123
|
|
124
|
// Add a log checkbox and timestamp field to a history tab.
|
125
|
$form['order_history'] = array(
|
126
|
'#type' => 'fieldset',
|
127
|
'#title' => t('Order history', array(), array('context' => 'a drupal commerce order')),
|
128
|
'#collapsible' => TRUE,
|
129
|
'#collapsed' => FALSE,
|
130
|
'#group' => 'additional_settings',
|
131
|
'#attached' => array(
|
132
|
'js' => array(drupal_get_path('module', 'commerce_order') . '/commerce_order.js'),
|
133
|
),
|
134
|
'#weight' => 40,
|
135
|
);
|
136
|
$form['order_history']['revision'] = array(
|
137
|
'#type' => 'checkbox',
|
138
|
'#title' => t('Create new revision on update'),
|
139
|
'#description' => t('If an update log message is entered, a revision will be created even if this is unchecked.'),
|
140
|
'#default_value' => variable_get('commerce_order_auto_revision', TRUE),
|
141
|
'#access' => user_access('administer commerce_order entities'),
|
142
|
);
|
143
|
$form['order_history']['date'] = array(
|
144
|
'#type' => 'textfield',
|
145
|
'#title' => t('Created on'),
|
146
|
'#description' => t('Format: %time. The date format is YYYY-MM-DD and %timezone is the time zone offset from UTC. Leave blank to use the time of form submission.', array('%time' => !empty($order->date) ? date_format(date_create($order->date), 'Y-m-d H:i:s O') : format_date($order->created, 'custom', 'Y-m-d H:i:s O'), '%timezone' => !empty($order->date) ? date_format(date_create($order->date), 'O') : format_date($order->created, 'custom', 'O'))),
|
147
|
'#maxlength' => 25,
|
148
|
'#default_value' => !empty($order->created) ? format_date($order->created, 'custom', 'Y-m-d H:i:s O') : '',
|
149
|
);
|
150
|
$form['order_history']['created'] = array(
|
151
|
'#type' => 'hidden',
|
152
|
'#value' => !empty($order->created) ? format_date($order->created, 'short') : '',
|
153
|
'#attributes' => array('id' => 'edit-created'),
|
154
|
);
|
155
|
$form['order_history']['changed'] = array(
|
156
|
'#type' => 'hidden',
|
157
|
'#value' => !empty($order->changed) ? format_date($order->changed, 'short') : '',
|
158
|
'#attributes' => array('id' => 'edit-changed'),
|
159
|
);
|
160
|
|
161
|
// We add the form's #submit array to this button along with the actual submit
|
162
|
// handler to preserve any submit handlers added by a form callback_wrapper.
|
163
|
$submit = array();
|
164
|
|
165
|
if (!empty($form['#submit'])) {
|
166
|
$submit += $form['#submit'];
|
167
|
}
|
168
|
|
169
|
$form['actions'] = array('#type' => 'actions');
|
170
|
$form['actions']['submit'] = array(
|
171
|
'#type' => 'submit',
|
172
|
'#value' => t('Save order', array(), array('context' => 'a drupal commerce order')),
|
173
|
'#submit' => array_merge($submit, array('commerce_order_order_form_submit')),
|
174
|
'#weight' => 40,
|
175
|
);
|
176
|
|
177
|
// We append the validate handler to #validate in case a form callback_wrapper
|
178
|
// is used to add validate handlers earlier.
|
179
|
$form['#validate'][] = 'commerce_order_order_form_validate';
|
180
|
|
181
|
return $form;
|
182
|
}
|
183
|
|
184
|
/**
|
185
|
* Validation callback for commerce_order_order_form().
|
186
|
*/
|
187
|
function commerce_order_order_form_validate($form, &$form_state) {
|
188
|
$order = $form_state['commerce_order'];
|
189
|
|
190
|
// Validate the "owned by" field.
|
191
|
if (!empty($form_state['values']['name']) && !($account = user_load_by_name($form_state['values']['name']))) {
|
192
|
// The use of empty() is mandatory in the context of usernames as the empty
|
193
|
// string denotes an anonymous user.
|
194
|
form_set_error('name', t('The username %name does not exist.', array('%name' => $form_state['values']['name'])));
|
195
|
}
|
196
|
|
197
|
// Validate the "created on" field.
|
198
|
if (!empty($form_state['values']['date']) && strtotime($form_state['values']['date']) === FALSE) {
|
199
|
form_set_error('date', t('You have to specify a valid date.'));
|
200
|
}
|
201
|
|
202
|
// Validate the e-mail address entered.
|
203
|
if (!empty($form_state['values']['mail']) && !valid_email_address($form_state['values']['mail'])) {
|
204
|
form_set_error('mail', t('You have specified an invalid e-mail address.'));
|
205
|
}
|
206
|
|
207
|
// TODO: Pending token patterns for order numbers, validate the characters and
|
208
|
// the final string for uniqueness.
|
209
|
|
210
|
// Notify field widgets to validate their data.
|
211
|
field_attach_form_validate('commerce_order', $order, $form, $form_state);
|
212
|
}
|
213
|
|
214
|
/**
|
215
|
* Submit callback for commerce_order_order_form().
|
216
|
*/
|
217
|
function commerce_order_order_form_submit($form, &$form_state) {
|
218
|
global $user;
|
219
|
|
220
|
// If the user is editing an order, load a fresh copy to merge changes to.
|
221
|
if ($form_state['commerce_order']->order_id) {
|
222
|
$form_state['commerce_order'] = commerce_order_load($form_state['commerce_order']->order_id);
|
223
|
}
|
224
|
|
225
|
// Merge changes into the order object in the form state so it is accessible
|
226
|
// by field handlers.
|
227
|
$order = $form_state['commerce_order'];
|
228
|
|
229
|
if ($form_state['values']['revision'] || !empty($form_state['values']['log'])) {
|
230
|
$order->revision = TRUE;
|
231
|
$order->log = $form_state['values']['log'];
|
232
|
}
|
233
|
|
234
|
// Set the order's owner uid based on the supplied name.
|
235
|
$converted = FALSE;
|
236
|
|
237
|
if (!empty($form_state['values']['name']) && $account = user_load_by_name($form_state['values']['name'])) {
|
238
|
// If the order is being converted to an authenticated order from an
|
239
|
// anonymous order...
|
240
|
if ($order->uid == 0) {
|
241
|
// Set the converted boolean for later processing.
|
242
|
$converted = TRUE;
|
243
|
}
|
244
|
|
245
|
$order->uid = $account->uid;
|
246
|
|
247
|
if (empty($form_state['values']['mail'])) {
|
248
|
$order->mail = $account->mail;
|
249
|
}
|
250
|
}
|
251
|
else {
|
252
|
$order->uid = 0;
|
253
|
}
|
254
|
|
255
|
if (!empty($form_state['values']['mail'])) {
|
256
|
$order->mail = $form_state['values']['mail'];
|
257
|
}
|
258
|
|
259
|
$order->created = !empty($form_state['values']['date']) ? strtotime($form_state['values']['date']) : REQUEST_TIME;
|
260
|
|
261
|
// Notify field widgets.
|
262
|
field_attach_submit('commerce_order', $order, $form, $form_state);
|
263
|
|
264
|
// Ensure the attached customer profiles are associated with the order owner
|
265
|
// if they do not have a uid yet and the order does.
|
266
|
if ($converted) {
|
267
|
$wrapper = entity_metadata_wrapper('commerce_order', $order);
|
268
|
|
269
|
foreach (field_info_instances('commerce_order', $order->type) as $field_name => $instance) {
|
270
|
$field_info = field_info_field($field_name);
|
271
|
|
272
|
if ($field_info['type'] == 'commerce_customer_profile_reference') {
|
273
|
if (!is_null($wrapper->{$field_name}->value()) &&
|
274
|
$wrapper->{$field_name}->uid->value() == 0) {
|
275
|
$wrapper->{$field_name}->uid = $order->uid;
|
276
|
$wrapper->{$field_name}->save();
|
277
|
}
|
278
|
}
|
279
|
}
|
280
|
}
|
281
|
|
282
|
// Update the order status if specified.
|
283
|
if ($form_state['values']['status'] != $form_state['values']['status_original']) {
|
284
|
// We skip order saving in the update since we do it below once for the
|
285
|
// entire form submission.
|
286
|
commerce_order_status_update($order, $form_state['values']['status'], TRUE);
|
287
|
}
|
288
|
|
289
|
// Save the order.
|
290
|
commerce_order_save($order);
|
291
|
|
292
|
// Ensure the attached line items are associated with the order if they do not
|
293
|
// have an order_id set yet.
|
294
|
foreach (entity_metadata_wrapper('commerce_order', $order)->commerce_line_items as $delta => $line_item_wrapper) {
|
295
|
if ($line_item_wrapper->order_id->value() == 0) {
|
296
|
$line_item_wrapper->order_id = $order->order_id;
|
297
|
commerce_line_item_save($line_item_wrapper->value());
|
298
|
}
|
299
|
}
|
300
|
}
|
301
|
|
302
|
/**
|
303
|
* Form callback: confirmation form for deleting an order.
|
304
|
*
|
305
|
* @param $order
|
306
|
* The order object to delete through the form.
|
307
|
*
|
308
|
* @return
|
309
|
* The form array to add or edit an order.
|
310
|
*
|
311
|
* @see confirm_form()
|
312
|
*/
|
313
|
function commerce_order_order_delete_form($form, &$form_state, $order) {
|
314
|
$form_state['order'] = $order;
|
315
|
|
316
|
// Ensure this include file is loaded when the form is rebuilt from the cache.
|
317
|
$form_state['build_info']['files']['form'] = drupal_get_path('module', 'commerce_order') . '/includes/commerce_order.forms.inc';
|
318
|
|
319
|
$form['#submit'][] = 'commerce_order_order_delete_form_submit';
|
320
|
|
321
|
$form = confirm_form($form,
|
322
|
t('Are you sure you want to delete order @number?', array('@number' => $order->order_number)),
|
323
|
'',
|
324
|
'<p>' . t('Deleting this order cannot be undone.') . '</p>',
|
325
|
t('Delete'),
|
326
|
t('Cancel'),
|
327
|
'confirm'
|
328
|
);
|
329
|
|
330
|
return $form;
|
331
|
}
|
332
|
|
333
|
/**
|
334
|
* Submit callback for commerce_order_order_delete_form().
|
335
|
*/
|
336
|
function commerce_order_order_delete_form_submit($form, &$form_state) {
|
337
|
$order = $form_state['order'];
|
338
|
|
339
|
if (commerce_order_delete($order->order_id)) {
|
340
|
drupal_set_message(t('Order @number has been deleted.', array('@number' => $order->order_number)));
|
341
|
watchdog('commerce_order', 'Deleted order @number.', array('@number' => $order->order_number), WATCHDOG_NOTICE);
|
342
|
}
|
343
|
else {
|
344
|
drupal_set_message(t('Order @number could not be deleted.', array('@number' => $order->order_number)), 'error');
|
345
|
}
|
346
|
}
|