Completed
Push — master ( cfe99f...9a5934 )
by Dan Michael O.
02:13
created

Bib::load()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 3
nop 0
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Scriptotek\Alma\Bibs;
4
5
use Danmichaelo\QuiteSimpleXMLElement\QuiteSimpleXMLElement;
6
use Scriptotek\Alma\Client;
7
use Scriptotek\Alma\Exception\NoLinkedNetworkZoneRecordException;
8
use Scriptotek\Marc\Record as MarcRecord;
9
use Scriptotek\Sru\Record as SruRecord;
10
11
class Bib
12
{
13
    public $mms_id;
14
15
    /** @var Client */
16
    protected $client;
17
18
    /** @var QuiteSimpleXMLElement */
19
    protected $bib_data = null;
20
21
    /* @var MarcRecord */
22
    protected $marc_data = null;
23
24
    protected $_holdings = null;
25
26
    public function __construct(Client $client = null, $mms_id = null, MarcRecord $marc_data = null, QuiteSimpleXMLElement $bib_data = null)
27
    {
28
        $this->mms_id = $mms_id;
29
        $this->client = $client;
30
        $this->marc_data = $marc_data;
31
        $this->bib_data = $bib_data;
32
        $this->extractMarcDataFromBibData();
33
    }
34
35
    /**
36
     * Initialize from SRU record without having to fetch the Bib record.
37
     */
38
    public static function fromSruRecord(SruRecord $record, Client $client = null)
39
    {
40
        $record->data->registerXPathNamespace('marc', 'http://www.loc.gov/MARC21/slim');
41
        $marcRecord = MarcRecord::fromString($record->data->asXML());
42
43
        return new self($client, strval($marcRecord->id), $marcRecord);
44
    }
45
46
    /* Lazy load */
47
    protected function load()
48
    {
49
        if (!is_null($this->bib_data)) {
50
            return;  // we already have the data and won't re-fetch
51
        }
52
53
        $options = [];
54
        $this->bib_data = $this->client->getXML('/bibs/' . $this->mms_id, $options);
55
56
        $mms_id = $this->bib_data->text('mms_id');
57
        if ($mms_id != $this->mms_id) {
58
            throw new \ErrorException('Record mms_id ' . $mms_id . ' does not match requested mms_id ' . $this->mms_id . '.');
59
        }
60
61
        $this->extractMarcDataFromBibData();
62
    }
63
64
    /**
65
     * Extract and parse the MARC data in the <record> tag
66
     * as a MarcRecord object.
67
     */
68
    protected function extractMarcDataFromBibData()
69
    {
70
        if (is_null($this->bib_data)) {
71
            return;
72
        }
73
74
        $bibNode = $this->bib_data->el;
75
76
        // If we already have the MARC record (from SRU), we should not
77
        // overwrite it in case the user has made edits to it.
78
        if (is_null($this->marc_data)) {
79
            $this->marc_data = MarcRecord::fromString($bibNode->record->asXML());
80
        }
81
82
        $bibNode->record = null;
83
    }
84
85
    public function getHolding($holding_id)
86
    {
87
        return new Holding($this->client, $this->mms_id, $holding_id);
88
    }
89
90
    public function getHoldings()
91
    {
92
        if (is_null($this->_holdings)) {
93
            $this->_holdings = new Holdings($this->client, $this->mms_id);
94
        }
95
96
        return $this->_holdings;
97
    }
98
99
    public function save()
100
    {
101
        // If initialized from an SRU record, we need to fetch the
102
        // remaining parts of the Bib record.
103
        $this->load();
104
105
        // Inject the MARC record
106
        $marcXml = new QuiteSimpleXMLElement($this->marc_data->toXML('UTF-8', false, false));
107
        $this->bib_data->first('record')->replace($marcXml);
108
109
        // Serialize
110
        $newData = $this->bib_data->asXML();
111
112
        // Alma doesn't like namespaces
113
        $newData = str_replace(' xmlns="http://www.loc.gov/MARC21/slim"', '', $newData);
114
115
        return $this->client->putXML('/bibs/' . $this->mms_id, $newData);
116
    }
117
118
    public function getXml()
119
    {
120
        if (is_null($this->bib_data)) {
121
            $this->load();
122
        }
123
        return $this->bib_data->asXML();
124
    }
125
126
    public function getNzRecord()
127
    {
128
        // If initialized from an SRU record, we need to fetch the
129
        // remaining parts of the Bib record.
130
        $this->load();
131
132
        $nz_mms_id = $this->bib_data->text('linked_record_id[@type="NZ"]');
133
        if (!$nz_mms_id) {
134
            throw new NoLinkedNetworkZoneRecordException("Record $this->mms_id is not linked to a network zone record.");
135
        }
136
137
        return $this->client->nz->bibs->get($nz_mms_id);
138
    }
139
140
141
    /**
142
     * Returns the MARC record
143
     */
144
    public function getRecord()
145
    {
146
        if (is_null($this->marc_data)) {
147
            $this->load();
148
        }
149
150
        return $this->marc_data;
151
    }
152
153
    public function __get($key)
154
    {
155
        if ($key == 'record') {
156
            return $this->getRecord();
157
        }
158
        if ($key == 'holdings') {
159
            return $this->getHoldings();
160
        }
161
        $this->load();
162
        return $this->bib_data->text($key);
163
    }
164
}
165