Subversion Repositories sopac

Rev

Rev 145 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
22 jblyberg 1
<?php
2
/**
3
 * SOPAC is The Social OPAC: a Drupal module that serves as a wholly integrated web OPAC for the Drupal CMS
4
 * This file contains the Drupal include functions for all the SOPAC admin pieces and configuration options
5
 * This file is called via hook_user
6
 *
7
 * @package SOPAC
102 jblyberg 8
 * @version 2.1
22 jblyberg 9
 * @author John Blyberg
10
 */
11
 
12
/**
13
 * This is a sub-function of the hook_user "view" operation.
14
 */
15
function sopac_user_view($op, &$edit, &$account, $category = NULL) {
135 smaskit 16
  $locum = sopac_get_locum();
99 jblyberg 17
  // SOPAC uses the first 7 characters of the MD5 hash instead of caching the user's password
18
  // like it used to do.  It's more secure this way, IMHO.
19
  $account->locum_pass = substr($account->pass, 0, 7);
22 jblyberg 20
 
99 jblyberg 21
  // Patron information table (top of the page)
22
  $patron_details_table = sopac_user_info_table($account, $locum);
23
  if (variable_get('sopac_summary_enable', 1)) {
24
    $result['patroninfo']['#title'] = t('Account Summary');
25
    $result['patroninfo']['#weight'] = 1;
26
    $result['patroninfo']['#type'] = 'user_profile_category';
27
    $result['patroninfo']['details']['#value'] = $patron_details_table;
28
  }
144 kloostere 29
 
99 jblyberg 30
  // Patron checkouts (middle of the page)
31
  if ($account->valid_card && $account->bcode_verify) {
32
    $co_table = sopac_user_chkout_table($account, $locum);
33
    if ($co_table) {
34
      $result['patronco']['#title'] = t('Checked-out Items');
35
      $result['patronco']['#weight'] = 2;
36
      $result['patronco']['#type'] = 'user_profile_category';
37
      $result['patronco']['details']['#value'] = $co_table;
38
    }
39
  }
22 jblyberg 40
 
99 jblyberg 41
  // Patron holds (bottom of the page)
42
  if ($account->valid_card && $account->bcode_verify) {
131 smaskit 43
    $holds_table = drupal_get_form('sopac_user_holds_form');
99 jblyberg 44
    if ($holds_table) {
45
      $result['patronholds']['#title'] = t('Requested Items');
46
      $result['patronholds']['#weight'] = 3;
47
      $result['patronholds']['#type'] = 'user_profile_category';
48
      $result['patronholds']['details']['#value'] = $holds_table;
49
    }
50
  }
22 jblyberg 51
 
99 jblyberg 52
  // Commit the page content
53
  $account->content[] = $result;
144 kloostere 54
 
99 jblyberg 55
  // The Summary is not really needed.
144 kloostere 56
  if (variable_get('sopac_history_hide', 1)) {
57
    unset($account->content['summary']);
58
  }
99 jblyberg 59
  unset($account->content['Preferences']);
22 jblyberg 60
}
61
 
62
/**
63
 * Returns a Drupal themed table of patron information for the "My Account" page.
64
 *
65
 * @param object $account Drupal user object for account being viewed
66
 * @param object $locum Instansiated Locum object
67
 * @return string Drupal themed table
68
 */
69
function sopac_user_info_table(&$account, &$locum) {
70
 
99 jblyberg 71
  $rows = array();
144 kloostere 72
 
99 jblyberg 73
  // create home branch link if appropriate
74
  if ($account->profile_pref_home_branch) {
75
    $home_branch_link = l($account->profile_pref_home_branch, 'user/' . $account->uid . '/edit/Preferences');
76
  }
102 jblyberg 77
  elseif (variable_get('sopac_home_selector_options', FALSE)) {
99 jblyberg 78
    $home_branch_link = l(t('Click to select your home branch'), 'user/' . $account->uid . '/edit/Preferences');
79
  }
144 kloostere 80
  else {
81
    $home_branch_link = NULL;
82
  }
83
 
99 jblyberg 84
  if ($account->profile_pref_cardnum) {
85
    $cardnum = $account->profile_pref_cardnum;
144 kloostere 86
    $cardnum_link = l($cardnum, 'user/' . $account->uid . '/edit/Preferences');
99 jblyberg 87
    $userinfo = $locum->get_patron_info($cardnum);
88
    $bcode_verify = sopac_bcode_isverified($account);
23 jblyberg 89
 
144 kloostere 90
    if ($bcode_verify) {
91
      $account->bcode_verify = TRUE;
92
    }
93
    else {
94
      $account->bcode_verify = FALSE;
95
    }
96
    if ($userinfo['pnum']) {
97
      $account->valid_card = TRUE;
98
    }
99
    else {
100
      $account->valid_card = FALSE;
101
    }
23 jblyberg 102
 
99 jblyberg 103
    // Construct the user details table based on what is configured in the admin interface
104
    if ($account->valid_card && $bcode_verify) {
105
      if (variable_get('sopac_pname_enable', 1)) {
106
        $rows[] = array(array('data' => t('Patron Name'), 'class' => 'attr_name'), $userinfo['name']);
107
      }
108
      if (variable_get('sopac_lcard_enable', 1)) {
109
        $rows[] = array(array('data' => t('Library Card Number'), 'class' => 'attr_name'), $cardnum_link);
110
      }
123 jblyberg 111
      // Add row for home branch if appropriate
99 jblyberg 112
      if ($home_branch_link) {
113
        $rows[] = array(array('data' => t('Home Branch'), 'class' => 'attr_name'), $home_branch_link);
114
      }
123 jblyberg 115
      // Checkout history, if it's turned on
116
      if (variable_get('sopac_checkout_history_enable', 0)) {
117
        $cohist_enabled = $user->profile_pref_cohist ? 'Enabled' : 'Disabled';
118
        $last_import = db_result(db_query("SELECT DATESUB(NOW() - last_hist_check) FROM {sopac_last_hist_check} WHERE uid = '" . $user->uid . "'"));
119
        if ($cohist_enabled = 'Enabled') {
120
          // TODO Check ILS, enable it if it's not (w/ cache check)
121
          // Grab + update newest checkouts
144 kloostere 122
        }
123
        else {
123 jblyberg 124
          // TODO Check ILS, disable it is it's not (w/ cache check)
125
        }
126
        // Reset cache age
127
        db_query("UPDATE {sopac_last_hist_check} SET last_hist_check = NOW()");
144 kloostere 128
        $rows[] = array(array('data' => t('Checkout History'), 'class' => 'attr_name'), l($cohist_enabled, 'user/checkout/history'));
123 jblyberg 129
      }
99 jblyberg 130
      if (variable_get('sopac_numco_enable', 1)) {
131
        $rows[] = array(array('data' => t('Items Checked Out'), 'class' => 'attr_name'), $userinfo['checkouts']);
132
      }
133
      if (variable_get('sopac_fines_display', 1) && variable_get('sopac_fines_enable', 1)) {
144 kloostere 134
        $amount_link = l('$' . number_format($userinfo['balance'], 2, '.', ''), 'user/fines');
99 jblyberg 135
        $rows[] = array(array('data' => t('Fine Balance'), 'class' => 'attr_name'), $amount_link);
136
      }
137
      if (variable_get('sopac_cardexp_enable', 1)) {
138
        $rows[] = array(array('data' => t('Card Expiration Date'), 'class' => 'attr_name'), date('m-d-Y', $userinfo['expires']));
139
      }
140
      if (variable_get('sopac_tel_enable', 1)) {
141
        $rows[] = array(array('data' => t('Telephone'), 'class' => 'attr_name'), $userinfo['tel1']);
142
      }
144 kloostere 143
    }
144
    else {
99 jblyberg 145
      $rows[] = array(array('data' => t('Library Card Number'), 'class' => 'attr_name'), $cardnum_link);
146
    }
144 kloostere 147
  }
148
  else {
145 kloostere 149
    $cardnum_link = l(t('Click to add your library card'), 'user/' . $account->uid . '/edit/Preferences');
99 jblyberg 150
    $rows[] = array(array('data' => t('Library Card Number'), 'class' => 'attr_name'), $cardnum_link);
151
    // add row for home branch if appropriate
152
    if ($home_branch_link) {
153
      $rows[] = array(array('data' => t('Home Branch'), 'class' => 'attr_name'), $home_branch_link);
154
    }
155
  }
22 jblyberg 156
 
144 kloostere 157
  if ($account->mail && variable_get('sopac_email_enable', 1)) {
99 jblyberg 158
    $rows[] = array(array('data' => t('Email'), 'class' => 'attr_name'), $account->mail);
159
  }
22 jblyberg 160
 
99 jblyberg 161
  // Begin creating the user information display content
162
  $user_info_disp = theme('table', NULL, $rows, array('id' => 'patroninfo-summary', 'cellspacing' => '0'));
144 kloostere 163
 
99 jblyberg 164
  if ($account->valid_card && !$bcode_verify) {
165
    $user_info_disp .= '<div class="error">' . variable_get('sopac_uv_cardnum', t('The card number you have provided has not yet been verified by you.  In order to make sure that you are the rightful owner of this library card number, we need to ask you some simple questions.')) . '</div>' . drupal_get_form('sopac_bcode_verify_form', $account->uid, $cardnum);
144 kloostere 166
  }
167
  elseif ($cardnum && !$account->valid_card) {
107 jblyberg 168
    $user_info_disp .= '<div class="error">' . variable_get('sopac_invalid_cardnum', t('It appears that the library card number stored on our website is invalid. If you have received a new card, or feel that this is an error, please click on the card number above to change it to your most recent library card. If you need further help, please contact us.')) . '</div>';
99 jblyberg 169
  }
22 jblyberg 170
 
99 jblyberg 171
  return $user_info_disp;
22 jblyberg 172
}
173
 
174
/**
175
 * Returns a Drupal-themed table of checked-out items as well as the renewal form functionality.
176
 *
177
 * @param object $account Drupal user object for account being viewed
178
 * @param object $locum Instansiated Locum object
179
 * @return string Drupal themed table
180
 */
38 jblyberg 181
function sopac_user_chkout_table(&$account, &$locum, $max_disp = NULL) {
22 jblyberg 182
 
99 jblyberg 183
  // Process any renew requests that have been submitted
184
  if ($_POST['sub_type'] == 'Renew Selected') {
185
    if (count($_POST['inum'])) {
186
      foreach ($_POST['inum'] as $inum => $varname) {
187
        $items[$inum] = $varname;
188
      }
189
      $renew_status = $locum->renew_items($account->profile_pref_cardnum, $account->locum_pass, $items);
190
    }
144 kloostere 191
  }
192
  elseif ($_POST['sub_type'] == 'Renew All') {
99 jblyberg 193
    $renew_status = $locum->renew_items($account->profile_pref_cardnum, $account->locum_pass, 'all');
194
  }
24 jblyberg 195
 
99 jblyberg 196
  // Create the check-outs table
197
  $rows = array();
198
  if ($account->profile_pref_cardnum) {
199
    $locum_pass = substr($account->pass, 0, 7);
200
    $cardnum = $account->profile_pref_cardnum;
201
    $checkouts = $locum->get_patron_checkouts($cardnum, $locum_pass);
24 jblyberg 202
 
144 kloostere 203
    if (!count($checkouts)) {
204
      return t('No items checked out.');
205
    }
99 jblyberg 206
    $header = array('',t('Title'),t('Due Date'));
207
    foreach ($checkouts as $co) {
208
      if ($renew_status[$co['inum']]['error']) {
209
        $duedate = '<span style="color: red;">' . $renew_status[$co['inum']]['error'] . '</span>';
144 kloostere 210
      }
211
      else {
99 jblyberg 212
        if (time() > $co['duedate']) {
213
          $duedate = '<span style="color: red;">' . date('m-d-Y', $co['duedate']) . '</span>';
144 kloostere 214
        }
215
        else {
99 jblyberg 216
          $duedate = date('m-d-Y', $co['duedate']);
217
        }
218
      }
144 kloostere 219
 
99 jblyberg 220
      $rows[] = array(
221
        '<input type="checkbox" name="inum[' . $co['inum'] . ']" value="' . $co['varname'] . '">',
144 kloostere 222
        l($co['title'], 'catalog/record/' . $co['bnum']),
99 jblyberg 223
        $duedate,
224
      );
225
    }
226
    $submit_buttons = '<input type="submit" name="sub_type" value="' . t('Renew Selected') . '"> <input type="submit" name="sub_type" value="' . t('Renew All') . '">';
227
    $rows[] = array( 'data' => array(array('data' => $submit_buttons, 'colspan' => 3)), 'class' => 'profile_button' );
144 kloostere 228
  }
229
  else {
99 jblyberg 230
    return FALSE;
231
  }
144 kloostere 232
 
99 jblyberg 233
  // Wrap it together inside a form
234
  $content = '<form method="post">' . theme('table', $header, $rows, array('id' => 'patroninfo', 'cellspacing' => '0')) . '</form>';
235
  return $content;
22 jblyberg 236
}
237
 
238
/**
131 smaskit 239
 * Use form API to creat holds table
22 jblyberg 240
 *
131 smaskit 241
 * @return string
22 jblyberg 242
 */
131 smaskit 243
function sopac_user_holds_form() {
244
  global $user;
245
  $form = array();
144 kloostere 246
 
131 smaskit 247
  $cardnum = $user->profile_pref_cardnum;
248
  $ils_pass = $user->locum_pass;
135 smaskit 249
  $locum = sopac_get_locum();
131 smaskit 250
  $holds = $locum->get_patron_holds($cardnum, $ils_pass);
144 kloostere 251
 
131 smaskit 252
  if (!count($holds)) {
253
    $form['empty'] = array(
254
      '#type' => 'markup',
255
      '#value' => t('No items on hold.'),
256
    );
257
    return $form;
258
  }
144 kloostere 259
 
137 smaskit 260
  $suspend_holds = variable_get('sopac_suspend_holds', FALSE);
261
  if ($suspend_holds) {
144 kloostere 262
    return _sopac_user_holds_form_multirow($holds);
131 smaskit 263
  }
144 kloostere 264
 
142 smaskit 265
  $form = array(
266
    '#theme' => 'form_theme_bridge',
267
    '#layout_theme' => 'sopac_user_holds_list',
268
  );
144 kloostere 269
 
131 smaskit 270
  $sopac_prefix = variable_get('sopac_url_prefix', 'cat/seek') . '/record/';
99 jblyberg 271
  $freezes_enabled = variable_get('sopac_hold_freezes_enable', 1);
144 kloostere 272
 
142 smaskit 273
  $form['holds'] = array(
274
    '#tree' => TRUE,
131 smaskit 275
    '#iterable' => TRUE,
276
  );
277
  foreach ($holds as $hold) {
278
    $bnum = $hold['bnum'];
279
    $hold_to_theme = array();
144 kloostere 280
 
131 smaskit 281
    if ($freezes_enabled) {
142 smaskit 282
      $hold_to_theme['cancel'] = array(
131 smaskit 283
        '#type' => 'checkbox',
284
        '#default_value' => FALSE,
285
      );
286
    }
287
    $hold_to_theme['title_link'] = array(
288
      '#type' => 'markup',
289
      '#value' => l(t($hold['title']), $sopac_prefix . $bnum),
290
    );
291
    $hold_to_theme['status'] = array(
292
      '#type' => 'markup',
293
      '#value' => $hold['status']
294
    );
295
    $hold_to_theme['pickup'] = array(
296
      '#type' => 'markup',
297
      '#value' => $hold['pickuploc']['options'][$hold['pickuploc']['selected']],
298
    );
299
    if ($freezes_enabled) {
300
      if ($hold['can_freeze']) {
142 smaskit 301
        $hold_to_theme['freeze'] = array(
131 smaskit 302
          '#type' => 'checkbox',
303
          '#default_value' => $hold['is_frozen'],
304
        );
99 jblyberg 305
      }
131 smaskit 306
      else {
307
        $hold_to_theme['freeze'] = array(
308
          '#type' => 'markup',
309
          '#value' => '&nbsp;'
310
        );
99 jblyberg 311
      }
312
    }
144 kloostere 313
 
142 smaskit 314
    $form['holds'][$bnum] = $hold_to_theme;
131 smaskit 315
  }
144 kloostere 316
 
131 smaskit 317
  $form['submit'] = array(
318
    '#type' => 'submit',
319
    '#name' => 'op',
320
    '#value' => $freezes_enabled ? t('Update Holds') : t('Cancel Selected Holds'),
321
  );
144 kloostere 322
 
131 smaskit 323
  return $form;
324
}
325
 
326
/**
327
 * Validate request to change holds.
328
 *
329
 * @param array $form
330
 * @param array $form_state
331
 */
332
function sopac_user_holds_form_validate(&$form, &$form_state) {
333
  global $user;
334
  // Set defaults to avoid errors when debugging.
335
  $pickup_changes = $suspend_from_changes = $suspend_to_changes = NULL;
144 kloostere 336
 
142 smaskit 337
  $update_holds = FALSE;
338
  $cancellations = array();
339
  $freeze_changes = array();
340
  $pickup_changes = array();
341
  $suspend_from_changes = array();
342
  $suspend_to_changes = array();
144 kloostere 343
 
131 smaskit 344
  // Get holds.
345
  $cardnum = $user->profile_pref_cardnum;
346
  $password = $user->locum_pass;
135 smaskit 347
  $locum = sopac_get_locum();
131 smaskit 348
  $holds = $locum->get_patron_holds($cardnum, $password);
349
  // Should be how it comes back from locum
350
  $holds_by_bnum = array();
351
  foreach ($holds as $hold) {
352
    $holds_by_bnum[$hold['bnum']] = $hold;
353
  }
142 smaskit 354
  $submitted_holds = $form_state['values']['holds'];
144 kloostere 355
 
142 smaskit 356
  $change_pickup = variable_get('sopac_changeable_pickup_location', FALSE);
357
  $suspend_holds = variable_get('sopac_suspend_holds', FALSE);
358
  if ($suspend_holds) {
359
    // Set up time object for use in validating suspension dates
360
    $locum = sopac_get_locum();
361
    $sClosedByTimezone = $locum->locum_config['harvest_config']['timezone'];
362
    $date_object = new DateTime(now, new DateTimeZone($sClosedByTimezone));
363
  }
144 kloostere 364
 
142 smaskit 365
  foreach ($submitted_holds as $bnum => $hold_data) {
144 kloostere 366
    if ($hold_data['cancel']) {
146 smaskit 367
      $cancellations[$bnum] = TRUE;
144 kloostere 368
      $update_holds = TRUE;
369
      continue;
370
    }
371
    $freeze_requested = $hold_data['freeze'];
372
    if ($freeze_requested != $holds_by_bnum[$bnum]['is_frozen']) {
373
      $freeze_changes[$bnum] = $freeze_requested;
374
      $update_holds = TRUE;
375
    }
142 smaskit 376
    if ($change_pickup) {
377
      $pickup_location = $hold_data['pickup'];
144 kloostere 378
      if ($pickup_location != $holds_by_bnum[$bnum]['pickuploc']['selected']) {
379
        $pickup_changes[$bnum] = $pickup_location;
380
        $update_holds = TRUE;
381
      }
99 jblyberg 382
    }
142 smaskit 383
    if ($suspend_holds) {
384
      $suspend_from = $hold_data['suspend_from'];
134 smaskit 385
      // Catch unchanged default.
386
      if ($suspend_from == 'mm/dd/yyyy') {
142 smaskit 387
        $suspend_from = '';
134 smaskit 388
      }
137 smaskit 389
      // Make sure it's a date (allow 2-digit years, but ask for 4).
142 smaskit 390
      elseif (!preg_match('/^([1-9]|1[012])\/([1-9]|[12][0-9]|3[01])\/(20[1-9][0-9]|[1-9][0-9])$/', $suspend_from)) {
144 kloostere 391
        form_set_error("holds[$bnum][suspend_from", t('Please enter suspend dates in the form 4/15/1980 (mm/dd/yyyy).'));
134 smaskit 392
      }
144 kloostere 393
      elseif ($suspend_from != $holds_by_bnum[$bnum]['start_suspend']) {
394
        $suspend_from_changes[$bnum] = $suspend_from;
395
        $update_holds = TRUE;
396
      }
397
 
142 smaskit 398
      $suspend_to = $hold_data['suspend_to'];
134 smaskit 399
      // Catch unchanged default.
400
      if ($suspend_to == 'mm/dd/yyyy') {
144 kloostere 401
        $suspend_to = '';
134 smaskit 402
      }
137 smaskit 403
      // Make sure it's a date (allow 2-digit years, but ask for 4).
142 smaskit 404
      elseif (!preg_match('/^([1-9]|1[012])\/([1-9]|[12][0-9]|3[01])\/(20[1-9][0-9]|[1-9][0-9])$/', $suspend_to)) {
144 kloostere 405
        form_set_error("holds[$bnum][suspend_to", t('Please enter suspend dates in the form 4/15/1980 (mm/dd/yyyy).'));
134 smaskit 406
      }
144 kloostere 407
      elseif ($suspend_to != $holds_by_bnum[$bnum]['end_suspend']) {
408
        $suspend_to_changes[$bnum] = $suspend_to;
409
        $update_holds = TRUE;
410
      }
411
      if ($suspend_to && !$suspend_from) {
412
        form_set_error("holds][$bnum][suspend_to", t('You cannot set a suspend to date without a corresponding suspend from date.'));
413
      }
414
      elseif ($suspend_to && $suspend_from) {
142 smaskit 415
        $date_parts = explode('/', $suspend_from);
134 smaskit 416
        $date_object->setDate($date_parts[2], $date_parts[0], $date_parts[1]);
417
        $from_date = $date_object->format('Ymd');
418
        $date_parts = explode('/', $suspend_to);
419
        $date_object->setDate($date_parts[2], $date_parts[0], $date_parts[1]);
420
        $to_date = $date_object->format('Ymd');
421
        if ($to_date < $from_date) {
144 kloostere 422
          form_set_error("holds[$bnum][suspend_to", t('A suspend to date cannot be before the corresponding suspend from date.'));
134 smaskit 423
        }
144 kloostere 424
      }
131 smaskit 425
    }
99 jblyberg 426
  }
144 kloostere 427
 
137 smaskit 428
  $errors = form_get_errors();
429
  if (is_array($errors)) {
144 kloostere 430
    // Skip rest of this structure.
137 smaskit 431
  }
432
  elseif (!$update_holds) {
144 kloostere 433
    form_set_error('', 'Your request to ' . $form['submit']['#value'] . ' did not include any changes.');
131 smaskit 434
  }
435
  // Store data for use by submit function.
436
  else {
144 kloostere 437
    $form_state['sopac_user_holds'] = array(
438
     'cancellations' => $cancellations,
439
     'freeze_changes' => $freeze_changes,
440
     'pickup_changes' => $pickup_changes,
441
     'suspend_from_changes' => $suspend_from_changes,
442
     'suspend_to_changes' => $suspend_to_changes,
443
    );
131 smaskit 444
  }
22 jblyberg 445
}
446
 
447
/**
131 smaskit 448
 * Pass locum validated request to update holds.
449
 *
450
 * @param array $form
451
 * @param array $form_state
452
 */
453
function sopac_user_holds_form_submit(&$form, &$form_state) {
454
  global $user;
455
  $cardnum = $user->profile_pref_cardnum;
456
  $password = $user->locum_pass;
457
  $cancellations = $form_state['sopac_user_holds']['cancellations'];
458
  $freeze_changes = $form_state['sopac_user_holds']['freeze_changes'];
459
  $pickup_changes = $form_state['sopac_user_holds']['pickup_changes'];
460
  $suspend_changes = array(
461
    'from' => $form_state['sopac_user_holds']['suspend_from_changes'],
462
    'to' => $form_state['sopac_user_holds']['suspend_to_changes'],
463
  );
135 smaskit 464
  $locum = sopac_get_locum();
131 smaskit 465
  $locum->update_holds($cardnum, $password, $cancellations, $freeze_changes, $pickup_changes, $suspend_changes);
466
}
467
 
468
/**
144 kloostere 469
 * Fork to allow support for changing hold pickup location, and suspend dates. Uses
137 smaskit 470
 * different tpl since extra options require different layout.
131 smaskit 471
 *
472
 * @param array $holds
473
 * @return array
474
 */
140 smaskit 475
function _sopac_user_holds_form_multirow($holds) {
131 smaskit 476
  // <CraftySpace+> TODO: do we need to check for multi-branch, else no pickup location?
477
  $form = array(
478
    '#theme' => 'form_theme_bridge',
142 smaskit 479
    '#layout_theme' => 'sopac_user_holds_list_multirow',
131 smaskit 480
  );
144 kloostere 481
 
131 smaskit 482
  $sopac_prefix = variable_get('sopac_url_prefix', 'cat/seek') . '/record/';
142 smaskit 483
  $form['holds'] = array(
484
    '#tree' => TRUE,
131 smaskit 485
    '#iterable' => TRUE,
486
  );
487
  foreach ($holds as $hold) {
488
    $bnum = $hold['bnum'];
144 kloostere 489
 
142 smaskit 490
    $form['holds'][$bnum] = array(
491
      'cancel' => array(
492
        '#type' => 'checkbox',
493
        '#default_value' => FALSE,
494
      ),
495
      'title_link' => array(
496
        '#type' => 'markup',
497
        '#value' => l(t($hold['title']), $sopac_prefix . $bnum),
498
      ),
499
      'status' => array(
500
        '#type' => 'markup',
501
        '#value' => $hold['status']
502
      ),
503
      'pickup' => array(
504
        '#type' => 'select',
505
        '#options' => sopac_get_branch_options(),
506
        '#default_value' => $hold['pickuploc']['selected'],
507
      ),
508
      'freeze' => array(
509
        '#type' => 'radios',
510
        '#default_value' => $hold['is_frozen'],
511
        '#options' => array(0 => t('Active'), 1 => t('Inactive')),
512
      ),
513
      'suspend_from' => array(
514
        '#type' => 'textfield',
515
        '#title' => 'From',
516
        '#default_value' => $hold['start_suspend'] ? $hold['start_suspend'] : 'mm/dd/yyyy',
517
        '#attributes' => array('maxlength' => '10', 'size' => '15'),
518
      ),
519
      'suspend_to' => array(
520
        '#type' => 'textfield',
521
        '#title' => 'To',
522
        '#default_value' => $hold['end_suspend'] ? $hold['end_suspend'] : 'mm/dd/yyyy',
523
        '#attributes' => array('maxlength' => '10', 'size' => '15'),
524
      ),
131 smaskit 525
    );
526
  }
144 kloostere 527
 
131 smaskit 528
  $form['submit'] = array(
529
    '#type' => 'submit',
530
    '#name' => 'op',
531
    '#value' => t('Update Holds'),
532
  );
144 kloostere 533
 
131 smaskit 534
  return $form;
535
}
536
 
537
/**
33 jblyberg 538
 * A dedicated check-outs page to list all checkouts.
539
 */
540
function sopac_checkouts_page() {
99 jblyberg 541
  global $user;
144 kloostere 542
 
100 jblyberg 543
  $account = user_load($user->uid);
544
  $cardnum = $account->profile_pref_cardnum;
135 smaskit 545
  $locum = sopac_get_locum();
100 jblyberg 546
  $userinfo = $locum->get_patron_info($cardnum);
547
  $bcode_verify = sopac_bcode_isverified($account);
144 kloostere 548
  if ($bcode_verify) {
549
    $account->bcode_verify = TRUE;
550
  }
551
  else {
552
    $account->bcode_verify = FALSE;
553
  }
554
  if ($userinfo['pnum']) {
555
    $account->valid_card = TRUE;
556
  }
557
  else {
558
    $account->valid_card = FALSE;
559
  }
99 jblyberg 560
  profile_load_profile(&$user);
144 kloostere 561
 
100 jblyberg 562
  if ($account->valid_card && $bcode_verify) {
563
    $content = sopac_user_chkout_table(&$user, &$locum);
144 kloostere 564
  }
565
  elseif ($account->valid_card && !$bcode_verify) {
100 jblyberg 566
    $content = '<div class="error">' . variable_get('sopac_uv_cardnum', t('The card number you have provided has not yet been verified by you.  In order to make sure that you are the rightful owner of this library card number, we need to ask you some simple questions.')) . '</div>' . drupal_get_form('sopac_bcode_verify_form', $account->uid, $cardnum);
144 kloostere 567
  }
568
  elseif ($cardnum && !$account->valid_card) {
107 jblyberg 569
    $content = '<div class="error">' . variable_get('sopac_invalid_cardnum', t('It appears that the library card number stored on our website is invalid. If you have received a new card, or feel that this is an error, please click on the card number above to change it to your most recent library card. If you need further help, please contact us.')) . '</div>';
100 jblyberg 570
  }
144 kloostere 571
  elseif (!$user->uid) {
145 kloostere 572
    $content = '<div class="error">' . t('You must be ') . l(t('logged in'), 'user') . t(' to view this page.') . '</div>';
144 kloostere 573
  }
574
  elseif (!$cardnum) {
145 kloostere 575
    $content = '<div class="error">' . t('You must register a valid ') . l(t('library card number'), 'user/' . $user->uid . '/edit/Preferences') . t(' to view this page.') . '</div>';
144 kloostere 576
  }
577
 
99 jblyberg 578
  return $content;
33 jblyberg 579
}
580
 
581
/**
93 smaskit 582
 * A dedicated checkout history page.
583
 */
584
function sopac_checkout_history_page() {
99 jblyberg 585
  global $user;
586
  profile_load_profile(&$user);
587
  if ($user->profile_pref_cardnum) {
123 jblyberg 588
 
589
    // Get the time since the last update
590
    $last_import = db_result(db_query("SELECT DATESUB(NOW() - last_hist_check) FROM {sopac_last_hist_check} WHERE uid = '" . $user->uid . "'"));
144 kloostere 591
 
123 jblyberg 592
    // Check profile to see if CO hist is enabled
593
    $user_co_hist_enabled = $user->profile_pref_cohist;
594
    if (!$user_co_hist_enabled) {
595
      // CO hist is not enabled, would you like to enable it?
596
      return $content;
597
    }
598
    // CO hist is enabled, would you like to disable it?
144 kloostere 599
 
123 jblyberg 600
    // Set up our data sets
601
    $url_prefix = variable_get('sopac_url_prefix', 'cat/seek');
136 smaskit 602
    $insurge = sopac_get_insurge();
135 smaskit 603
    $locum = sopac_get_locum();
99 jblyberg 604
    $locum_pass = substr($user->pass, 0, 7);
605
    $cardnum = $user->profile_pref_cardnum;
123 jblyberg 606
    $last_checkout_result = $insurge->get_checkout_history($user->uid, 1);
607
    $last_checkout[(string) $last_checkout_result['bnum']] = $last_checkout_result['codate']; // Like this?
144 kloostere 608
 
123 jblyberg 609
    // If we haven't imported data recently, do it now.
610
    if ($last_import >= variable_get('sopac_checkout_history_cache_time', 60)) {
144 kloostere 611
 
123 jblyberg 612
      $checkouts = $locum->get_patron_checkout_history($cardnum, $locum_pass, $last_checkout);
144 kloostere 613
 
123 jblyberg 614
      // Check: if profile->co hist is enabled , verify that it's on in the ILS
615
      // check: "" disables "" off
616
      if (!is_array($checkouts)) {
617
        if ($checkouts == 'out') {
618
          $content = '<div>'. t('This feature is currently turned off.') . '</div>';
145 kloostere 619
          $toggle = l(t('Opt In'), 'user/checkouts/history/opt/in');
123 jblyberg 620
        }
621
        if ($checkouts == 'in') {
622
          $content = '<div>There are no items in your checkout history.</div>';
145 kloostere 623
          $toggle = l(t('Opt Out'), 'user/checkouts/history/opt/out');
123 jblyberg 624
        }
144 kloostere 625
      }
626
      else {
123 jblyberg 627
        foreach ($checkouts as $checkout) {
628
          $bib_item = $locum->get_bib_item($checkout['bnum']);
629
          if ($bib_item['bnum']) {
630
            $insurge->add_checkout_history($user->uid, $checkout['bnum'], $bib_item['title'], $bib_item['author'] . ' ' . $bib_item['addl_author']);
631
          }
632
        }
99 jblyberg 633
      }
123 jblyberg 634
      // Reset cache age
635
      db_query("UPDATE {sopac_last_hist_check} SET last_hist_check = NOW()");
99 jblyberg 636
    }
144 kloostere 637
 
123 jblyberg 638
    // Set up pagination
144 kloostere 639
 
123 jblyberg 640
    // Grab checkout history from Insurge
641
    $checkout_history = $insurge->get_checkout_history($user->uid);
144 kloostere 642
 
123 jblyberg 643
    if (count ($checkout_history)) {
644
      // Set up the table
645
      $header = array('', t('Title'), t('Author'), t('Check-Out Date'));
99 jblyberg 646
      $rows = array();
123 jblyberg 647
      foreach ($checkout_history as $hist_item) {
648
        $item = $locum->get_bib_item($hist_item['bnum']);
649
        $new_author_str = sopac_author_format($item['author'], $item['addl_author']);
99 jblyberg 650
        $rows[] = array(
144 kloostere 651
          l(ucwords($item['title']), $url_prefix . '/record/' . $item['bnum']),
652
          l($new_author_str, $url_prefix . '/search/author/' . urlencode($new_author_str)),
123 jblyberg 653
          $hist_item['codate'], // Figure out the best way to format this
99 jblyberg 654
        );
123 jblyberg 655
        $content = theme('table', $header, $rows, array('id' => 'patroninfo', 'cellspacing' => '0'));
99 jblyberg 656
      }
144 kloostere 657
    }
658
    else {
123 jblyberg 659
      // nothing in users co hist
660
      $content = t('You do not have anything in your checkout history yet.');
99 jblyberg 661
    }
144 kloostere 662
 
663
  }
664
  else {
123 jblyberg 665
    $content = '<div class="cohist_nocard">' . t('Please register your library card to take advantage of this feature.') . '</div>';
99 jblyberg 666
  }
667
  return $content;
93 smaskit 668
}
116 jblyberg 669
 
93 smaskit 670
/**
671
 * Handle toggling checkout history on or off.
672
 */
673
function sopac_checkout_history_toggle($action) {
99 jblyberg 674
  global $user;
116 jblyberg 675
  if ($action != 'in' && $action != 'out') { drupal_goto('user/checkouts/history'); }
102 jblyberg 676
  $adjective = $action == 'in' ? t('on') : t('off');
99 jblyberg 677
  profile_load_profile(&$user);
678
  if ($user->profile_pref_cardnum) {
679
    if (!$_GET['confirm']) {
145 kloostere 680
      $confirm_link = l(t('confirm'), $_GET['q'], array('query' => 'confirm=true'));
99 jblyberg 681
      $content = "<div>Please $confirm_link that you wish to turn $adjective your checkout history.";
682
      if ($action == 'out') {
102 jblyberg 683
        $content .= ' ' . t('Please note: this will delete your entire checkout history.');
99 jblyberg 684
      }
685
    }
686
    else {
135 smaskit 687
      $locum = sopac_get_locum();
99 jblyberg 688
      $locum_pass = substr($user->pass, 0, 7);
689
      $cardnum = $user->profile_pref_cardnum;
690
      $success = $locum->set_patron_checkout_history($cardnum, $locum_pass, $action);
102 jblyberg 691
      if ($success === TRUE) {
99 jblyberg 692
        $content = "<div>Your checkout history has been turned $adjective.</div>";
144 kloostere 693
      }
694
      else {
99 jblyberg 695
        $content = "<div>An error occurred. Your checkout history has not been turned $adjective. Please try again.</div>";
696
      }
697
    }
698
  }
144 kloostere 699
  else {
700
    $content = '<div>' . t('Please register your library card to take advantage of this feature.') . '</div>';
701
  }
99 jblyberg 702
  return $content;
93 smaskit 703
}
704
 
705
/**
33 jblyberg 706
 * A dedicated holds page to list all holds.
707
 */
708
function sopac_holds_page() {
99 jblyberg 709
  global $user;
144 kloostere 710
 
100 jblyberg 711
  $account = user_load($user->uid);
712
  $cardnum = $account->profile_pref_cardnum;
135 smaskit 713
  $locum = sopac_get_locum();
100 jblyberg 714
  $userinfo = $locum->get_patron_info($cardnum);
715
  $bcode_verify = sopac_bcode_isverified($account);
144 kloostere 716
  if ($bcode_verify) {
717
    $account->bcode_verify = TRUE;
718
  }
719
  else {
720
    $account->bcode_verify = FALSE;
721
  }
722
  if ($userinfo['pnum']) {
723
    $account->valid_card = TRUE;
724
  }
725
  else {
726
    $account->valid_card = FALSE;
727
  }
99 jblyberg 728
  profile_load_profile(&$user);
144 kloostere 729
 
100 jblyberg 730
  if ($account->valid_card && $bcode_verify) {
131 smaskit 731
    $content = drupal_get_form('sopac_user_holds_form');
144 kloostere 732
  }
733
  elseif ($account->valid_card && !$bcode_verify) {
100 jblyberg 734
    $content = '<div class="error">' . variable_get('sopac_uv_cardnum', t('The card number you have provided has not yet been verified by you.  In order to make sure that you are the rightful owner of this library card number, we need to ask you some simple questions.')) . '</div>' . drupal_get_form('sopac_bcode_verify_form', $account->uid, $cardnum);
144 kloostere 735
  }
736
  elseif ($cardnum && !$account->valid_card) {
107 jblyberg 737
    $content = '<div class="error">' . variable_get('sopac_invalid_cardnum', t('It appears that the library card number stored on our website is invalid. If you have received a new card, or feel that this is an error, please click on the card number above to change it to your most recent library card. If you need further help, please contact us.')) . '</div>';
100 jblyberg 738
  }
144 kloostere 739
  elseif (!$user->uid) {
145 kloostere 740
    $content = '<div class="error">' . t('You must be ') . l(t('logged in'), 'user') . t(' to view this page.') . '</div>';
144 kloostere 741
  }
742
  elseif (!$cardnum) {
145 kloostere 743
    $content = '<div class="error">' . t('You must register a valid ') . l(t('library card number'), 'user/' . $user->uid . '/edit/Preferences') . t(' to view this page.') . '</div>';
144 kloostere 744
  }
745
 
99 jblyberg 746
  return $content;
33 jblyberg 747
}
748
 
749
/**
750
 * A dedicated page for managing fines and payments.
751
 */
752
function sopac_fines_page() {
99 jblyberg 753
  global $user;
34 jblyberg 754
 
135 smaskit 755
  $locum = sopac_get_locum();
99 jblyberg 756
  profile_load_profile(&$user);
34 jblyberg 757
 
99 jblyberg 758
  if ($user->profile_pref_cardnum && sopac_bcode_isverified(&$user)) {
759
    $locum_pass = substr($user->pass, 0, 7);
760
    $cardnum = $user->profile_pref_cardnum;
761
    $fines = $locum->get_patron_fines($cardnum, $locum_pass);
144 kloostere 762
 
99 jblyberg 763
    if (!count($fines)) {
764
      $notice = t('You do not have any fines, currently.');
144 kloostere 765
    }
766
    else {
767
      $header = array('', t('Amount'), t('Description'));
99 jblyberg 768
      $fine_total = (float) 0;
769
      foreach ($fines as $fine) {
770
        $col1 = variable_get('sopac_payments_enable', 1) ? '<input type="checkbox" name="varname[]" value="' . $fine['varname'] . '">' : '';
771
        $rows[] = array(
772
          $col1,
773
          '$' . number_format($fine['amount'], 2),
774
          $fine['desc'],
775
        );
776
        $hidden_vars .= '<input type="hidden" name="fine_summary[' . $fine['varname'] . '][amount]" value="' . addslashes($fine['amount']) . '">';
777
        $hidden_vars .= '<input type="hidden" name="fine_summary[' . $fine['varname'] . '][desc]" value="' . addslashes($fine['desc']) . '">';
778
        $fine_total = $fine_total + $fine['amount'];
779
      }
780
      $rows[] = array('<strong>Total:</strong>', '$' . number_format($fine_total, 2), '');
781
      $submit_button = '<input type="submit" value="' . t('Pay Selected Charges') . '">';
782
      if (variable_get('sopac_payments_enable', 1)) {
783
        $rows[] = array( 'data' => array(array('data' => $submit_button, 'colspan' => 3)), 'class' => 'profile_button' );
784
      }
785
      $fine_table = '<form method="post" action="/user/fines/pay">' . theme('table', $header, $rows, array('id' => 'patroninfo', 'cellspacing' => '0')) . $hidden_vars . '</form>';
786
      $notice = t('Your current fine balance is $') . number_format($fine_total, 2) . '.';
787
    }
788
  }
144 kloostere 789
  else {
145 kloostere 790
    $notice = t('You do not yet have a library card validated with our system.  You can add and validate a card using your ') . l(t('account page'), 'user') . '.';
144 kloostere 791
  }
792
 
99 jblyberg 793
  $result_page = theme('sopac_fines', $notice, $fine_table, &$user);
794
  return '<p>'. t($result_page) .'</p>';
33 jblyberg 795
}
796
 
797
/**
34 jblyberg 798
 * A dedicated page for viewing payment information.
799
 */
800
function sopac_finespaid_page() {
99 jblyberg 801
  global $user;
802
  $limit = 20; // TODO Make this configurable
144 kloostere 803
 
99 jblyberg 804
  if (count($_POST['payment_id'])) {
805
    foreach ($_POST['payment_id'] as $pid) {
806
      db_query('DELETE FROM {sopac_fines_paid} WHERE payment_id = ' . $pid . ' AND uid = ' . $user->uid);
807
    }
808
  }
144 kloostere 809
 
99 jblyberg 810
  if (db_result(db_query('SELECT COUNT(*) FROM {sopac_fines_paid} WHERE uid = ' . $user->uid))) {
144 kloostere 811
    $header = array('', 'Payment Date', 'Payment Description', 'Amount');
99 jblyberg 812
    $dbq = pager_query('SELECT payment_id, UNIX_TIMESTAMP(trans_date) as trans_date, fine_desc, amount FROM {sopac_fines_paid} WHERE uid = ' . $user->uid . ' ORDER BY trans_date DESC', $limit);
813
    while ($payment_arr = db_fetch_array($dbq)) {
814
      $checkbox = '<input type="checkbox" name="payment_id[]" value="' . $payment_arr['payment_id'] . '">';
815
      $payment_date = date('m-d-Y, H:i:s', $payment_arr['trans_date']);
816
      $payment_desc = $payment_arr['fine_desc'];
817
      $payment_amt = '$' . number_format($payment_arr['amount'], 2);
818
      $rows[] = array($checkbox, $payment_date, $payment_desc, $payment_amt);
819
    }
102 jblyberg 820
    $submit_button = '<input type="submit" value="' . t('Remove Selected Payment Records') . '">';
144 kloostere 821
    $rows[] = array('data' => array(array('data' => $submit_button, 'colspan' => 4)), 'class' => 'profile_button');
99 jblyberg 822
    $page_disp = '<form method="post">' . theme('pager', NULL, $limit, 0, NULL, 6) . theme('table', $header, $rows, array('id' => 'patroninfo', 'cellspacing' => '0')) . '</form>';
144 kloostere 823
  }
824
  else {
99 jblyberg 825
    $page_disp = t('You do not have any payments on record.');
826
  }
43 jblyberg 827
 
99 jblyberg 828
  return $page_disp;
34 jblyberg 829
}
830
 
41 jblyberg 831
function sopac_makepayment_page() {
99 jblyberg 832
  global $user;
41 jblyberg 833
 
135 smaskit 834
  $locum = sopac_get_locum();
99 jblyberg 835
  profile_load_profile(&$user);
41 jblyberg 836
 
99 jblyberg 837
  if ($user->profile_pref_cardnum && sopac_bcode_isverified(&$user)) {
838
    if ($_POST['varname'] && is_array($_POST['varname'])) {
839
      $varname = $_POST['varname'];
144 kloostere 840
    }
841
    else {
99 jblyberg 842
      $varname = explode('|', $_POST['varname']);
843
    }
844
    $locum_pass = substr($user->pass, 0, 7);
845
    $cardnum = $user->profile_pref_cardnum;
846
    $fines = $locum->get_patron_fines($cardnum, $locum_pass);
847
    if (!count($fines) || !count($varname)) {
848
      $notice = t('You did not select any payable fines.');
144 kloostere 849
    }
850
    else {
851
      $header = array('', t('Amount'), t('Description'));
99 jblyberg 852
      $fine_total = (float) 0;
853
      foreach ($fines as $fine) {
854
        if (in_array($fine['varname'], $varname)) {
855
          $rows[] = array(
856
            '',
857
            '$' . number_format($fine['amount'], 2),
858
            $fine['desc'],
859
          );
860
          $fine_total = $fine_total + $fine['amount'];
861
          $hidden_vars_arr[$fine['varname']]['amount'] = $_POST['fine_summary'][$fine['varname']]['amount'];
862
          $hidden_vars_arr[$fine['varname']]['desc'] = $_POST['fine_summary'][$fine['varname']]['desc'];
863
        }
864
      }
865
      $payment_form = drupal_get_form('sopac_fine_payment_form', $varname, (string) $fine_total, $hidden_vars_arr);
866
      $rows[] = array('<strong>Total:</strong>', '$' . number_format($fine_total, 2), '') ;
867
      $fine_table = theme('table', $header, $rows, array('id' => 'patroninfo', 'cellspacing' => '0'));
868
      $notice = t('You have selected to pay the following fines:');
869
    }
870
  }
144 kloostere 871
  else {
145 kloostere 872
    $notice = t('You do not yet have a library card validated with our system.  You can add and validate a card using your ') . l(t('account page'), 'user') . '.';
144 kloostere 873
  }
874
 
99 jblyberg 875
  $result_page = theme('sopac_fines', $notice, $fine_table, &$user, $payment_form);
876
  return '<p>'. t($result_page) .'</p>';
41 jblyberg 877
}
878
 
879
function sopac_fine_payment_form() {
99 jblyberg 880
  global $user;
144 kloostere 881
 
99 jblyberg 882
  $args = func_get_args();
883
  $varname = $args[1];
884
  $fine_total = $args[2];
885
  $hidden_vars_arr = $args[3];
41 jblyberg 886
 
99 jblyberg 887
  $form['#redirect'] = 'user/fines';
888
  $form['sopac_payment_billing_info'] = array(
889
    '#type' => 'fieldset',
890
    '#title' => t('Billing Information'),
891
    '#collapsible' => FALSE,
892
  );
41 jblyberg 893
 
99 jblyberg 894
  $form['sopac_payment_billing_info']['name'] = array(
895
    '#type' => 'textfield',
896
    '#title' => t('Name on the credit card'),
897
    '#size' => 48,
898
    '#maxlength' => 200,
899
    '#required' => TRUE,
900
  );
144 kloostere 901
 
99 jblyberg 902
  $form['sopac_payment_billing_info']['address1'] = array(
903
    '#type' => 'textfield',
904
    '#title' => t('Billing Address'),
905
    '#size' => 48,
906
    '#maxlength' => 200,
907
    '#required' => TRUE,
908
  );
144 kloostere 909
 
99 jblyberg 910
  $form['sopac_payment_billing_info']['city'] = array(
911
    '#type' => 'textfield',
912
    '#title' => t('City/Town'),
913
    '#size' => 32,
914
    '#maxlength' => 200,
915
    '#required' => TRUE,
916
  );
144 kloostere 917
 
99 jblyberg 918
  $form['sopac_payment_billing_info']['state'] = array(
919
    '#type' => 'textfield',
920
    '#title' => t('State'),
921
    '#size' => 3,
922
    '#maxlength' => 2,
923
    '#required' => TRUE,
924
  );
144 kloostere 925
 
99 jblyberg 926
  $form['sopac_payment_billing_info']['zip'] = array(
927
    '#type' => 'textfield',
928
    '#title' => t('ZIP Code'),
929
    '#size' => 7,
930
    '#maxlength' => 200,
931
    '#required' => TRUE,
932
  );
144 kloostere 933
 
99 jblyberg 934
  $form['sopac_payment_billing_info']['email'] = array(
935
    '#type' => 'textfield',
936
    '#title' => t('Email Address'),
937
    '#size' => 48,
938
    '#maxlength' => 200,
939
    '#required' => TRUE,
940
  );
144 kloostere 941
 
99 jblyberg 942
  $form['sopac_payment_cc_info'] = array(
943
    '#type' => 'fieldset',
944
    '#title' => t('Credit Card Information'),
945
    '#collapsible' => FALSE,
946
  );
41 jblyberg 947
 
99 jblyberg 948
  $form['sopac_payment_cc_info']['ccnum'] = array(
949
    '#type' => 'textfield',
950
    '#title' => t('Credit Card Number'),
951
    '#size' => 24,
952
    '#maxlength' => 20,
953
    '#required' => TRUE,
954
  );
144 kloostere 955
 
99 jblyberg 956
  $form['sopac_payment_cc_info']['ccexpmonth'] = array(
957
    '#type' => 'textfield',
958
    '#title' => t('Expiration Month'),
959
    '#size' => 4,
960
    '#maxlength' => 2,
961
    '#required' => TRUE,
962
    '#prefix' => '<table class="fines-form-table"><tr><td>',
963
    '#suffix' => '</td>',
964
  );
144 kloostere 965
 
99 jblyberg 966
  $form['sopac_payment_cc_info']['ccexpyear'] = array(
967
    '#type' => 'textfield',
968
    '#title' => t('Expiration Year'),
969
    '#size' => 5,
970
    '#maxlength' => 4,
971
    '#required' => TRUE,
972
    '#prefix' => '<td>',
973
    '#suffix' => '</td></tr></table>',
974
  );
144 kloostere 975
 
99 jblyberg 976
  $form['sopac_payment_cc_info']['ccseccode'] = array(
977
    '#type' => 'textfield',
978
    '#title' => t('Security Code'),
979
    '#size' => 5,
980
    '#maxlength' => 5,
981
    '#required' => TRUE,
982
  );
144 kloostere 983
 
99 jblyberg 984
  foreach ($hidden_vars_arr as $hkey => $hvar) {
985
    $form['sopac_payment_form']['fine_summary[' . $hkey . '][amount]'] = array('#type' => 'hidden', '#value' => $hvar['amount']);
986
    $form['sopac_payment_form']['fine_summary[' . $hkey . '][desc]'] = array('#type' => 'hidden', '#value' => $hvar['desc']);
987
  }
988
  $form['sopac_payment_form']['varname'] = array('#type' => 'hidden', '#value' => implode('|', $varname));
989
  $form['sopac_payment_form']['total'] = array('#type' => 'hidden', '#value' => $fine_total);
990
  $form['sopac_savesearch_form']['submit'] = array('#type' => 'submit', '#value' => t('Make Payment'));
41 jblyberg 991
 
99 jblyberg 992
  return $form;
41 jblyberg 993
}
994
 
995
function sopac_fine_payment_form_submit($form, &$form_state) {
99 jblyberg 996
  global $user;
135 smaskit 997
  $locum = sopac_get_locum();
99 jblyberg 998
  profile_load_profile(&$user);
999
  $locum_pass = substr($user->pass, 0, 7);
41 jblyberg 1000
 
99 jblyberg 1001
  if ($user->profile_pref_cardnum && sopac_bcode_isverified(&$user)) {
1002
    $fines = $locum->get_patron_fines($cardnum, $locum_pass);
1003
    $payment_details['name'] = $form_state['values']['name'];
1004
    $payment_details['address1'] = $form_state['values']['address1'];
1005
    $payment_details['city'] = $form_state['values']['city'];
1006
    $payment_details['state'] = $form_state['values']['state'];
1007
    $payment_details['zip'] = $form_state['values']['zip'];
1008
    $payment_details['email'] = $form_state['values']['email'];
1009
    $payment_details['ccnum'] = $form_state['values']['ccnum'];
1010
    $payment_details['ccexpmonth'] = $form_state['values']['ccexpmonth'];
1011
    $payment_details['ccexpyear'] = $form_state['values']['ccexpyear'];
1012
    $payment_details['ccseccode'] = $form_state['values']['ccseccode'];
1013
    $payment_details['total'] = $form_state['values']['total'];
1014
    $payment_details['varnames'] = explode('|', $form_state['values']['varname']);
1015
    $payment_result = $locum->pay_patron_fines($user->profile_pref_cardnum, $locum_pass, $payment_details);
50 jblyberg 1016
 
99 jblyberg 1017
    if (!$payment_result['approved']) {
1018
      if ($payment_result['reason']) {
1019
        $error = '<strong>' . t('Your payment was not processed:') . '</strong> ' . $payment_result['reason'];
144 kloostere 1020
      }
1021
      else {
99 jblyberg 1022
        $error = t('We were unable to process your payment.');
1023
      }
1024
      drupal_set_message(t('<span class="fine-notice">' . $error . '</span>'));
1025
      if ($payment_result['error']) {
1026
        drupal_set_message(t('<span class="fine-notice">' . $payment_result['error'] . '</span>'));
1027
      }
144 kloostere 1028
    }
1029
    else {
99 jblyberg 1030
      foreach ($_POST['fine_summary'] as $fine_var => $fine_var_arr) {
1031
        $fine_desc = db_escape_string($fine_var_arr['desc']);
1032
        $sql = 'INSERT INTO {sopac_fines_paid} (payment_id, uid, amount, fine_desc) VALUES (0, ' . $user->uid . ', ' . $fine_var_arr['amount'] . ', "' . $fine_desc . '")';
1033
        db_query($sql);
1034
      }
1035
      $amount = '$' . number_format($form_state['values']['total'], 2);
1036
      drupal_set_message('<span class="fine-notice">' . t('Your payment of ') . $amount . t(' was successful.  Thank-you!') . '</span>');
1037
    }
1038
  }
41 jblyberg 1039
}
1040
 
1041
 
34 jblyberg 1042
/**
33 jblyberg 1043
 * A dedicated page for showing and managing saved searches from the catalog.
1044
 */
1045
function sopac_saved_searches_page() {
99 jblyberg 1046
  global $user;
1047
  $limit = 20; // TODO Make this configurable
144 kloostere 1048
 
99 jblyberg 1049
  if (count($_POST['search_id'])) {
1050
    foreach ($_POST['search_id'] as $sid) {
1051
      db_query('DELETE FROM {sopac_saved_searches} WHERE search_id = ' . $sid . ' AND uid = ' . $user->uid);
1052
    }
1053
  }
144 kloostere 1054
 
99 jblyberg 1055
  if (db_result(db_query('SELECT COUNT(*) FROM {sopac_saved_searches} WHERE uid = ' . $user->uid))) {
1056
    $header = array('','Search Description','');
1057
    $dbq = pager_query('SELECT * FROM {sopac_saved_searches} WHERE uid = ' . $user->uid . ' ORDER BY savedate DESC', $limit);
1058
    while ($search_arr = db_fetch_array($dbq)) {
1059
      $checkbox = '<input type="checkbox" name="search_id[]" value="' . $search_arr['search_id'] . '">';
144 kloostere 1060
      $parts = explode('?', $search_arr['search_url']);
1061
      $search_desc = l($search_arr['search_desc'], $parts[0], array('query' => $parts[1]));
99 jblyberg 1062
      // TODO: implement RSS feeds for saved searches.
107 jblyberg 1063
      $search_feed_url = sopac_update_url($search_arr['search_url'], 'output', 'rss');
1064
      $search_feed = theme_feed_icon($search_feed_url, 'RSS Feed: ' . $search_arr['search_desc']);
99 jblyberg 1065
      $rows[] = array($checkbox, $search_desc, $search_feed);
1066
    }
1067
    $submit_button = '<input type="submit" value="' . t('Remove Selected Searches') . '">';
1068
    $rows[] = array( 'data' => array(array('data' => $submit_button, 'colspan' => 3)), 'class' => 'profile_button' );
1069
    $page_disp = '<form method="post">' . theme('pager', NULL, $limit, 0, NULL, 6) . theme('table', $header, $rows, array('id' => 'patroninfo', 'cellspacing' => '0')) . '</form>';
144 kloostere 1070
  }
1071
  else {
99 jblyberg 1072
    $page_disp = '<div class="overview-nodata">' . t('You do not currently have any saved searches.') . '</div>';
1073
  }
36 jblyberg 1074
 
99 jblyberg 1075
  return $page_disp;
33 jblyberg 1076
}
1077
 
41 jblyberg 1078
 
36 jblyberg 1079
/**
41 jblyberg 1080
 * Returns the form array for saving searches
36 jblyberg 1081
 *
41 jblyberg 1082
 * @return array Drupal form array.
36 jblyberg 1083
 */
41 jblyberg 1084
function sopac_savesearch_form() {
99 jblyberg 1085
  global $user;
144 kloostere 1086
 
1087
  $search_path = str_replace('/savesearch/', '/search/', $_GET['q']);
1088
  $search_query = sopac_make_pagevars(sopac_parse_get_vars());
99 jblyberg 1089
  $uri_arr = sopac_parse_uri();
144 kloostere 1090
 
1091
  $form_desc = 'How would you like to label your ' . $uri_arr[1] . ' search for "' . l($uri_arr[2], $search_path, array('query' => $search_query)) . '" ?';
99 jblyberg 1092
  $form['#redirect'] = 'user/library/searches';
1093
  $form['sopac_savesearch_form'] = array(
1094
    '#type' => 'fieldset',
1095
    '#title' => t($form_desc),
1096
    '#collapsible' => FALSE,
1097
  );
36 jblyberg 1098
 
99 jblyberg 1099
  $form['sopac_savesearch_form']['searchname'] = array(
1100
    '#type' => 'textfield',
1101
    '#title' => t('Search Label'),
1102
    '#size' => 48,
1103
    '#maxlength' => 128,
1104
    '#required' => TRUE,
144 kloostere 1105
    '#default_value' => 'My custom ' . $uri_arr[1] . ' search for "' . $uri_arr[2] . '"',
99 jblyberg 1106
  );
144 kloostere 1107
 
1108
  $form['sopac_savesearch_form']['uri'] = array('#type' => 'hidden', '#value' => $search_path . '?' . $search_query);
99 jblyberg 1109
  $form['sopac_savesearch_form']['submit'] = array('#type' => 'submit', '#value' => t('Save'));
41 jblyberg 1110
 
99 jblyberg 1111
  return $form;
144 kloostere 1112
 
36 jblyberg 1113
}
1114
 
41 jblyberg 1115
 
1116
function sopac_savesearch_form_submit($form, &$form_state) {
99 jblyberg 1117
  global $user;
144 kloostere 1118
 
99 jblyberg 1119
  $desc = db_escape_string($form_state['values']['searchname']);
1120
  db_query('INSERT INTO {sopac_saved_searches} VALUES (0, ' . $user->uid . ', NOW(), "' . $desc . '", "' . $form_state['values']['uri'] . '")');
41 jblyberg 1121
 
144 kloostere 1122
  $parts = explode('?', $form_state['values']['uri']);
145 kloostere 1123
  $submsg = '<strong>»</strong> ' . t('You have saved this search.') . '<br /><strong>»</strong> ' . l(t('Return to your search'), $parts[0], array('query' => $parts[1])) . '<br /><br />';
99 jblyberg 1124
  drupal_set_message($submsg);
41 jblyberg 1125
 
1126
}
1127
 
1128
 
33 jblyberg 1129
function sopac_update_locum_acct($op, &$edit, &$account) {
144 kloostere 1130
 
135 smaskit 1131
  $locum = sopac_get_locum();
144 kloostere 1132
 
99 jblyberg 1133
  // Make sure we're all legit on this account
1134
  $cardnum = $account->profile_pref_cardnum;
144 kloostere 1135
  if (!$cardnum) {
1136
    return 0;
1137
  }
99 jblyberg 1138
  $userinfo = $locum->get_patron_info($cardnum);
1139
  $bcode_verify = sopac_bcode_isverified($account);
144 kloostere 1140
  if ($bcode_verify) {
1141
    $account->bcode_verify = TRUE;
1142
  }
1143
  else {
1144
    $account->bcode_verify = FALSE;
1145
  }
1146
  if ($userinfo['pnum']) {
1147
    $account->valid_card = TRUE;
1148
  }
1149
  else {
1150
    $account->valid_card = FALSE;
1151
  }
1152
  if (!$account->valid_card || !$bcode_verify) {
1153
    return 0;
1154
  }
1155
 
99 jblyberg 1156
  if ($edit['mail'] && $pnum) {
1157
    // TODO update email. etc.
1158
  }
33 jblyberg 1159
}
1160
 
1161
/**
22 jblyberg 1162
 * Creates and returns the barcode/patron card number verification form.  It also does the neccesary processing
1163
 * If this function has just successfully processed a form result, then it will instead return a message indicating thus.
1164
 *
1165
 * @param string $cardnum Library patron barcode/card number
1166
 * @return string Either the verification form or a confirmation of success.
1167
 */
24 jblyberg 1168
function sopac_bcode_verify_form() {
144 kloostere 1169
 
99 jblyberg 1170
  $args = func_get_args();
23 jblyberg 1171
 
144 kloostere 1172
  if (variable_get('sopac_require_cfg', 'one') == 'one') {
99 jblyberg 1173
    $req_flds = FALSE;
1174
    $form_desc = t('Please correctly <strong>answer <u>one</u> of the following questions</strong>:');
144 kloostere 1175
  }
1176
  else {
99 jblyberg 1177
    $req_flds = TRUE;
1178
        $form_desc = t('Please correctly <strong>answer <u>all</u> of the following questions</strong>:');
1179
  }
144 kloostere 1180
 
99 jblyberg 1181
  $form['sopac_card_verify'] = array(
1182
    '#type' => 'fieldset',
1183
    '#title' => t('Verify your Library Card Number'),
1184
    '#description' => t($form_desc),
1185
    '#collapsible' => FALSE,
1186
    '#validate' => 'sopac_bcode_verify_form_validate',
1187
  );
144 kloostere 1188
 
99 jblyberg 1189
  if (variable_get('sopac_require_name', 1)) {
1190
    $form['sopac_card_verify']['last_name'] = array(
1191
      '#type' => 'textfield',
1192
      '#title' => t('What is your last name?'),
1193
      '#size' => 32,
1194
      '#maxlength' => 128,
1195
      '#required' => $req_flds,
1196
      '#value' => $_POST['last_name'],
1197
    );
1198
  }
144 kloostere 1199
 
99 jblyberg 1200
  if (variable_get('sopac_require_streetname', 1)) {
1201
    $form['sopac_card_verify']['streetname'] = array(
1202
      '#type' => 'textfield',
1203
      '#title' => t('What is the name of the street you live on?'),
1204
      '#size' => 24,
1205
      '#maxlength' => 32,
1206
      '#required' => $req_flds,
1207
      '#value' => $_POST['streetname'],
1208
    );
1209
  }
144 kloostere 1210
 
99 jblyberg 1211
  if (variable_get('sopac_require_tel', 1)) {
1212
    $form['sopac_card_verify']['telephone'] = array(
1213
      '#type' => 'textfield',
1214
      '#title' => t('What is your telephone number?'),
1215
      '#description' => t("Please provide your area code as well as your phone number, eg: 203-555-1234."),
1216
      '#size' => 18,
1217
      '#maxlength' => 24,
1218
      '#required' => $req_flds,
1219
      '#value' => $_POST['telephone'],
1220
    );
1221
  }
144 kloostere 1222
 
99 jblyberg 1223
  $form['sopac_card_verify']['vfy_post'] = array('#type' => 'hidden', '#value' => '1');
1224
  $form['sopac_card_verify']['uid'] = array('#type' => 'hidden', '#value' => $args[1]);
1225
  $form['sopac_card_verify']['cardnum'] = array('#type' => 'hidden', '#value' => $args[2]);
1226
  $form['sopac_card_verify']['vfy_submit'] = array('#type' => 'submit', '#value' => t('Verify!'));
144 kloostere 1227
 
99 jblyberg 1228
  return $form;
22 jblyberg 1229
}
24 jblyberg 1230
 
1231
function sopac_bcode_verify_form_validate($form, $form_state) {
99 jblyberg 1232
  global $account;
144 kloostere 1233
 
135 smaskit 1234
  $locum = sopac_get_locum();
99 jblyberg 1235
  $cardnum = $form_state['values']['cardnum'];
1236
  $uid = $form_state['values']['uid'];
1237
  $userinfo = $locum->get_patron_info($cardnum);
1238
  $numreq = 0;
1239
  $correct = 0;
1240
  $validated = FALSE;
24 jblyberg 1241
 
99 jblyberg 1242
  $req_cfg = variable_get('sopac_require_cfg', 'one');
144 kloostere 1243
 
99 jblyberg 1244
  // Match the name given
1245
  if (variable_get('sopac_require_name', 1)) {
1246
    if (trim($form_state['values']['last_name'])) {
1247
      $locum_name = ereg_replace("[^A-Za-z0-9 ]", "", trim(strtolower($userinfo['name'])));
1248
      $sub_name = ereg_replace("[^A-Za-z0-9 ]", "", trim(strtolower($form_state['values']['last_name'])));
1249
      if (preg_match('/\b' . $sub_name . '\b/i', $locum_name)) {
1250
        $correct++;
144 kloostere 1251
      }
1252
      else {
99 jblyberg 1253
        $error[] = t('The last name you entered does not appear to match what we have on file.');
1254
      }
144 kloostere 1255
    }
1256
    else {
99 jblyberg 1257
      $error[] = t('You did not provide a last name.');
1258
    }
1259
    $numreq++;
1260
  }
144 kloostere 1261
 
99 jblyberg 1262
  if (variable_get('sopac_require_streetname', 1)) {
1263
    if (trim($form_state['values']['streetname'])) {
1264
      $locum_addr = ereg_replace("[^A-Za-z ]", "", trim(strtolower($userinfo['address'])));
1265
      $sub_addr = ereg_replace("[^A-Za-z ]", "", trim(strtolower($form_state['values']['streetname'])));
1266
      $sub_addr_arr = explode(' ', $sub_addr);
1267
      if (strlen($sub_addr_arr[0]) == 1 || $sub_addr_arr[0] == 'north' || $sub_addr_arr[0] == 'east' || $sub_addr_arr[0] == 'south' || $sub_addr_arr[0] == 'west') {
1268
        $sub_addr = $sub_addr_arr[1];
144 kloostere 1269
      }
1270
      else {
99 jblyberg 1271
        $sub_addr = $sub_addr_arr[0];
1272
      }
1273
      if (preg_match('/\b' . $sub_addr . '\b/i', $locum_addr)) {
1274
        $correct++;
144 kloostere 1275
      }
1276
      else {
99 jblyberg 1277
        $error[] = t('The street name you entered does not appear to match what we have on file.');
1278
      }
144 kloostere 1279
    }
1280
    else {
99 jblyberg 1281
      $error[] = t('You did not provide a street name.');
1282
    }
1283
    $numreq++;
1284
  }
144 kloostere 1285
 
99 jblyberg 1286
  if (variable_get('sopac_require_tel', 1)) {
1287
    if (trim($form_state['values']['telephone'])) {
1288
      $locum_tel = ereg_replace("[^A-Za-z0-9 ]", "", trim(strtolower($userinfo['tel1'] . ' ' . $userinfo['tel2'])));
1289
      $sub_tel = ereg_replace("[^A-Za-z0-9 ]", "", trim(strtolower($form_state['values']['telephone'])));
1290
      if (preg_match('/\b' . $sub_tel . '\b/i', $locum_tel)) {
1291
        $correct++;
144 kloostere 1292
      }
1293
      else {
99 jblyberg 1294
        $error[] = t('The telephone number you entered does not appear to match what we have on file.');
1295
      }
144 kloostere 1296
    }
1297
    else {
99 jblyberg 1298
      $error[] = t('You did not provide a telephone number.');
1299
    }
1300
    $numreq++;
1301
  }
144 kloostere 1302
 
99 jblyberg 1303
  if ($req_cfg == 'one') {
144 kloostere 1304
    if ($correct > 0) {
1305
      $validated = TRUE;
1306
    }
99 jblyberg 1307
  }
144 kloostere 1308
  else {
1309
    if ($correct == $numreq) {
1310
      $validated = TRUE;
1311
    }
1312
  }
1313
 
99 jblyberg 1314
  if (count($error) && !$validated) {
1315
    foreach ($error as $errkey => $errmsg) {
1316
      form_set_error($errkey, t($errmsg));
1317
    }
1318
  }
144 kloostere 1319
 
99 jblyberg 1320
  if ($validated) {
1321
    db_query("INSERT INTO {sopac_card_verify} VALUES ($uid, '$cardnum', 1, NOW())");
1322
  }
144 kloostere 1323
 
24 jblyberg 1324
}