Skip to content

Commit 14d0925

Browse files
committed
refactor: Merge Collection and Records [BC]
- `Collection::fromOaiPmhResponse()` has been removed. Use `Collection::fromString()` instead. - `Collection::records` has been removed. Records are now available directly on the `Collection` class. - `Record::fromString` now throws a `RecordNotFound` exception rather than an `ErrorException` exception if no record was found.
1 parent 455d39d commit 14d0925

File tree

10 files changed

+157
-148
lines changed

10 files changed

+157
-148
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Binary MARC or XML (namespaced or not).
3030
use Scriptotek\Marc\Collection;
3131

3232
$collection = Collection::fromFile($someFileName);
33-
foreach ($collection->records as $record) {
33+
foreach ($collection as $record) {
3434
echo $record->getField('250')->getSubfield('a')->getData() . "\n";
3535
}
3636
```
@@ -47,8 +47,8 @@ $response = file_get_contents('http://lx2.loc.gov:210/lcdb?' . http_build_query(
4747
'query' => 'bath.isbn=0761532692',
4848
]));
4949

50-
$collection = Collection::fromString($response);
51-
foreach ($collection->records as $record) {
50+
$records = Collection::fromString($response);
51+
foreach ($records as $record) {
5252
...
5353
}
5454

src/Collection.php

Lines changed: 74 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,70 +3,114 @@
33
namespace Scriptotek\Marc;
44

55
use Scriptotek\Marc\Importers\Importer;
6-
use Scriptotek\Marc\Importers\XmlImporter;
7-
use Scriptotek\Marc\Importers\SruResponse;
86

9-
class Collection
7+
class Collection implements \Iterator
108
{
119
protected $parser;
1210
protected $_records;
11+
protected $useCache = false;
12+
protected $position = 0;
13+
protected $_current;
14+
15+
/**
16+
* Collection constructor.
17+
*
18+
* @param \File_MARC|\File_MARCXML $parser
19+
*/
20+
public function __construct($parser = null)
21+
{
22+
$this->parser = $parser;
23+
}
1324

25+
/**
26+
* Load records from a file (Binary MARC or XML).
27+
*
28+
* @param string $filename
29+
* @return Collection
30+
*/
1431
public static function fromFile($filename)
1532
{
16-
$importer = new Importer($filename, true);
33+
$importer = new Importer();
1734

18-
return $importer->getCollection();
35+
return $importer->fromFile($filename);
1936
}
2037

38+
/**
39+
* Load records from a string (Binary MARC or XML).
40+
*
41+
* @param string $data
42+
* @return Collection
43+
*/
2144
public static function fromString($data)
2245
{
23-
$importer = new Importer($data, false);
46+
$importer = new Importer();
2447

25-
return $importer->getCollection();
48+
return $importer->fromString($data);
2649
}
2750

28-
public static function fromOaiPmhResponse($data)
51+
/**
52+
* Returns an array representation of the collection.
53+
*
54+
* @return Collection[]
55+
*/
56+
public function toArray()
2957
{
30-
$importer = new XmlImporter($data);
31-
32-
return $importer->getCollection();
58+
return iterator_to_array($this);
3359
}
3460

35-
public static function fromSruResponse($data)
61+
/*********************************************************
62+
* Iterator
63+
*********************************************************/
64+
65+
public function valid()
3666
{
37-
$importer = new SruResponse($data);
67+
return !is_null($this->_current);
68+
}
3869

39-
return $importer->getCollection();
70+
public function current()
71+
{
72+
return $this->_current;
4073
}
4174

42-
public function __construct(\Factory $factory = null)
75+
public function key()
4376
{
44-
$this->factory = $factory ?: new Factory();
77+
return $this->position;
4578
}
4679

47-
public function parse($source, $isXml, $ns = '', $isPrefix = true)
80+
public function next()
4881
{
49-
if ($isXml) {
50-
$this->parser = $this->factory->make('File_MARCXML', $source, \File_MARCXML::SOURCE_STRING, $ns, $isPrefix);
82+
++$this->position;
83+
if ($this->useCache) {
84+
$rec = isset($this->_records[$this->position]) ? $this->_records[$this->position] : false;
5185
} else {
52-
$this->parser = $this->factory->make('File_MARC', $source, \File_MARC::SOURCE_STRING);
86+
$rec = isset($this->parser) ? $this->parser->next() : null;
87+
if ($rec) {
88+
$rec = new Record($rec);
89+
$this->_records[] = $rec;
90+
}
5391
}
92+
$this->_current = $rec ?: null;
5493
}
5594

56-
public function __get($key = '')
95+
public function rewind()
5796
{
58-
if ($key == 'records') {
59-
if (is_null($this->parser)) {
60-
$this->_records = new Records();
61-
}
62-
if (is_null($this->_records)) {
63-
$this->_records = new Records($this->parser);
64-
}
65-
66-
return $this->_records;
97+
$this->position = -1;
98+
if (is_null($this->_records)) {
99+
$this->_records = [];
100+
} else {
101+
$this->useCache = true;
67102
}
103+
$this->next();
68104
}
69105

106+
// public function count()
107+
// {
108+
// }
109+
110+
/*********************************************************
111+
* Magic
112+
*********************************************************/
113+
70114
public function __call($name, $arguments)
71115
{
72116
return call_user_func_array(array($this->parser, $name), $arguments);

src/Exceptions/RecordNotFound.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Scriptotek\Marc\Exceptions;
4+
5+
class RecordNotFound extends \RuntimeException
6+
{
7+
}

src/Importers/Importer.php

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,34 @@
22

33
namespace Scriptotek\Marc\Importers;
44

5+
use File_MARC;
56
use Scriptotek\Marc\Collection;
7+
use Scriptotek\Marc\Factory;
68

79
class Importer
810
{
9-
protected $data;
11+
public function __construct(Factory $factory = null)
12+
{
13+
$this->factory = isset($factory) ? $factory : new Factory();
14+
}
1015

11-
public function __construct($data, $isFile)
16+
public function fromFile($filename)
1217
{
13-
if ($isFile) {
14-
$data = file_get_contents($data);
15-
}
16-
$this->data = trim($data);
18+
$data = file_get_contents($filename);
19+
20+
return $this->fromString($data);
1721
}
1822

19-
public function getCollection()
23+
public function fromString($data)
2024
{
21-
$isXml = (substr($this->data, 0, 1) == '<');
25+
$isXml = (substr($data, 0, 1) == '<');
2226
if ($isXml) {
23-
$importer = new XmlImporter($this->data);
27+
$importer = new XmlImporter($data);
2428

2529
return $importer->getCollection();
2630
} else {
27-
$c = new Collection();
28-
$c->parse($this->data, false);
29-
30-
return $c;
31+
$parser = $this->factory->make('File_MARC', $data, File_MARC::SOURCE_STRING);
32+
return new Collection($parser);
3133
}
3234
}
3335
}

src/Importers/XmlImporter.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22

33
namespace Scriptotek\Marc\Importers;
44

5+
use File_MARCXML;
56
use Scriptotek\Marc\Collection;
67
use Scriptotek\Marc\Exceptions\XmlException;
8+
use Scriptotek\Marc\Factory;
79

810
class XmlImporter
911
{
12+
protected $factory;
1013
protected $source;
11-
protected $collection;
1214

13-
public function __construct($data, $ns = '', $isPrefix = false, Collection $collection = null)
15+
public function __construct($data, $ns = '', $isPrefix = false, $factory = null)
1416
{
15-
$this->collection = $collection ?: new Collection();
17+
$this->factory = isset($factory) ? $factory : new Factory();
1618

1719
if (strlen($data) < 256 && file_exists($data)) {
1820
$data = file_get_contents($data);
@@ -68,7 +70,7 @@ public function getCollection()
6870
{
6971
$records = $this->getRecords();
7072
if (!count($records)) {
71-
return $this->collection;
73+
return new Collection();
7274
}
7375

7476
list($prefix, $ns) = $this->getMarcNamespace($records[0]->getNamespaces(true));
@@ -98,8 +100,8 @@ public function getCollection()
98100
implode('', $records) .
99101
'</' . $pprefix . 'collection>';
100102

101-
$this->collection->parse($marcCollection, true, $prefix);
103+
$parser = $this->factory->make('File_MARCXML', $marcCollection, File_MARCXML::SOURCE_STRING, $prefix, true);
102104

103-
return $this->collection;
105+
return new Collection($parser);
104106
}
105107
}

src/Record.php

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,58 @@
22

33
namespace Scriptotek\Marc;
44

5+
use File_MARC_Record;
56
use File_MARC_Reference;
7+
use Scriptotek\Marc\Exceptions\RecordNotFound;
68

79
class Record
810
{
911
protected $record;
1012
protected $factory;
1113

12-
public function __construct(\File_MARC_Record $record, Factory $factory = null)
14+
/**
15+
* Record constructor.
16+
* @param File_MARC_Record $record
17+
* @param Factory|null $factory
18+
*/
19+
public function __construct(File_MARC_Record $record, Factory $factory = null)
1320
{
1421
$this->record = $record;
1522
$this->factory = $factory ?: new Factory();
1623
}
1724

25+
/**
26+
* Returns the first record found in the file $filename, or null if no records found.
27+
*
28+
* @param $filename
29+
* @return null|Collection
30+
*/
1831
public static function fromFile($filename)
1932
{
20-
$collection = Collection::fromFile($filename);
33+
$records = Collection::fromFile($filename)->toArray();
2134

22-
return $collection->records->toArray()[0];
35+
if (!count($records)) {
36+
throw new RecordNotFound();
37+
}
38+
39+
return $records[0];
2340
}
2441

42+
/**
43+
* Returns the first record found in the string $data, or null if no records found.
44+
*
45+
* @param $data
46+
* @return null|Collection
47+
*/
2548
public static function fromString($data)
2649
{
27-
$collection = Collection::fromString($data);
50+
$records = Collection::fromString($data)->toArray();
2851

29-
$recs = $collection->records->toArray();
30-
if (!count($recs)) {
31-
throw new \ErrorException('Record not found');
52+
if (!count($records)) {
53+
throw new RecordNotFound();
3254
}
3355

34-
return $recs[0];
56+
return $records[0];
3557
}
3658

3759
/*************************************************************************

0 commit comments

Comments
 (0)