16require_once
"grima-util.php";
17require_once
"grima-xmlbag.php";
18require_once
"grima-splats.php";
19require_once
"MARC21.php";
21if (!defined(
'sodium_crypto_secretbox')) {
22 @include_once
"vendor/paragonie/sodium_compat/autoload.php";
44 if ($session_module_name==
"none") {
46 }
else if ($session_module_name==
"encrypted_cookie") {
47 $session_key = base64_decode(
49 'SESSION_KEY',
"base64EncodedGrimaKeyOf32BytesTotallyRandom="
53 ini_set(
"session.use_cookies",
false);
54 }
else if ($session_module_name) {
55 $new_name = session_module_name($session_module_name);
56 if ($new_name != $session_module_name) {
57 session_name(
"grima_failsafe");
64 session_name($session_name);
67 'SESSION_PATH',
join_paths(sys_get_temp_dir(),
'grima')
69 if (session_module_name()===
'files') {
70 @mkdir($session_path, 0700,
true);
72 session_save_path($session_path);
74 session_set_cookie_params(365*24*60*60);
75 ini_set(
'session.gc_maxlifetime', 525600*60);
83 'SESSION_MODULE',
'encrypted_cookie'
85 if ($session_module_name ===
"none") {
89 foreach ($result as $key => $value) {
90 $_SESSION[$key] = $value;
92 session_write_close();
98 'SESSION_MODULE',
'encrypted_cookie'
100 if ($session_module_name ===
"none") {
104 if (ini_get(
"session.use_cookies")) {
105 $params = session_get_cookie_params();
106 $params[
'expires'] = time() - 42000;
107 unset($params[
'lifetime']);
108 setcookie(session_name(),
'', $params);
124 isset($_REQUEST[
'apikey']) && $_REQUEST[
'apikey'] ? $_REQUEST[
'apikey'] : (
125 isset($_SESSION[
'apikey']) && $_SESSION[
'apikey'] ? $_SESSION[
'apikey'] : (
129 isset($_REQUEST[
'server']) && $_REQUEST[
'server'] ? $_REQUEST[
'server'] : (
130 isset($_SESSION[
'server']) && $_SESSION[
'server'] ? $_SESSION[
'server'] : (
133 if (strlen($this->server)==2) {
134 $this->server =
"https://api-" . $this->server .
".hosted.exlibrisgroup.com";
137 if (!preg_match(
'!https://api-[a-z]*\.hosted\.exlibrisgroup\.com!', $this->server)) {
141 if ($this->apikey==
'EDITME') {
145 if ($this->apikey && $this->server) {
150 session_write_close();
171 function request($method, $url, $URLparams, $QSparams, $body =
null)
174 'Authorization: apikey ' . urlencode($this->apikey),
175 "Accept: application/xml",
179 foreach ($URLparams as $k => $v) {
181 throw new Exception(
"URL parameter $k is empty in $method $url");
183 $url = str_replace(
'{'.$k.
'}', urlencode($v), $url);
187 $url = $this->server . $url .
'?apikey=' . urlencode($this->apikey) .
'&format=xml';
190 foreach ($QSparams as $k => $v) {
191 $url .=
"&$k=" . urlencode($v);
197 $bodyxml = $body->saveXML();
198 $headers[] =
'Content-Type: application/xml';
202 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
203 curl_setopt($ch, CURLOPT_URL, $url);
204 curl_setopt($ch, CURLOPT_RETURNTRANSFER,
true);
205 curl_setopt($ch, CURLOPT_FOLLOWLOCATION,
true);
208 curl_setopt($ch, CURLOPT_HEADERFUNCTION, [&$headerCapture,
"capture"]);
214 if (OPENSSL_VERSION_NUMBER >= 0x010101000) {
216 curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST,
"DEFAULT@SECLEVEL=1");
220 if (isset($bodyxml)) {
221 curl_setopt($ch, CURLOPT_POSTFIELDS, $bodyxml);
223 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
226 $today = date(
"Y-m-d-H_i_s");
227 $debug = fopen(
"/tmp/grima/debug/curl-$today.log",
'a+');
231 "REQUEST_URI"=>isset($_SERVER[
"REQUEST_METHOD"])?($_SERVER[
"REQUEST_METHOD"].
" ".$_SERVER[
"SERVER_NAME"].$_SERVER[
"REQUEST_URI"]):
"cli",
232 "_REQUEST"=>$_REQUEST,
233 "request_body"=>$body,
239 curl_setopt($ch, CURLOPT_VERBOSE,
true);
240 curl_setopt($ch, CURLOPT_STDERR, $debug);
243 $response = curl_exec($ch);
246 fwrite($debug, serialize([
"response"=>$response]).
"\n\n");
250 $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
251 if (curl_errno($ch)) {
252 throw new Exception(
"Network error: " . curl_error($ch));
259 $xml =
new DOMDocument();
260 $xml->formatOutput =
true;
262 if (preg_match(
',^application/json,', $headerCapture->headers[
'content-type'])) {
263 $array = json_decode($response,
true);
264 $xml->loadXML(
'<?xml version="1.0"?' .
'><json/>');
266 }
else if (!preg_match(
'/^</', $response)) {
268 '<?xml version="1.0"?' .
'><html><body><h1>Not xml</h1><pre>'
269 . htmlspecialchars($response).
270 '</pre></body></html>'
273 $xml->loadXML($response);
275 }
catch (Exception $e) {
276 throw new Exception(
"Malformed XML from Alma:\n$method $url -> $code\n$e");
279 $xml->rawText = $response;
280 $xml->httpCode = $code;
281 $xml->headers = $headerCapture->headers;
282 $xml->rawHeaders = $headerCapture->rawHeaders;
298 function get($url, $URLparams, $QSparams)
300 return $this->
request(
"GET", $url, $URLparams, $QSparams,
null);
314 function post($url, $URLparams, $QSparams, $body)
316 return $this->
request(
"POST", $url, $URLparams, $QSparams, $body);
330 function put($url, $URLparams, $QSparams, $body)
332 return $this->
request(
"PUT", $url, $URLparams, $QSparams, $body);
346 function delete($url, $URLparams, $QSparams)
348 return $this->
request(
"DELETE", $url, $URLparams, $QSparams,
null);
359 if ($xml instanceOf DomDocument) {
360 $xpath =
new DomXpath($xml);
361 $xpath->registerNamespace(
"err",
"http://com/exlibris/urm/general/xmlbeans");
362 $error = $xpath->query(
'//err:errorMessage');
363 if ($error->length > 0) {
364 throw new Exception(
"Alma says: " . $error[0]->nodeValue);
394 function getBib($mms_id, $view =
'full', $expand =
'None')
397 '/almaws/v1/bibs/{mms_id}',
398 array(
'mms_id' => $mms_id),
399 array(
'view' => $view,
'expand' => $expand)
447 '/almaws/v1/bibs/{mms_id}',
448 array(
'mms_id' => $mms_id),
471 $ret = $this->
delete(
472 '/almaws/v1/bibs/{mms_id}',
473 array(
'mms_id' => $mms_id),
474 array(
'override' => $override)
509 '/almaws/v1/bibs/{mms_id}/holdings',
510 array(
'mms_id' => $mms_id),
547 '/almaws/v1/bibs/{mms_id}/holdings/{holding_id}',
550 'holding_id' => $holding_id
575 '/almaws/v1/bibs/{mms_id}/holdings',
576 array(
'mms_id' => $mms_id),
602 '/almaws/v1/bibs/{mms_id}/holdings/{holding_id}',
603 array(
'mms_id' => $mms_id,
'holding_id' => $holding_id),
627 $ret = $this->
delete(
628 '/almaws/v1/bibs/{mms_id}/holdings/{holding_id}',
631 'holding_id' => $holding_id
633 array(
'override' => $override)
670 '/almaws/v1/bibs/{mms_id}/holdings/{holding_id}/items', array(
'mms_id' => $mms_id,
'holding_id' => $holding_id),
671 array(
'limit' => $limit,
'offset' => $offset)
704 function getItem($mms_id, $holding_id, $item_pid)
707 '/almaws/v1/bibs/{mms_id}/holdings/{holding_id}/items/{item_pid}', array(
709 'holding_id' => $holding_id,
710 'item_pid' => $item_pid
736 'item_barcode' => $barcode,
761 '/almaws/v1/bibs/{mms_id}/holdings/{holding_id}/items',
762 array(
'mms_id' => $mms_id,
'holding_id' => $holding_id),
786 function putItem($mms_id, $holding_id, $item_pid, $item)
789 '/almaws/v1/bibs/{mms_id}/holdings/{holding_id}/items/{item_pid}',
790 array(
'mms_id' => $mms_id,
'holding_id' => $holding_id,
'item_pid' => $item_pid),
813 function deleteItem($mms_id, $holding_id, $item_pid, $override =
"false",
816 $ret = $this->
delete(
817 '/almaws/v1/bibs/{mms_id}/holdings/{holding_id}/items/{item_pid}', array(
819 'holding_id' => $holding_id,
820 'item_pid' => $item_pid
822 'override' => $override,
823 'holdings' => $holdings
860 '/almaws/v1/electronic/e-collections/{collection_id}/e-services/{service_id}/portfolios/{portfolio_id}',
861 array(
'collection_id' => $collection_id,
'service_id' => $service_id,
'portfolio_id' => $portfolio_id),
885 '/almaws/v1/bibs/{mms_id}/portfolios/{portfolio_id}',
886 array(
'mms_id' => $mms_id,
'portfolio_id' => $portfolio_id),
911 '/almaws/v1/electronic/e-collections/{collection_id}/e-services/{service_id}/portfolios',
912 array(
'collection_id' => $collection_id,
'service_id' => $service_id),
938 '/almaws/v1/bibs/{mms_id}/portfolios/',
939 array(
'mms_id' => $mms_id),
945 $portfolio->loadXML($ret->saveXML());
967 '/almaws/v1/bibs/{mms_id}/portfolios/{portfolio_id}',
968 array(
'mms_id' => $mms_id,
'portfolio_id' => $portfolio_id),
992 $ret = $this->
delete(
993 '/almaws/v1/electronic/e-collections/{collection_id}/e-services/{service_id}/portfolios/{portfolio_id}',
994 array(
'collection_id' => $collection_id,
'service_id' => $service_id,
'portfolio_id' => $portfolio_id),
1019 '/almaws/v1/electronic/e-collections/{collection_id}/e-services/{service_id}/portfolios',
1020 array(
'collection_id' => $collection_id,
'service_id' => $service_id),
1021 array(
'limit' => $limit, $offset = $offset)
1045 '/almaws/v1/bibs/{mms_id}/portfolios',
1046 array(
'mms_id' => $mms_id),
1047 array(
'limit' => $limit, $offset = $offset)
1069 '/almaws/v1/electronic/e-collections/{collection_id}',
1070 array(
'collection_id' => $collection_id),
1094 '/almaws/v1/electronic/e-collections/{collection_id}',
1095 array(
'collection_id' => $collection_id),
1120 '/almaws/v1/electronic/e-collections/{collection_id}/e-services',
1121 array(
'collection_id' => $collection_id),
1157 '/almaws/v1/conf/libraries/{libraryCode}',
1158 array(
'libraryCode' => $libraryCode),
1180 '/almaws/v1/conf/libraries',
1203 '/almaws/v1/conf/libraries/{libraryCode}/locations',
1204 array(
'libraryCode' => $libraryCode),
1240 '/almaws/v1/conf/libraries/{libraryCode}/locations/{locationCode}',
1242 'libraryCode' => $libraryCode,
1243 'locationCode' => $locationCode,
1280 '/almaws/v1/conf/sets/{set_id}',
1281 array(
'set_id' => $set_id),
1303 '/almaws/v1/conf/sets/',
1331 '/almaws/v1/conf/sets/{set_id}',
1332 array(
'set_id' => $set_id),
1333 array(
'id_type' => $id_type,
'op' => $op),
1357 $body =
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?' .
'>
1359 <name>Grima set from ' . $job_instance_id .
'</name>
1360 <description>members of ' . $job_instance_id .
'</description>
1361 <type desc="Itemized">ITEMIZED</type>
1362 <content desc="All Titles">BIB_MMS</content>
1363 <private desc="No">false</private>
1384 $bodyxml =
new DomDocument();
1385 $bodyxml->loadXML($body);
1387 $ret = $this->
post(
'/almaws/v1/conf/sets', array(), array(
'job_instance_id' => $job_instance_id,
'population' => $population), $bodyxml);
1407 $ret = $this->
delete(
1408 '/almaws/v1/conf/sets/{set_id}',
1410 'set_id' => $set_id,
1434 '/almaws/v1/conf/sets/{set_id}/members',
1435 array(
'set_id' => $set_id),
1436 array(
'limit' => $limit,
'offset' => $offset)
1460 '/almaws/v1/analytics/reports',
1462 array(
'path' => urlencode($path),
'filter' => urlencode($filter),
1463 'limit' => $limit,
'token' => $token)
1497 '/almaws/v1/conf/jobs/{job_id}',
1498 array(
'job_id' => $job_id),
1535 return isset($this->args[$offset]);
1540 return $this->args[$offset];
1545 $this->args[$offset] = $value;
1550 unset($this->args[$offset]);
1556 $base = get_class($this);
1557 if (file_exists(
join_paths($webroot, $base,
"$base.xml")) and (!isset($this->formxml))) {
1558 $this->formxml = file_get_contents(
join_paths($webroot, $base,
"$base.xml"));
1560 if (isset($this->formxml)) {
1562 $this->form->fromXML($this->formxml);
1569 $basename = get_class($this);
1573 $this->splat->addBases(
1575 "$webroot/$basename/splats",
1580 $this->splatVars = array(
1581 'title' => $this->form->title,
1582 'basename' => $basename,
1583 'webroot' => $webroot,
1584 'local_stylesheets' => array(
'Grima.css'),
1585 'form' => &$this->form,
1586 'messages' => &$this->messages,
1589 if (isset($this[
'redirect_url'])) {
1590 $this->splatVars[
'redirect_url'] = $this[
'redirect_url'];
1596 $this->form->loadValues($this);
1597 $this->splat->splat(
'print_form', $this->splatVars);
1602 $this->form->loadPersistentValues($this);
1603 $this->splat->splat(
'print_success', $this->splatVars);
1608 $this->form->loadValues($this);
1609 $this->splat->splat(
'print_failure', $this->splatVars);
1620 GrimaTask::call(
'Login', array(
"redirect_url"=>$_SERVER[
'PHP_SELF']));
1634 $this->error =
false;
1640 }
catch (Exception $e) {
1641 $this->
addMessage(
'error', $e->getMessage());
1642 $this->error =
true;
1657 $task =
new static();
1663 if (isset($this->form)) {
1664 if (php_sapi_name() ==
"cli") {
1667 foreach ($this->form->fields as $field) {
1668 $short = $field->shortname;
1669 if ($field->required) {
1670 $param .=
"$short:";
1672 $param .=
"$short::";
1676 if ($option = getopt($param)) {
1677 foreach ($this->form->fields as $field) {
1678 if (isset($option[$field->shortname])) {
1679 $this[$field->name] = $option[$field->shortname];
1689 $this->
usage(); exit;
1693 foreach ($this->form->fields as $field) {
1694 if (isset($_REQUEST[$field->name])) {
1695 $this[$field->name] = $_REQUEST[$field->name];
1709 if (isset($this->form)) {
1711 foreach ($this->form->fields as $field) {
1712 if ($field->required) {
1713 if (!isset($this[$field->name])
1714 or !($this[$field->name])
1716 $field->error_condition =
"error";
1717 $field->error_message =
"Field is required\n";
1718 $input_good =
false;
1725 foreach ($this->auto_args as $k => $v) {
1726 if (preg_match(
'/[^:]:$/', $k)) {
1727 if (!isset($this->args[$v]) or !($this->args[$v])) {
1738 if (php_sapi_name() ==
"cli") {
1739 if ($options = getopt(implode(array_keys($param)))) {
1740 foreach ($param as $k => $v) {
1741 $this->args[$v] = $options[$k[0]];
1744 $this->
usage(); exit;
1747 $this->
usage(); exit;
1750 foreach ($param as $k => $v) {
1751 if (isset($_REQUEST[$v])) {
1752 $this->args[$v] = $_REQUEST[$v];
1767 print
"Usage: php ${argv[0]} ";
1769 foreach ($this->form->fields as $field) {
1770 $k = $field->shortname;
1772 if ($field->required) {
1775 print
"[-$k <$n>] ";
1803 $url = rtrim(
"../$grimaname/$grimaname.php?" . http_build_query(
$args),
"?");
1824 $this->type =
$type;
1850 foreach ($this->fields as $field) {
1851 if (isset($obj[$field->name])) {
1852 $field->value = $obj[$field->name];
1866 foreach ($this->fields as $field) {
1867 if (($field->persistent) and isset($obj[$field->name])) {
1868 $field->value = $obj[$field->name];
1881 $doc =
new DomDocument();
1882 $doc->loadXML($xml);
1883 $xpath =
new DomXpath($doc);
1884 $this->title = $xpath->query(
'//Title')[0]->nodeValue;
1885 $this->action = basename($_SERVER[
'PHP_SELF']);
1887 $nodes = $xpath->query(
'//Field');
1888 foreach ($nodes as $node) {
1889 $this->fields[$node->getAttribute(
'name')] =
new GrimaFormField($node);
1921 $this->item =
new Item();
1924 }
catch (Exception $e) {
1928 $this->
bib->loadFromAlma($this->item[
'mms_id']);
1929 $this->
bib->useNormac();
1936 $fields = $this->
bib->marc->getFields(
'ZEM');
1937 foreach ($fields as $field) {
1938 $keys = $field->getSubfields(
'k');
1939 if ($keys[0]->data == $offset) {
1948 $fields = $this->
bib->marc->getFields(
'ZEM');
1949 foreach ($fields as $field) {
1950 $keys = $field->getSubfields(
'k');
1951 if ($keys[0]->data == $offset) {
1952 $values = $field->getSubfields(
'v');
1953 return $values[0]->data;
1961 $fields = $this->
bib->marc->getFields(
'ZEM');
1962 foreach ($fields as $field) {
1963 $keys = $field->getSubfields(
'k');
1964 if ($keys[0]->data == $offset) {
1965 $values = $field->getSubfields(
'v');
1966 $values[0]->data = $value;
1967 $this->
bib->updateAlma();
1975 $field =
new ISO2709Field(
'ZEM',
null,
" ", $subarray);
1976 $this->
bib->marc->appendField($field);
1977 $this->
bib->updateAlma();
1983 $fields = $this->
bib->marc->getFields(
'ZEM');
1984 foreach ($fields as $field) {
1985 $keys = $field->getSubfields(
'k');
1986 if ($keys[0]->data == $offset) {
1988 $this->
bib->updateAlma();
2004 $bib[
'title'] =
"GRIMA'S DATA STORE";
2005 $bib[
'suppress_from_publishing'] =
"true";
2008 $this->
bib->useNormac();
2011 $location = $library->getOneLocation();
2014 $holding[
'library_code'] = $library[
'code'];
2015 $holding[
'location_code'] = $location[
'code'];
2022 $this->item =
$item;
2024 preg_match(
'/\d{5}$/',
$bib[
'mms_id'], $m);
2025 $this[
'alma institution code'] = $m[0];
2040 }
catch (Exception $e) {
2058 $bib->deleteTreeFromAlma();
2101 function booly($str, $default =
'undefined')
2103 switch(strtolower($str)) {
2130 $this->name = $field->getAttribute(
'name');
2131 $this->shortname = $field->getAttribute(
'shortname');
2132 $this->label = $field->getAttribute(
'label');
2133 $this->placeholder = $field->getAttribute(
'placeholder');
2134 $this->rows = $field->getAttribute(
'rows');
2135 $this->type = $field->getAttribute(
'type');
2137 $this->type =
'input';
2139 $this->required = $this->
booly($field->getAttribute(
'required'),
true);
2140 $this->persistent = $this->
booly($field->getAttribute(
'persistent'),
false);
2141 $this->autofocus = $this->
booly($field->getAttribute(
'autofocus'),
false);
2142 $this->autocomplete = $this->
booly($field->getAttribute(
'autocomplete'),
false);
2143 $this->visible = $this->
booly($field->getAttribute(
'visible'),
true);
2144 $this->dataset = $field->getAttribute(
'dataset');
2145 $this->options = array();
2146 if ($this->dataset) {
2147 if ($this->dataset ==
"institutions") {
2150 foreach ($institutions as $institution) {
2151 $i = htmlspecialchars($institution);
2152 $s = ($institution === $currentUser[
'institution']) ?
' selected="selected"' :
'';
2153 $this->options[] =
"<option value=\"$i\"$s>$i</option>";
2157 foreach ($field->getElementsByTagName(
"option") as $option) {
2158 $this->options[] = $option->ownerDocument->saveXML($option);
2185 $this->xml =
new DomDocument();
2186 $blankRecord = get_class($this);
2187 $this->xml->loadXML(file_get_contents(
"{$this->templateDir}/{$blankRecord}.xml"));
2193 if (isset($this->el_override)) {
2194 return array_key_exists($offset, $this->el_override);
2196 return array_key_exists($offset, $this->el_access);
2201 if ((isset($this->el_override))
2202 and (isset($this->el_override[$offset]))
2204 return $this->el_override[$offset];
2206 $xpath =
new DomXpath($this->xml);
2207 $node = $xpath->query($this->el_address[$offset]);
2208 if (
sizeof($node) >= 1) {
2209 return $node[0]->nodeValue;
2217 $xpath =
new DomXpath($this->xml);
2218 $node = $xpath->query($this->el_address[$offset]);
2219 $node[0]->nodeValue =
2220 preg_replace(
'/&(?!#?[a-z0-9]+;)/',
'&', $value); # XXX
2225 $xpath =
new DomXpath($this->xml);
2226 $node = $xpath->query($this->el_address[$offset]);
2227 $node[0]->nodeValue =
null;
2246 if (isset($this->marc)) {
2250 $this->marc->loadFromString($this->xml->saveXML());
2263 $subarray = array();
2265 $this->marc->AppendField($field,
true);
2280 $subarray = array();
2281 foreach ($subfields as $k => $v) {
2284 $field =
new ISO2709Field($tag,
null, $indicators, $subarray);
2285 $fieldstr = $field->AsMnemonicString();
2287 $fields = $this->marc->getFields($tag);
2289 foreach($fields as $f) {
2290 $fstr = $f->AsMnemonicString();
2291 if ($fstr == $fieldstr) {
2294 #error_log($fstr . " vs " . $fieldstr);
2298 $this->marc->AppendField($field,
true);
2309 if (isset($this->marc)) {
2310 $newRecord =
new DOMDocument;
2311 $marc = preg_replace(
'/&(?!#?[a-z0-9]+;)/',
'&',
2312 $this->marc->asXMLString());
2313 $newRecord->loadXML(
$marc);
2315 $xpath =
new DOMXpath($this->xml);
2316 $record = $xpath->query(
'//record');
2318 $node->parentNode->removeChild($node);
2320 $node = $this->xml->importNode($newRecord->documentElement,
true);
2321 $this->xml->documentElement->appendChild($node);
2337 ## XXX: replace with normac
2342 foreach ($subfields as $k => $v) {
2346 $field =
new ISO2709Field($tag,
null, $ind1.$ind2, $subs);
2347 $this->marc->AppendField($field,
true);
2372 return $this->marc->getFields($tag);
2385 $xpath =
new DomXpath($this->xml);
2386 $tag = preg_replace(
'/X*$/',
'', $tag);
2387 $tag = preg_replace(
'/\.*$/',
'', $tag);
2388 $fields = $xpath->query(
"//record/datafield[starts-with(@tag,'$tag')]");
2389 $fieldarr = array();
2390 foreach ($fields as $field) {
2391 $marcfield =
new MARCField();
2393 $subfieldarr = array();
2394 foreach ($field->childNodes as $child) {
2395 $subfieldarr[] = array(
2396 $child->attributes[0]->value,
2400 $fieldarr[] = $subfieldarr;
2416 $xpath =
new DomXpath($this->xml);
2417 $subfields = $xpath->query(
"//record/datafield[@tag='$tag']/subfield[@code='$code']");
2419 foreach ($subfields as $subfield) {
2420 $arr[] = $subfield->nodeValue;
2434 $xpath =
new DomXpath($this->xml);
2435 $fields = $xpath->query(
"//record/datafield[@tag='$tag']");
2436 foreach ($fields as $field) {
2437 $field->parentNode->removeChild($field);
2450 $xpath =
new DomXPath($this->xml);
2451 $subfs = $xpath->query(
"//datafield[@tag='$tag']/subfield[@code='$code']");
2452 foreach ($subfs as $subf) {
2453 if (preg_match($regex, $subf->nodeValue)) {
2454 $subf->parentNode->removeChild($subf);
2475 foreach ($this->
getFields($tag) as $field) {
2476 foreach ($field->getSubfields($code) as $subfield) {
2477 if (preg_match($regex,$subfield->data)) {
2495 ## XXX: replace with normac
2498 $xpath =
new DomXpath($this->xml);
2499 $fields = $xpath->query(
"//record/datafield[@tag='$tag']");
2500 if (
sizeof($fields) == 0) {
2501 $this->
appendField($tag,
' ',
' ', array($code => $value));
2504 foreach ($fields[0]->childNodes as $subfield) {
2505 if ($subfield->nodeType !== 1) {
2508 if ($subfield->getAttribute(
"code") == $code) {
2509 $subfield->nodeValue = $value;
2515 $subfield = $this->xml->createElement(
"subfield");
2516 $subfield->setAttribute(
"code", $code);
2517 $subfield->appendChild($this->xml->createTextNode($value));
2518 $fields[0]->appendChild($subfield);
2545 'mms_id' =>
'//mms_id',
2546 'leader' =>
'//leader',
2547 'record_format' =>
'//record_format',
2548 'title' =>
'//title',
2549 'author' =>
'//author',
2550 'place_of_publication' =>
'//place_of_publication',
2551 'publisher_const' =>
'//publisher_const',
2552 'publisher' =>
'//publisher_const',
2553 'suppress_from_publishing' =>
'//suppress_from_publishing',
2558 if ($offset ==
'Type') {
2559 $leader = $this[
'leader'];
2562 if ($offset ==
'BLvl') {
2563 $leader = $this[
'leader'];
2566 if ($offset ==
'ELvl') {
2567 $leader = $this[
'leader'];
2570 if ($offset ==
'Desc') {
2571 $leader = $this[
'leader'];
2574 if ($offset ==
'Lang') {
2576 $my008 = $my008s[0];
2577 $data = $my008->data;
2578 return substr($data,35,3);
2580 return parent::offsetGet($offset);
2586 parent::offsetSet($offset, $value);
2587 if ($offset ==
'author') {
2590 if ($offset ==
'title') {
2593 if (($offset ==
'publisher_const') or ($offset ==
'publisher')) {
2596 if ($offset ==
'place_of_publication') {
2610 $this->xml =
$grima->getBib($mms_id);
2624 $this->xml =
$grima->postBib($this->xml);
2637 $this->xml =
$grima->putBib($this[
'mms_id'], $this->xml);
2648 $grima->deleteBib($this[
'mms_id']);
2661 $report->path =
"/shared/Community/Reports/Institutions/University of Kentucky/Kathryn/OclcToMMS";
2663<sawx:expr xsi:type="sawx:comparison" op="equal" xmlns:saw="com.siebel.analytics.web/report/v1.1"
2664xmlns:sawx="com.siebel.analytics.web/expression/v1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2665xmlns:xsd="http://www.w3.org/2001/XMLSchema">
2666 <sawx:expr xsi:type="sawx:sqlExpression">"Holding Details"."Holding Id"</sawx:expr><sawx:expr xsi:type="xsd:string">{holding_id}</sawx:expr>
2670<sawx:expr xsi:type="sawx:comparison" op="equal" xmlns:saw="com.siebel.analytics.web/report/v1.1"
2671xmlns:sawx="com.siebel.analytics.web/expression/v1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2672xmlns:xsd="http://www.w3.org/2001/XMLSchema">
2673 <sawx:expr xsi:type="sawx:sqlExpression">"Bibliographic Details"."OCLC Control Number (035a)"</sawx:expr></sawx:expr>
2676 $report->runReport(array(
'oclc' => $oclc), 1);
2677 if (count($report->rows) == 1) {
2678 return $report->rows[0][1];
2680 throw new Exception(
"No MMS for OCLC #$oclc");
2693 foreach ($this->holdings as $holding) {
2694 $holding->deleteTreeFromAlma();
2697 $grima->deleteBib($this[
'mms_id']);
2708 if (count($this->holdingsList->entries) > 0) {
2712 if (count($this->portfolioList) > 0) {
2713 print_r($this->portfolioList);
2727 $xpath =
new DomXPath($this->xml);
2728 $nodes = $xpath->query(
"//linked_record_id[@type='CZ']");
2729 return (count($nodes) > 0);
2740 $xpath =
new DomXPath($this->xml);
2741 $nodes = $xpath->query(
"//linked_record_id[@type='CZ']");
2742 foreach ($nodes as $node) {
2743 $node->parentNode->removeChild($node);
2756 foreach ($this->holdingsList->entries as $entry) {
2758 $holding->loadFromAlma($this[
'mms_id'], $entry[
'holding_id']);
2759 $holding[
'mms_id'] = $this[
'mms_id'];
2760 $this->holdings[] = $holding;
2774 foreach ($this->portfolioList as $portfolio) {
2775 error_log(
"deleting " . $portfolio[
'pid'] .
"\n");
2776 $portfolio->deleteFromAlma();
2778 $this->portfolioList = array();
2790 $this->holdingsList =
new HoldingsList($this[
'mms_id']);
2802 $limit = 10; $offset = 0;
2803 $ret =
$grima->getElectronicPortfoliosForBib($this[
'mms_id'], $limit, $offset);
2804 $xpath =
new DOMXpath($ret);
2805 $ports = $xpath->query(
'//portfolio');
2806 foreach ($ports as $portnode) {
2808 $newport->loadFromPortfolioListNode($portnode);
2809 $this->portfolioList[] = $newport;
2811 return count($ports);
2822 foreach ($this->portfolioList as $port) {
2823 $port->loadFromAlma($port[
'portfolio_id']);
2836 $this->items =& $this->itemList->items;
2849 $this->itemList =
new ItemList($this[
'mms_id'],
'ALL');
2860 $xpath =
new DomXpath($this->xml);
2861 $title = $xpath->query(
"//record/datafield[@tag='245']/subfield[@code='a']");
2862 return preg_replace(
"/[ \/=:,;\.]*$/",
"", $title[0]->nodeValue);
2886 $xpath =
new DomXPath($this->xml);
2888 foreach (array(
'050',
'090') as $tag) {
2889 foreach ($xpath->query(
"//datafield[@tag='$tag']") as $call) {
2895 foreach ($calls as $node) {
2896 $classs = $xpath->query(
"subfield[@code='a']", $node);
2897 $items = $xpath->query(
"subfield[@code='b']", $node);
2898 if ((count($classs) > 0) and (count(
$items) > 0)) {
2899 $ret = array($classs[0]->nodeValue,
$items[0]->nodeValue);
2917 'mms_id' =>
'//mms_id',
2918 'title' =>
'//title',
2919 'author' =>
'//author',
2927 if (!is_null($mms_id)) {
2935 $this->xml =
$grima->getHoldingsList($mms_id);
2936 $xpath =
new DomXpath($this->xml);
2937 $hs = $xpath->query(
'//holding');
2938 $this->entries = array();
2940 foreach ($hs as $h) {
2956 'holding_id' =>
'//holding_id',
2957 'call_number' =>
'//holding/call_number',
2958 'library_code' =>
'//holding/library',
2959 'library' =>
'//holding/library/@desc',
2960 'location_code' =>
'//holding/location',
2961 'location' =>
'//holding/location/@desc'
2967 $this->xml =
new DomDocument();
2968 $this->xml->appendChild($this->xml->importNode($node,
true));
2969 $this->el_override[
'mms_id'] = $mms_id;
2975 $this->getMmsIfNeeded();
2976 $this->itemList =
new ItemList($this[
'mms_id'], $this[
'holding_id'], $limit);
2995 $req_limit = ($limit == -1)?100:$limit;
2998 if ($curr_offset > 0) {
2999 if (($curr_offset+1)*100 > $limit) {
3000 $req_limit = $limit - $curr_offset*100;
3005 $xml =
$grima->getItemList($mms_id, $holding_id, $req_limit, $curr_offset*100);
3006 $xpath =
new DomXpath(
$xml);
3007 $is = $xpath->query(
'//item');
3008 foreach ($is as $i) {
3009 $new_item =
new Item();
3010 $new_item->loadFromItemListNode($i);
3011 $this->items[] = $new_item;
3013 $xpath =
new DomXPath(
$xml);
3014 if (!$curr_offset) {
3015 $length = $xpath->query(
'//items/@total_record_count')[0]->nodeValue;
3016 if ($limit == -1) { $limit = $length;
3021 }
while (($curr_offset*100 < $length) and ($curr_offset*100 < $limit));
3041 if ($offset ==
"mms_id") {
3042 $this->el_override[
'mms_id'] = $value;
3045 if ($offset ==
"location_code") {
3049 parent::offsetSet($offset, $value);
3055 if ($offset ==
"library") {
3057 $lib->loadFromAlma($this[
'library_code']);
3058 return $lib[
'name'];
3060 if ($offset ==
"location") {
3062 $loc->loadFromAlma($this[
'library_code'], $this[
'location_code']);
3063 return $loc[
'name'];
3065 if ($offset ==
"inst_code") {
3068 if ($offset ==
"library_code") {
3071 if ($offset ==
"location_code") {
3074 if ($offset ==
"call_number") {
3078 foreach ($Hs as $h) {
3081 foreach ($Is as $i) {
3086 return parent::offsetGet($offset);
3091 'holding_id' =>
'//holding_id',
3092 'shelving_scheme' =>
"/holding/record/datafield[@tag='852']/@ind1",
3095 'inst_code' =>
"/holding/record/datafield[@tag='852']/subfield[@code='a']",
3096 'library_code' =>
"/holding/record/datafield[@tag='852']/subfield[@code='b']",
3097 'location_code' =>
"/holding/record/datafield[@tag='852']/subfield[@code='c']",
3099 'classification_part' =>
"/holding/record/datafield[@tag='852']/subfield[@code='h']",
3100 '852h' =>
"/holding/record/datafield[@tag='852']/subfield[@code='h']",
3102 'item_part' =>
"/holding/record/datafield[@tag='852']/subfield[@code='i']",
3103 '852i' =>
"/holding/record/datafield[@tag='852']/subfield[@code='i']",
3119 $this->xml =
$grima->getHolding($mms_id, $holding_id);
3120 $this[
'mms_id'] = $mms_id;
3134 $report->path =
"/shared/Community/Reports/Institutions/University of Kentucky/Kathryn/HoldingToMMS";
3136<sawx:expr xsi:type="sawx:comparison" op="equal" xmlns:saw="com.siebel.analytics.web/report/v1.1"
3137xmlns:sawx="com.siebel.analytics.web/expression/v1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3138xmlns:xsd="http://www.w3.org/2001/XMLSchema">
3139 <sawx:expr xsi:type="sawx:sqlExpression">"Holding Details"."Holding Id"</sawx:expr><sawx:expr xsi:type="xsd:string">{holding_id}</sawx:expr>
3142 $report->runReport(array(
'holding_id' => $holding_id), 1);
3143 if (count($report->rows) == 1) {
3144 return $report->rows[0][1];
3146 throw new Exception(
"No MMS for Holding ID $holding_id");
3159 if (!isset($this[
'mms_id']) or (!$this[
'mms_id'])) {
3176 $this->xml =
$grima->getHolding($mms_id, $holding_id);
3177 $this[
'mms_id'] = $mms_id;
3191 $this->xml =
$grima->postHolding($mms_id, $this->xml);
3192 $this[
'mms_id'] = $mms_id;
3203 return (
sizeof($this->itemList->items) > 0);
3215 #error_log($this->xml->saveXML());
3216 $grima->putHolding($this[
'mms_id'], $this[
'holding_id'], $this->xml);
3227 $grima->deleteHolding($this[
'mms_id'], $this[
'holding_id']);
3240 $fixed_fields = $this->
getFields(
"008")[0];
3241 return substr($fixed_fields->data, 7, 1);
3255 $fixed_fields = $this->
getFields(
"008")[0];
3256 $newstr = substr_replace($fixed_fields->data,$code,7,1);
3257 $fixed_fields->data = $newstr;
3269 return $this->
getFields(
"852")[0]->getSubFields(
"a")[0]->data;
3282 $instsf = $this->
getFields(
"852")[0]->getSubFields(
"a")[0];
3283 $instsf->data = $code;
3295 return $this->
getFields(
"852")[0]->getSubFields(
"b")[0]->data;
3308 $libsf = $this->
getFields(
"852")[0]->getSubFields(
"b")[0];
3309 $libsf->data = $code;
3321 return $this->
getFields(
"852")[0]->getSubFields(
"c")[0]->data;
3334 $locsf = $this->
getFields(
"852")[0]->getSubFields(
"c")[0];
3335 $locsf->data = $code;
3341 # XXX check argument
3344 $the852->indicators[0] = $ind1;
3371 $xpath =
new DomXpath($this->xml);
3372 $xpath->query(
"//record/datafield[@tag='852']")->item(0)->setAttribute(
"ind1", $ind1);
3374 $field852 = $xpath->query(
"//record/datafield[@tag='852']")->item(0);
3375 $subfieldHs = $xpath->query(
"subfield[@code='h']", $field852);
3376 foreach ($subfieldHs as $subfieldH) {
3377 $subfieldH->parentNode->removeChild($subfieldH);
3379 $subfieldIs = $xpath->query(
"subfield[@code='i']", $field852);
3380 foreach ($subfieldIs as $subfieldI) {
3381 $subfieldI->parentNode->removeChild($subfieldI);
3408 $this->items =& $this->itemList->items;
3421 $this->itemList =
new ItemList($this[
'mms_id'], $this[
'holding_id']);
3433 foreach ($this->itemList->items as $item) {
3434 $item->deleteFromAlma(
"true");
3455 foreach ($this->
getFields($tag) as $field) {
3456 foreach ($field->getSubfields($code) as $subfield) {
3457 if (preg_match($regex,$subfield->data)) {
3458 $subfield->delete();
3480 foreach ($this->
getFields($tag) as $field) {
3481 foreach ($field->getSubfields($code) as $subfield) {
3482 if (preg_match($regex,$subfield->data)) {
3504 'item_pid' =>
'//pid',
3505 'barcode' =>
'//barcode',
3506 'creation_date' =>
'//creation_date',
3507 'modification_date' =>
'//modification_date',
3508 'base_status' =>
'//base_status',
3509 'physical_material_type_code' =>
'//physical_material_type',
3510 'physical_material_type' =>
'//physical_material_type/@desc',
3511 'location' =>
'//location/@desc',
3512 'location_code' =>
'//location',
3513 'library' =>
'//location/@desc',
3514 'library_code' =>
'//library',
3515 'policy' =>
'//policy',
3516 'item_policy' =>
'//policy',
3517 'provenance' =>
'//provenance',
3518 'po_line' =>
'//po_line',
3519 'is_magnetic' =>
'//is_magnetic',
3520 'arrival_date' =>
'//arrival_date',
3521 'year_of_issue' =>
'//year_of_issue',
3522 'enumeration_a' =>
'//enumeration_a',
3523 'enumeration_b' =>
'//enumeration_b',
3524 'enumeration_c' =>
'//enumeration_c',
3525 'enumeration_d' =>
'//enumeration_d',
3526 'enumeration_e' =>
'//enumeration_e',
3527 'enumeration_f' =>
'//enumeration_f',
3528 'enumeration_g' =>
'//enumeration_g',
3529 'enumeration_h' =>
'//enumeration_h',
3530 'chronology_i' =>
'//chronology_i',
3531 'chronology_j' =>
'//chronology_j',
3532 'chronology_k' =>
'//chronology_k',
3533 'chronology_l' =>
'//chronology_l',
3534 'chronology_m' =>
'//chronology_m',
3535 'description' =>
'//description',
3536 'alternative_call_number' =>
'//alternative_call_number',
3537 'alternative_call_number_type' =>
'//alternative_call_number_type',
3538 'storage_location_id' =>
'//storage_location_id',
3539 'receiving_operator' =>
'//receiving_operator',
3540 'process_type' =>
'//process_type',
3541 'in_temp_location' =>
'//in_temp_location',
3542 'mms_id' =>
'//mms_id',
3543 'holding_id' =>
'//holding_id',
3544 'title' =>
'//title',
3545 'author' =>
'//author',
3546 'call_number' =>
'//call_number',
3547 'pages' =>
'//pages',
3548 'pieces' =>
'//pieces',
3549 'public_note' =>
'//public_note',
3550 'fulfillment_note' =>
'//fulfillment_note',
3551 'internal_note_1' =>
'//internal_note_1',
3552 'internal_note_2' =>
'//internal_note_2',
3553 'internal_note_3' =>
'//internal_note_3',
3554 'statistics_note_1' =>
'//statistics_note_1',
3555 'statistics_note_2' =>
'//statistics_note_2',
3556 'statistics_note_3' =>
'//statistics_note_3',
3557 'requested' =>
'//requested',
3558 'physical_condition' =>
'//physical_condition',
3559 'temp_library' =>
'//temp_library',
3560 'temp_location' =>
'//temp_location',
3561 'temp_policy' =>
'//temp_policy',
3562 'copy_id' =>
'//copy_id',
3563 'inventory_date' =>
'//inventory_date',
3564 'inventory_number' =>
'//inventory_number',
3565 'inventory_price' =>
'//inventory_price',
3575 $fields = array( # XXX: fill with the rest
3581 $xpath =
new DomXpath($this->xml);
3582 $stem = $xpath->query(
"//item_data")[0];
3583 foreach($fields as $field) {
3584 $try = $xpath->query(
"//$field");
3585 if (
sizeof($try) == 0) {
3586 # XXX add empty node with that name
3587 $node = $this->xml->createElement($field);
3588 $stem->appendChild($node);
3605 $this->xml =
$grima->getItem($mms_id, $holding_id, $item_pid);
3617 $this->xml =
$grima->getItem(
'X',
'X', $item_pid);
3629 $this->xml =
$grima->getItemBC($barcode);
3643 if (preg_match(
"/^23.*/", $id)) {
3660 $this->xml =
new DomDocument();
3661 $this->xml->appendChild($this->xml->importNode($node,
true));
3675 $this->mms_id = $mms_id;
3676 $this->holding_id = $holding_id;
3677 $this->xml =
$grima->postItem($mms_id, $holding_id, $this->xml);
3706 $this[
'holding_id'],
3723 $grima->deleteItem($this[
'mms_id'], $this[
'holding_id'], $this[
'item_pid'], $override, $holdings);
3744 'collection_id' =>
'//id',
3746 'public_name' =>
'//public_name',
3757 $this->xml =
$grima->getElectronicCollection($collection_id);
3769 $this->xml =
$grima->putElectronicCollection($this[
'collection_id'], $this->xml);
3780 $ret =
$grima->getElectronicServices($this[
'collection_id']);
3781 $xpath =
new DomXpath($ret);
3782 $eservices = $xpath->query(
'//electronic_services/electronic_service');
3783 foreach ($eservices as $service) {
3784 $service_id = $service->firstChild->nodeValue;
3786 $ser->loadFromServiceListNode($service);
3787 $this->services[] = $ser;
3808 'service_id' =>
'//id',
3820 if ($offset ==
"collection_id") {
3821 $this->el_override[
'collection_id'] = $value;
3823 parent::offsetSet($offset, $value);
3834 $this->xml =
$grima->getElectronicService($collection_id, $service_id);
3835 $this[
'collection_id'] = $collection_id;
3847 $this->xml =
new DomDocument();
3848 $this->xml->appendChild($this->xml->importNode($node,
true));
3849 $xpath =
new DomXPath($this->xml);
3850 $service_link = $xpath->query(
'//electronic_service')->item(0)->attributes[
'link']->nodeValue;
3851 preg_match(
'!/e-collections/(.*)/e-services/!', $service_link, $m);
3852 $this[
'collection_id'] = $m[1];
3860 $curr_offset += 100;
3861 }
while ($retrieved == 100);
3877 $ret =
$grima->getElectronicPortfoliosForService($this[
'collection_id'], $this[
'service_id'], $limit, $offset);
3878 $xpath =
new DOMXpath($ret);
3879 $ports = $xpath->query(
'//portfolio');
3880 foreach ($ports as $portnode) {
3882 $newport->loadFromPortfolioListNode($portnode);
3883 $this->portfolios[] = $newport;
3885 return count($ports);
3900 foreach ($this->portfolios as $portfolio) {
3901 $portfolio->deleteFromAlma($bib_treat);
3903 $this->portfolios = array();
3942 'portfolio_id' =>
'//portfolio/id',
3943 'is_local' =>
'//is_local',
3944 'is_standalone' =>
'//is_standalone',
3945 'mms_id' =>
'//mms_id',
3946 'title' =>
'//title',
3947 'service' =>
'//service',
3949 'static_url' =>
'//static_url',
3950 'availability' =>
'//availability',
3951 'collection_id' =>
'//electronic_collection/id',
3952 'service_id' =>
'//electronic_collection/service',
3953 'material_type' =>
'//material_type',
3954 'url_type' =>
'//url_type',
3955 'public_note' =>
'//public_note',
3956 'proxy_enabled' =>
'//proxy_enabled',
3957 'proxy' =>
'//proxy',
3958 'library' =>
'//library',
3959 'po_line' =>
'//po_line'
3973 $ret =
$grima->postElectronicPortfolio($collection_id, $service_id, $this->xml);
3989 $ret =
$grima->postElectronicPortfolioOnBib($mms_id, $this->xml);
4003 $this->xml =
$grima->getElectronicPortfolio(
'X',
'X', $portfolio_id);
4009 $this->xml =
$grima->getElectronicPortfolio(
'X',
'X', $portfolio_id);
4021 $this->xml =
new DomDocument();
4022 $this->xml->appendChild($this->xml->importNode($node,
true));
4033 $this->xml =
$grima->putElectronicPortfolioOnBib($this[
'mms_id'], $this[
'portfolio_id'], $this->xml);
4047 $mms_id = $this[
'mms_id'];
4048 $grima->deleteElectronicPortfolio(
4050 $this[
'portfolio_id']
4052 if ($bib_treat ==
"delete") {
4054 $bib->loadFromAlma($mms_id);
4056 if (! $bib->hasInventory()) {
4057 if ($bib->linkedToCZ()) {
4058 print
"LINKED TO CZ";
4059 $bib->unlinkFromCZ();
4062 $bib->deleteFromAlma();
4075 $this[
'availability'] = 11;
4085 $this[
'availability'] = 10;
4113 'set_id' =>
'//set/id',
4115 'name' =>
'//set/name',
4116 'description' =>
'//set/description',
4117 'type' =>
'//set/type',
4118 'content' =>
'//content',
4119 'private' =>
'//private',
4120 'status' =>
'//status',
4121 'status_date' =>
'//status_date',
4123 'created_by' =>
'//created_by',
4124 'created_date' =>
'//created_date',
4125 'query' =>
'//query',
4126 'number_of_members' =>
'//number_of_members',
4127 'additional_info' =>
'//additional_info',
4138 $this->xml =
$grima->postSet($this->xml);
4151 $this->xml =
$grima->getSet($set_id);
4165 $this->xml =
$grima->createSetFromImport($job_id, $population);
4177 function runOnElements($function, $args = array(), $filter =
null, $filter_args = array())
4180 $xml =
$grima->getSetMembers($this[
'set_id'], 0);
4181 $xpath =
new DomXpath(
$xml);
4182 $this->size = $xpath->query(
"//members")->item(0)->getAttribute(
"total_record_count");
4183 $limit = $this->size;
4184 for ($j = 0; $j < ceil($limit/100); $j++) {
4185 $xml =
$grima->getSetMembers($this[
'id'], 100, $j*100);
4186 $xpath =
new DomXpath(
$xml);
4187 foreach ($xpath->query(
"//member") as $member) {
4188 $id = $member->childNodes[0]->nodeValue;
4189 if (!isset($filter) or ($filter($id, $filter_args))) {
4190 $function($id, $args);
4204 $xml =
$grima->getSetMembers($this[
'set_id'], 0);
4205 $xpath =
new DomXpath(
$xml);
4206 $this->size = $xpath->query(
"//members")->item(0)->getAttribute(
"total_record_count");
4207 $limit = $this->size;
4210 for ($j = 0; $j < ceil($limit/100); $j++) {
4211 $xml =
$grima->getSetMembers($this[
'id'], 100, $j*100);
4212 $xpath =
new DomXpath(
$xml);
4213 foreach ($xpath->query(
"//member") as $member) {
4215 $member->childNodes[0]->nodeValue,
4216 $member->childNodes[1]->nodeValue
4229 $grima->deleteSet($this[
'set_id']);
4241 $frag =
"<member><id>$id</id></member>";
4242 $source =
new DOMDocument();
4243 $source->loadXML($frag);
4245 $xpath =
new DomXpath($this->xml);
4246 $members = $xpath->query(
'//members')->item(0);
4247 $members->appendChild($this->xml->importNode($source->documentElement,
true));
4261 $grima->postSetManageMembers(
4262 $this[
'set_id'],
null,
'add_members',
4275 $emptyset =
new Set();
4276 $emptyset->addMember(
'9941266686802636');
4277 $grima->postSetManageMembers(
4278 $this[
'set_id'],
null,
'replace_members',
4281 $grima->postSetManageMembers(
4282 $this[
'set_id'],
null,
'delete_members',
4321 'resource_sharing' =>
'//resource_sharing',
4333 $this->xml =
$grima->getLibrary($code);
4347 $xpath =
new DomXpath(
$xml);
4348 $codes = $xpath->query(
'//library/code');
4349 $libarray = array();
4350 foreach ($codes as $code) {
4352 $lib->loadFromAlma($code->nodeValue);
4370 $xpath =
new DomXpath(
$xml);
4371 $codes = $xpath->query(
'//library/code');
4373 foreach ($codes as $code) {
4374 if (! in_array($code, $otherthan)) {
4376 $lib->loadFromAlma($code);
4380 throw new Exception(
"No libraries found.");
4393 $xml =
$grima->getAllLocations($this[
'code']);
4394 $xpath =
new DomXpath(
$xml);
4395 $codes = $xpath->query(
'//location/code');
4396 $locarray = array();
4397 foreach ($codes as $code) {
4399 $loc->loadFromAlma($this[
'code'], $code->nodeValue);
4416 $xml =
$grima->getAllLocations($this[
'code']);
4417 $xpath =
new DomXpath(
$xml);
4418 $codes = $xpath->query(
'//location/code');
4419 foreach ($codes as $code) {
4420 if (! in_array($code->nodeValue, $otherthan)) {
4422 $loc->loadFromAlma($this[
'code'], $code->nodeValue);
4426 throw new Exception(
"No locations found.");
4443 $xpath =
new DomXpath(
$xml);
4444 $library_codes = $xpath->query(
'//library/code');
4446 foreach ($library_codes as $library_code) {
4448 $lib->loadFromAlma($library_code->nodeValue);
4450 foreach ($otherthan as $other) {
4451 if ($other[0] == $library_code->nodeValue) {
4456 $loc = $lib->getOneLocation($arr);
4458 }
catch (Exception $e) {
4462 throw new Exception(
"No suitable library/location found.");
4482 'external_name' =>
'//external_name',
4484 'remote_storage' =>
'//remote_storage',
4486 'suppress_from_publishing' =>
'//suppress_from_publishing',
4487 'fulfillment_unit' =>
'//fulfillment_unit',
4488 'accession_placement' =>
'//accession_placement',
4489 'call_number_type' =>
'//call_number_type',
4494 if (in_array($offset, $this->el_override_fields)) {
4495 $this->el_override[$offset] = $value;
4497 parent::offsetSet($offset, $value);
4517 $this->xml =
$grima->getLocation($libraryCode, $locationCode);
4518 $this[
'library_code'] = $libraryCode;
4535 'description' =>
'//description',
4537 'category' =>
'//category',
4538 'content' =>
'//content',
4539 'schedule' =>
'//schedule',
4540 'creator' =>
'//creator',
4541 'next_run' =>
'//next_run',
4542 'related_profile' =>
'//related_profile',
4543 'additional_info' =>
'//additional_info',
4555 $frag =
"<parameter><name>$name</name><value>$value</value></parameter>";
4556 $source =
new DOMDocument();
4557 $source->loadXML($frag);
4559 $xpath =
new DomXpath($this->xml);
4560 $members = $xpath->query(
'//parameters')->item(0);
4561 $members->appendChild($this->xml->importNode($source->documentElement,
true));
4574 $grima->postJob($this[
'id'],
'run', $this->xml);
4600 function runReport($filter_params = array(), $limit = -1, $token =
"")
4603 if (isset($this->filter)) {
4605 foreach ($filter_params as $k => $v) {
4606 $passfilter = str_replace(
'{'.$k.
'}', urlencode($v), $passfilter);
4612 if ($limit == -1) { $limit = 1000;
4614 if ($limit < 25) { $limit = 25;
4616 $this->reportXml =
$grima->getAnalytics($this->path, $passfilter, $limit, $token);
4618 $xpath =
new DomXpath($this->reportXml);
4619 $xpath->registerNamespace(
"x",
"urn:schemas-microsoft-com:xml-analysis:rowset");
4621 $rows = $xpath->query(
'//x:Row');
4622 foreach (
$rows as $row) {
4624 $cols = $xpath->query(
"./*[contains(name(),'Column')]", $row);
4625 foreach ($cols as $col) {
4626 $newrow[] = $col->nodeValue;
4628 $this->rows[] = $newrow;
4644 $table_esc =
"\"" . preg_replace(
"/\"/",
"\"\"", $table) .
"\"";
4646 $result = $pdo->query(
"SELECT 1 FROM $table_esc LIMIT 1");
4647 }
catch (Exception $e) {
4652 return $result !==
false;
4662class GrimaDB implements ArrayAccess, IteratorAggregate
4676 if (
$db ===
'stateless') {
4679 $result =
$db->query(
'SELECT COUNT(*) as c FROM institutions');
4681 foreach ($result as $row) {
4682 if ($row[
'c']>0) {
return false;
4692 return $db ===
'stateless';
4702 if ($db_user && $db_pass) {
4703 self::$db =
new PDO($db_url, $db_user, $db_pass);
4705 self::$db =
new PDO($db_url);
4708 self::$db->exec(
"CREATE TABLE institutions ( institution VARCHAR(100) PRIMARY KEY, apikey VARCHAR(100), server VARCHAR(100) )");
4711 self::$db->exec(
"CREATE TABLE users ( institution VARCHAR(100), username VARCHAR(100), password VARCHAR(255), isAdmin INTEGER )");
4713 }
catch (Exception $e) {
4714 self::$db =
'stateless';
4722 return defined(
"PASSWORD_ARGON2I") ? constant(
"PASSWORD_ARGON2I") : PASSWORD_DEFAULT;
4730 if (
$db ===
'stateless') {
4733 $result =
$db->query(
'SELECT institution FROM institutions');
4734 foreach ($result as $row) {
4735 $ret[] = $row[
'institution'];
4737 }
catch (Exception $e) {
4744 return isset($this->info[$offset]);
4749 return isset($this->info[$offset]) ? $this->info[$offset] :
'';
4754 $this->info[$offset] = $value;
4759 unset($this->info[$offset]);
4764 return new ArrayIterator($this->info);
4781 if (
$db ===
'stateless') {
4782 throw new Exception(
"No database has been specified. Grima cannot add an institution until it knows where to add it.");
4784 $query =
$db->prepare(
'INSERT INTO institutions(institution,apikey,server) VALUES (:institution,:apikey,:server)');
4786 $errorCode =
$db->errorCode();
4787 $errorInfo =
$db->errorInfo();
4788 throw new Exception(
4789 "Could not even prepare to insert into institution database: [$errorCode] {$errorInfo[0]} {$errorInfo[2]}"
4792 $success = $query->execute(
4794 'institution' => $this[
'institution'],
4795 'apikey' => $this[
'apikey'],
4796 'server' => $this[
'server'],
4800 $errorCode = $query->errorCode();
4801 $errorInfo = $query->errorInfo();
4802 throw new Exception(
4803 "Could not insert into user database: [$errorCode] {$errorInfo[0]} {$errorInfo[2]}"
4821 foreach ($data as $key => $val) {
4827 public static function LookupUser($username, $institution =
'', $password =
false)
4830 if (
$db ===
'stateless') {
4833 $query =
$db->prepare(
4835 'FROM institutions NATURAL JOIN users '.
4836 'WHERE institution=:institution '.
4837 'AND username=:username'
4839 $success = $query->execute(
4841 'institution' => $institution,
4842 'username' => $username,
4846 $row = $query->fetch(PDO::FETCH_ASSOC);
4847 if ($row===
false) {
return false;
4850 if (($password !==
false) && ($user[
'password']!=
'')) {
4851 if (!password_verify($password, $user[
'password'])) {
return false;
4853 if (password_needs_rehash($user[
'password'], $user->getPasswordAlgorithm())) {
4854 $user[
'password'] = $password;
4858 unset($user[
'password']);
4861 $errorCode = $query->errorCode();
4862 $errorInfo = $query->errorInfo();
4863 throw new Exception(
4864 "Could not select from user database: [$errorCode] {$errorInfo[0]} {$errorInfo[2]}"
4869 public static function RenameUser($username, $institution, $newusername)
4872 if (
$db ===
'stateless') {
4873 throw new Exception(
"No database has been specified. Grima cannot save changes to users if it does not where to save them.");
4875 $query =
$db->prepare(
4877 'SET username=:newusername ' .
4878 'WHERE institution=:institution '.
4879 'AND username=:username'
4881 $success = $query->execute(
4883 'institution' => $institution,
4884 'username' => $username,
4885 'newusername' => $newusername,
4891 $errorCode = $query->errorCode();
4892 $errorInfo = $query->errorInfo();
4893 throw new Exception(
4894 "Could not update user database: [$errorCode] {$errorInfo[0]} {$errorInfo[2]}"
4902 if (
$db ===
'stateless') {
4903 throw new Exception(
"No database specified. Grima cannot save changes to users if it doesn't know where to save them.");
4905 $query =
$db->prepare(
4907 'SET password=:password ' .
4908 'WHERE institution=:institution '.
4909 'AND username=:username'
4911 $passwordHash = password_hash($password, self::getPasswordAlgorithm());
4912 $success = $query->execute(
4914 'institution' => $institution,
4915 'username' => $username,
4916 'password' => $passwordHash,
4922 $errorCode = $query->errorCode();
4923 $errorInfo = $query->errorInfo();
4924 throw new Exception(
4925 "Could not update user database: [$errorCode] {$errorInfo[0]} {$errorInfo[2]}"
4932 if (!isset($_SESSION)) {
return false;
4941 if ($user !==
false) {
4942 $grima->sessionSave($user);
4951 $grima->sessionDestroy();
4957 if (
$db ===
'stateless') {
4958 throw new Exception(
"No database specified. Grima cannot add a user to the database, if it doesn't where to add it.");
4960 $query =
$db->prepare(
'INSERT INTO users( username, password, institution, isAdmin ) VALUES (:username, :password, :institution, :isAdmin)');
4962 $errorCode =
$db->errorCode();
4963 $errorInfo =
$db->errorInfo();
4964 throw new Exception(
4965 "Could not even prepare to insert into user database: [$errorCode] {$errorInfo[0]} {$errorInfo[2]}"
4968 $success = $query->execute(
4970 'username' => $this[
'username'],
4972 'institution' => $this[
'institution'],
4973 'isAdmin' => $this[
'isAdmin'],
4977 $errorCode = $query->errorCode();
4978 $errorInfo = $query->errorInfo();
4979 throw new Exception(
4980 "Could not insert into user database: [$errorCode] {$errorInfo[0]} {$errorInfo[2]}"
4988 if (
$db ===
'stateless') {
4989 throw new Exception(
"No database specified. Grima cannot save changes to users if it doesn't know where to save them.");
4991 $query =
$db->prepare(
'UPDATE users SET isAdmin=:isAdmin, password=:password WHERE username=:username AND institution=:institution');
4993 $errorCode =
$db->errorCode();
4994 $errorInfo =
$db->errorInfo();
4995 throw new Exception(
4996 "Could not even prepare to update user database: [$errorCode] {$errorInfo[0]} {$errorInfo[2]}"
4999 $success = $query->execute(
5001 'username' => $this[
'username'],
5003 'institution' => $this[
'institution'],
5004 'isAdmin' => $this[
'isAdmin'],
5008 $errorCode = $query->errorCode();
5009 $errorInfo = $query->errorInfo();
5010 throw new Exception(
5011 "Could not update user database: [$errorCode] {$errorInfo[0]} {$errorInfo[2]}"
5019 if (
$db ===
'stateless') {
5020 throw new Exception(
"No database specified. Grima cannot save changes to users if it doesn't know where to save them.");
5022 $query =
$db->prepare(
'DELETE FROM users WHERE username=:username AND institution=:institution');
5024 $errorCode =
$db->errorCode();
5025 $errorInfo =
$db->errorInfo();
5026 throw new Exception(
5027 "Could not even prepare to delete from user database: [$errorCode] {$errorInfo[0]} {$errorInfo[2]}"
5030 $success = $query->execute(
5032 'username' => $this[
'username'],
5033 'institution' => $this[
'institution'],
5037 $errorCode = $query->errorCode();
5038 $errorInfo = $query->errorInfo();
5039 throw new Exception(
5040 "Could not delete from user database: [$errorCode] {$errorInfo[0]} {$errorInfo[2]}"
5053implements SessionHandlerInterface
5063 $this->session_key = $key;
5064 $this->last_read =
"Not This";
5084 $params = session_get_cookie_params();
5085 $params[
'expires'] = time() - 42000;
5086 unset($params[
'lifetime']);
5087 setcookie($this->session_name,
'', $params);
5091 public function gc($maxlifetime)
5100 $nonce_ciphertext_b64 = isset($_COOKIE[$this->session_name]) ? $_COOKIE[
$this->session_name] :
"";
5101 if ($nonce_ciphertext_b64) {
5102 $nonce_ciphertext = base64_decode($nonce_ciphertext_b64);
5103 if (strlen($nonce_ciphertext)>24+16) {
5104 $nonce = substr($nonce_ciphertext, 0, 24);
5105 $ciphertext = substr($nonce_ciphertext, 24);
5106 $plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $this->session_key);
5108 $this->last_read = $plaintext;
5109 return $plaintext ?:
"";
5111 error_log(
"cookie too short: $nonce_ciphertext_b64");
5119 public function write($session_id, $session_data)
5122 if (!$session_data) {
return true;
5124 if ($this->last_read == $session_data) {
return true;
5126 $nonce = random_bytes(24);
5127 $ciphertext = sodium_crypto_secretbox($session_data, $nonce, $this->session_key);
5128 $nonce_ciphertext = $nonce.$ciphertext;
5129 $nonce_ciphertext_b64 = base64_encode($nonce_ciphertext);
5130 $options = session_get_cookie_params();
5131 if (isset($options[
'expires']) && $options[
'expires']) {
5132 $options[
'expires'] += time();
5134 unset($options[
'lifetime']);
5135 setcookie($this->session_name, $nonce_ciphertext_b64, $options);
Methods for fields and subfields in Alma's MARCXML.
appendField($tag, $ind1, $ind2, $subfields) ## XXX
add a field to the MARC record
getFields($tag)
get fields for the given MARC tag
addDataField($tag, $indicators, $subfields)
add a data field to the MARC record using Normac
getMarcFields($tag)
get fields for the given MARC tag
deleteFieldMatching($tag, $code, $regex)
delete fields with subfields matching a regex
deleteField($tag)
delete all $tag fields from the MARC record
addControlField($tag, $data)
add a data field to the MARC record using Normac
deleteSubfieldMatching($tag, $code, $regex)
delete subfields matching a regex
normacToXML()
convert normac fields back to XML
getSubfieldValues($tag, $code)
get subfield value
replaceOrAddSubfield($tag, $code, $value) ## XXX
replace or add subfield value in marc
Base class for objects returned from alma APIs (mostly just array access)
__construct()
create new blank Alma Object
offsetSet($offset, $value)
runReport($filter_params=array(), $limit=-1, $token="")
pull Analytics report from Alma
deleteFromAlma()
deletes the Bib from Alma
deleteAllPortfolios()
delete all portfolios from the bib
getHoldingsList()
populate holdingsList property with info from Alma
getItemList()
populates itemList property from Alma
getPortfolios()
get full portfolios for the bib
unlinkFromCZ()
does this work @XXX: Not supported for CZ
linkedToCZ()
is the bib linked to the community zone?
getHoldings()
populate holdings property with Holdings items
getLCCallNumber()
get LC call number, giving pref to 090 and later fields
get_title_proper()
a tidy title proper
addToAlma()
adds record as a new record to Alma, updates Bib with current Alma version
loadFromAlma($mms_id)
populates the bib with a record from Alma
static getMmsFromOCLC($oclc) # XXX
populates the MMS ID
offsetSet($offset, $value)
getPortfolioList()
populate portfolioList property with brief info from Alma
hasInventory()
populate holdings property with Holdings items
deleteTreeFromAlma()
deletes the Bib and its inventory #XXX
updateAlma()
replaces the Bib in Alma
getItems()
populate items property with Items objects ## XXX TEST
class ElectronicCollection
loadFromAlma($collection_id)
load record from Alma
getServices()
load record from Alma
updateAlma()
replace the collection record in Alma
class ElectronicPortfolio
loadFromAlma($portfolio_id)
populate portfolio with info from Alma
updateAlma()
replaces the Portfolio in Alma
addToAlmaBib($mms_id)
add portfolio to Bib in Alma @XXX: Insufficient permission
addToAlmaService($collection_id, $service_id)
populate item record from the information in an PortfolioList node @XXX: Insufficient permission
loadFromPortfolioListNode($node)
populate item record from the information in an PortfolioList node
deleteFromAlma($bib_treat="retain")
delete portfolio from Alma
deactivate()
deactivates the portfolio record
activate()
activates the portfolio record
loadFromAlmaX($portfolio_id)
loadFromAlma($collection_id, $service_id)
load record from Alma
deleteAllPortfolios($bib_treat)
delete all portfolios from the service
__construct()
create new blank Alma Object
getPortfolios($limit=10, $offset=0)
get list of portfolios from Alma
loadFromServiceListNode($node)
populate item record from the information in an ServiceList node
offsetSet($offset, $value)
open($save_path, $session_name)
write($session_id, $session_data)
Shared access to the database for GrimaUser and GrimaInstitution.
offsetSet($offset, $value)
This object lets grima store data in a catalog record.
setup()
create the record structure in Alma
offsetSet($offset, $value)
static exists()
checks whether a grima data store has been set up in Alma
destroy()
remove the grima data store from Alma
__construct()
make sure it exists
Interface to the GrimaDB database to retrieve API keys.
A thin wrapper around a message and urgency level.
__construct($type, $message)
The base class for most "grimas".
offsetSet($offset, $value)
addMessage($type, $message)
static call($grimaname, $args=array())
Interface to the GrimaDB database to check password and get institution's apikey.
static RenameUser($username, $institution, $newusername)
static LookupUser($username, $institution='', $password=false)
static LogoutCurrentUser()
static SetCurrentUser($username, $password, $institution='')
static ResetPassword($username, $institution, $password)
postJob($job_id, $op, $job)
Submit a manual or scheduled job.
getHoldingsList($mms_id)
Retrieve Holdings list - download brief descriptions of holdings for the bib.
put($url, $URLparams, $QSparams, $body)
general function for PUT (update) API calls
postElectronicPortfolioOnBib($mms_id, $portfolio, $update=true)
Create Electronic Portfolio - add a new portfolio to Alma Bib.
getElectronicCollection($collection_id)
Retrieve Electronic Collection - retrieve a collection record from Alma.
deleteBib($mms_id, $override='false')
Delete Bib Record - deletes the bib record from Alma.
getItemList($mms_id, $holding_id, $limit, $offset)
Retrieve Items list - retrieve the items list from a holding or bib from Alma.
sessionInit($force=false)
deleteSet($set_id)
Delete a Set - delete a set (not its items) from Alma.
getSet($set_id)
Retrieve a Set - retrieve a Set from Alma.
request($method, $url, $URLparams, $QSparams, $body=null)
general function for REST API calls
putElectronicCollection($collection_id, $collection)
Update Electronic Collection Record - updates the copy of the collection in Alma.
postHolding($mms_id, $holding)
Create holding record - add a new holdings record to a bib.
createSetFromImport($job_instance_id, $population)
Create a Set from an import job.
putBib($mms_id, $bib)
Update Bib Record - updates the copy of the bib in Alma.
postSetManageMembers($set_id, $id_type, $op, $set)
Manage Members - modify sets in Alma.
getElectronicPortfoliosForService($collection_id, $service_id, $limit, $offset)
Retrieve Portfolios - retrieve a list of portfolios from Alma.
getAllLocations($libraryCode)
Retrieve Locations - retrieve all locations in a library.
getSetMembers($set_id, $limit=10, $offset=0)
get the members of a set, IF IT WORKS?!?!
getBib($mms_id, $view='full', $expand='None')
Retrieve Bib - retrieve a bib record from Alma.
getAllLibraries()
Retrieve Libraries - retrieve all libraries.
getLibrary($libraryCode)
Retrieve a Library - retrieve a Library from Alma.
postItem($mms_id, $holding_id, $item)
Create Item - add a new item to a holding in Alma.
getItemBC($barcode)
Retrieve Item and print label information (by barcode))
post($url, $URLparams, $QSparams, $body)
general function for POST (create) API calls
deleteHolding($mms_id, $holding_id, $override='false')
Delete Holdings Record - delete the holdings record from Alma.
getElectronicPortfoliosForBib($mms_id, $limit, $offset)
Retrieve Portfolios list (Bib) - retrieve a list of portfolios from Alma.
getHolding($mms_id, $holding_id)
Retrieve Holdings Record - retrieve holdings record from Alma.
postBib($bib)
Create Record - adds a new bib record to Alma.
deleteElectronicPortfolio($collection_id, $service_id, $portfolio_id)
Delete Electronic Portfolio - delete portfolio from Alma.
getLocation($libraryCode, $locationCode)
Retrieve Location - retrieve a Library Location from Alma.
getElectronicServices($collection_id)
Retrieve Electronic Services - retrieve a list of services from a collection in Alma.
putElectronicPortfolioOnBib($mms_id, $portfolio_id, $portfolio)
Update Electronic Portfolio - update portfolio in Alma.
putHolding($mms_id, $holding_id, $holding)
Update Holdings Record - replace the holdings record in Alma.
checkForErrorMessage($xml)
checks for errorMessage tag, throws exceptions
putItem($mms_id, $holding_id, $item_pid, $item)
Update Item information - replace item record in Alma.
getItem($mms_id, $holding_id, $item_pid)
Retrieve Item and print label information.
deleteItem($mms_id, $holding_id, $item_pid, $override="false", $holdings="retain")
Withdraw Item - delete an item record from Alma.
getElectronicPortfolioFromBib($mms_id, $portfolio_id)
Retrieve Portfolio - retrieve a portfolio record from Alma.
postElectronicPortfolio($collection_id, $service_id, $portfolio)
Create Electronic Portfolio - add a new portfolio to Alma.
getAnalytics($path, $filter, $limit=25, $token=null)
getElectronicPortfolio($collection_id, $service_id, $portfolio_id)
Retrieve Portfolio - retrieve a portfolio record from Alma.
postSet($set)
Create a Set - add a new set to Alma.
addToAlmaBib($mms_id)
adds a new holding record to the specified bib
moveToBib($mms_id)
moves the holding from one bib to another – only for empty holdings!
static getMmsFromHoldingID($holding_id)
populates the MMS ID
deleteFieldMatching($tag, $code, $regex)
delete fields with subfields matching a regex
deleteFromAlma()
delete the holding record from Alma
getMethodOfAcquisition()
retrieves method of acquisition, fixed field 008/07 https://www.loc.gov/marc/holdings/hd008....
deleteSubfieldMatching($tag, $code, $regex)
delete subfields matching a regex
offsetSet($offset, $value)
updateAlma()
update holding record in Alma
setMethodOfAcquisition($code)
sets method of acquisition, fixed field 008/07 https://www.loc.gov/marc/holdings/hd008....
loadFromAlmaX($holding_id)
populates the record from Alma - only requires holding_id
getItemList()
populates itemList property from Alma
getLibraryCode()
retrieves library code from 852b
deleteTreeFromAlma()
delete the holding and all of its items
getMmsIfNeeded()
populates the MMS ID if not already known
getItems()
populate items property with Items objects ## XXX TEST
setCallNumber($h, $i, $ind1) # upgrade to normac
setLibraryCode($code)
sets library code from 852b
setLocationCode($code)
sets location code from 852c
getInstitutionCode()
retrieves institution code from 852a
loadFromAlma($mms_id, $holding_id)
populates the record from Alma
getLocationCode()
retrieves location code from 852c
setCallNumberType($ind1) # upgrade to normac
hasItems()
checks whether a holding record has any items
setInstitutionCode($code)
sets institution code from 852a
__construct($node, $mms_id)
__construct($mms_id=null)
__construct($mms_id, $holding_id, $limit=-1)
addToAlmaHolding($mms_id, $holding_id)
add new item record to holding in Alma
loadFromItemListNode($node)
populate item record from the information in an ItemList node
updateAlma()
replace item record in Alma
loadFromAlma($mms_id, $holding_id, $item_pid)
populates item record from Alma
addToAlmaHoldingX($holding_id)
add new item record to holding in Alma
fluff()
populates item record from Alma
loadFromAlmaBarcode($barcode)
populates item record from Alma, using barcode
loadFromAlmaBCorX($id)
populates item record from Alma using either identifier
loadFromAlmaX($item_pid)
populates item record from Alma, only needs item_pid
deleteFromAlma($override="false", $holdings="retain")
delete record from Alma
addParameter($name, $value)
add a parameter to the job
runInAlma()
run a job in Alma
static getOneLibraryLocation($otherthan=array())
get one library configured by the institution
static getOneLibrary($otherthan=array())
get one library configured by the institution
getAllLocations()
get all locations configured for the library
loadFromAlma($code)
populate library with info from Alma
static getAllLibraries()
get all libraries configured for the institution
getOneLocation($otherthan=array())
get one location configured for the library
loadFromAlma($libraryCode, $locationCode)
populate location with info from Alma
offsetSet($offset, $value)
__construct($id, $description)
createFromImport($job_id, $population)
create a new set in Alma based on a job that just ran
removeAllMembersInAlma()
remove all members of the set
runOnElements($function, $args=array(), $filter=null, $filter_args=array())
run a function on every element in the set
appendInAlma($setToAppend)
add elements to a set
loadFromAlma($set_id)
populate set with info from Alma
addMember($id)
add member to a local set
addToAlma()
adds Set to Alma, updates object with current Alma version
deleteFromAlma()
delete set from Alma
bib records returned from alma
tableExists($pdo, $table)
getenvWithFileFallbackAndDefault( $env_name, $default=false)
arrayToXml($array, &$xml)
appendInnerXML( $elt, $xmlString)