PageRenderTime 51ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/OpenruthClient/OpenruthClient.class.php

https://github.com/dingproject/openruth
PHP | 483 lines | 369 code | 32 blank | 82 comment | 49 complexity | 8654a8905657bbc88f934f742963f1b7 MD5 | raw file
  1. <?php
  2. // $Id$
  3. class OpenruthClient {
  4. /**
  5. * Our SOAP client.
  6. **/
  7. private $client;
  8. /**
  9. * The OpenRuth wsdl url.
  10. **/
  11. private $wsdl_url;
  12. /**
  13. * The OpenRuth agency id.
  14. **/
  15. private $agency_id;
  16. /**
  17. * Whether we're logging requests.
  18. */
  19. private $logging = FALSE;
  20. /**
  21. * Start time of request, used for logging.
  22. */
  23. private $log_timestamp = NULL;
  24. /**
  25. * The salt which will be used to scramble sensitive information in logging
  26. * across all requests for the page load.
  27. */
  28. private static $salt;
  29. /**
  30. * Constructor
  31. */
  32. public function __construct($wsdl_url, $agency_id) {
  33. $this->wsdl_url = $wsdl_url;
  34. $this->agency_id = $agency_id;
  35. $options = array(
  36. 'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
  37. 'exceptions' => TRUE,
  38. );
  39. if (variable_get('openruth_enable_logging', FALSE)) {
  40. $this->logging = TRUE;
  41. $options['trace'] = TRUE;
  42. }
  43. $this->client = new SoapClient($this->wsdl_url, $options);
  44. self::$salt = rand();
  45. }
  46. /**
  47. * Log start of request, for adding to log entry later.
  48. */
  49. private function log_start() {
  50. if ($this->logging) {
  51. $this->log_timestamp = microtime(TRUE);
  52. }
  53. }
  54. /**
  55. * Log last request, if logging is enabled.
  56. *
  57. * @param ...
  58. * A variable number of arguments, whose values will be redacted.
  59. */
  60. private function log() {
  61. if ($this->logging) {
  62. if ($this->log_timestamp) {
  63. $time = round(microtime(TRUE) - $this->log_timestamp, 2);
  64. $this->log_timestamp = NULL;
  65. }
  66. $sensitive = func_get_args();
  67. // For some reason PHP doesn't have array_flatten, and this is the
  68. // shortest alternative.
  69. $replace_values = array();
  70. foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($sensitive)) as $value) {
  71. $replace_values['>' . $value . '<'] = '>' . substr(md5($value . self::$salt), 0, strlen($value)) . '<';
  72. }
  73. if ($time) {
  74. watchdog('openruth', 'Sending request (@seconds sec): @xml',array('@xml' => strtr($this->client->__getLastRequest(), $replace_values), '@seconds' => $time), WATCHDOG_DEBUG);
  75. } else {
  76. watchdog('openruth', 'Sending request: @xml',array('@xml' => strtr($this->client->__getLastRequest(), $replace_values)), WATCHDOG_DEBUG);
  77. }
  78. watchdog('openruth', 'Response: @xml',array('@xml' => strtr($this->client->__getLastResponse(), $replace_values)), WATCHDOG_DEBUG);
  79. }
  80. }
  81. /**
  82. * Get information about an agency's counters
  83. */
  84. public function get_agency_counters() {
  85. $this->log_start();
  86. $res = $this->client->agencyCounters(array(
  87. 'agencyId' => $this->agency_id,
  88. ));
  89. $this->log();
  90. if (isset($res->agencyError)) {
  91. return $res->agencyError;
  92. }
  93. elseif (isset($res->agencyCounters) && isset($res->agencyCounters->agencyCounterInfo)) {
  94. $result = array();
  95. foreach ($res->agencyCounters->agencyCounterInfo as $agencyCounterInfo) {
  96. $result[$agencyCounterInfo->agencyCounter] = $agencyCounterInfo->agencyCounterName;
  97. }
  98. return $result;
  99. }
  100. else {
  101. return FALSE;
  102. }
  103. }
  104. /**
  105. * Holdings information (agency info, location, availability etc.) about an given item.
  106. */
  107. public function get_holdings($ids) {
  108. $this->log_start();
  109. $res = $this->client->holdings(array(
  110. 'agencyId' => $this->agency_id,
  111. 'itemId' => $ids,
  112. ));
  113. $this->log();
  114. if (isset($res->agencyError)) {
  115. return $res->agencyError;
  116. }
  117. elseif (isset($res->holding)) {
  118. $holdings = array();
  119. foreach ($res->holding as $holding) {
  120. $available = $holding->agencyHoldings->itemAvailability == 'copies available for loan and reservation';
  121. $reservable = $available || $holding->agencyHoldings->itemAvailability == 'no copies available, but item can be reserved';
  122. $h = array(
  123. 'local_id' => $holding->itemId,
  124. 'available' => $available,
  125. 'reservable' => $reservable,
  126. 'show_reservation_button' => $reservable,
  127. 'holdings' => array(),
  128. 'reserved_count' => 0,
  129. 'issues' => array(),
  130. );
  131. $total = 0;
  132. $available = 0;
  133. if ($holding->itemHoldings) {
  134. foreach ($holding->itemHoldings as $itemHolding) {
  135. if (isset($itemHolding->ordersCount) && $itemHolding->ordersCount) {
  136. $h['reserved_count'] += $itemHolding->ordersCount;
  137. }
  138. $holding_reservable = FALSE;
  139. $fields = array('itemLocation', 'itemComingLocation');
  140. foreach ($fields as $field) {
  141. if (isset($itemHolding->{$field})){
  142. foreach ($itemHolding->{$field} as $itemLocation) {
  143. if ($itemLocation->bookingAllowed) {
  144. $holding_reservable = TRUE;
  145. }
  146. $total += $itemLocation->copiesCount;
  147. $available += $itemLocation->copiesAvailableCount;
  148. $parts = array();
  149. if (isset($itemLocation->agencyBranchId->agencyBranchName)) {
  150. $parts[] = $itemLocation->agencyBranchId->agencyBranchName;
  151. }
  152. if (isset($itemLocation->agencyDepartmentId->agencyDepartmentName)) {
  153. $parts[] = $itemLocation->agencyDepartmentId->agencyDepartmentName;
  154. }
  155. if (isset($itemLocation->agencyCollectionId->agencyCollectionName)) {
  156. $parts[] = $itemLocation->agencyCollectionId->agencyCollectionName;
  157. }
  158. if (isset($itemLocation->agencyPlacementId->agencyPlacementName)) {
  159. $parts[] = $itemLocation->agencyPlacementId->agencyPlacementName;
  160. }
  161. if ($parts && $itemLocation->copiesAvailableCount > 0) {
  162. $h['holdings'][] = join(' → ', $parts);
  163. }
  164. }
  165. }
  166. }
  167. if (isset($itemHolding->itemSerialPartId) ||
  168. isset($itemHolding->itemSerialPartVolume) ||
  169. isset($itemHolding->itemSerialPartIssue)) {
  170. $issue = array(
  171. 'local_id' => $itemHolding->itemSerialPartId,
  172. 'reservable' => $holding_reservable,
  173. );
  174. $h['issues'][$itemHolding->itemSerialPartVolume][$itemHolding->itemSerialPartIssue] = $issue;
  175. }
  176. }
  177. }
  178. $h['total_count'] = $total;
  179. $h['reservable_count'] = $available;
  180. if (sizeof($h['issues'])) {
  181. $h['holdings'] = array_unique($h['holdings']);
  182. }
  183. $holdings[$holding->itemId] = $h;
  184. }
  185. return $holdings;
  186. }
  187. else {
  188. return FALSE;
  189. }
  190. }
  191. /**
  192. * Renewing one or more loans
  193. */
  194. public function renew_loan($username, $copy_ids) {
  195. $this->log_start();
  196. $res = $this->client->renewLoan(array(
  197. 'agencyId' => $this->agency_id,
  198. 'userId' => $username,
  199. 'copyId' => $copy_ids,
  200. ));
  201. $this->log($username);
  202. if (isset($res->renewLoanError)) {
  203. return $res->renewLoanError;
  204. }
  205. elseif (isset($res->renewLoan)) {
  206. $result = array();
  207. foreach ($res->renewLoan as $renewLoan) {
  208. $result[$renewLoan->copyId] = isset($renewLoan->renewLoanError) ? $renewLoan->renewLoanError : TRUE;
  209. }
  210. return $result;
  211. }
  212. else {
  213. return FALSE;
  214. }
  215. }
  216. /**
  217. * Booking an item
  218. */
  219. public function book_item($username, $provider_id, $count, $start_date, $end_date, $pickup_branch) {
  220. $this->log_start();
  221. $res = $this->client->bookItem(array(
  222. 'agencyId' => $this->agency_id,
  223. 'userId' => $username,
  224. // 'bookingNote' => '',
  225. 'agencyCounter' => $pickup_branch,
  226. 'itemId' =>$provider_id,
  227. 'bookingTotalCount' => $count,
  228. 'bookingStartDate' => $start_date,
  229. 'bookingEndDate' => $end_date,
  230. ));
  231. $this->log($username);
  232. if (isset($res->bookingError)) {
  233. return $res->bookingError;
  234. }
  235. elseif (isset($res->bookingOk)) {
  236. return TRUE;
  237. }
  238. else {
  239. return FALSE;
  240. }
  241. }
  242. /**
  243. * Making a reservation in the local system
  244. */
  245. public function order_item($username, $provider_id, $expiry, $pickup_branch) {
  246. $this->log_start();
  247. $res = $this->client->orderItem(array(
  248. 'agencyId' => $this->agency_id,
  249. 'userId' => $username,
  250. // 'orderNote' => '',
  251. 'orderLastInterestDate' => $expiry,
  252. 'agencyCounter' => $pickup_branch,
  253. 'orderOverRule' => FALSE,
  254. 'orderPriority' => 'normal',
  255. 'orderItemId' => array(
  256. 'itemId' => $provider_id,
  257. ),
  258. ));
  259. $this->log($username);
  260. if (isset($res->orderItemError)) {
  261. return $res->orderItemError;
  262. }
  263. elseif (isset($res->orderItem)) {
  264. $result = array();
  265. foreach ($res->orderItem as $orderItem) {
  266. $result[$orderItem->orderItemId->itemId] = isset($orderItem->orderItemError) ? $orderItem->orderItemError : TRUE;
  267. }
  268. return $result;
  269. }
  270. else {
  271. return FALSE;
  272. }
  273. }
  274. /**
  275. * Get information about number of copies in a booking available at various times
  276. */
  277. public function booking_info() {}
  278. /**
  279. * Updating details about a booking
  280. */
  281. public function update_booking() {}
  282. /**
  283. * Cancelling a booking of an item
  284. */
  285. public function cancel_booking($bookings_id) {
  286. $this->log_start();
  287. $res = $this->client->cancelBooking(array(
  288. 'agencyId' => $this->agency_id,
  289. 'bookingId' => $bookings_id,
  290. ));
  291. $this->log();
  292. if (isset($res->bookingError)) {
  293. return $res->bookingError;
  294. }
  295. elseif (isset($res->bookingOk)) {
  296. return TRUE;
  297. }
  298. else {
  299. return FALSE;
  300. }
  301. }
  302. /**
  303. * Updating details about a reservation in the local system
  304. */
  305. public function update_order($order_id, $pickup_branch, $expiry) {
  306. $this->log_start();
  307. $res = $this->client->updateOrder(array(
  308. 'agencyId' => $this->agency_id,
  309. 'orderId' => $order_id,
  310. 'orderNote' => '',
  311. 'orderLastInterestDate' => $expiry,
  312. 'agencyCounter' => $pickup_branch,
  313. ));
  314. $this->log();
  315. if (isset($res->updateOrderError)) {
  316. return $res->updateOrderError;
  317. }
  318. elseif (isset($res->updateOrderOk)) {
  319. return TRUE;
  320. }
  321. else {
  322. return FALSE;
  323. }
  324. }
  325. /**
  326. * Deleting a reservation
  327. */
  328. public function cancel_order($order_id) {
  329. $this->log_start();
  330. $res = $this->client->cancelOrder(array(
  331. 'agencyId' => $this->agency_id,
  332. 'orderId' => $order_id,
  333. ));
  334. $this->log();
  335. if (isset($res->cancelOrderError)) {
  336. return $res->cancelOrderError;
  337. }
  338. elseif (isset($res->cancelOrderOk)) {
  339. return TRUE;
  340. }
  341. else {
  342. return FALSE;
  343. }
  344. }
  345. /**
  346. * Changing userinfo (pincode, contact, preferences etc.)
  347. */
  348. public function update_userinfo($name, $pass, $changes) {
  349. static $mapping = array(
  350. 'pass' => 'userPinCodeNew',
  351. 'mail' => 'userEmail',
  352. // 'phone' => 'userTelephone', // No?
  353. 'mobile_phone' => 'userMobilePhone',
  354. 'reminder' => 'userPreReturnReminder',
  355. 'first_name' => 'userFirstName',
  356. 'last_name' => 'userLastName',
  357. 'preferred_branch' => 'agencyCounter',
  358. );
  359. $this->log_start();
  360. $args = array(
  361. 'agencyId' => $this->agency_id,
  362. 'userId' => $name,
  363. 'userPinCode' => $pass,
  364. );
  365. foreach ($mapping as $from => $to) {
  366. if (isset($changes[$from])) {
  367. $args[$to] = $changes[$from];
  368. }
  369. }
  370. $res = $this->client->updateUserInfo($args);
  371. $this->log($name, $pass);
  372. if (isset($res->userError)) {
  373. return $res->userError;
  374. }
  375. elseif (isset($res->updateUserInfoOk)) {
  376. return TRUE;
  377. }
  378. else {
  379. return FALSE;
  380. }
  381. }
  382. /**
  383. * Performing a user check (whether the user exists in the system and user's various rights and parameters)
  384. *
  385. * @return mixed
  386. * UserCheck response object, a string error message or FALSE.
  387. */
  388. public function user_check($username, $pin_code) {
  389. $res = $this->client->userCheck(array(
  390. 'agencyId' => $this->agency_id,
  391. 'userId' => $username,
  392. 'userPinCode' => $pin_code,
  393. ));
  394. $this->log($username, $pin_code);
  395. if (isset($res->userError)) {
  396. return $res->userError;
  397. }
  398. elseif (isset($res->userCheck)) {
  399. return $res->userCheck;
  400. }
  401. else {
  402. return FALSE;
  403. }
  404. }
  405. /**
  406. * User's status, includings loans, orders, ILLs and fines
  407. */
  408. public function user_status($username, $pin_code) {
  409. $this->log_start();
  410. $res = $this->client->userStatus(array(
  411. 'agencyId' => $this->agency_id,
  412. 'userId' => $username,
  413. 'userPinCode' => $pin_code,
  414. ));
  415. $this->log($username, $pin_code);
  416. if (isset($res->userError)) {
  417. return $res->userError;
  418. }
  419. elseif (isset($res->userStatus)) {
  420. return $res->userStatus;
  421. }
  422. else {
  423. return FALSE;
  424. }
  425. }
  426. /**
  427. * paying user fines
  428. */
  429. public function user_payment($username, $amount, $transaction_id = NULL) {
  430. $this->log_start();
  431. $params = array(
  432. 'agencyId' => $this->agency_id,
  433. 'userId' => $username,
  434. 'feeAmountPaid' => $amount,
  435. );
  436. if ($transaction_id) {
  437. $params['userPaymentTransactionId'] = $transaction_id;
  438. }
  439. $res = $this->client->userPayment($params);
  440. $this->log($username);
  441. if (isset($res->userPaymentError)) {
  442. return $res->userPaymentError;
  443. }
  444. elseif (isset($res->userPaymentOk)) {
  445. return TRUE;
  446. }
  447. else {
  448. return FALSE;
  449. }
  450. }
  451. }