diff --git a/COPYING b/COPYING old mode 100644 new mode 100755 diff --git a/alma.features.field.inc b/alma.features.field.inc old mode 100644 new mode 100755 diff --git a/alma.info b/alma.info old mode 100644 new mode 100755 index bd4eaad..17b03e7 --- a/alma.info +++ b/alma.info @@ -1,23 +1,23 @@ -core = "7.x" -dependencies[] = "date" -dependencies[] = "ding_provider" -dependencies[] = "features" -dependencies[] = "list" -description = "Implementation of Axiell’s Alma API for DDELibra." -features[field][] = "profile2-provider_alma-field_absent_id" -features[field][] = "profile2-provider_alma-field_alma_interest_period" -features[field][] = "profile2-provider_alma-field_alma_mobile_phone" -features[field][] = "profile2-provider_alma-field_alma_phone_id" -features[field][] = "profile2-provider_alma-field_alma_preferred_branch" -features[field][] = "profile2-provider_alma-field_alma_reservation_pause" -files[] = "alma.module" -files[] = "includes/alma.availability.inc" -files[] = "includes/alma.debt.inc" -files[] = "includes/alma.reservation.inc" -files[] = "includes/alma.user.inc" -files[] = "lib/AlmaClient/AlmaClient.class.php" -name = "Alma" -package = "Ding!" -php = "5.2.4" -project = "alma" -version = "7.x-0.12" +core = "7.x" +dependencies[] = "date" +dependencies[] = "ding_provider" +dependencies[] = "features" +dependencies[] = "list" +description = "Implementation of Axiell’s Alma API for DDELibra." +features[field][] = "profile2-provider_alma-field_absent_id" +features[field][] = "profile2-provider_alma-field_alma_interest_period" +features[field][] = "profile2-provider_alma-field_alma_mobile_phone" +features[field][] = "profile2-provider_alma-field_alma_phone_id" +features[field][] = "profile2-provider_alma-field_alma_preferred_branch" +features[field][] = "profile2-provider_alma-field_alma_reservation_pause" +files[] = "alma.module" +files[] = "includes/alma.availability.inc" +files[] = "includes/alma.debt.inc" +files[] = "includes/alma.reservation.inc" +files[] = "includes/alma.user.inc" +files[] = "lib/AlmaClient/AlmaClient.class.php" +name = "Alma" +package = "Ding!" +php = "5.2.4" +project = "alma" +version = "7.x-0.20-dev" diff --git a/alma.install b/alma.install old mode 100644 new mode 100755 diff --git a/alma.make b/alma.make old mode 100644 new mode 100755 diff --git a/alma.module b/alma.module old mode 100644 new mode 100755 index a837e89..40ff52e --- a/alma.module +++ b/alma.module @@ -1,632 +1,676 @@ -data); - } - else { - $alma_pickup_branches = alma_client_invoke('get_reservation_branches'); - cache_set( 'alma_pickup_branches', serialize($alma_pickup_branches),'cache'); - } - } - return $alma_pickup_branches; -} - -/** - * Implements hook_requirements(). - */ -function alma_requirements($phase) { - $requirements = array(); - // Ensure translations don't break at install time. - $t = get_t(); - - if (!function_exists('simplexml_load_string')) { - $requirements['simplexml'] = array( - 'title' => 'SimpleXML', - 'description' => $t('The Alma module requires SimpleXML to function. Please install and/or enable SimpleXML in your PHP configuration.'), - 'severity' => REQUIREMENT_ERROR, - ); - } - - return $requirements; -} - -/** - * Implements hook_ding_provider(). - */ -function alma_ding_provider() { - $path = drupal_get_path('module', 'alma'); - - return array( - 'title' => 'Alma provider', - 'settings' => 'alma_settings_form', - 'provides' => array( - 'availability' => array( - 'prefix' => 'availability', - 'file' => $path . '/includes/alma.availability.inc', - ), - 'debt' => array( - 'prefix' => 'debt', - 'file' => $path . '/includes/alma.debt.inc', - ), - 'loan' => array( - 'prefix' => 'loan', - 'file' => $path . '/includes/alma.loan.inc', - ), - 'reservation' => array( - 'prefix' => 'reservation', - 'file' => $path . '/includes/alma.reservation.inc', - ), - 'user' => array( - 'prefix' => 'user', - 'file' => $path . '/includes/alma.user.inc', - ), - ), - ); -} - -/** - * Form callback for provider module settings. - * - * This is a regular form callback. - */ -function alma_settings_form() { - $form['alma'] = array( - '#type' => 'fieldset', - '#title' => t('Alma service settings'), - '#tree' => FALSE, - ); - - $form['alma']['alma_base_url'] = array( - '#type' => 'textfield', - '#title' => t('Alma base URL'), - '#description' => t('Base URL for Alma service.'), - '#required' => TRUE, - '#default_value' => variable_get('alma_base_url', ''), - ); - - $form['alma']['alma_enable_logging'] = array( - '#type' => 'checkbox', - '#title' => t('Enable logging'), - '#default_value' => variable_get('alma_enable_logging', FALSE), - '#description' => t('Logs requests to the Alma webservice. Sensitive information such as CPR number and PIN code is stripped from the requests.'), - ); - - return system_settings_form($form); -} - -/** - * Implements hook_form_FORM_ID_alter(). - * pjo notes: user_profile_form - * Add in pincode validation. - */ -function alma_form_user_profile_form_alter(&$form, &$form_state) { - // Ensure that we're dealing with a provider user. - if (!ding_user_is_provider_user($form_state['user'])) { - return; - } - - // change size and length of pincode - $form['account']['pincode']['#size'] = 32; - $form['account']['pincode']['#maxlength'] = 32; - - // @todo; WHAT are the rules for alma pincode - // HOW do we validate - - // custom validator ?? maybe pincode validator ?? - // $form['#validate'][] = 'alma_profile_form_validate'; -} - - - -/** - * Return a fully instantiated AlmaClient instance. - */ -function alma_client() { - // This is basically a singleton. We also wait until right before - // instantiating to include our required classes. That seems like a - // decent performance tradeoff instead of loading everything on every - // page load. - static $client; - if (!isset($client)) { - $path = drupal_get_path('module', 'alma'); - try { - $client = new AlmaClient(variable_get('alma_base_url', '')); - } - catch (Exception $e) { - watchdog('alma', 'Constructor error: “@message”', array('@message' => $e->getMessage(), WATCHDOG_ERROR)); - return NULL; - } - - } - return $client; -} - -/** - * Calls the Alma backend, possibly caching the result. - * - * @param $method - * The desired method. - * @param ... - * Arguments to the method. - * - * @return mixed - * NULL on error, or the result of the method call. - */ -function alma_client_invoke($method) { - $args = func_get_args(); - array_shift($args); // Lose the method. - $client = alma_client(); - - try { - $result = call_user_func_array(array($client, $method), $args); - } - catch (Exception $e) { - watchdog('alma', '@method error: “@message”', array('@method' => $method, '@message' => $e->getMessage()), WATCHDOG_ERROR); - throw $e; - } - - return $result; -} - -/** - * Get the complete organisation info from Alma. - * - * Includes branches, departments, locations, sublocations and collections. The - * information is cache until the cache is cleared or the reset parameter is - * TRUE. - * - * @param boolean $reset - * Optional. If TRUE reset the cached data and reload. - * @return array - * Array of the different organisational unit, each an array of their - * member units. - */ -function alma_get_organisation($reset = FALSE) { - // Return data from cache if available. - static $organisation; - if (!$organisation || $reset) { - if (($cache = cache_get('alma_organisation')) && !empty($cache->data) && !$reset) { - $organisation = $cache->data; - } - else { - $organisation = array( - 'branch' => alma_client_invoke('get_branches'), - 'department' => alma_client_invoke('get_departments'), - 'location' => alma_client_invoke('get_locations'), - 'sublocation' => alma_client_invoke('get_sublocations'), - 'collection' => alma_client_invoke('get_collections'), - 'reservation' => alma_reservation_pickup_branches(),//alma_client_invoke('get_reservation_branches'), - ); - - // Cache output for 24 hours if we got all the data correctly. - if ($organisation['branch'] && $organisation['department'] && - $organisation['location'] && $organisation['sublocation'] && - $organisation['collection'] && $organisation['reservation']) { - cache_set('alma_organisation', $organisation, 'cache'); - } - } - } - - return $organisation; -} - -/** - * Implements hook_user_view - */ -function alma_user_view( $account, $view_mode, $langcode ) { - $creds = ding_user_get_creds($account); - if (($userInfo = alma_user_info($creds)) && isset($userInfo)) { - foreach ($userInfo as $key=>$prop) { - $data[$key] = isset($prop) ? $prop : ''; - } - - $account->content['name'] = array( - '#type' => 'item', - '#title' => t('Name'), - '#markup' => $data['firstname'], - ); - - $address_parts = array($data['address']); - if (!empty($data['postal']) || !empty($data['city'])) { - $address_parts[] = join('
', array_filter(array($data['postal'], $data['city']))); - } - - // @todo: really, there should be a template for this. - $account->content['address'] = array( - '#type' => 'item', - '#title' => t('Address'), - '#markup' => '

' . join('
',$address_parts) . '

', - ); - }; - // @todo: add provider specific fields - alma_set_profile2_fields( $account ); - -} - - -function alma_set_profile2_fields($account) { - if( !module_exists('profile2') ) { - return; - } - - $profile2 = profile2_load_by_user($account, 'provider_alma'); - if( empty($profile2) ) { - return; - } - - // wrapper for profile2-fields - $account->content['profile2'] = array( - '#type' => 'item', - '#title' => t('My library'), - '#prefix' => '
', - '#suffix' => '
', - ); - - // set preferred branch - if( $pref_branch = alma_get_preferred_branch( $profile2 ) ) { - $account->content['profile2']['preferred_branch'] = array( - '#type' => 'item', - '#title' => t('Pickup branch'), - '#markup' => ''.$pref_branch.'', - ); - } - - // set interest period - if( $interest_period = alma_get_interest_period($profile2) ) { - $account->content['profile2']['interest_period'] = array( - '#type' => 'item', - '#title' => t('Interest period'), - '#markup' => ''.$interest_period['value'].'', - ); - } - - // set mobile phone - if( $mob = alma_get_mobile_phone($profile2) ) { - $account->content['profile2']['mobile'] = array( - '#type' => 'item', - '#title' => t('Mobile phone'), - '#markup' => ''.$mob.'', - ); - } - - // set reservation pause - if( $reservation_pause = alma_get_reservation_pause( $profile2 ) ) { - //wrapper for reservation pause - $account->content['profile2']['reservation_pause'] = array( - '#type' => 'item', - '#title' => t('Reservation pause'), - '#prefix' => '
', - '#suffix' => '
', - ); - - $account->content['profile2']['reservation_pause']['start'] = array( - '#type' => 'item', - '#title' => t('Start'), - '#markup' => ''.str_replace('T00:00:00','',$reservation_pause['start']).'', - ); - - $account->content['profile2']['reservation_pause']['stop'] = array( - '#type' => 'item', - '#title' => t('Stop'), - '#markup' => ''.str_replace('T00:00:00','',$reservation_pause['stop']).'', - ); - } -} - -function alma_get_mobile_phone( $profile2 ) { - $langs = field_language('profile2', $profile2); - - if( empty($profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']] ) ) { - return false; - } - - $mob = - isset($profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value']) ? - $profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value'] : FALSE; - - return $mob; -} - -function alma_get_reservation_pause($profile2){ - // get field languages - $langs = field_language('profile2', $profile2); - - if( empty($profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']] ) ) { - return false; - } - - $res_pause['start'] = $profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value']; - $res_pause['stop'] = $profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value2']; - - if( strlen($res_pause['start']) < 2 || strlen($res_pause['stop']) < 2 ) { - return false; - } - - return $res_pause; -} - -function alma_get_interest_period( $profile2 ) { - // get field languages - $langs = field_language('profile2', $profile2); - // get field-info to retrieve values for select list - $field_info = field_info_field('field_alma_interest_period'); - - $interest_period = FALSE; - $int_values = isset( $field_info['settings']['allowed_values'] ) ? $field_info['settings']['allowed_values']: FALSE; - if( $int_values ) { - $int_period = $profile2->field_alma_interest_period[$langs['field_alma_interest_period']][0]['value']; - $interest_period = isset($int_values[$int_period]) ? array('key'=>$int_period,'value'=>$int_values[$int_period]) : FALSE; - } - return $interest_period; -} - -function alma_get_preferred_branch( $profile2 ) { - // get field languages - $langs = field_language('profile2', $profile2); - - //get preferred branch - $pref_branch = - isset($profile2->field_alma_preferred_branch[$langs['field_alma_preferred_branch']][0]['value']) ? - $profile2->field_alma_preferred_branch[$langs['field_alma_preferred_branch']][0]['value']:''; - - $branches = alma_reservation_pickup_branches(); - $pref = isset($branches[$pref_branch]) ? $branches[$pref_branch] : FALSE; - - return $pref; -} - -/** - * Implements hook_profile2_presave(). - * - * Sends changes to Alma - */ -function alma_profile2_presave($profile2) { - if( !$profile2->type == 'provider_alma' ) { - return; - } - // do not presave when initializing - // @see alma.user/alma_user_profile_init - if( isset($profile2->alma_init) ) { - return; - } - // providerfields: field_alma_preferred_branch, field_alma_interest_period, field_alma_reservation_pause; field_alma_mobile_phone - $langs = field_language('profile2', $profile2); - - // reservation pause - if( !empty( $profile2->original->field_alma_reservation_pause ) ) { - $start = - isset($profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value']) ? - $profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value'] : ''; - $start = str_replace('T00:00:00','',$start); - - $stop = - isset($profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value2']) ? - $profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value2'] : ''; - $stop = str_replace('T00:00:00','',$stop); - - $org_start = $profile2->original->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value']; - $org_start = str_replace('T00:00:00','',$org_start); - - $org_stop = $profile2->original->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value2']; - $org_stop = str_replace('T00:00:00','',$org_stop); - - if( $start != $org_start || $stop != $org_stop ) { - $changes['reservation_pause_start'] = $start; - $changes['reservation_pause_stop'] = $stop; - $changes['absent_id'] = $profile2->field_absent_id[$langs['field_absent_id']][0]['value']; - } - } - - // alma_preferred_branch (patronBranch) - if( !empty( $profile2->original->field_alma_preferred_branch ) ) { - $org_branch = $profile2->original->field_alma_preferred_branch[$langs['field_alma_preferred_branch']][0]['value']; - $new_branch = $profile2->field_alma_preferred_branch[$langs['field_alma_preferred_branch']][0]['value']; - - if( $org_branch != $new_branch ) { - $changes['preferred_branch'] = $new_branch; - } - } - - //change or remove - if( !empty($profile2->original->field_alma_mobile_phone ) ) { - $org_phone = $profile2->original->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value']; - $new_phone = - !empty( $profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value']) ? - $profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value'] : - 'DELETE'; - if( $org_phone != $new_phone ) { - $changes['mobile'] = $new_phone; - $changes['phone_id'] = $profile2->field_alma_phone_id[$langs['field_alma_phone_id']][0]['value']; - } - } - // add - elseif( isset( $profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value'] ) && - !isset( $profile2->original->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value'] )) { - $changes['mobile'] = $profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value']; - } - - - // Interest period ? apparently not an alma parameter.. @todo; check if Interest period should be saved on provider - - // update provider - if( isset($changes) ) { - alma_update_provider( $changes,$profile2 ); - } - -} - -function alma_update_provider( $changes, $profile2 ) { - $error_message = t('Error communicating with library system. '); - - try{ $creds = ding_user_get_creds( $profile2 );} - catch(Exception $e){ - // rethrow ?? - throw $e; - } - - // mobile phone; add, change, delete - if( isset($changes['phone_id']) ) { - if( $changes['mobile'] == 'DELETE' ) { - //delete mobile - try{ - $res = alma_client_invoke('remove_phone_number', $creds['name'], $creds['pass'], $changes['phone_id']); - } - catch(Exception $e){ - watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); - } - if( !$res ) { - $error_message .= t('mobile not deleted'); - drupal_set_message($error_message,'warning'); - } - } - else { - //update mobile - try{ - $res = alma_client_invoke('change_phone_number', $creds['name'], $creds['pass'], $changes['phone_id'], $changes['mobile']); - } - catch(Exception $e){ - watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); - } - if( !$res ) { - $error_message .= t('mobile not updated'); - drupal_set_message($error_message,'warning'); - } - } - } - elseif( isset($changes['mobile']) ){ - // add mobile - try{ - $res = alma_client_invoke('add_phone_number', $creds['name'], $creds['pass'], $changes['mobile'] ); - } - catch(Exception $e){ - watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); - } - if( !$res ) { - $error_message .= t('mobile not added'); - drupal_set_message($error_message,'warning'); - } - } - - // update reservation pause (absentPeriod) - if( !empty( $changes['absent_id'] ) && - !empty($changes['reservation_pause_start']) && - !empty( $changes['reservation_pause_stop'] )) { - - try { - $res = alma_client_invoke('change_absent_period',$creds['name'], $creds['pass'], $changes['absent_id'], $changes['reservation_pause_start'],$changes['reservation_pause_stop'] ); - } - catch(Exception $e){ - watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); - } - if( !$res ) { - $error_message .= t('reservation pause not updated'); - drupal_set_message($error_message,'warning'); - } - } - // add reservation pause - elseif( !empty($changes['reservation_pause_start']) && - !empty( $changes['reservation_pause_stop'] ) ) { - try { - $res = alma_client_invoke('add_absent_period',$creds['name'], $creds['pass'], $changes['reservation_pause_start'],$changes['reservation_pause_stop']); - } - catch(Exception $e){ - watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); - } - if( !$res ) { - $error_message .= t('reservation pause not added'); - drupal_set_message($error_message,'warning'); - } - } - // delete reservation pause - elseif( !empty( $changes['absent_id'] ) ) { - try { - $res = alma_client_invoke('remove_absent_period', $creds['name'], $creds['pass'], $changes['absent_id']); - } - catch(Exception $e){ - watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); - } - - // this one actually deletes the reservation pause, but returns an error ?? - // for now disable messages...@todo; fix it. - /* if( !$res ) { - $error_message .= t('reservation pause not deleted'); - drupal_set_message($error_message,'warning'); - }*/ - } - - // update preferred branch (patronBranch) - if( !empty($changes['preferred_branch'] ) ) { - try { - $res = alma_client_invoke( 'change_patron_preferences' , $creds['name'], $creds['pass'], $changes['preferred_branch']); - } - catch(Exception $e){ - watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); - } - if( !$res ) { - $error_message .= t('pickup branch not saved'); - drupal_set_message($error_message,'warning'); - } - } - - // refresh patron - alma_get_patron($creds, TRUE); -} - -/** - * Get patron data from Alma. - * - * @param array $creds - * Array with 'name' and 'pass' keys, used to authenticate user with Alma. - * @param boolean $reset - * Reset static caching for this function. - * @return stdClass - * Patron object. - */ -function alma_get_patron($creds = NULL, $reset = FALSE, $as_array = FALSE) { - if (is_null($creds)) { - // Get creds, which may throw an exception that login is required. - global $user; - $creds = ding_user_get_creds($user); - } - - static $patron; - if (!$patron || $reset) { - $info = alma_client_invoke('get_patron_info', $creds['name'], $creds['pass'], TRUE); - $organisation = alma_get_organisation(); - $patron = array( - 'name' => $info['user_name'], - 'email' => isset($info['mails'][0]) ? $info['mails'][0]['mail'] : '', - 'address' => isset($info['addresses'][0]) ? $info['addresses'][0]['street'] : '', - 'postal' => isset($info['addresses'][0]) ? $info['addresses'][0]['postal_code'] : '', - 'city' => isset($info['addresses'][0]) ? $info['addresses'][0]['city'] : '', - 'mobiles' => isset($info['phones']) ? $info['phones'] : '', - 'branch' => $info['preferences']['patron_branch'], - 'branchName' => $organisation['branch'][$info['preferences']['patron_branch']], - 'absentPeriods'=>isset($info['absent_periods']) ? $info['absent_periods'] : '', - ); - } - if( $as_array ) { - return $patron; - } - - return (object) $patron; -} - +data); + } + else { + $alma_pickup_branches = alma_client_invoke('get_reservation_branches'); + cache_set( 'alma_pickup_branches', serialize($alma_pickup_branches),'cache'); + } + } + return $alma_pickup_branches; +} + +/** + * Implements hook_requirements(). + */ +function alma_requirements($phase) { + $requirements = array(); + // Ensure translations don't break at install time. + $t = get_t(); + + if (!function_exists('simplexml_load_string')) { + $requirements['simplexml'] = array( + 'title' => 'SimpleXML', + 'description' => $t('The Alma module requires SimpleXML to function. Please install and/or enable SimpleXML in your PHP configuration.'), + 'severity' => REQUIREMENT_ERROR, + ); + } + + return $requirements; +} + +/** + * Implements hook_ding_provider(). + */ +function alma_ding_provider() { + $path = drupal_get_path('module', 'alma'); + + return array( + 'title' => 'Alma provider', + 'settings' => 'alma_settings_form', + 'provides' => array( + 'availability' => array( + 'prefix' => 'availability', + 'file' => $path . '/includes/alma.availability.inc', + ), + 'debt' => array( + 'prefix' => 'debt', + 'file' => $path . '/includes/alma.debt.inc', + ), + 'loan' => array( + 'prefix' => 'loan', + 'file' => $path . '/includes/alma.loan.inc', + ), + 'reservation' => array( + 'prefix' => 'reservation', + 'file' => $path . '/includes/alma.reservation.inc', + ), + 'user' => array( + 'prefix' => 'user', + 'file' => $path . '/includes/alma.user.inc', + ), + 'user_consent' => array( + 'prefix' => 'user_consent', + 'file' => $path . '/includes/alma.user_consent.inc', + ), + ), + ); +} + +/** + * Form callback for provider module settings. + * + * This is a regular form callback. + */ +function alma_settings_form() { + $form['alma'] = array( + '#type' => 'fieldset', + '#title' => t('Alma service settings'), + '#tree' => FALSE, + ); + + $form['alma']['alma_base_url'] = array( + '#type' => 'textfield', + '#title' => t('Alma base URL'), + '#description' => t('Base URL for Alma service.'), + '#required' => TRUE, + '#default_value' => variable_get('alma_base_url', ''), + ); + + $form['alma']['alma_enable_logging'] = array( + '#type' => 'checkbox', + '#title' => t('Enable logging'), + '#default_value' => variable_get('alma_enable_logging', FALSE), + '#description' => t('Logs requests to the Alma webservice. Sensitive information such as CPR number and PIN code is stripped from the requests.'), + ); + + return system_settings_form($form); +} + +/** + * Implements hook_form_FORM_ID_alter(). + * pjo notes: user_profile_form + * Add in pincode validation. + */ +function alma_form_user_profile_form_alter(&$form, &$form_state) { + // Ensure that we're dealing with a provider user. + if (!ding_user_is_provider_user($form_state['user'])) { + return; + } + + // change size and length of pincode + $form['account']['pincode']['#size'] = 32; + $form['account']['pincode']['#maxlength'] = 32; + + // @todo; WHAT are the rules for alma pincode + // HOW do we validate + + // custom validator ?? maybe pincode validator ?? + // $form['#validate'][] = 'alma_profile_form_validate'; +} + + + +/** + * Return a fully instantiated AlmaClient instance. + */ +function alma_client() { + // This is basically a singleton. We also wait until right before + // instantiating to include our required classes. That seems like a + // decent performance tradeoff instead of loading everything on every + // page load. + static $client; + if (!isset($client)) { + $path = drupal_get_path('module', 'alma'); + try { + $client = new AlmaClient(variable_get('alma_base_url', '')); + } + catch (Exception $e) { + watchdog('alma', 'Constructor error: “@message”', array('@message' => $e->getMessage(), WATCHDOG_ERROR)); + return NULL; + } + + } + return $client; +} + +/** + * Calls the Alma backend, possibly caching the result. + * + * @param $method + * The desired method. + * @param ... + * Arguments to the method. + * + * @return mixed + * NULL on error, or the result of the method call. + */ +function alma_client_invoke($method) { + $args = func_get_args(); + array_shift($args); // Lose the method. + $client = alma_client(); + + try { + $result = call_user_func_array(array($client, $method), $args); + } + catch (Exception $e) { + watchdog('alma', '@method error: “@message”', array('@method' => $method, '@message' => $e->getMessage()), WATCHDOG_ERROR); + throw $e; + } + + return $result; +} + +/** + * Get the complete organisation info from Alma. + * + * Includes branches, departments, locations, sublocations and collections. The + * information is cache until the cache is cleared or the reset parameter is + * TRUE. + * + * @param boolean $reset + * Optional. If TRUE reset the cached data and reload. + * @return array + * Array of the different organisational unit, each an array of their + * member units. + */ +function alma_get_organisation($reset = FALSE) { + // Return data from cache if available. + static $organisation; + if (!$organisation || $reset) { + if (($cache = cache_get('alma_organisation')) && !empty($cache->data) && !$reset) { + $organisation = $cache->data; + } + else { + $organisation = array( + 'branch' => alma_client_invoke('get_branches'), + 'department' => alma_client_invoke('get_departments'), + 'location' => alma_client_invoke('get_locations'), + 'sublocation' => alma_client_invoke('get_sublocations'), + 'collection' => alma_client_invoke('get_collections'), + 'reservation' => alma_reservation_pickup_branches(),//alma_client_invoke('get_reservation_branches'), + ); + + // Cache output for 24 hours if we got all the data correctly. + if ($organisation['branch'] && $organisation['department'] && + $organisation['location'] && $organisation['sublocation'] && + $organisation['collection'] && $organisation['reservation']) { + cache_set('alma_organisation', $organisation, 'cache'); + } + } + } + + return $organisation; +} + +/** + * Implements hook_user_view + */ +function alma_user_view( $account, $view_mode, $langcode ) { + if (ding_user_is_provider_user($account)) { + $creds = ding_user_get_creds($account); + + if ($creds && ($userInfo = ding_provider_invoke('user', 'info', $creds)) && isset($userInfo)) { + foreach ($userInfo as $key => $prop) { + $data[$key] = isset($prop) ? $prop : ''; + } + + $account->content['name'] = array( + '#type' => 'item', + '#title' => t('Name'), + '#markup' => $data['firstname'], + ); + + $address_parts = array($data['address']); + if (!empty($data['postal']) || !empty($data['city'])) { + $address_parts[] = join('
', array_filter(array($data['postal'], $data['city']))); + } + + // @todo: really, there should be a template for this. + $account->content['address'] = array( + '#type' => 'item', + '#title' => t('Address'), + '#markup' => '

' . join('
', $address_parts) . '

', + ); + + // @todo: add provider specific fields + alma_set_profile2_fields($account); + }; + } +} + +function alma_set_profile2_fields($account) { + if( !module_exists('profile2') ) { + return; + } + + $profile2 = profile2_load_by_user($account, 'provider_alma'); + if( empty($profile2) ) { + return; + } + + // wrapper for profile2-fields + $account->content['profile2'] = array( + '#type' => 'item', + '#title' => t('My library'), + '#prefix' => '
', + '#suffix' => '
', + ); + + // set preferred branch + if( $pref_branch = alma_get_preferred_branch( $profile2 ) ) { + $account->content['profile2']['preferred_branch'] = array( + '#type' => 'item', + '#title' => t('Pickup branch'), + '#markup' => ''.$pref_branch.'', + ); + } + + // set interest period + if( $interest_period = alma_get_interest_period($profile2) ) { + $account->content['profile2']['interest_period'] = array( + '#type' => 'item', + '#title' => t('Interest period'), + '#markup' => ''.$interest_period['value'].'', + ); + } + + // set mobile phone + if( $mob = alma_get_mobile_phone($profile2) ) { + $account->content['profile2']['mobile'] = array( + '#type' => 'item', + '#title' => t('Mobile phone'), + '#markup' => ''.$mob.'', + ); + } + + // set reservation pause + if( $reservation_pause = alma_get_reservation_pause( $profile2 ) ) { + //wrapper for reservation pause + $account->content['profile2']['reservation_pause'] = array( + '#type' => 'item', + '#title' => t('Reservation pause'), + '#prefix' => '
', + '#suffix' => '
', + ); + + $account->content['profile2']['reservation_pause']['start'] = array( + '#type' => 'item', + '#title' => t('Start'), + '#markup' => ''.str_replace('T00:00:00','',$reservation_pause['start']).'', + ); + + $account->content['profile2']['reservation_pause']['stop'] = array( + '#type' => 'item', + '#title' => t('Stop'), + '#markup' => ''.str_replace('T00:00:00','',$reservation_pause['stop']).'', + ); + } +} + +function alma_get_mobile_phone( $profile2 ) { + $langs = field_language('profile2', $profile2); + + if( empty($profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']] ) ) { + return false; + } + + $mob = + isset($profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value']) ? + $profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value'] : FALSE; + + return $mob; +} + +function alma_get_reservation_pause($profile2){ + // get field languages + $langs = field_language('profile2', $profile2); + + if( empty($profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']] ) ) { + return false; + } + + $res_pause['start'] = $profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value']; + $res_pause['stop'] = $profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value2']; + + if( strlen($res_pause['start']) < 2 || strlen($res_pause['stop']) < 2 ) { + return false; + } + + return $res_pause; +} + +function alma_get_interest_period( $profile2 ) { + // get field languages + $langs = field_language('profile2', $profile2); + // get field-info to retrieve values for select list + $field_info = field_info_field('field_alma_interest_period'); + + $interest_period = FALSE; + $int_values = isset( $field_info['settings']['allowed_values'] ) ? $field_info['settings']['allowed_values']: FALSE; + if( $int_values ) { + $int_period = $profile2->field_alma_interest_period[$langs['field_alma_interest_period']][0]['value']; + $interest_period = isset($int_values[$int_period]) ? array('key'=>$int_period,'value'=>$int_values[$int_period]) : FALSE; + } + return $interest_period; +} + +function alma_get_preferred_branch( $profile2 ) { + // get field languages + $langs = field_language('profile2', $profile2); + + //get preferred branch + $pref_branch = + isset($profile2->field_alma_preferred_branch[$langs['field_alma_preferred_branch']][0]['value']) ? + $profile2->field_alma_preferred_branch[$langs['field_alma_preferred_branch']][0]['value']:''; + + $branches = alma_reservation_pickup_branches(); + $pref = isset($branches[$pref_branch]) ? $branches[$pref_branch] : FALSE; + + return $pref; +} + +/** + * Implements hook_profile2_presave(). + * + * Sends changes to Alma + */ +function alma_profile2_presave($profile2) { + if( !$profile2->type == 'provider_alma' ) { + return; + } + // do not presave when initializing + // @see alma.user/alma_user_profile_init + if( isset($profile2->alma_init) ) { + return; + } + // providerfields: field_alma_preferred_branch, field_alma_interest_period, field_alma_reservation_pause; field_alma_mobile_phone + $langs = field_language('profile2', $profile2); + + // reservation pause + if( !empty( $profile2->original->field_alma_reservation_pause ) ) { + $start = + isset($profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value']) ? + $profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value'] : ''; + $start = str_replace('T00:00:00','',$start); + + $stop = + isset($profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value2']) ? + $profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value2'] : ''; + $stop = str_replace('T00:00:00','',$stop); + + $org_start = $profile2->original->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value']; + $org_start = str_replace('T00:00:00','',$org_start); + + $org_stop = $profile2->original->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value2']; + $org_stop = str_replace('T00:00:00','',$org_stop); + + if( $start != $org_start || $stop != $org_stop ) { + $changes['reservation_pause_start'] = $start; + $changes['reservation_pause_stop'] = $stop; + if(isset($profile2->field_absent_id[$langs['field_absent_id']][0])) + $changes['absent_id'] = $profile2->field_absent_id[$langs['field_absent_id']][0]['value']; + } + } + + // alma_preferred_branch (patronBranch) + if( !empty( $profile2->original->field_alma_preferred_branch ) ) { + if(isset($profile2->original->field_alma_preferred_branch[$langs['field_alma_preferred_branch']])) { + $org_branch = $profile2->original->field_alma_preferred_branch[$langs['field_alma_preferred_branch']][0]['value']; + if(isset($profile2->field_alma_preferred_branch[$langs['field_alma_preferred_branch']])) + $new_branch = $profile2->field_alma_preferred_branch[$langs['field_alma_preferred_branch']][0]['value']; + + if( $org_branch != $new_branch ) { + $changes['preferred_branch'] = $new_branch; + } + } + } + + //change or remove + if( !empty($profile2->original->field_alma_mobile_phone ) ) { + $org_phone = $profile2->original->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value']; + $new_phone = + !empty( $profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value']) ? + $profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value'] : + 'DELETE'; + if( $org_phone != $new_phone ) { + $changes['mobile'] = $new_phone; + if(isset($profile2->field_alma_phone_id[$langs['field_alma_phone_id']][0])) + $changes['phone_id'] = $profile2->field_alma_phone_id[$langs['field_alma_phone_id']][0]['value']; + } + } + // add + elseif( isset($profile2->field_alma_mobile_phone) && isset( $profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0] ) && + !isset( $profile2->original->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0] )) { + $changes['mobile'] = $profile2->field_alma_mobile_phone[$langs['field_alma_mobile_phone']][0]['value']; + } + + + // Interest period ? apparently not an alma parameter.. @todo; check if Interest period should be saved on provider + + // update provider + if( isset($changes) ) { + alma_update_provider($changes, $profile2); + } + +} + +function alma_update_provider( $changes, $profile2 ) { + $error_message = t('Error communicating with library system. '); + + try{ $creds = ding_user_get_creds( $profile2 );} + catch(Exception $e){ + // rethrow ?? + throw $e; + } + + // mobile phone; add, change, delete + if( isset($changes['phone_id']) ) { + if( $changes['mobile'] == 'DELETE' ) { + //delete mobile + try{ + $res = alma_client_invoke('remove_phone_number', $creds['name'], $creds['pass'], $changes['phone_id']); + } + catch(Exception $e){ + watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); + } + if( !$res ) { + $error_message .= t('mobile not deleted'); + drupal_set_message($error_message,'warning'); + } + } + else { + //update mobile + try{ + $res = alma_client_invoke('change_phone_number', $creds['name'], $creds['pass'], $changes['phone_id'], $changes['mobile']); + } + catch(Exception $e){ + watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); + } + if( !$res ) { + $error_message .= t('mobile not updated'); + drupal_set_message($error_message,'warning'); + } + } + } + if( isset($changes['mobile']) ){ + // add mobile + try{ + $res = alma_client_invoke('add_phone_number', $creds['name'], $creds['pass'], $changes['mobile'] ); + } + catch(Exception $e){ + watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); + } + if( !$res ) { + $error_message .= t('mobile not added'); + drupal_set_message($error_message,'warning'); + } + } + // update reservation pause (absentPeriod) + if (!empty( $changes['absent_id']) && + !empty($changes['reservation_pause_start']) && + !empty($changes['reservation_pause_stop'])) { + + try{ + // Hack. In order to retrieve current absent id + $ext_info = alma_client_invoke('get_patron_info', $creds['name'], $creds['pass'], TRUE); + } + catch (Exception $e){ + watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); + } + if (!empty($ext_info) && $ext_info['absent_periods'][0]['id'] != $changes['absent_id']) { + $changes['absent_id'] = $ext_info['absent_periods'][0]['id']; + } + $res = FALSE; + try { + $res = alma_client_invoke('change_absent_period',$creds['name'], $creds['pass'], $changes['absent_id'], $changes['reservation_pause_start'],$changes['reservation_pause_stop'] ); + } + catch (Exception $e){ + watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); + } + if (!$res) { + $error_message .= t('reservation pause not updated'); + drupal_set_message($error_message,'warning'); + } + } + // add reservation pause + elseif (!empty($changes['reservation_pause_start']) && !empty($changes['reservation_pause_stop'])) { + try{ + $ext_info = alma_client_invoke('get_patron_info', $creds['name'], $creds['pass'], TRUE); + } + catch(Exception $e){ + watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); + } + if(!empty($ext_info) && $ext_info['absent_periods'][0]['id'] != $changes['absent_id']) { + $changes['absent_id'] = $ext_info['absent_periods'][0]['id']; + } + try { + $res = alma_client_invoke('add_absent_period',$creds['name'], $creds['pass'], $changes['reservation_pause_start'],$changes['reservation_pause_stop']); + } + catch(Exception $e){ + watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); + } + if (!isset($res)) { + $error_message .= t('reservation pause not added'); + drupal_set_message($error_message,'warning'); + } + } + // delete reservation pause + elseif( !empty( $changes['absent_id'] ) ) { + try { + $res = alma_client_invoke('remove_absent_period', $creds['name'], $creds['pass'], $changes['absent_id']); + } + catch(Exception $e){ + watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); + } + + // this one actually deletes the reservation pause, but returns an error ?? + // for now disable messages...@todo; fix it. + /* if( !$res ) { + $error_message .= t('reservation pause not deleted'); + drupal_set_message($error_message,'warning'); + }*/ + } + + // update preferred branch (patronBranch) + if( !empty($changes['preferred_branch'] ) ) { + try { + $res = alma_client_invoke( 'change_patron_preferences' , $creds['name'], $creds['pass'], $changes['preferred_branch']); + } + catch(Exception $e){ + watchdog('Alma provider', $e->getMessage(), array(), WATCHDOG_ERROR); + } + if( !$res ) { + $error_message .= t('pickup branch not saved'); + drupal_set_message($error_message,'warning'); + } + } + + // refresh patron + alma_get_patron($creds, TRUE); +} + +/** + * Get patron data from Alma. + * + * @param array $creds + * Array with 'name' and 'pass' keys, used to authenticate user with Alma. + * @param boolean $reset + * Reset static caching for this function. + * @return stdClass + * Patron object. + */ +function alma_get_patron($creds = NULL, $reset = FALSE, $as_array = FALSE) { + if (is_null($creds)) { + // Get creds, which may throw an exception that login is required. + global $user; + $creds = ding_user_get_creds($user); + } + + static $patron; + if (!$patron || $reset) { + $info = alma_client_invoke('get_patron_info', $creds['name'], $creds['pass'], TRUE); + $organisation = alma_get_organisation(); + $patron = array( + 'name' => $info['user_name'], + 'email' => isset($info['mails'][0]) ? $info['mails'][0]['mail'] : '', + 'address' => isset($info['addresses'][0]) ? $info['addresses'][0]['street'] : '', + 'postal' => isset($info['addresses'][0]) ? $info['addresses'][0]['postal_code'] : '', + 'city' => isset($info['addresses'][0]) ? $info['addresses'][0]['city'] : '', + 'mobiles' => isset($info['phones']) ? $info['phones'] : '', + 'branch' => $info['preferences']['patron_branch'], + 'branchName' => $organisation['branch'][$info['preferences']['patron_branch']], + 'absentPeriods' => isset($info['absent_periods']) ? $info['absent_periods'] : '', + 'category' => isset($info['category']) ? $info['category'] : '', + 'allows' => isset($info['allows']) ? $info['allows'] : '', + ); + } + if( $as_array ) { + return $patron; + } + + return (object) $patron; +} + +/** + * Update order, by defining new expiry date or pickup branch. + */ +function alma_get_remote_data($account, $id, $reset = FALSE) { + $creds = ding_user_get_creds($account); + + // Try to look in the session for reservation information. + if (!isset($_SESSION['catalogue_record_detail'][$id]) || !is_array($_SESSION['catalogue_record_detail']) || $reset) { + $_SESSION['catalogue_record_detail'][$id] = alma_client_invoke('catalogue_record_detail', $id); + } + + return $_SESSION['catalogue_record_detail'][$id]; +} \ No newline at end of file diff --git a/includes/alma.availability.inc b/includes/alma.availability.inc old mode 100644 new mode 100755 index 78c18ee..bae45b1 --- a/includes/alma.availability.inc +++ b/includes/alma.availability.inc @@ -4,121 +4,319 @@ */ function alma_availability_holdings($provider_ids) { $ids = join(',', $provider_ids); - $holding_parts = array('branch', 'department', 'location', 'sublocation', 'collection'); + $details = alma_client_invoke('catalogue_record_detail', $ids); $org = alma_get_organisation(); + $result = array(); if ($details && isset($details['records'])) { foreach ($details['records'] as $alma_id => $record) { $holding = array( 'local_id' => $alma_id, 'available' => ($record['available_count'] > 0), - 'reservable' => $record['show_reservation_button'], + 'reservable' => ($record['show_reservation_button']), 'show_reservation_button' => $record['show_reservation_button'], 'reserved_count' => (int) $record['reservation_count'], 'deferred_period' => FALSE, - - 'is_periodical' => ($record['media_class'] == 'periodical'), + 'is_periodical' => ($record['media_class'] == 'periodical'), + 'is_internet' => ($record['media_class'] == 'internet' || in_array($record['resource_type'], array('electronic', 'electronical'))), ); + + $holding['location'] = alma_get_holding_location($record, $holding['is_periodical'], $org); + $holding['holdings'] = _alma_get_holdings($details, $holding['is_periodical']); + + $result[$alma_id] = $holding; + } + } + return $result; +} - $total = $total_reservable = 0; - - // START periodicals - if( $holding['is_periodical'] ) { - $parts = array(); - $holding['holdings'] = array(); - foreach( $record['holdings'] as $volume => $issues ) { - foreach($issues as $issue_no => $holds){ - $issue = array(); - $issue['branches'] = array(); - foreach( $holds as $key => $branch_holding) { - - if( !in_array( $branch_holding['branch_id'], $issue['branches'] ) ) { - $issue['branches'][] = $branch_holding['branch_id']; - } - - $issue['local_id'] = $branch_holding['reservable']; - $issue['reservable'] = (($branch_holding['status'] == 'availableForLoan') && - ((int) $branch_holding['total_count'] - (int) $branch_holding['reference_count'])); - $issues_array[$volume][$issue_no] = $issue; +/** + * @param type $holdings; array containing holding informations + * @param type $is_periodical; Boolean that indicates whether the shown record is a periodical or not + * @return sum of all total_count in $holdings + */ +function _alma_count_total($holdings, $is_periodical) { + $total = 0; + if ($is_periodical) { + foreach ($holdings as $year => $issues) { + foreach ($issues as $issue) { + foreach ($issue as $holding) { + $total += $holding['total_count']; + } + } + } + } + else { + foreach ($holdings as $holding) { + $total += $holding['total_count']; + } + } + return $total; +} - if (in_array($branch_holding['collection_id'], array('karens', 'karens-'))) { - $holding['deferred_period'] = TRUE; - } +/** + * @param type $res; returned array from alma_client class + * @param type $is_periodical; Boolean that indicates whether the shown record is a periodical or not + * @return html to be shown. Returns FALSE if no data is received from alma_client class + */ +function _alma_get_holdings($res, $is_periodical = FALSE) { + if(isset($res['records'])) { + if($is_periodical){ + return _alma_set_holdings_periodical($res); + } + else { + return _alma_set_holdings($res); + } + } + else { + return FALSE; + } +} - $parts = array(); - $total += (int) $branch_holding['total_count']; - // Reservable is total items minus reference (which cannot be - // loaned). - $reservable = (int) $branch_holding['total_count'] - (int) $branch_holding['reference_count']; - $total_reservable += $reservable; - foreach ($holding_parts as $part) { - if (!empty($branch_holding[$part . '_id'])) { - $parts[] = $org[$part][$branch_holding[$part . '_id']]; - } - } + /** + * set holdings for all kinds of material except periodicals + * @param array $res + * @return array $result; + */ +function _alma_set_holdings($res) { + $holdings = array(); + foreach ($res['records'] as $alma_id => $records) { + foreach ($records['holdings'] as $holding) { + $holdings[] = $holding; + } + } + + $result = _alma_set_table_html($holdings); + return $result; +} - if (!empty($branch_holding['shelf_mark'])) { - // Shelf mark might have leading >, strip any and replace the rest - // with the proper arrow. - $parts[] = strtr(trim($branch_holding['shelf_mark'], " >\n\t"), array('>' => '→')); - } + /** + * set holdings if material is periodical only + * @param array $res + * @return array $result + */ +function _alma_set_holdings_periodical($res){ + $holdings = array(); + foreach ($res['records'] as $alma_id => $records) { + foreach ($records['holdings'] as $holding => $issue_year) { + foreach ($issue_year as $key) { + $holdings = array_merge($holdings, $key); + } + } + } + + $result = _alma_set_table_html($holdings); + return $result; +} + /** + * Make the html-table + * @params $h; holding information for a given material + * @return html-table + */ +function _alma_set_table_html($h) { + // set a classname for styling the table + $variables['attributes'] = array( + 'class' => array( + drupal_html_class('availability_holdings_table'), + ), + ); + // set table header + $variables['header'] = array( + 'placement' => t('Placement'), + 'copies' => t('Copies'), + 'home' => t('At home'), + 'reference' => t('Not for loan'), + 'checked_out' => t('Checked out'), + 'reservations' => t('Reservations'), + ); + // set table rows + $variables['rows'] = _alma_set_rows($h); - $parts = array_filter($parts); - - if ($parts && $branch_holding['total_count'] > $branch_holding['checked_out_count']) { - $branch_string = join(' → ', $parts); - $holding['holdings_available'][] = $branch_string; - if( !in_array($branch_string,$holding['holdings']) ) { - $holding['holdings'][] = $branch_string; - } - } - } - } - } - if( is_array($holding['holdings']) ) { - asort($holding['holdings']); - } - $holding['issues'] = $issues_array; - } // END periodicals + return $variables; +} - else { - foreach ($record['holdings'] as $branch_holding) { - if (in_array($branch_holding['collection_id'], array('karens', 'karens-'))) { - $holding['deferred_period'] = TRUE; - } + /** + * set rows in table for given holdings + * @param $h; holding information for a given material + * @return array; + */ +function _alma_set_rows($h) { + $rows = array(); + $org = alma_get_organisation(); + + $copies_total = 0; + $home_total = 0; + $reservations_total = 0; + $reference_total = 0; + $checked_out_total = 0; + + foreach ($h as $key => $data) { + $row = array(); + $row['placement'] = ''; + if(isset($data['branch_id'])) + $row['placement'] = $org['branch'][$data['branch_id']]; + + if(isset($data['department_id'])) + $row['placement'] = $row['placement'] .' → '. $org['department'][$data['department_id']]; + + if(isset($data['collection_id'])) + $row['placement'] = $row['placement'] .' → '. $org['collection'][$data['collection_id']]; + + $row['copies'] = isset($data['total_count']) ? (int) $data['total_count'] : 0; + $copies_total += $row['copies']; + $row['home'] = isset($data['available_count']) ? (int) $data['available_count'] : 0; + $home_total += $row['home']; + $row['reference'] = isset($data['reference_count']) ? (int) $data['reference_count'] : 0; + $reference_total += $row['reference']; + $row['checked_out'] = isset($data['checked_out_count']) ? (int) $data['checked_out_count'] : 0; + $checked_out_total += $row['checked_out']; + $row['reservations'] = isset($data['ordered_count']) ? (int) $data['ordered_count'] : 0; + $reservations_total += $row['reservations']; + $rows[] = $row; + } + + if(count($rows) >= 1){ + $rows = _clean_up_rows($rows); + } + //Adding last row - totals + $row = array(); + $row['data']['Library'] = t('Total'); + $row['data']['Copies'] = $copies_total; + $row['data']['Home'] = $home_total; + $row['data']['Reference'] = $reference_total; + $row['data']['Checked_out'] = $checked_out_total; + $row['data']['Reservations'] = $reservations_total; + $row['class'] = array(drupal_html_class('availability_holdings_last_row')); + $rows[] = $row; + return $rows; +} - $parts = array(); - $total += (int) $branch_holding['total_count']; - // Reservable is total items minus reference (which cannot be - // loaned). - $reservable = (int) $branch_holding['total_count'] - (int) $branch_holding['reference_count']; - $total_reservable += $reservable; - foreach ($holding_parts as $part) { - if (!empty($branch_holding[$part . '_id'])) { - $parts[] = $org[$part][$branch_holding[$part . '_id']]; - } - } + /** + * if the same placement exists several times collect them in one line + * @param array + * @return array; + */ +function _clean_up_rows($_rows) { + $rows = array(); + $placements = array(); + + foreach ($_rows as $row) { + $currkey = $row['placement']; + if(!in_array($currkey, $placements)){ + $placements[] = $currkey; + $placementsarr = _get_placements_with_key($_rows, $currkey); + $this_row = _sum_placement($placementsarr); + $rows[] = $this_row; + } + } + return $rows; +} - if (!empty($branch_holding['shelf_mark'])) { - // Shelf mark might have leading >, strip any and replace the rest - // with the proper arrow. - $parts[] = strtr(trim($branch_holding['shelf_mark'], " >\n\t"), array('>' => '→')); - } + /** + * collect materials with the same placement + * @param array $_rows + * @param String $currkey + * @return array $rows; + */ +function _get_placements_with_key($_rows, $currkey){ + $rows = array(); + foreach ($_rows as $key) { + if($key['placement'] == $currkey){ + $rows[] = $key; + } + } + return $rows; +} + /** + * sum material for same placement in one row + * @param $placementsarr; array with all instances of the same placement - ie. 'Hovedbiblioteket' + * @return array; $row + */ +function _sum_placement($placementsarr){ + $row = $placementsarr[0]; + for($i = 1; $i < count($placementsarr);$i++){ + $next_row = $placementsarr[$i]; + $row['copies'] += $next_row['copies']; + $row['home'] += $next_row['home']; + $row['reference'] += $next_row['reference']; + $row['checked_out'] += $next_row['checked_out']; + $row['reservations'] += $next_row['reservations']; + } + return $row; +} - $parts = array_filter($parts); +function alma_get_holding_location($record, $is_periodical = FALSE, $org = NULL) { + $holding_parts = array('branch', 'department', 'location', 'sublocation', 'collection'); + + $parts = array(); + $result = array(); + $result['holdings'] = array(); + if($is_periodical) { + foreach( $record['holdings'] as $volume => $issues ) { + foreach($issues as $issue_no => $holds){ + $issue = array( + 'branches' => array(), + ); + foreach( $holds as $key => $branch_holding) { + if( !in_array( $branch_holding['branch_id'], $issue['branches'] ) ) { + $issue['branches'][] = $branch_holding['branch_id']; + } - if ($parts && $branch_holding['total_count'] > $branch_holding['checked_out_count']) { - $holding['holdings'][] = join(' → ', $parts); - } - } + $issue['local_id'] = $branch_holding['reservable']; + $issue['reservable'] = (($branch_holding['status'] == 'availableForLoan') && + ((int) $branch_holding['total_count'] - (int) $branch_holding['reference_count'])); + $issues_array[$volume][$issue_no] = $issue; + $parts = array(); + foreach ($holding_parts as $part) { + if (!empty($branch_holding[$part . '_id']) && !empty($org[$part][$branch_holding[$part . '_id']])) { + $parts[] = $org[$part][$branch_holding[$part . '_id']]; + } + } + + if (!empty($branch_holding['shelf_mark'])) { + // Shelf mark might have leading >, strip any and replace the rest + // with the proper arrow. + $parts[] = strtr(trim($branch_holding['shelf_mark'], " >\n\t"), array('>' => '')); + } + + $parts = array_filter($parts); + + if ($parts) { + $branch_string = join(' → ', $parts); + $result['holdings_available'][] = $parts; + if( !in_array($parts, $result['holdings']) ) { + $result['holdings'][] = $parts; + } + } + } } + } + if( is_array($result['holdings']) ) { + asort($result['holdings']); + } + $result['issues'] = $issues_array; + } // END periodicals + else { + foreach ($record['holdings'] as $branch_holding) { + $parts = array(); + foreach ($holding_parts as $part) { + if (!empty($branch_holding[$part . '_id'])) { + $parts[] = $org[$part][$branch_holding[$part . '_id']]; + } + } + if (!empty($branch_holding['shelf_mark'])) { + // Shelf mark might have leading >, strip any and replace the rest + // with the proper arrow. + $parts[] = strtr(trim($branch_holding['shelf_mark'], " >\n\t"), array('>' => '→')); + } - $holding['reservable_count'] = $total_reservable; - $holding['total_count'] = $total; - $result[$alma_id] = $holding; + $parts = array_filter($parts); + + if ($parts) { + $result['holdings'][] = $parts; + } } } - return $result; -} +} \ No newline at end of file diff --git a/includes/alma.debt.inc b/includes/alma.debt.inc old mode 100644 new mode 100755 diff --git a/includes/alma.loan.inc b/includes/alma.loan.inc old mode 100644 new mode 100755 index c5a0179..8a28878 --- a/includes/alma.loan.inc +++ b/includes/alma.loan.inc @@ -21,7 +21,7 @@ function alma_loan_list($account) { } catch (Exception $e) { throw new DingProviderLoanUserError($e->getMessage()); } - + foreach ($loans as $loan) { $results[$loan['id']] = new DingProviderLoan($loan['id'], array( 'ding_entity_id' => variable_get('ting_agency', '') . ':' . $loan['record_id'], @@ -30,6 +30,7 @@ function alma_loan_list($account) { 'renewable' => $loan['is_renewable'], 'materials_number' => $loan['id'], 'notes' => isset($loan['notes']) ? $loan['notes'] : DingEntityBase::NULL, + 'message' => isset($loan['message']) ? alma_loan_message($loan['message']) : DingEntityBase::NULL, )); } @@ -45,17 +46,77 @@ function alma_loan_renew($account, $ids) { $creds = ding_user_get_creds($account); $result = array(); $res = alma_client_invoke('renew_loan', $creds['name'], $creds['pass'], $ids); - foreach ($ids as $id) { if (isset($res[$id]) && $res[$id] === TRUE) { - $result[$id] = DingProviderLoan::STATUS_RENEWED; + $result[$id] = array( + 'state' => DingProviderLoan::STATUS_RENEWED, + ); } else { - /** - * @todo there are message saying why, the renew failed. - */ - $result[$id] = DingProviderLoan::STATUS_NOT_RENEWED; + $result[$id] = array( + 'state' => DingProviderLoan::STATUS_NOT_RENEWED, + 'message' => $res[$id], + ); } } return $result; } + +/** + * Implements hook_loan_list(). + * + * This functions finds all loans for a given user account and returns the loans + * as DingProviderLoan objects. + * + */ +function alma_loan_overdue($account) { + $creds = ding_user_get_creds($account); + $results = array(); + + try { + // Get all loans form alma for the user account given. + $loans = alma_client_invoke('get_overdue_loans', $creds['name'], $creds['pass']); + } catch (Exception $e) { + throw new DingProviderLoanUserError($e->getMessage()); + } + + foreach ($loans as $loan) { + $results[$loan['id']] = new DingProviderLoan($loan['id'], array( + 'ding_entity_id' => variable_get('ting_agency', '') . ':' . $loan['record_id'], + 'loan_date' => $loan['loan_date'], + 'expiry' => $loan['due_date'], + 'renewable' => $loan['is_renewable'], + 'materials_number' => $loan['id'], + 'notes' => isset($loan['notes']) ? $loan['notes'] : DingEntityBase::NULL, + )); + } + + return $results; +} + +/** + * Return one or all of the possible loan messages. + * In cases where renewing loans is not possible the system returns a reason message and + * this function converts that system message into a human readable message. + * + * @param string $message_key + * The message key returned by Alma, or null to retrieve the entire list. + * + * @return string or array + * + */ +function alma_loan_message($message_key = null) { + $messages = array( + 'isLoanedToday' => t('This has been loaned today'), + 'isRenewedToday' => t('This has been renewed today'), + 'isOverdue' => t('This is overdue'), + 'patronIsDeniedLoan' => t('You have been denied loans'), + 'patronHasDebt' => t('You have debt'), + 'maxNofRenewals' => t('The maximum loans has been reached'), + 'patronIsInvoiced' => t('You have invoices to payed'), + 'copyHasSpecialCircCat' => t('This copy has a special category'), + 'copyIsReserved' => t('This is reserved by another'), + 'renewalIsDenied' => t('It is not possible to renew'), + ); + return ($message_key) ? $messages[$message_key] : $messages; +} \ No newline at end of file diff --git a/includes/alma.reservation.inc b/includes/alma.reservation.inc old mode 100644 new mode 100755 index 98192ce..3123e98 --- a/includes/alma.reservation.inc +++ b/includes/alma.reservation.inc @@ -17,23 +17,57 @@ function alma_reservation_options($type, $account, $reservables) { if (!module_exists('ding_reservation')) { throw new Exception('Alma reservation options requires ding_reservation.'); - } + } $form = array(); $profile = ding_user_provider_profile($account); $branches = alma_reservation_pickup_branches($account); // @todo; use local branches from issue - some migth not be available in all branches + $periods = array( + 7 => '1 week', + 14 => '2 weeks', + 21 => '3 weeks', + 30 => '1 month', + 60 => '2 months', + 90 => '3 months', + 180 => '6 months', + ); if(ding_user_is_provider_user($account)) { - $preferred_branch = 'hb'; - // $preferred_branch = $profile->openruth_preferred_branch[field_language('profile2', $profile, 'openruth_preferred_branch')][0]['value']; + if(isset($profile->field_alma_preferred_branch)) + $preferred_branch = $profile->field_alma_preferred_branch[field_language('profile2', $profile, 'field_alma_preferred_branch')][0]['value']; + else + $preferred_branch = NULL; + + if(isset($profile->field_alma_interest_period)) + $preferred_period = $profile->field_alma_interest_period[field_language('profile2', $profile, 'field_alma_interest_period')][0]['value']; + else + $preferred_period = NULL; } else { - //$preferred_branch = NULL; + $preferred_branch = NULL; + $preferred_period = NULL; } - - $form += ding_reservation_default_options_branch($type, 'alma_preferred_branch',$preferred_branch, $branches); + + // $collection = ting_collection_load($reservables->entity->ding_entity_id); + // $reserve_id = array(); + // if(!empty($collection)) { + // $options = array(); + // foreach ($collection->getEntities() as $entity) { + // $options[$entity->ding_entity_id] = $entity->type; + // } + // $reserve_id = array('reserve_id' => array( + // '#type' => 'select', + // '#title' => t('Format'), + // '#options' => $options + // )); + // } + + + // $form += $reserve_id; + $form += ding_reservation_default_options_branch($type, 'alma_preferred_branch', $preferred_branch, $branches); + $form += ding_reservation_interest_period_selector($type, 'alma_interest_period', $preferred_period, $periods); return $form; } @@ -56,42 +90,50 @@ function alma_reservation_set_preferred_branch($account, $branch) { /** * Get list of reserved items. + * + * @param $account + * A user account + * + * @return array + * An array of DingProviderReservation objects + * + * @see ding_provider.reservation.inc */ - function alma_reservation_list($account) { - $creds = ding_user_get_creds($account); - $reservations = alma_reservation_get_reservations($account); - $result = array(); - - // Create DingProviderReservation objects into to categories base on pickup - // status. - foreach ($reservations as $reservation) { - if (isset($reservation['pickup_number'])) { - $result[$reservation['id']] = new DingProviderReservation($reservation['id'], array( - 'order_id' => $reservation['id'], - 'ding_entity_id' => variable_get('ting_agency', '') . ':' . $reservation['record_id'], - 'pickup_branch_id' => $reservation['pickup_branch'], - 'pickup_date' => $reservation['pickup_expire_date'], - 'created' => $reservation['create_date'], - 'expiry' => $reservation['valid_to'], - 'queue_number' => $reservation['queue_number'], - 'ready_for_pickup' => 1, - )); - } - else { - $result[$reservation['id']] = new DingProviderReservation($reservation['id'], array( - 'order_id' => $reservation['id'], - 'ding_entity_id' => variable_get('ting_agency', '') . ':' . $reservation['record_id'], - 'pickup_branch_id' => $reservation['pickup_branch'], - 'created' => $reservation['create_date'], - 'expiry' => $reservation['valid_to'], - 'queue_number' => $reservation['queue_number'], - 'ready_for_pickup' => 0, - )); - } - } - - return $result; - } +function alma_reservation_list($account) { + $creds = ding_user_get_creds($account); + $reservations = alma_reservation_get_reservations($account); + $result = array(); + + // Create DingProviderReservation objects into to categories base on pickup + // status. + foreach ($reservations as $reservation) { + // Setup base data. + $data = array( + 'order_id' => $reservation['id'], + 'organisation_Id' => $reservation['organisation_id'], + 'ding_entity_id' => variable_get('ting_agency', '') . ':' . $reservation['record_id'], + 'pickup_branch_id' => $reservation['pickup_branch'], + 'created' => $reservation['create_date'], + 'expiry' => $reservation['valid_to'], + 'can_delete' => $reservation['deletable'], + 'queue_number' => $reservation['queue_number'], + 'status' => $reservation['status'], + ); + // Add status specific data + if (isset($reservation['pickup_number'])) { + $data['pickup_date'] = $reservation['pickup_expire_date']; + $data['ready_for_pickup'] = 1; + $data['pickup_number'] = $reservation['pickup_number']; + } + else { + $data['ready_for_pickup'] = 0; + } + // Create new Ding Provider Reservation object + $result[$reservation['id']] = new DingProviderReservation($reservation['id'], $data); + } + + return $result; +} /** @@ -111,25 +153,25 @@ function alma_reservation_create($account, $id, $branch, $expiry=null) { if( !isset($expiry) ) { // get interest period from profile2 $interest_period = alma_get_interest_period($profile2); - if( $interest_period ){ - $expiry = REQUEST_TIME + ($interest_period['key'] * 24 * 60 * 60 ); - } - } + if( $interest_period ){ + $expiry = REQUEST_TIME + ($interest_period['key'] * 24 * 60 * 60 ); + } + } if( !isset($expiry) ) { $expiry = REQUEST_TIME + DING_RESERVATION_DEFAULT_INTEREST_PERIOD; } - + // preferred branch if( empty($branch) ) { $pref_branch = alma_get_preferred_branch($profile2); if( $pref_branch ){ - $branches = alma_reservation_pickup_branches(); - foreach($branches as $key => $val){ - if( $val == $pref_branch ) { - $branch = $key; - break; - } - } + $branches = alma_reservation_pickup_branches(); + foreach($branches as $key => $val){ + if( $val == $pref_branch ) { + $branch = $key; + break; + } + } } } } @@ -192,7 +234,7 @@ function alma_reservation_update_order($account, $id, $pickup_branch, $expiry_da function alma_reservation_delete($account, $id) { $creds = ding_user_get_creds($account); $reservations = alma_reservation_get_reservations($account); - + alma_reservation_clear_cache(); if( isset($reservations[$id]) ) { return alma_client_invoke('remove_reservation', $creds['name'], $creds['pass'], $reservations[$id]); @@ -239,8 +281,8 @@ function alma_reservation_exists($account, $item_id) { if ($res['record_id'] == $item_id) { return TRUE; } - return FALSE; } + return FALSE; } function alma_reservation_format_date($datetime) { diff --git a/includes/alma.user.inc b/includes/alma.user.inc old mode 100644 new mode 100755 index 7d4d9db..5a0cb3e --- a/includes/alma.user.inc +++ b/includes/alma.user.inc @@ -105,7 +105,7 @@ function alma_user_profile_init( $profile2, $auth_res ){ // @todo - check if it's correct to handle the first only $langs = field_language('profile2', $profile2); // reservation pause - if( isset($patron->absentPeriods[0]['from_date']) && isset($patron->absentPeriods[0]['to_date'] ) ) { + if(isset($patron->absentPeriods[0]) && isset($patron->absentPeriods[0]['from_date']) && isset($patron->absentPeriods[0]['to_date'] ) ) { $profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value'] = $patron->absentPeriods[0]['from_date']; $profile2->field_alma_reservation_pause[$langs['field_alma_reservation_pause']][0]['value2'] = $patron->absentPeriods[0]['to_date']; $profile2->field_absent_id[$langs['field_absent_id']][0]['value'] = $patron->absentPeriods[0]['id']; @@ -136,7 +136,7 @@ function alma_user_profile_init( $profile2, $auth_res ){ */ function alma_user_account_update($account, $changes) { $creds = ding_user_get_creds($account); - + $result = array(); if( isset($changes['mail']) ) { // add email if( empty( $account->mail ) && !empty($changes['mail'] ) ) { @@ -147,7 +147,7 @@ function alma_user_account_update($account, $changes) { $res = alma_client_invoke('change_email_address', $creds['name'], $creds['pass'], $account->mail, $changes['mail']); } } - + // change password if (isset($changes['pass'])) { $res = alma_client_invoke('change_pin', $creds['name'], $creds['pass'], $changes['pass']); @@ -156,8 +156,8 @@ function alma_user_account_update($account, $changes) { // Set new password. $creds['pass'] = $changes['pass']; // Update creds. - $result['creds'] = $creds; - return $result; + $result['creds'] = $creds; } } + return $result; } diff --git a/includes/alma.user_consent.inc b/includes/alma.user_consent.inc new file mode 100755 index 0000000..bfbfc32 --- /dev/null +++ b/includes/alma.user_consent.inc @@ -0,0 +1,127 @@ + array( + 'title' => t('Personalisation'), + 'description' => t('In order to use this function, we request your permission to store your personal information'), + 'required' => TRUE, + ), + ); +} + +/** + * Update the user concent + * The return value is TRUE or FALSE depending on the success of the request. + * + * @param $account Object + * @param $concent String + * @param $previous_consents Boolean + * + * @return $status Boolean + */ +function alma_user_consent_add($account, $consent, $previous_consents) { + switch($consent) { + case 'loan_history_store': + $creds = ding_user_get_creds($account); + $patron = alma_get_patron($creds); + if (isset($patron->category)) { + // Changes mapped from the category structure in Axiell. + $new_category = alma_user_consent_get_category_change($consent); + // Alma do not return a status. + b14dpm(3, $new_category); + $res = alma_client_invoke('add_user_concent', $creds['name'], $creds['pass'], $new_category); + return ($res == 'ok'); + } + break; + } + return FALSE; +} + +/** + * Delete the users concent. + * The return value is TRUE or FALSE depending on the success of the request. + * + * @param $account Object + * @param $concent String + * @param $previous_consents Boolean + * + * @return $status Boolean + */ +function alma_user_consent_remove($account, $consent, $previous_consents) { + switch($consent) { + case 'loan_history_store': + $creds = ding_user_get_creds($account); + $patron = alma_get_patron($creds); + if (isset($patron->category)) { + // Changes mapped from the category structure in Axiell. + $new_category = alma_user_consent_get_category_change($consent); + // Alma do not return a status. + $res = alma_client_invoke('remove_user_concent', $creds['name'], $creds['pass'], $new_category); + return ($res == 'ok'); + } + break; + } + return FALSE; +} + +/** + * Helper functions + */ + +/** + * Retrieve any consent record which the user has saved. + * The return value is an array of consent arrays sorted by the date they were accepted. + * + * @param $account Object + * @param $reset Boolean + * + * @return $alma_user_consent Array + */ +function alma_user_consent_get_consent($account) { + try{ + $creds = ding_user_get_creds($account); + } + catch (DingProviderAuthException $e) { + return NULL; + } + $patron = alma_get_patron($creds, TRUE); + if(ding_user_is_provider_user($account)) { + $consents = alma_user_consent_info(); + $return = array(); + foreach($consents as $id => $values) { + $new_category = alma_user_consent_get_category_change($id); + if(isset($patron->allows)) + $return[$id] = isset($patron->allows[$new_category]); + else + $return[$id] = 0; + } + return $return; + } +} + +/** + * Get the category which matches the current when changing. + * @alma currently only supports one type of consent. + * + * @param $category String + * + * @return String + */ +function alma_user_consent_get_category_change($category) { + $consent_categories = array( + 'loan_history_store' => 'keepLoan', + ); + return $consent_categories[$category]; +} diff --git a/lib/AlmaClient/AlmaClient.class.php b/lib/AlmaClient/AlmaClient.class.php old mode 100644 new mode 100755 index d651954..caaf7eb --- a/lib/AlmaClient/AlmaClient.class.php +++ b/lib/AlmaClient/AlmaClient.class.php @@ -70,13 +70,15 @@ public function request($method, $params = array(), $check_status = TRUE) { // Log the request watchdog('alma', 'Sent request: @url (@seconds s)', array('@url' => url($this->base_url . $method, array('query' => $params)), '@seconds' => $seconds), WATCHDOG_DEBUG); } - + if ($request->code == 200) { // Since we currently have no need for the more advanced stuff // SimpleXML provides, we'll just use DOM, since that is a lot // faster in most cases. $doc = new DOMDocument(); $doc->loadXML($request->data); + // $doc->formatOutput = true; + // b14kpr(3, $doc->saveXML()); if (!$check_status || $doc->getElementsByTagName('status')->item(0)->getAttribute('value') == 'ok') { return $doc; } @@ -256,6 +258,7 @@ public function get_patron_info($borr_card, $pin_code, $extended = FALSE) { 'addresses' => array(), 'mails' => array(), 'phones' => array(), + 'category' => $info->getAttribute('patronCategory'), ); foreach ($info->getElementsByTagName('address') as $address) { @@ -306,7 +309,14 @@ public function get_patron_info($borr_card, $pin_code, $extended = FALSE) { 'to_date' => $period->getAttribute('absentToDate'), ); } + b14dpm(3, $data['absent_periods']); + foreach ($info->getElementsByTagName('patronAllow') as $allow) { + $data['allows'][$allow->getAttribute('allowType')] = array( + 'date' => $allow->getAttribute('allowDate'), + ); + } + return $data; } @@ -321,6 +331,7 @@ public function get_reservations($borr_card, $pin_code) { $reservation = array( 'id' => $item->getAttribute('id'), 'status' => $item->getAttribute('status'), + 'deletable' => $item->getAttribute('isDeletable'), 'pickup_branch' => $item->getAttribute('reservationPickUpBranch'), 'create_date' => $item->getAttribute('createDate'), 'valid_from' => $item->getAttribute('validFromDate'), @@ -358,6 +369,38 @@ private static function reservation_sort($a, $b) { */ public function get_loans($borr_card, $pin_code) { $doc = $this->request('patron/loans', array('borrCard' => $borr_card, 'pinCode' => $pin_code)); + + $loans = array(); + foreach ($doc->getElementsByTagName('loan') as $item) { + $id = $item->getAttribute('id'); + $loan = array( + 'id' => $id, + 'branch' => $item->getAttribute('loanBranch'), + 'loan_date' => $item->getAttribute('loanDate'), + 'due_date' => $item->getAttribute('loanDueDate'), + 'remaining_renewals' => $item->getAttribute('remainingRenewals'), + 'is_renewable' => ($item->getElementsByTagName('loanIsRenewable')->item(0)->getAttribute('value') == 'yes') ? TRUE : FALSE, + 'renewal_status' => $item->getAttribute('renewalStatus'), + 'record_id' => $item->getElementsByTagName('catalogueRecord')->item(0)->getAttribute('id'), + 'record_available' => $item->getElementsByTagName('catalogueRecord')->item(0)->getAttribute('isAvailable'), + ); + if ($item->getElementsByTagName('note')->length > 0) { + $loan['notes'] = $item->getElementsByTagName('note')->item(0)->getAttribute('value'); + } + if($item->getElementsByTagName('loanIsRenewable')->item(0)->getAttribute('value') == 'no') { + $loan['message'] = $item->getElementsByTagName('loanIsRenewable')->item(0)->getAttribute('message'); + } + $loans[$id] = $loan; + } + uasort($loans, 'AlmaClient::loan_sort'); + return $loans; + } + + /** + * Get patron's overdue loans. + */ + public function get_overdue_loans($borr_card, $pin_code) { + $doc = $this->request('patron/loans/overdue', array('borrCard' => $borr_card, 'pinCode' => $pin_code)); $loans = array(); foreach ($doc->getElementsByTagName('loan') as $item) { @@ -370,6 +413,8 @@ public function get_loans($borr_card, $pin_code) { 'is_renewable' => ($item->getElementsByTagName('loanIsRenewable')->item(0)->getAttribute('value') == 'yes') ? TRUE : FALSE, 'record_id' => $item->getElementsByTagName('catalogueRecord')->item(0)->getAttribute('id'), 'record_available' => $item->getElementsByTagName('catalogueRecord')->item(0)->getAttribute('isAvailable'), + 'renewalCost' => $item->getAttribute('renewalCost'), + 'renewalStatus' => $item->getAttribute('renewalStatus'), ); if ($item->getElementsByTagName('note')->length > 0) { $loan['notes'] = $item->getElementsByTagName('note')->item(0)->getAttribute('value'); @@ -386,13 +431,77 @@ public function get_loans($borr_card, $pin_code) { private static function loan_sort($a, $b) { return strcmp($a['due_date'], $b['due_date']); } + + /** + * Add user consent. + */ + public function add_user_concent($borr_card, $pin_code, $type) { + // Initialise the query parameters with the current value from the + // reservation array. + $params = array( + 'borrCard' => $borr_card, + 'pinCode' => $pin_code, + 'allowType' => $type, + ); + + try { + $doc = $this->request('patron/allow/add', $params); + $res_status = $doc->getElementsByTagName('status')->item(0)->getAttribute('value'); + // Return error code when patron is blocked. + if ($res_status != 'ok') { + return ALMA_AUTH_BLOCKED; + } + + // General catchall if status is not okay is to report failure. + if ($res_status == 'concentNotOk') { + return FALSE; + } + } + catch (AlmaClientConsentNotFound $e) { + return FALSE; + } + + return $res_status; + } + + /** + * Remove user consent. + */ + public function remove_user_concent($borr_card, $pin_code, $type) { + // Initialise the query parameters with the current value from the + // reservation array. + $params = array( + 'borrCard' => $borr_card, + 'pinCode' => $pin_code, + 'allowType' => $type, + ); + + try { + $doc = $this->request('patron/allow/remove', $params); + $res_status = $doc->getElementsByTagName('status')->item(0)->getAttribute('value'); + // Return error code when patron is blocked. + if ($res_status != 'ok') { + return ALMA_AUTH_BLOCKED; + } + + // General catchall if status is not okay is to report failure. + if ($res_status == 'concentNotOk') { + return FALSE; + } + } + catch (AlmaClientConsentNotFound $e) { + return FALSE; + } + return $res_status; + } + /** * Get patron's debts. */ public function get_debts($borr_card, $pin_code) { $doc = $this->request('patron/debts', array('borrCard' => $borr_card, 'pinCode' => $pin_code)); - + $data = array( 'total_formatted' => 0, 'debts' => array(), @@ -532,13 +641,9 @@ public function renew_loan($borr_card, $pin_code, $loan_ids) { //Even if this is not the case any error in the current renewal is irrelevant //as the loan has previously been renewed so don't report it as such if ($message == 'isRenewedToday' || $renewable == 'yes') { - $reservations[$id] = TRUE; - } elseif ($message == 'maxNofRenewals') { - $reservations[$id] = t('Maximum number of renewals reached'); - } elseif ($message == 'copyIsReserved') { - $reservations[$id] = t('The material is reserved by another loaner'); + $reservations[$id] = TRUE; } else { - $reservations[$id] = t('Unable to renew material'); + $reservations[$id] = $message; } } } @@ -646,9 +751,9 @@ public function change_pin($borr_card, $pin_code, $new_pin) { /** * Get details about one or more catalogue record. */ - public function catalogue_record_detail($alma_ids) { + public function catalogue_record_detail($alma_id) { $params = array( - 'catalogueRecordKey' => $alma_ids, + 'catalogueRecordKey' => $alma_id, ); $doc = $this->request('catalogue/detail', $params, FALSE); $data = array( @@ -877,6 +982,8 @@ public function change_absent_period($borr_card, $pin_code, $absent_id, $from_da ); $doc = $this->request('patron/absentPeriod/change', $params); + $doc->formatOutput = TRUE; + b14dpm(3, $doc->saveXML()); return TRUE; }