Test Failed
Push — master ( c6b6d3...528954 )
by Dan Michael O.
03:21
created

Bib::extractMarcDataFromBibData()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 0
dl 0
loc 16
rs 9.7333
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\Alma\GhostModel;
9
use Scriptotek\Alma\GhostResource;
10
use Scriptotek\Marc\Record as MarcRecord;
11
use Scriptotek\Sru\Record as SruRecord;
12
13
class Bib extends GhostModel
14
{
15
    /** @var string */
16
    public $mms_id;
17
18
    /* @var Holdings */
19
    public $holdings;
20
21
    /* @var MarcRecord */
22
    protected $_marc;
23
24
    public function __construct(Client $client = null, $mms_id = null)
25
    {
26
        parent::__construct($client);
0 ignored issues
show
Bug introduced by
It seems like $client defined by parameter $client on line 24 can be null; however, Scriptotek\Alma\GhostModel::__construct() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
27
        $this->mms_id = $mms_id;
28
        $this->holdings = Holdings::make($this->client, $this);
29
    }
30
31
    /**
32
     * Load MARC record onto this Bib object. Chainable method.
33
     *
34
     * @param string $xml
35
     *
36
     * @return Bib
37
     */
38
    public function setMarcRecord($xml)
39
    {
40
        // Workaround for a long-standing API-bug
41
        $xml = str_replace('UTF-16', 'UTF-8', $xml);
42
43
        $this->_marc = MarcRecord::fromString($xml);
0 ignored issues
show
Documentation Bug introduced by
It seems like \Scriptotek\Marc\Record::fromString($xml) of type object<Scriptotek\Marc\Collection> is incompatible with the declared type object<Scriptotek\Marc\Record> of property $_marc.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
44
        // Note: do not marc as initialized, since we miss some other data from the Bib record. Oh, Alma :/
45
46
        return $this;
47
    }
48
49
    /**
50
     * Initialize from SRU record without having to fetch the Bib record.
51
     * @param SruRecord $record
52
     * @param Client|null $client
53
     * @return Bib
54
     */
55
    public static function fromSruRecord(SruRecord $record, Client $client = null)
56
    {
57
        $record->data->registerXPathNamespace('marc', 'http://www.loc.gov/MARC21/slim');
58
        $mmsId = $record->data->text('.//controlfield[@tag="001"]');
59
60
        return (new self($client, $mmsId))
61
            ->setMarcRecord($record->data->asXML());
62
    }
63
64
    public function getHoldings()
65
    {
66
        return $this->holdings;
67
    }
68
69
    public function save()
70
    {
71
        // If initialized from an SRU record, we need to fetch the
72
        // remaining parts of the Bib record.
73
        $this->init();
74
75
        // Serialize the MARC record
76
        $data = $this->_marc->toXML('UTF-8', false, false);
77
78
        // but wait, Alma hates namespaces, so we have to remove them...
79
        $data = str_replace(' xmlns="http://www.loc.gov/MARC21/slim"', '', $data);
80
81
        $this->data->anies = [$data];
82
83
        return $this->client->putJSON('/bibs/' . $this->mms_id, $data);
84
    }
85
86
    /**
87
     * Get the MMS ID of the linked record in network zone.
88
     */
89
    public function getNzMmsId()
90
    {
91
        // If initialized from an SRU record, we need to fetch the
92
        // remaining parts of the Bib record.
93
        $this->init();
94
95
        // @TODO: What if record is also linked to CZ? Probably an array is returned.
96
        $nz_mms_id = $this->data->linked_record_id->value;
97
        if (!$nz_mms_id) {
98
            throw new NoLinkedNetworkZoneRecordException("Record $this->mms_id is not linked to a network zone record.");
99
        }
100
101
        return $nz_mms_id;
102
    }
103
104
    /**
105
     * Get the Bib of the linked record in network zone.
106
     */
107
    public function getNzRecord()
108
    {
109
        return $this->client->nz->bibs->get($this->getNzMmsId());
110
    }
111
112
    /**
113
     * Returns the MARC record. Load it if we don't have it yet.
114
     */
115
    public function getRecord()
116
    {
117
        if (is_null($this->_marc)) {
118
            $this->init();
119
        }
120
        return $this->_marc;
121
    }
122
123
    /**
124
     * Store data onto object.
125
     *
126
     * @param \stdClass $data
127
     */
128
    protected function setData(\stdClass $data)
129
    {
130
        $this->setMarcRecord($data->anies[0]);
131
    }
132
133
    /**
134
     * Check if we have the full representation of our data object.
135
     *
136
     * @param \stdClass $data
137
     * @return boolean
138
     */
139
    protected function isInitialized($data)
140
    {
141
        return isset($data->anies);
142
    }
143
144
    /**
145
     * Generate the base URL for this resource.
146
     *
147
     * @return string
148
     */
149
    protected function urlBase()
150
    {
151
        return "/bibs/{$this->mms_id}";
152
    }
153
}
154