Subversion Repositories Web Services

Rev

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

Rev Author Line No. Line
97699 fvs 1
<?php
2
/**
3
 *
4
 * This file is part of Open Library System.
5
 * Copyright © 2016, Dansk Bibliotekscenter a/s,
6
 * Tempovej 7-11, DK-2750 Ballerup, Denmark. CVR: 15149043
7
 *
8
 * Open Library System is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * Open Library System is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with Open Library System.  If not, see <http://www.gnu.org/licenses/>.
118250 fvs 20
 **/
97699 fvs 21
 
22
/**
23
 * makes open_agency_class, search_profile_class, show_priority_class and agency_type_class obsolete
24
 *
25
 * \brief
26
 *
27
 *
28
 *
29
 * need curl_class and memcache_class to be defined
30
 *
31
 * @author Finn Stausgaard - DBC
118250 fvs 32
 **/
97699 fvs 33
 
34
require_once('OLS_class_lib/memcache_class.php');
35
require_once('OLS_class_lib/curl_class.php');
36
 
118250 fvs 37
/**
38
 * Class OpenAgency
39
 */
97699 fvs 40
class OpenAgency {
41
 
118250 fvs 42
  private $config;
43
  private $agency_cache;      // cache object
44
  private $agency_uri;        // uri of openagency service
45
  private $tracking_id;        //
97699 fvs 46
  private $library_type_tab = FALSE;
47
 
118250 fvs 48
  /**
49
   * OpenAgency constructor.
50
   * @param $config
51
   */
97699 fvs 52
  public function __construct($config) {
118250 fvs 53
    define('AGENCY_TYPE', 'a');
54
    define('BRANCH_TYPE', 'b');
97699 fvs 55
    $this->config = $config;
56
    if ($this->config['cache_host']) {
57
      $this->agency_cache = new cache($this->config['cache_host'], $this->config['cache_port'], $this->config['cache_expire']);
58
    }
118250 fvs 59
    if (!isset($this->config['timeout'])) {
60
      $this->config['timeout'] = 10;
61
    }
120114 fvs 62
    if (class_exists('VerboseJson')) {
63
      $this->tracking_id = VerboseJson::$tracking_id;
97699 fvs 64
    }
65
  }
66
 
67
  /**
118250 fvs 68
   * \brief Fetch agencies by rule using openAgency::libraryRules
69
   *
70
   * @param string $rule
71
   * @param string $setting (0 or 1)
72
   * @param string $agency_type
73
   * @return array
74
   *
75
   **/
76
  public function get_libraries_by_rule($rule, $setting = '1', $agency_type = '') {
104354 fvs 77
    $libraries = FALSE;
78
    if ($this->agency_cache) {
79
      $cache_key = md5(__CLASS__ . __FUNCTION__ . $rule . $setting . $agency_type);
80
      $libraries = $this->agency_cache->get($cache_key);
81
    }
82
 
83
    if ($libraries === FALSE) {
118259 fvs 84
      $libraries = array();
104354 fvs 85
      self::trace(__CLASS__ . '::' . __FUNCTION__ . '(): Cache miss (' . $rule . ')');
86
      $curl = new curl();
87
      $curl->set_option(CURLOPT_TIMEOUT, $this->config['timeout']);
88
      $url = sprintf(self::oa_uri($this->config['librariesByRule']), $rule, $setting, $this->tracking_id);
89
      $res_xml = $curl->get($url);
90
      $curl_err = $curl->get_status();
91
      if ($curl_err['http_code'] < 200 || $curl_err['http_code'] > 299) {
92
        self::fatal(__CLASS__ . '::' . __FUNCTION__ . '(): Cannot fetch library Rules from ' . $url);
93
      }
94
      else {
95
        $dom = new DomDocument();
96
        $dom->preserveWhiteSpace = false;
97
        if (@ $dom->loadXML($res_xml)) {
98
          foreach ($dom->getElementsByTagName('libraryRules') as $agency) {
99
            if ($agency_type == '' || $agency_type == $agency->getElementsByTagName('agencyType')->item(0)->nodeValue) {
118250 fvs 100
              $libraries[$agency->getElementsByTagName('agencyId')->item(0)->nodeValue] = $agency->getElementsByTagName('agencyId')->item(0)->nodeValue;
104354 fvs 101
            }
102
          }
103
        }
104
        if ($this->agency_cache) {
112846 fvs 105
          if (!$this->agency_cache->set($cache_key, $libraries))
106
            self::fatal(__CLASS__ . '::' . __FUNCTION__ . '(): Cannot set cache. key: ' . $cache_key);
104354 fvs 107
        }
108
      }
109
      $curl->close();
110
    }
111
    return $libraries;
112
  }
113
 
114
  /**
118250 fvs 115
   * \brief Fetch agency rules using openAgency::libraryRules
116
   *
117
   * @param string $agency
118
   * @return array
119
   *
120
   **/
97699 fvs 121
  public function get_library_rules($agency) {
122
    $library_rules = FALSE;
123
    if ($this->agency_cache) {
124
      $cache_key = md5(__CLASS__ . __FUNCTION__ . $agency);
125
      $library_rules = $this->agency_cache->get($cache_key);
126
    }
127
 
128
    if ($library_rules === FALSE) {
118259 fvs 129
      $library_rules = array();
97699 fvs 130
      self::trace(__CLASS__ . '::' . __FUNCTION__ . '(): Cache miss (' . $agency . ')');
131
      $curl = new curl();
132
      $curl->set_option(CURLOPT_TIMEOUT, $this->config['timeout']);
133
      $url = sprintf(self::oa_uri($this->config['libraryRules']), $agency, $this->tracking_id);
134
      $res_xml = $curl->get($url);
135
      $curl_err = $curl->get_status();
136
      if ($curl_err['http_code'] < 200 || $curl_err['http_code'] > 299) {
137
        self::fatal(__CLASS__ . '::' . __FUNCTION__ . '(): Cannot fetch library Rules from ' . $url);
138
      }
139
      else {
140
        $dom = new DomDocument();
141
        $dom->preserveWhiteSpace = false;
142
        if (@ $dom->loadXML($res_xml)) {
143
          foreach ($dom->getElementsByTagName('libraryRule') as $rule) {
144
            $library_rules[$rule->getElementsByTagName('name')->item(0)->nodeValue] = self::xs_boolean($rule->getElementsByTagName('bool')->item(0)->nodeValue);
145
          }
146
        }
147
        if ($this->agency_cache) {
112846 fvs 148
          if (!$this->agency_cache->set($cache_key, $library_rules))
149
            self::fatal(__CLASS__ . '::' . __FUNCTION__ . '(): Cannot set cache. key: ' . $cache_key);
97699 fvs 150
        }
151
      }
152
      $curl->close();
153
    }
154
    return $library_rules;
155
  }
156
 
157
  /**
118250 fvs 158
   * \brief Get a given prority list for the agency
159
   *
160
   * @param $agency string - agency-id
161
   * @return array - array with agency as index and priority as value
162
   **/
97699 fvs 163
  public function get_show_priority($agency) {
119060 fvs 164
    return self::get_priority($agency, 'showOrder');
165
  }
97699 fvs 166
 
119060 fvs 167
  public function get_request_priority($agency) {
168
    return self::get_priority($agency, 'requestOrder');
97699 fvs 169
  }
170
 
171
  /**
118250 fvs 172
   * \brief Get a given profile for the agency
173
   *
174
   * @param $agency string - name of profile
175
   * @param $profile_name string - name of profile
176
   * @param $profile_version string - version of profile: 2 or 3
177
   *
178
   * @return mixed - profile if found, FALSE otherwise
179
   **/
108826 fvs 180
  public function get_search_profile($agency, $profile_name, $profile_version = '3') {
97699 fvs 181
    if ($this->agency_cache) {
182
      $cache_key = md5(__CLASS__ . __FUNCTION__ . $agency . '_' . $profile_version);
183
      $this->profiles = $this->agency_cache->get($cache_key);
184
    }
185
 
186
    if (!$this->profiles) {
187
      self::trace(__CLASS__ . '::' . __FUNCTION__ . '(): Cache miss (' . $agency . ')');
188
      $curl = new curl();
189
      $curl->set_option(CURLOPT_TIMEOUT, $this->config['timeout']);
190
      $url = sprintf(self::oa_uri($this->config['searchProfile']), $agency, $profile_version, $this->tracking_id);
191
      $res_xml = $curl->get($url);
192
      $curl_err = $curl->get_status();
193
      if ($curl_err['http_code'] < 200 || $curl_err['http_code'] > 299) {
118250 fvs 194
        $this->profiles[strtolower($profile_name)] = FALSE;
97699 fvs 195
        self::fatal(__CLASS__ . '::' . __FUNCTION__ . '(): Cannot fetch search profile from ' . $url);
196
      }
197
      else {
198
        $dom = new DomDocument();
199
        $dom->preserveWhiteSpace = false;
200
        if (@ $dom->loadXML($res_xml)) {
201
          foreach ($dom->getElementsByTagName('profile') as $profile) {
202
            $p_name = '';
118259 fvs 203
            $p_val = array();
97699 fvs 204
            foreach ($profile->childNodes as $p) {
205
              if ($p->localName == 'profileName') {
206
                $p_name = $p->nodeValue;
207
              }
208
              elseif ($p->localName == 'source') {
209
                foreach ($p->childNodes as $s) {
210
                  if ($s->localName == 'relation') {
211
                    foreach ($s->childNodes as $r) {
212
                      $rels[$r->localName] = $r->nodeValue;
213
                    }
214
                    $source[$s->localName][] = $rels;
215
                    unset($rels);
216
                  }
217
                  else {
218
                    $source[$s->localName] = $s->nodeValue;
219
                  }
220
                }
221
                if ($source) {
222
                  $p_val[] = $source;
223
                  unset($source);
224
                }
225
              }
226
            }
227
            $this->profiles[strtolower($p_name)] = $p_val;
228
            unset($p_val);
229
          }
230
        }
231
        else {
118259 fvs 232
          $this->profiles = array();
97699 fvs 233
        }
234
        if ($this->agency_cache) {
112846 fvs 235
          if (!$this->agency_cache->set($cache_key, $this->profiles))
236
            self::fatal(__CLASS__ . '::' . __FUNCTION__ . '(): Cannot set cache. key: ' . $cache_key);
97699 fvs 237
        }
238
      }
239
    }
240
 
241
    if ($p = &$this->profiles[strtolower($profile_name)]) {
242
      return $p;
243
    }
244
    else {
245
      return FALSE;
246
    }
247
  }
248
 
249
  /**
118250 fvs 250
   * \brief Get a given agency_type for the agency
251
   *
252
   * @param string $agency       name of agency
253
   * @return mixed agency_type if found, NULL otherwise
254
   **/
97699 fvs 255
  public function get_agency_type($agency) {
256
    if ($this->library_type_tab === FALSE) {
257
      self::fetch_library_type_tab();
258
    }
117947 fvs 259
    return isset($this->library_type_tab[$agency]) ? $this->library_type_tab[$agency][AGENCY_TYPE] : null;
97699 fvs 260
  }
261
 
262
  /**
118250 fvs 263
   * \brief Get a given branch_type for the agency
264
   *
265
   * @param string $agency       name of agency
266
   * @return mixed branch_type if found, NULL otherwise
267
   **/
97699 fvs 268
  public function get_branch_type($agency) {
269
    if ($this->library_type_tab === FALSE) {
270
      self::fetch_library_type_tab();
271
    }
272
    return $this->library_type_tab[$agency][BRANCH_TYPE];
273
  }
274
 
275
  /**
118250 fvs 276
   * \brief Fetch agencyType and branchType using openAgency::findLibrary
277
   **/
97699 fvs 278
  private function fetch_library_type_tab() {
279
    if ($this->agency_cache) {
280
      $cache_key = md5(__CLASS__ . __FUNCTION__);
281
      $this->library_type_tab = $this->agency_cache->get($cache_key);
282
    }
283
 
284
    if (!$this->library_type_tab) {
118259 fvs 285
      $this->library_type_tab = array();
97699 fvs 286
      $curl = new curl();
287
      $curl->set_option(CURLOPT_TIMEOUT, $this->config['timeout']);
288
      $url = sprintf(self::oa_uri($this->config['libraryType']), $this->tracking_id);
289
      $res_json = $curl->get($url);
290
      $curl_err = $curl->get_status();
291
      if ($curl_err['http_code'] < 200 || $curl_err['http_code'] > 299) {
292
        self::fatal(__CLASS__ . '::' . __FUNCTION__ . '(): Cannot fetch agencies from ' . $url);
293
      }
294
      else {
295
        $libs = json_decode($res_json);
296
        if (is_object($libs)) {
297
          if (isset($libs->libraryTypeListResponse)) {   // if libraryTypeList operation is used
298
            $struct = @$libs->libraryTypeListResponse->libraryTypeInfo;
299
          }
300
          else {          // if findLibrary operation is used - this is old style for openagency 2.18 or older
301
            $struct = @$libs->findLibraryResponse->pickupAgency;
302
          }
303
          foreach ($struct as $agency) {
304
            $this->library_type_tab[$agency->branchId->{'$'}] =
118259 fvs 305
              array(AGENCY_TYPE => $agency->agencyType->{'$'},
306
                    BRANCH_TYPE => $agency->branchType->{'$'});
97699 fvs 307
          }
308
        }
309
        else {
112846 fvs 310
          self::fatal(__CLASS__ . '::' . __FUNCTION__ . '(): No agencies found ' . sprintf($this->agency_uri));
97699 fvs 311
        }
312
        $curl->close();
313
        if ($this->agency_cache) {
112846 fvs 314
          if (!$this->agency_cache->set($cache_key, $this->library_type_tab))
315
            self::fatal(__CLASS__ . '::' . __FUNCTION__ . '(): Cannot set cache. key: ' . $cache_key);
97699 fvs 316
        }
317
      }
318
      self::trace(__CLASS__ . '::' . __FUNCTION__ . '(): Cache miss');
319
    }
320
  }
321
 
119060 fvs 322
  /**
323
   * \brief Get a given prority list for the agency
324
   *
325
   * @param $agency string - agency-id
326
   * @param $priority_type string - showOrder or requestOrder
327
   * @return array - array with agency as index and priority as value
328
   **/
329
  private function get_priority($agency, $priority_type) {
330
    if ($this->agency_cache) {
331
      $cache_key = md5(__CLASS__ . __FUNCTION__ . $agency . $priority_type);
332
      $agency_list = $this->agency_cache->get($cache_key);
333
    }
97699 fvs 334
 
119060 fvs 335
    if (empty($agency_list)) {
336
      $agency_list = array();
337
      self::trace(__CLASS__ . '::' . __FUNCTION__ . '(): Cache miss (' . $agency . ')');
338
      $curl = new curl();
339
      $curl->set_option(CURLOPT_TIMEOUT, $this->config['timeout']);
340
      $url = sprintf(self::oa_uri($this->config[$priority_type]), $agency, $this->tracking_id);
341
      $res_xml = $curl->get($url);
342
      $curl_err = $curl->get_status();
343
      if ($curl_err['http_code'] < 200 || $curl_err['http_code'] > 299) {
344
        $agency_list = FALSE;
345
        self::fatal(__CLASS__ . '::' . __FUNCTION__ . '(): Cannot fetch ' . $request_type . ' from ' . $url);
346
      }
347
      else {
348
        $dom = new DomDocument();
349
        $dom->preserveWhiteSpace = false;
350
        if (@ $dom->loadXML($res_xml)) {
351
          foreach ($dom->getElementsByTagName('agencyId') as $id) {
352
            $agency_list[$id->nodeValue] = count($agency_list) + 1;
353
          }
354
        }
355
        if (!isset($agency_list[$agency])) {
356
          $agency_list[$agency] = 0;
357
        }
358
        if ($this->agency_cache) {
359
          if (!$this->agency_cache->set($cache_key, $agency_list))
360
            self::fatal(__CLASS__ . '::' . __FUNCTION__ . '(): Cannot set cache. key: ' . $cache_key);
361
        }
362
      }
363
    }
364
 
365
    return $agency_list;
366
  }
367
 
97699 fvs 368
  /**
118250 fvs 369
   * \brief Make a full url for the openagency call.
370
   *        if $operation only conatin parameter part of the url, 'base_uri' is added to $operation
371
   * @param string $operation
372
   * @return string - full url
373
   *
374
   **/
97699 fvs 375
  private function oa_uri($operation) {
376
    if (strpos($operation, '://') && (substr($operation, 0, 4) == 'http')) {
377
      return $operation;
378
    }
379
    return $this->config['base_uri'] . $operation;
380
  }
381
 
382
  /** \brief - xs:boolean to php bolean
383
   * @param string $str
118250 fvs 384
   * @return boolean - return true if xs:boolean is so
97699 fvs 385
   */
386
  private function xs_boolean($str) {
387
    return (strtolower($str) == 'true' || $str == 1);
388
  }
389
 
118250 fvs 390
  /** \brief -
97699 fvs 391
   * @param string $msg
392
   */
393
  private function trace($msg) {
394
    self::local_verbose(TRACE, $msg);
395
  }
396
 
118250 fvs 397
  /** \brief -
97699 fvs 398
   * @param string $msg
399
   */
400
  private function fatal($msg) {
401
    self::local_verbose(FATAL, $msg);
402
  }
403
 
118250 fvs 404
  /** \brief -
97699 fvs 405
   * @param string $level
406
   * @param string $msg
407
   */
408
  private function local_verbose($level, $msg) {
120114 fvs 409
    if (method_exists('VerboseJson', 'log')) {
410
      VerboseJson::log($level, $msg);
411
    }
412
    elseif (method_exists('verbose', 'log')) {
97699 fvs 413
      verbose::log($level, $msg);
414
    }
415
  }
416
 
417
}