/[drupal]/contributions/modules/ubercart/uc_roles/uc_roles.module
ViewVC logotype

Contents of /contributions/modules/ubercart/uc_roles/uc_roles.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Thu Jul 10 12:41:04 2008 UTC (16 months, 2 weeks ago) by islandusurper
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--2
Changes since 1.1: +806 -754 lines
File MIME type: text/x-php
Begin the Ubercart 6.x-2.x branch.
1 <?php
2 // $Id$
3
4 /**
5 * @file
6 * Grants roles upon accepted payment of products
7 *
8 * The uc_roles module will grant specified roles upon purchase of specified
9 * products. Granted roles can be set to have a expiration date. Users can also
10 * be notified of the roles they are granted and when the roles will
11 * expire/need to be renewed/etc
12 *
13 * Development sponsored by the Ubercart project. http://www.ubercart.org
14 */
15
16 /* ************************************************************************* *
17 * Hook Functions (Drupal) *
18 * ************************************************************************* */
19
20 /**
21 * Implementation of hook_help()
22 */
23 function uc_roles_help($section) {
24 switch ($section) {
25 case 'admin/user/user/expiration':
26 return t('&Uuml;bercart grants certain roles to customers when they purchase products with a role assignment feature. These can be permanent or temporary roles. Here you can view and edit when temporary roles are set to expire.');
27 }
28 }
29
30 /**
31 * Implementation of hook_cron().
32 */
33 function uc_roles_cron() {
34 $reminder_granularity = variable_get('uc_roles_reminder_granularity', 'never');
35 $reminder_qty = variable_get('uc_roles_reminder_length', NULL);
36
37 $result = db_query("SELECT * FROM {uc_roles_expirations}");
38 while ($expiration = db_fetch_object($result)) {
39 $user = user_load(array('uid' => $expiration->uid));
40
41 if (is_array($user->roles) && count($user->roles) > 0) {
42 if (!in_array($expiration->rid, array_keys($user->roles))) {
43 _role_action('delete', $user, $expiration->rid);
44 }
45 elseif ($expiration->expiration <= time()) {
46 _role_action('revoke', $user, $expiration->rid);
47 _role_email_user('revoke', $user, $expiration);
48 }
49 elseif ($reminder_granularity != 'never') {
50 $threshold = _get_expiration_date(-$reminder_qty, $reminder_granularity, $expiration->expiration);
51 if ($threshold <= time() && intval($expiration->notified) < 1) {
52 _role_email_user('reminder', $user, $expiration);
53 db_query("UPDATE {uc_roles_expirations} SET notified = 1 WHERE uid = %d AND rid = %d", $user->uid, $expiration->rid);
54 }
55 }
56 }
57 }
58 }
59
60 /**
61 * Implementation of hook_menu().
62 */
63 function uc_roles_menu($may_cache) {
64 if ($may_cache) {
65 $items[] = array(
66 'path' => 'admin/user/user/expiration',
67 'title' => t('Role expiration'),
68 'access' => user_access('administer users'),
69 'callback' => 'drupal_get_form',
70 'callback arguments' => array('uc_roles_expiration'),
71 'description' => t('Edit and view role expirations set by Ubercart'),
72 'type' => MENU_LOCAL_TASK,
73 );
74 }
75 else {
76 if (module_exists('uc_notify')) {
77 $items[] = array(
78 'path' => 'admin/store/settings/notify/edit/role',
79 'title' => t('Role assignment'),
80 'access' => user_access('administer store'),
81 'callback' => 'drupal_get_form',
82 'callback arguments' => array('uc_roles_notify_settings'),
83 'description' => t('Edit the notification settings for roles granted by Ubercart.'),
84 'type' => MENU_LOCAL_TASK,
85 );
86 }
87 if (is_numeric(arg(5)) && is_numeric(arg(6))) {
88 $items[] = array(
89 'path' => 'admin/user/user/expiration/delete/'. arg(5) .'/'. arg(6),
90 'title' => t('Delete role expiration'),
91 'access' => user_access('administer users'),
92 'callback' => 'drupal_get_form',
93 'callback arguments' => array('uc_roles_deletion_form'),
94 'description' => t('Delete a specified role expiration'),
95 'type' => MENU_CALLBACK,
96 );
97 }
98 drupal_add_css(drupal_get_path('module', 'uc_roles') .'/uc_roles.css');
99 }
100
101 return $items;
102 }
103
104 /**
105 * Implementation of hook_perm().
106 */
107 function uc_roles_perm() {
108 return array('view all role expirations');
109 }
110
111 /**
112 * Implementation of hook_nodeapi().
113 */
114 function uc_roles_nodeapi(&$node, $op, $arg3 = null, $arg4 = NULL) {
115 switch ($op) {
116 case 'delete':
117 if (in_array($node->type, module_invoke_all('product_types'))) {
118 db_query("DELETE FROM {uc_roles_products} WHERE nid = %d", $node->nid);
119 }
120 break;
121 default:
122 break;
123 }
124 }
125
126 /**
127 * Implementation of hook_user().
128 */
129 function uc_roles_user($op, &$edit, &$account, $category = NULL) {
130 global $user;
131 switch ($op) {
132 case 'delete':
133 db_query("DELETE FROM {uc_roles_expirations} WHERE uid = %d", $account->uid);
134 break;
135 case 'form':
136 if (user_access('administer users') && (is_null($category) || $category == 'account')) {
137 $role_choices = _get_role_choices(array_keys($account->roles));
138
139 //Assoc array, for Drupal form elements
140 $div = array('#prefix' => '<div class="expiration">', '#suffix' => '</div>');
141 $polarity_widget = array(
142 '#type' => 'select',
143 '#options' => array(
144 'add' => '+',
145 'remove' => '-',
146 ),
147 );
148 $polarity_widget = $polarity_widget + $div;
149 $qty_widget = array(
150 '#type' => 'textfield',
151 '#size' => 4,
152 '#maxlength' => 4
153 );
154 $qty_widget = $qty_widget + $div;
155 $granularity_widget = array(
156 '#type' => 'select',
157 '#options' => array(
158 'day' => t('day(s)'),
159 'week' => t('week(s)'),
160 'month' => t('month(s)'),
161 'year' => t('year(s)'),
162 ),
163 );
164 $granularity_widget = $granularity_widget + $div;
165
166 $form['account']['expirations'] = array(
167 '#type' => 'fieldset',
168 '#title' => t('Role expirations'),
169 '#collapsible' => TRUE,
170 '#collapsed' => TRUE,
171 '#weight' => 10
172 );
173 $expirations = db_query("SELECT * FROM {uc_roles_expirations} WHERE uid = %d", $account->uid);
174
175 $form['account']['expirations']['intro'] = array(
176 '#type' => 'markup',
177 '#value' => '<p>'. t('Below you can add or remove time to the expiration dates of the following roles.') .'</p>',
178 );
179
180 //There are expirations to administer
181 if (db_num_rows($expirations) > 0) {
182
183 $form['account']['expirations']['table_start'] = array('#type' => 'markup', '#value' => '<table><thead><th>Role</th><th>Expiration</th><th>Add/Remove time</th></thead><tbody>');
184 while ($expiration = db_fetch_object($expirations)) {
185 $class = (is_null($class) || $class == "even") ? "odd" : "even";
186 $form['account']['expirations']['role_'. $expiration->rid] = array(
187 '#type' => 'markup',
188 '#value' => '<tr class="'. $class .'"><td>'. _get_role_name($expiration->rid) .'</td><td>'. format_date($expiration->expiration, 'small') .'</td><td>',
189 );
190 $form['account']['expirations']['role_'. $expiration->rid .'_polarity'] = $polarity_widget;
191 $form['account']['expirations']['role_'. $expiration->rid .'_qty'] = $qty_widget;
192 $form['account']['expirations']['role_'. $expiration->rid .'_granularity'] = $granularity_widget;
193 $form['account']['expirations']['role_'. $expiration->rid .'_granularity']['#suffix'] .= '</tr>';
194 $form['account']['expirations']['role_'. $expiration->rid .'_expiration'] = array('#type' => 'value', '#value' => $expiration->expiration);
195 }
196 $form['account']['expirations']['table_end'] = array('#type' => 'markup', '#value' => '</tbody></table><br/>');
197 }
198 else { //There are no expirations to administer
199 $form['account']['expirations']['no_expirations'] = array(
200 '#type' => 'markup',
201 '#value' => '<table><thead><th>'. t('Role') .'</th><th>'. t('Expiration') .'</th><th>'. t('Operation') .'</th></thead><tbody><tr><td colspan="3">'. t('There are no pending expirations for roles this user.') .'</td></tr></tbody></table><br/>',
202 );
203 }
204
205 //Option to allow temporary roles
206 if (!empty($role_choices)) {
207 $form['account']['expirations']['new_role'] = array(
208 '#type' => 'checkbox',
209 '#title' => t('Add role'),
210 ) + $div;
211 $form['account']['expirations']['new_role_add'] = array(
212 '#type' => 'select',
213 '#default_value' => variable_get('uc_roles_default_role', NULL),
214 '#options' => $role_choices,
215 ) + $div;
216 $form['account']['expirations']['new_role_add']['#suffix'] = t(' for ') . $form['account']['expirations']['new_role_add']['#suffix'];
217 $form['account']['expirations']['new_role_add_qty'] = $qty_widget;
218 $form['account']['expirations']['new_role_add_granularity'] = $granularity_widget;
219
220 if (($default_granularity = variable_get('uc_roles_default_granularity', 'never')) != 'never') {
221 $form['account']['expirations']['new_role_add_qty'] = $form['account']['expirations']['new_role_add_qty'] + array('#default_value' => variable_get('uc_roles_default_length', NULL));
222 $form['account']['expirations']['new_role_add_granularity'] = $form['account']['expirations']['new_role_add_granularity'] + array('#default_value' => $default_granularity);
223 }
224 }
225 }
226 return $form;
227 case 'submit':
228 //If a new temporary role is added
229 if ($edit['new_role'] && $category == 'account') {
230 db_query("INSERT INTO {uc_roles_expirations} (uid, rid, expiration) VALUES (%d, %d, %d)", $account->uid, $edit['new_role_add'], _get_expiration_date($edit['new_role_add_qty'], $edit['new_role_add_granularity']));
231 $edit['roles'][$edit['new_role_add']] = _get_role_name($edit['new_role_add']);
232 $edit['new_role'] = $edit['new_role_add'] = $edit['new_role_add_qty'] = $edit['new_role_add_granularity'] = NULL;
233 }
234 //If the expiration has been adjusted
235 foreach ($edit as $key => $value) {
236 if (preg_match("/role_(\d+)_qty/", $key, $matches) != 0 && !empty($value)) {
237 $rid = $matches[1];
238 $qty = ($edit['role_'. $rid .'_polarity'] == 'add') ? $edit['role_'. $rid .'_qty'] : -1 * $edit['role_'. $rid .'_qty'];
239 _role_action('renew', $account, $rid, _get_expiration_date($qty, $edit['role_'. $rid .'_granularity'], $edit['role_'. $rid .'_expiration']));
240 }
241 }
242 //If a user's role is removed, so is the expiration
243 if (!is_null($edit['roles']) && $category == 'account') {
244 foreach ($account->roles as $rid => $role) {
245 if (!in_array($rid, array_keys($edit['roles'])) && $rid != DRUPAL_AUTHENTICATED_RID) {
246 _role_action('revoke', $account, $rid);
247 }
248 }
249 }
250 break;
251 case 'validate':
252 //Validate the amount of time for the expiration
253 if ($edit['new_role'] && $category == 'account') {
254 if (intval($edit['new_role_add_qty']) < 1) {
255 form_set_error('new_role_add_qty', t('The expiration length must be a positive integer'));
256 }
257 }
258 //Validate adjusted expirations
259 foreach ($edit as $key => $value) {
260 if (preg_match("/role_(\d+)_qty/", $key, $matches) != 0 && !empty($value)) {
261 $rid = $matches[1];
262 $qty = ($edit['role_'. $rid .'_polarity'] == 'add') ? $edit['role_'. $rid .'_qty'] : -1 * $edit['role_'. $rid .'_qty'];
263 $new_expiration = _get_expiration_date($qty, $edit['role_'. $rid .'_granularity'], $edit['role_'. $rid .'_expiration']);
264 if (time() > $new_expiration) {
265 form_set_error('role_'. $rid .'_qty', t("The new expiration date, %date, has already occurred.", array('%date' => format_date($new_expiration, 'small'))));
266 }
267 }
268 }
269 break;
270 case 'view':
271 //Display role expirations
272 $show_expirations = variable_get('uc_roles_default_show_expiration', TRUE);
273 if ((user_access('view all role expirations') || ($user->uid == $account->uid && $show_expirations)) && $user->uid) {
274 $user_expirations = db_query("SELECT * FROM {uc_roles_expirations} WHERE uid = %d", $account->uid);
275 $items = array();
276
277 while ($expiration = db_fetch_object($user_expirations)) {
278 $substitution = array('!role_name' => _get_role_name($expiration->rid), '!date' => format_date($expiration->expiration, 'small'));
279 $items[$expiration->rid .'_expiration'] = array(
280 'title' => strtr(variable_get('uc_roles_default_expiration_title', uc_get_message('uc_roles_user_expiration_title')), $substitution),
281 'value' => strtr(variable_get('uc_roles_default_expiration_message', uc_get_message('uc_roles_user_expiration_message')), $substitution),
282 'class' => 'member',
283 );
284 }
285 return array(variable_get('uc_roles_default_expiration_header', uc_get_message('uc_roles_user_expiration_header')) => $items);
286 }
287 break;
288 default:
289 break;
290 }
291 }
292
293 /* ************************************************************************* *
294 * Übercart Hooks *
295 * ************************************************************************* */
296
297 /**
298 * Implementation of hook_cart_item().
299 */
300 function uc_roles_cart_item($op, &$item) {
301 switch ($op) {
302 case 'can_ship':
303 $roles = db_query("SELECT * FROM {uc_roles_products} WHERE nid = %d", $item->nid);
304 while ($role = db_fetch_object($roles)) {
305 $sku = (empty($item->data['model'])) ? $item->model : $item->data['model'];
306 if ($sku == $role->model || empty($role->model)) {
307 return ($role->shippable) ? TRUE : FALSE;
308 }
309 }
310 break;
311 }
312 }
313
314 /**
315 * Implementation of hook_order().
316 */
317 function uc_roles_order($op, $order, $status) {
318 global $user;
319
320 switch ($op) {
321 case 'update':
322 $order_user = user_load(array('uid' => $order->uid));
323 if ($order->uid > 0 && $order_user !== FALSE) {
324 // Check each product for a product role.
325 foreach ($order->products as $product) {
326 $roles = db_query("SELECT * FROM {uc_roles_products} WHERE nid = %d", $product->nid);
327 while ($role = db_fetch_object($roles)) {
328 // Grant (or renew) role upon successful completion of payment
329 if ($role->model == $product->model || empty($role->model)) {
330 if ($status == variable_get('uc_roles_default_order_status', 'completed')) {
331 $existing_role = db_fetch_object(db_query("SELECT * FROM {uc_roles_expirations} WHERE uid = %d AND rid = %d", $order_user->uid, $role->rid));
332 if (!is_null($existing_role->expiration)) {
333 $op = 'renew';
334 $comment = t('Customer user role %role renewed.', array('%role' => _get_role_name($role->rid)));
335 }
336 else {
337 $op = 'grant';
338 $comment = t('Customer granted user role %role.', array('%role' => _get_role_name($role->rid)));
339 }
340
341 $quantity = ($role->by_quantity) ? $product->qty : 1;
342 _role_action($op, $order_user, $role->rid, _get_expiration_date(($role->duration * $quantity), $role->granularity, $existing_role->expiration));
343
344 $new_expiration = db_fetch_object(db_query("SELECT * FROM {uc_roles_expirations} WHERE uid = %d AND rid = %d", $order_user->uid, $role->rid));
345 uc_order_comment_save($order->order_id, $user->uid, $comment);
346 _role_email_user($op, $order_user, $new_expiration, $order);
347 $order_user = user_load(array('uid' => $order->uid));
348 }
349 }
350 }
351 }
352 }
353 break;
354 }
355 }
356
357 /**
358 * Implementation of hook_product_feature().
359 */
360 function uc_roles_product_feature() {
361 $features[] = array(
362 'id' => 'role',
363 'title' => t('Role assignment'),
364 'callback' => 'uc_roles_feature_form',
365 'delete' => 'uc_roles_feature_delete',
366 'settings' => 'uc_roles_feature_settings',
367 );
368
369 return $features;
370 }
371
372 /**
373 * Implementation of hook_store_status().
374 */
375 function uc_roles_store_status() {
376 $message = array();
377 $role_choices = _get_role_choices();
378 if (empty($role_choices)) {
379 $message[] = array(
380 'status' => 'warning',
381 'title' => t('Roles'),
382 'desc' => t('There are no product role(s) that can be assigned upon product purchase. Set product roles in the <a href="!url">product feature settings</a> under the role assignment settings fieldset.', array('!url' => url('admin/store/settings/products/edit/features'))),
383 );
384 }
385 else {
386 $message[] = array(
387 'status' => 'ok',
388 'title' => t('Roles'),
389 'desc' => t('The role(s) %roles are set to be used with the Role Assignment product feature.', array('%roles' => implode(', ', $role_choices))),
390 );
391 }
392 return $message;
393 }
394
395 /**
396 * Implementation of hook_token_list().
397 */
398 function uc_roles_token_list($type = 'all') {
399 if ($type == 'uc_roles' || $type == 'ubercart' || $type == 'all') {
400 $tokens['uc_roles']['role-expiration-long'] = t('The role expiration date in long format');
401 $tokens['uc_roles']['role-expiration-medium'] = t('The role expiration date in medium format');
402 $tokens['uc_roles']['role-expiration-short'] = t('The role expiration date in short format');
403 $tokens['uc_roles']['role-name'] = t('The associated role name');
404 }
405
406 return $tokens;
407 }
408
409 /**
410 * Implementation of hook_token_values().
411 */
412 function uc_roles_token_values($type, $object = NULL) {
413 switch ($type) {
414 case 'uc_roles':
415 $values['role-expiration-long'] = format_date($object->expiration, 'large');
416 $values['role-expiration-medium'] = format_date($object->expiration, 'medium');
417 $values['role-expiration-short'] = format_date($object->expiration, 'small');
418 $values['role-name'] = check_plain(_get_role_name($object->rid));
419 break;
420 }
421
422 return $values;
423 }
424
425 /**
426 * Implementation of hook_uc_message().
427 */
428 function uc_roles_uc_message() {
429 $messages['uc_roles_grant_subject'] = t('[store-name]: [role-name] role granted');
430 $messages['uc_roles_grant_message'] = t("[order-first-name] [order-last-name], \n\nThanks to your order, [order-link], at [store-name] you now have a new role, [role-name].\n\nThanks again, \n\n[store-name]\n[site-slogan]");
431 $messages['uc_roles_revoke_subject'] = t('[store-name]: [role-name] role expired');
432 $messages['uc_roles_revoke_message'] = t("The role, [role-name], you acquired by purchasing a product at our store has expired. Any special access or privileges that came with it are now gone. You can purchase it again by going to [store-link]\n\nThanks again, \n\n[store-name]\n[site-slogan]");
433 $messages['uc_roles_renew_subject'] = t('[store-name]: [role-name] role renewed');
434 $messages['uc_roles_renew_message'] = t("[order-first-name] [order-last-name], \n\nThanks to your order, [order-link], at [store-name] you have renewed the role, [role-name]. It is now set to expire on [role-expiration-short].\n\nThanks again, \n\n[store-name]\n[site-slogan]");
435 $messages['uc_roles_reminder_subject'] = t('[store-name]: [role-name] role expiration notice');
436 $messages['uc_roles_reminder_message'] = t("This message is to remind you that the role, [role-name], you acquired by making a purchase at our store will expire at [role-expiration-short]. You may visit [store-link] to renew this role before it expires.\n\nThanks again, \n\n[store-name]\n[site-slogan]");
437 $messages['uc_roles_user_expiration_header'] = t("Expiring roles");
438 $messages['uc_roles_user_expiration_title'] = t("!role_name");
439 $messages['uc_roles_user_expiration_message'] = t("This role will expire on !date");
440
441 return $messages;
442 }
443
444 /* ************************************************************************* *
445 * Callback Functions, Forms, and Tables *
446 * ************************************************************************* */
447
448 /**
449 * Form builder for role expirations
450 */
451 function uc_roles_deletion_form() {
452 $expiration = db_result(db_query("SELECT expiration FROM {uc_roles_expirations} WHERE uid = %d AND rid = %d", arg(5), arg(6)));
453 if ($expiration) {
454 $user = user_load(array('uid' => arg(5)));
455 $role = _get_role_name(arg(6));
456 $form['user'] = array('#type' => 'value', '#value' => $user->name);
457 $form['uid'] = array('#type' => 'value', '#value' => $user->uid);
458 $form['role'] = array('#type' => 'value', '#value' => $role);
459 $form['rid'] = array('#type' => 'value', '#value' => arg(6));
460 $form = confirm_form($form, t('Delete expiration of role_name role for the user user_name?', array('user_name' => $user->name, 'role_name' => $role)), 'admin/user/user/expiration', t('Deleting the expiration will give user_name privileges set by the role_name role indefinitely unless manually removed.', array('user_name' => $user->name, 'role_name' => $role)), t('Yes'), t('No'));
461 }
462 else {
463 $form['error'] = array(
464 '#type' => 'markup',
465 '#value' => t('Invalid user id or role id'),
466 );
467 }
468
469 return $form;
470 }
471 function uc_roles_deletion_form_submit($form_id, $form_values) {
472 db_query("DELETE FROM {uc_roles_expirations} WHERE uid = %d AND rid = %d", $form_values['uid'], $form_values['rid']);
473 drupal_set_message(t('The expiration of role_name role for the user user_name has been deleted.', array('user_name' => $form_values['user'], 'role_name' => $form_values['role'])));
474 drupal_goto('admin/user/user/expiration');
475 }
476
477 /**
478 * Menu callback for viewing expirations
479 */
480 function uc_roles_expiration() {
481 $header = array(
482 array('data' => t('Username'), 'field' => 'u.name'),
483 array('data' => t('Role'), 'field' => 'e.rid'),
484 array('data' => t('Expiration date'), 'field' => 'e.expiration', 'sort' => 'asc'),
485 t('Operations')
486 );
487 $sql = 'SELECT * FROM {uc_roles_expirations} AS e INNER JOIN {users} AS u ON e.uid = u.uid';
488 $sql .= tablesort_sql($header);
489 $result = pager_query($sql, 50, 0, NULL);
490
491 while ($row = db_fetch_object($result)) {
492 $form['name'][$row->uid .' '. $row->rid] = array('#value' => theme('username', $row));
493 $form['role'][$row->uid .' '. $row->rid] = array('#value' => _get_role_name($row->rid));
494 $form['expiration'][$row->uid .' '. $row->rid] = array('#value' => format_date($row->expiration, 'small'));
495 $form['operations'][$row->uid .' '. $row->rid] = array('#value' => l(t('delete'), 'admin/user/user/expiration/delete/'. $row->uid .'/'. $row->rid) .' '. l(t('edit'), 'user/'. $row->uid .'/edit', array(), 'destination=admin%2Fuser%2Fuser%2Fexpiration'));
496 }
497 $form['pager'] = array('#value' => theme('pager', NULL, 50, 0));
498
499 return $form;
500 }
501
502 /**
503 * Theme user role expiration page
504 */
505 function theme_uc_roles_expiration($form) {
506 $header = array(
507 array('data' => t('Username'), 'field' => 'u.name'),
508 array('data' => t('Role'), 'field' => 'e.rid'),
509 array('data' => t('Expiration date'), 'field' => 'e.expiration', 'sort' => 'asc'),
510 t('Operations')
511 );
512 if (isset($form['name']) && is_array($form['name'])) {
513 foreach (element_children($form['name']) as $key) {
514 $rows[] = array(
515 drupal_render($form['name'][$key]),
516 drupal_render($form['role'][$key]),
517 drupal_render($form['expiration'][$key]),
518 drupal_render($form['operations'][$key]),
519 );
520 }
521 }
522 else {
523 $rows[] = array(array('data' => t('No expirations set to occur'), 'colspan' => '4'));
524 }
525 $output .= theme('table', $header, $rows);
526 if ($form['pager']['#value']) {
527 $output .= drupal_render($form['pager']);
528 }
529 $output .= drupal_render($form);
530
531 return $output;
532 }
533
534 /**
535 * product_feature delete function
536 */
537 function uc_roles_feature_delete($feature) {
538 db_query("DELETE FROM {uc_roles_products} WHERE pfid = %d", $feature['pfid']);
539 }
540
541 /**
542 * Form builder for hook_product_feature
543 */
544 function uc_roles_feature_form($node, $feature) {
545 uc_add_js('$(document).ready(function() { if ($("#edit-uc-roles-granularity").val() == "never") {$("#edit-uc-roles-qty").attr("disabled", "disabled").val("");} });', 'inline');
546 $models = array(NULL => t('Any'), $node->model => $node->model);
547
548 //Check if product adjustments exist and add models
549 if (module_exists('uc_attribute')) {
550 $adjustments = db_query("SELECT model FROM {uc_product_adjustments} WHERE nid = %d", $node->nid);
551 while ($adjustment = db_fetch_object($adjustments)) {
552 if (!in_array($adjustment->model, $models)) {
553 $models[$adjustment->model] = $adjustment->model;
554 }
555 }
556 }
557 //Check if editing or adding to set default values
558 if (!empty($feature)) {
559 $product_role = db_fetch_object(db_query("SELECT * FROM {uc_roles_products} WHERE pfid = %d", $feature['pfid']));
560 $default_model = $product_role->model;
561 $default_role = $product_role->rid;
562 $default_qty = $product_role->duration;
563 $default_granularity = $product_role->granularity;
564 $default_shippable = $product_role->shippable;
565 $default_by_quantity = $product_role->by_quantity;
566 $form['pfid'] = array(
567 '#type' => 'value',
568 '#value' => $feature['pfid'],
569 );
570 }
571 else {
572 $default_model = 0;
573 $default_role = variable_get('uc_roles_default_role', NULL);
574 $default_qty = (variable_get('uc_roles_default_granularity', 'never') == 'never') ? NULL : variable_get('uc_roles_default_length', NULL);
575 $default_granularity = variable_get('uc_roles_default_granularity', 'never');
576 $default_shippable = $node->shippable;
577 $default_by_quantity = 1;
578 }
579
580 $form['title'] = array(
581 '#type' => 'markup',
582 '#value' => '<h2>'. t('Role assignment') .'</h2>',
583 );
584 $form['nid'] = array(
585 '#type' => 'value',
586 '#value' => $node->nid,
587 );
588 $form['uc_roles_model'] = array(
589 '#type' => 'select',
590 '#title' => t('Model/SKU'),
591 '#default_value' => $default_model,
592 '#description' => t('This is the model/SKU of the product that will grant the role.'),
593 '#options' => $models,
594 );
595 $form['uc_roles_role'] = array(
596 '#type' => 'select',
597 '#title' => t('Role'),
598 '#default_value' => $default_role,
599 '#description' => t('This is the role the customer will receive after purchasing the product.'),
600 '#options' => _get_role_choices(),
601 );
602 $form['uc_roles_qty'] = array(
603 '#type' => 'textfield',
604 '#title' => t('Time until expiration'),
605 '#default_value' => $default_qty,
606 '#size' => 4,
607 '#maxlength' => 4,
608 '#prefix' => '<div class="expiration">',
609 '#suffix' => '</div>',
610 );
611 $form['uc_roles_granularity'] = array(
612 '#type' => 'select',
613 '#options' => array(
614 'never' => t('never'),
615 'day' => t('day(s)'),
616 'week' => t('week(s)'),
617 'month' => t('month(s)'),
618 'year' => t('year(s)')
619 ),
620 '#default_value' => $default_granularity,
621 '#attributes' => array( //Javascript to disable qty on never select
622 'onchange' => 'if (this.value == "never") {$("#edit-uc-roles-qty").attr("disabled", "disabled").val("");} else {$("#edit-uc-roles-qty").removeAttr("disabled");}'
623 ),
624 '#description' => t('This will set how long the specified role will last until it expires.'),
625 '#prefix' => '<div class="expiration">',
626 '#suffix' => '</div>',
627 );
628 $form['uc_roles_shippable'] = array(
629 '#type' => 'checkbox',
630 '#title' => t('Shippable product'),
631 '#default_value' => $default_shippable,
632 '#description' => t('Check if this product model/SKU that uses role assignment is associated with a shippable product.'),
633 );
634 $form['uc_roles_by_quantity'] = array(
635 '#type' => 'checkbox',
636 '#title' => t('Multiply by quantity'),
637 '#default_value' => $default_by_quantity,
638 '#description' => t('Check if the role duration should be multiplied by the quantity purchased.'),
639 );
640
641 return uc_product_feature_form($form);
642 }
643 function uc_roles_feature_form_validate($form_id, $form_values) {
644 if ($form_values['uc_roles_granularity'] != 'never' && intval($form_values['uc_roles_qty']) < 1) {
645 form_set_error('uc_roles_qty', t('The amount of time must be a positive integer.'));
646 }
647 if (empty($form_values['uc_roles_role'])) {
648 form_set_error('uc_roles_role', t('You must have a role to assign. You may need to <a href="!role_url">create a new role</a> or perhaps <a href="!feature_url">set role assignment defaults</a>.', array('!role_url' => url('admin/user/roles'), '!feature_url' => url('admin/store/settings/products/edit/features'))));
649 }
650 if ($product_roles = db_fetch_object(db_query("SELECT * FROM {uc_roles_products} WHERE nid = %d AND model = '%s' AND rid = %d", $form_values['nid'], $form_values['uc_roles_model'], $form_values['uc_roles_role'])) && $form_values['pfid'] == 0) {
651 form_set_error('uc_roles_role', t('The combination of model/SKU and role already exists for this product.'));
652 form_set_error('uc_roles_model', t(' '));
653 }
654 }
655 function uc_roles_feature_form_submit($form_id, $form_values) {
656 $description = (empty($form_values['uc_roles_model'])) ? t('<strong>SKU:</strong> Any<br/>') : t('<strong>SKU:</strong> !sku<br/>', array('!sku' => $form_values['uc_roles_model']));
657 $description .= t('<strong>Role:</strong> !role_name<br/>', array('!role_name' => _get_role_name($form_values['uc_roles_role'])));
658 switch ($form_values['uc_roles_granularity']) {
659 case 'never':
660 $description .= t('<strong>Expiration:</strong> never<br/>');
661 break;
662 case 'day':
663 $description .= t('<strong>Expiration:</strong> !qty day(s)<br/>', array('!qty' => $form_values['uc_roles_qty']));
664 break;
665 case 'week':
666 $description .= t('<strong>Expiration:</strong> !qty week(s)<br/>', array('!qty' => $form_values['uc_roles_qty']));
667 break;
668 case 'month':
669 $description .= t('<strong>Expiration:</strong> !qty month(s)<br/>', array('!qty' => $form_values['uc_roles_qty']));
670 break;
671 case 'year':
672 $description .= t('<strong>Expiration:</strong> !qty year(s)<br/>', array('!qty' => $form_values['uc_roles_qty']));
673 break;
674 default:
675 break;
676 }
677 $description .= ($form_values['uc_roles_shippable']) ? t('<strong>Shippable:</strong> Yes<br/>') : t('<strong>Shippable:</strong> No<br/>');
678 $shippable = ($form_values['uc_roles_shippable']) ? 1 : 0;
679 $description .= ($form_values['uc_roles_by_quantity']) ? t('<strong>Multiply by Quantity:</strong> Yes') : t('<strong>Multiply by Quantity:</strong> No');
680 $by_quantity = ($form_values['uc_roles_by_quantity']) ? 1 : 0;
681 $granularity = ($form_values['uc_roles_granularity'] != 'never') ? $form_values['uc_roles_granularity'] : NULL;
682 $duration = ($form_values['uc_roles_granularity'] != 'never') ? $form_values['uc_roles_qty'] : NULL;
683 $model = (!is_null($form_values['uc_roles_model'])) ? $form_values['uc_roles_model'] : NULL;
684
685 //Insert or update uc_roles_products table
686 if ($form_values['pfid'] == 0) {
687 $pfid = db_next_id('{uc_product_features}_pfid') + 1;
688 }
689 else {
690 $pfid = $form_values['pfid'];
691 db_query("DELETE FROM {uc_roles_products} WHERE pfid = %d", $pfid);
692 }
693
694 switch ($GLOBALS['db_type']) {
695 case 'mysqli':
696 case 'mysql':
697 db_query("INSERT INTO {uc_roles_products} (pfid, nid, model, rid, duration, granularity, by_quantity, shippable) VALUES (%d, %d, '%s', %d, %d, '%s', %d, %d)", $pfid, $form_values['nid'], $model, $form_values['uc_roles_role'], $duration, $granularity, $by_quantity, $shippable);
698 break;
699 case 'pgsql':
700 db_query("INSERT INTO {uc_roles_products} (pfid, nid, model, rid, duration, granularity, by_quantity, shippable) VALUES (%d, %d, '%s', %d, %d, '%s', '%d', '%d')", $pfid, $form_values['nid'], $model, $form_values['uc_roles_role'], $duration, $granularity, ($by_quantity ? 't' : 'f'), ($shippable ? 't' : 'f'));
701 break;
702 }
703
704 $data = array(
705 'pfid' => $pfid,
706 'nid' => $form_values['nid'],
707 'fid' => 'role',
708 'description' => $description,
709 );
710
711 return uc_product_feature_save($data);
712 }
713
714 /**
715 * Form builder for role settings
716 */
717 function uc_roles_feature_settings() {
718 uc_add_js('$(document).ready(function() { if ($("#edit-uc-roles-default-granularity").val() == "never") {$("#edit-uc-roles-default-length").attr("disabled", "disabled").val("");} });', 'inline');
719 $default_role_choices = user_roles(TRUE);
720 unset($default_role_choices[DRUPAL_AUTHENTICATED_RID]);
721 foreach (uc_order_status_list('general') as $status) {
722 $statuses[$status['id']] = $status['title'];
723 }
724
725 $form['uc_roles_default_order_status'] = array(
726 '#type' => 'select',
727 '#title' => t('Order status'),
728 '#default_value' => variable_get('uc_roles_default_order_status', 'completed'),
729 '#description' => t('Where in the order status that the role will be granted. Be aware that if payments are processed automatically, this happens before anonymous customers have an account created. This order status should not be reached before the user account exists.'),
730 '#options' => $statuses,
731 );
732 $form['uc_roles_default_length'] = array(
733 '#type' => 'textfield',
734 '#title' => t('Default expiration'),
735 '#default_value' => (variable_get('uc_roles_default_granularity', 'never') == 'never') ? NULL : variable_get('uc_roles_default_length', NULL),
736 '#size' => 4,
737 '#maxlength' => 4,
738 '#prefix' => '<div class="expiration">',
739 '#suffix' => '</div>',
740 );
741 $form['uc_roles_default_granularity'] = array(
742 '#type' => 'select',
743 '#default_value' => variable_get('uc_roles_default_granularity', 'never'),
744 '#options' => array(
745 'never' => t('never'),
746 'day' => t('day(s)'),
747 'week' => t('week(s)'),
748 'month' => t('month(s)'),
749 'year' => t('year(s)')
750 ),
751 '#description' => t('The default amount of time a granted &Uuml;bercart role will last until it expires.'),
752 '#prefix' => '<div class="expiration">',
753 '#suffix' => '</div>',
754 '#attributes' => array( //Javascript to disable qty on never select
755 'onchange' => 'if (this.value == "never") {$("#edit-uc-roles-default-length").attr("disabled", "disabled").val("");} else {$("#edit-uc-roles-default-length").removeAttr("disabled");}'
756 ),
757 );
758 $form['uc_roles_default_role'] = array(
759 '#type' => 'select',
760 '#title' => t('Default role'),
761 '#default_value' => variable_get('uc_roles_default_role', NULL),
762 '#description' => t('The default role &Uuml;bercart grants on specified products.'),
763 '#options' => _get_role_choices(),
764 );
765 $form['uc_roles_default_role_choices'] = array(
766 '#type' => 'checkboxes',
767 '#title' => t('Product roles'),
768 '#default_value' => variable_get('uc_roles_default_role_choices', array()),
769 '#multiple' => TRUE,
770 '#description' => t('These are roles that Ubercart can grant to customers who purchase specified products. If there are no choices here, you will need to <a href="!url">create new roles</a>.', array('!url' => url('admin/user/roles', 'destination=admin/store/settings/products/edit/features'))),
771 '#options' => $default_role_choices,
772 );
773 $form['uc_roles_expiration_display'] = array(
774 '#type' => 'fieldset',
775 '#title' => t('Expiration display'),
776 '#collapsible' => TRUE,
777 '#collapsed' => TRUE,
778 );
779 $form['uc_roles_expiration_display']['uc_roles_default_show_expiration'] = array(
780 '#type' => 'checkbox',
781 '#title' => t('Show expirations on user page'),
782 '#default_value' => variable_get('uc_roles_default_show_expiration', TRUE),
783 '#description' => t('If users have any role expirations they will be displayed on their account page.'),
784 );
785 $form['uc_roles_expiration_display']['uc_roles_default_expiration_header'] = array(
786 '#type' => 'textfield',
787 '#title' => t('Header'),
788 '#default_value' => variable_get('uc_roles_default_expiration_header', uc_get_message('uc_roles_user_expiration_header')),
789 );
790 $form['uc_roles_expiration_display']['uc_roles_default_expiration_title'] = array(
791 '#type' => 'textfield',
792 '#title' => t('Title'),
793 '#default_value' => variable_get('uc_roles_default_expiration_title', uc_get_message('uc_roles_user_expiration_title')),
794 );
795 $form['uc_roles_expiration_display']['uc_roles_default_expiration_message'] = array(
796 '#type' => 'textfield',
797 '#title' => t('Message'),
798 '#default_value' => variable_get('uc_roles_default_expiration_message', uc_get_message('uc_roles_user_expiration_message')),
799 '#description' => t('The message, with its accompanying title, and the header displayed above all role expirations. In the <strong>Title</strong> & <strong>Message</strong> fields "!role_name" and "!date" will translate to the corresponding Drupal role name and role expiration date.'),
800 );
801 return $form;
802 }
803
804 /**
805 * Form builder for role notification settings.
806 */
807 function uc_roles_notify_settings() {
808 uc_add_js('$(document).ready(function() { if ($("#edit-uc-roles-reminder-granularity").val() == "never") {$("#edit-uc-roles-reminder-length").attr("disabled", "disabled").val("");} });', 'inline');
809
810 //Set Granted Notifications
811 $form['grant'] = array(
812 '#type' => 'fieldset',
813 '#title' => t('Granted message'),
814 '#collapsible' => TRUE,
815 '#collapsed' => TRUE,
816 );
817 $form['grant']['uc_roles_grant_notification'] = array(
818 '#type' => 'checkbox',
819 '#default_value' => variable_get('uc_roles_grant_notification', FALSE),
820 '#title' => t('Send email after customer receives new role'),
821 );
822 $form['grant']['uc_roles_grant_notification_subject'] = array(
823 '#type' => 'textfield',
824 '#title' => t('Message subject'),
825 '#default_value' => variable_get('uc_roles_grant_notification_subject', uc_get_message('uc_roles_grant_subject')),
826 );
827 $form['grant']['uc_roles_grant_notification_message'] = array(
828 '#type' => 'textarea',
829 '#title' => t('Message text'),
830 '#default_value' => variable_get('uc_roles_grant_notification_message', uc_get_message('uc_roles_grant_message')),
831 '#description' => t('The message the user receives when granted a new role (<a href="!url">uses order, uc_roles, and global tokens</a>).', array('!url' => url('admin/store/help/tokens'))),
832 '#rows' => 10,
833 );
834 $form['grant']['uc_roles_grant_notification_format'] = filter_form(variable_get('uc_roles_grant_notification_format', FILTER_FORMAT_DEFAULT), NULL, array('uc_roles_grant_notification_format'));
835
836 //Set Revocation Notifications
837 $form['revoke'] = array(
838 '#type' => 'fieldset',
839 '#title' => t('Expiration message'),
840 '#collapsible' => TRUE,
841 '#collapsed' => TRUE,
842 );
843 $form['revoke']['uc_roles_revocation_notification'] = array(
844 '#type' => 'checkbox',
845 '#default_value' => variable_get('uc_roles_revocation_notification', FALSE),
846 '#title' => t('Send email after customer loses role'),
847 );
848 $form['revoke']['uc_roles_revocation_notification_subject'] = array(
849 '#type' => 'textfield',
850 '#title' => t('Message subject'),
851 '#default_value' => variable_get('uc_roles_revocation_notification_subject', uc_get_message('uc_roles_revoke_subject')),
852 );
853 $form['revoke']['uc_roles_revocation_notification_message'] = array(
854 '#type' => 'textarea',
855 '#title' => t('Message text'),
856 '#default_value' => variable_get('uc_roles_revocation_notification_message', uc_get_message('uc_roles_revoke_message')),
857 '#description' => t('The message the user receives when a role expires (<a href="!url">uses order, uc_roles, and global tokens</a>).', array('!url' => url('admin/store/help/tokens'))),
858 '#rows' => 10,
859 );
860 $form['revoke']['uc_roles_revocation_notification_format'] = filter_form(variable_get('uc_roles_revocation_notification_format', FILTER_FORMAT_DEFAULT), NULL, array('uc_roles_revocation_notification_format'));
861
862 //Set Renewal Notifications
863 $form['renew'] = array(
864 '#type' => 'fieldset',
865 '#title' => t('Renewal message'),
866 '#collapsible' => TRUE,
867 '#collapsed' => TRUE,
868 );
869 $form['renew']['uc_roles_renewal_notification'] = array(
870 '#type' => 'checkbox',
871 '#default_value' => variable_get('uc_roles_renewal_notification', FALSE),
872 '#title' => t('Send email after customer renews existing role'),
873 );
874 $form['renew']['uc_roles_renewal_notification_subject'] = array(
875 '#type' => 'textfield',
876 '#title' => t('Message subject'),
877 '#default_value' => variable_get('uc_roles_renewal_notification_subject', uc_get_message('uc_roles_renew_subject')),
878 );
879 $form['renew']['uc_roles_renewal_notification_message'] = array(
880 '#type' => 'textarea',
881 '#title' => t('Message text'),
882 '#default_value' => variable_get('uc_roles_renewal_notification_message', uc_get_message('uc_roles_renew_message')),
883 '#description' => t('The message the user receives when a role is renewed (<a href="!url">uses order, uc_roles, and global tokens</a>).', array('!url' => url('admin/store/help/tokens'))),
884 '#rows' => 10,
885 );
886 $form['renew']['uc_roles_renewal_notification_format'] = filter_form(variable_get('uc_roles_renewal_notification_format', FILTER_FORMAT_DEFAULT), NULL, array('uc_roles_renewal_notification_format'));
887
888 //Set Reminder Notifications
889 $form['reminder'] = array(
890 '#type' => 'fieldset',
891 '#title' => t('Expiration reminder message'),
892 '#collapsible' => TRUE,
893 '#collapsed' => TRUE,
894 );
895 $form['reminder']['uc_roles_reminder_length'] = array(
896 '#type' => 'textfield',
897 '#title' => t('Time before reminder'),
898 '#default_value' => (variable_get('uc_roles_reminder_granularity', 'never') == 'never') ? NULL : variable_get('uc_roles_reminder_length', NULL),
899 '#size' => 4,
900 '#maxlength' => 4,
901 '#prefix' => '<div class="expiration">',
902 '#suffix' => '</div>',
903 );
904 $form['reminder']['uc_roles_reminder_granularity'] = array(
905 '#type' => 'select',
906 '#default_value' => variable_get('uc_roles_reminder_granularity', 'never'),
907 '#options' => array(
908 'never' => t('never'),
909 'day' => t('day(s)'),
910 'week' => t('week(s)'),
911 'month' => t('month(s)'),
912 'year' => t('year(s)')
913 ),
914 '#description' => t('The amount of time before a role expiration takes place that a customer is notified of its expiration.'),
915 '#prefix' => '<div class="expiration">',
916 '#suffix' => '</div>',
917 '#attributes' => array( //Javascript to disable qty on never select
918 'onchange' => 'if (this.value == "never") {$("#edit-uc-roles-reminder-length").attr("disabled", "disabled").val("");} else {$("#edit-uc-roles-reminder-length").removeAttr("disabled");}'
919 ),
920 );
921 $form['reminder']['uc_roles_reminder_subject'] = array(
922 '#type' => 'textfield',
923 '#title' => t('Message subject'),
924 '#default_value' => variable_get('uc_roles_reminder_subject', uc_get_message('uc_roles_reminder_subject')),
925 );
926 $form['reminder']['uc_roles_reminder_message'] = array(
927 '#type' => 'textarea',
928 '#title' => t('Message text'),
929 '#default_value' => variable_get('uc_roles_reminder_message', uc_get_message('uc_roles_reminder_message')),
930 '#description' => t('The message the user receives reminding them of the role expiration (<a href="!url">uses order, uc_roles, and global tokens</a>).', array('!url' => url('admin/store/help/tokens'))),
931 '#rows' => 10,
932 );
933 $form['reminder']['uc_roles_reminder_format'] = filter_form(variable_get('uc_roles_reminder_format', FILTER_FORMAT_DEFAULT), NULL, array('uc_roles_reminder_format'));
934
935 return system_settings_form($form);
936 }
937
938 /* ************************************************************************* *
939 * Module and Helper Functions *
940 * ************************************************************************* */
941
942 /**
943 * Function sends a specified message to a user regarding role status
944 *
945 * @param $status
946 * The condition of role status
947 * - grant: new role
948 * - revoke: loose role
949 * - renew: update role's expirations date
950 * - reminder: expiration will occur soon
951 * @param $user
952 * The Drupal user object
953 * @param $role
954 * The role expiration object associated with message
955 * @param $order
956 * The order object associated with message
957 * @return:
958 * Sends result of drupal_mail
959 */
960 function _role_email_user($status, $user, $role, $order = NULL) {
961 $token_filters = array('global' => NULL, 'user' =><