Skip to content
Snippets Groups Projects
Commit 98d9506d authored by David Maus's avatar David Maus
Browse files

Adjust directory structure and coding style

parent 4076f763
No related branches found
No related tags found
No related merge requests found
Showing
with 507 additions and 1076 deletions
.build *~
dist \#*
.tmp .\#*
nbproject TAGS
review ChangeLog
vendor vendor
\#*# review
.#*# build
TAGS composer.phar
\ No newline at end of file composer.lock
test.php
syntax: glob
.build
.dist
nbproject
review
tmp
vendor
\#*#
.#*#
TAGS
\ No newline at end of file
<project name="local" default="help">
<target name="help">
<echo message="This component has no local build targets." />
</target>
</project>
<!-- vim: set tabstop=2 shiftwidth=2 expandtab: -->
project.name=PicaReader
project.channel=hab20.hab.de/service/pear
project.majorVersion=0
project.minorVersion=1
project.patchLevel=0
project.snapshot=true
component.type=php-library
component.version=11
This diff is collapsed.
{
"name": "hab/picareader",
"description": "Classes for reading Pica+ records encoded in Pica, PicaXML and PicaPlain",
"type": "library",
"license": "GPL-3.0+",
"authors": [
{
"name": "David Maus",
"email": "maus@hab.de",
"role": "Developer"
}
],
"support": {
"email": "maus@hab.de"
},
"repositories": [
{ "type": "vcs", "url": "http://github.com/dmj/PicaRecord"}
],
"require": {
"hab/picarecord": "dev-next"
},
"autoload": {
"psr-0": {
"HAB\\Pica": "src/"
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<package packagerversion="1.9.1" version="2.0"
xmlns="http://pear.php.net/dtd/package-2.0"
xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
http://pear.php.net/dtd/tasks-1.0.xsd
http://pear.php.net/dtd/package-2.0
http://pear.php.net/dtd/package-2.0.xsd">
<name>${project.name}</name>
<channel>${project.channel}</channel>
<summary>Classes for reading Pica+ records</summary>
<description>
This package provides classes for reading Pica+ records encoded in
PicaXML or PicaPlain.
</description>
<lead>
<name>David Maus</name>
<user>dmaus</user>
<email>maus@hab.de</email>
<active>yes</active>
</lead>
<date>${build.date}</date>
<time>${build.time}</time>
<version>
<release>${project.version}</release>
<api>${project.majorVersion}.${project.minorVersion}</api>
</version>
<stability>
<release>${project.stability}</release>
<api>stable</api>
</stability>
<license>GNU General Public License v3</license>
<notes>
No notes.
</notes>
<contents>
<dir baseinstalldir="/" name="/">
${contents}
</dir>
</contents>
<dependencies>
<required>
<php>
<min>5.3.0</min>
</php>
<pearinstaller>
<min>1.9.4</min>
</pearinstaller>
<package>
<name>Autoloader</name>
<channel>pear.phix-project.org</channel>
<min>3.0.0</min>
<max>3.999.9999</max>
</package>
<package>
<name>PicaRecord</name>
<channel>hab20.hab.de/service/pear</channel>
<min>0.1.0</min>
<max>0.999.9999</max>
</package>
</required>
</dependencies>
<phprelease />
<changelog>
<release>
<version>
<release>0.1.0</release>
<api>0.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2012-02-15</date>
<license>GNU General Public License v3</license>
<notes>
</notes>
</release>
</changelog>
</package>
<!-- vim: set tabstop=2 shiftwidth=2 expandtab: -->
<?xml version="1.0" encoding="utf-8"?>
<phpunit bootstrap="tests/bootstrap.php" strict="true">
<testsuites>
<testsuite name="Unit Tests">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
<filter>
<blacklist>
<directory suffix=".php">vendor</directory>
<directory suffix=".php">tests</directory>
</blacklist>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">bin</directory>
<directory suffix=".php">src</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="review/code-coverage"/>
</logging>
</phpunit>
<?xml version="1.0"?>
<phpunit bootstrap="src/tests/unit-tests/bootstrap.php">
<testsuites>
<testsuite name="Unit Tests">
<directory suffix="Test.php">src/tests/unit-tests</directory>
</testsuite>
</testsuites>
<filter>
<blacklist>
<directory suffix=".php">vendor</directory>
<directory suffix=".php">src/tests</directory>
</blacklist>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src/bin</directory>
<directory suffix=".php">src/php</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="review/code-coverage"/>
<log type="coverage-clover" target="review/logs/phpunit.xml"/>
<log type="json" target="review/logs/phpunit.json"/>
<log type="tap" target="review/logs/phpunit.tap"/>
<log type="junit" target="review/logs/phpunit-junit.xml"/>
<log type="testdox-html" target="review/testdox.html"/>
<log type="testdox-text" target="review/testdox.txt"/>
</logging>
</phpunit>
<!-- vim: set tabstop=4 shiftwidth=4 expandtab: -->
...@@ -20,31 +20,27 @@ ...@@ -20,31 +20,27 @@
* *
* @package PicaReader * @package PicaReader
* @author David Maus <maus@hab.de> * @author David Maus <maus@hab.de>
* @copyright Copyright (c) 2012 by Herzog August Bibliothek Wolfenbüttel * @copyright Copyright (c) 2012, 2013 by Herzog August Bibliothek Wolfenbüttel
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
*/ */
namespace HAB\Pica\Parser; namespace HAB\Pica\Parser;
/** use RuntimeException;
* Parser for Pica+ records encoded in PicaPlain.
*
* @package PicaReader
* @author David Maus <maus@hab.de>
* @copyright Copyright (c) 2012 by Herzog August Bibliothek Wolfenbüttel
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
*/
class PicaPlainParser class PicaPlainParser
{ {
/** /**
* Return array representation of the field encoded in a line. * Return array representation of the field encoded in a line.
* *
* @throws \RuntimeException Invalid characters in line * @throws RuntimeException Invalid characters in line
*
* @param string $line PicaPlain record line * @param string $line PicaPlain record line
* @return array Array representation of the encoded field * @return array
*/ */
public static function parseField ($line) { public static function parseField ($line)
{
$field = array('subfields' => array()); $field = array('subfields' => array());
$match = array(); $match = array();
if (preg_match('#^([012][0-9]{2}[A-Z@])(/([0-9]{2}))? (\$.*)$#Du', $line, $match)) { if (preg_match('#^([012][0-9]{2}[A-Z@])(/([0-9]{2}))? (\$.*)$#Du', $line, $match)) {
...@@ -52,7 +48,7 @@ class PicaPlainParser ...@@ -52,7 +48,7 @@ class PicaPlainParser
'occurrence' => $match[3] ?: null, 'occurrence' => $match[3] ?: null,
'subfields' => self::parseSubfields($match[4]));; 'subfields' => self::parseSubfields($match[4]));;
} else { } else {
throw new \RuntimeException("Invalid characters in PicaPlain record at line: {$line}"); throw new RuntimeException("Invalid characters in PicaPlain record at line: {$line}");
} }
return $field; return $field;
} }
...@@ -61,9 +57,10 @@ class PicaPlainParser ...@@ -61,9 +57,10 @@ class PicaPlainParser
* Return array of array representations of the subfields encode in argument. * Return array of array representations of the subfields encode in argument.
* *
* @param string $str Encoded subfields * @param string $str Encoded subfields
* @return array Array representions of the encoded subfields * @return array
*/ */
public static function parseSubfields ($str) { public static function parseSubfields ($str)
{
$subfields = array(); $subfields = array();
$subfield = null; $subfield = null;
$pos = 0; $pos = 0;
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* *
* @package PicaReader * @package PicaReader
* @author David Maus <maus@hab.de> * @author David Maus <maus@hab.de>
* @copyright Copyright (c) 2012 by Herzog August Bibliothek Wolfenbüttel * @copyright Copyright (c) 2012, 2013 by Herzog August Bibliothek Wolfenbüttel
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
*/ */
...@@ -28,70 +28,53 @@ namespace HAB\Pica\Reader; ...@@ -28,70 +28,53 @@ namespace HAB\Pica\Reader;
use HAB\Pica\Parser\PicaPlainParser; use HAB\Pica\Parser\PicaPlainParser;
/** class PicaPlainReader extends Reader
* Reader for Pica+ records encoded in PicaPlain. {
*
* @package PicaReader
* @author David Maus <maus@hab.de>
* @copyright Copyright (c) 2012 by Herzog August Bibliothek Wolfenbüttel
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
*/
class PicaPlainReader extends Reader {
/**
* Current input data.
*
* @var string
*/
protected $_data;
/** /**
* Open the reader with input data. * Current input data.
* *
* @param string $data Input data * @var string
* @return void */
*/ protected $_data;
public function open ($data) {
parent::open($data);
$this->_data = preg_split("/(?:\n\r|[\n\r])/", $data);
}
/** /**
* Read the next record in input data. * Open the reader with input data.
* *
* @see \HAB\Pica\Reader\Reader::next() * @param string $data Input data
* * @return void
* @return array|false Array representation of the record or FALSE if no more records */
*/ public function open ($data)
protected function next () { {
$record = false; parent::open($data);
if (current($this->_data) !== false) { $this->_data = preg_split("/(?:\n\r|[\n\r])/", $data);
$record = array('fields' => array());
do {
$line = current($this->_data);
$record['fields'] []= PicaPlainParser::parseField($line);
} while (next($this->_data));
next($this->_data);
} }
return $record;
}
/** /**
* Close the reader. * {@inheritDoc}
* */
* @return void protected function next ()
*/ {
public function close () { $record = false;
parent::close(); if (current($this->_data) !== false) {
$this->_data = null; $record = array('fields' => array());
} do {
$line = current($this->_data);
$record['fields'] []= PicaPlainParser::parseField($line);
} while (next($this->_data));
next($this->_data);
}
return $record;
}
/** /**
* Return the number of the line currently parsed. * Close the reader.
* *
* @return integer Number of currently parsed line * @return void
*/ */
protected function getCurrentLineNumber () { public function close ()
return key($this->_data); {
} parent::close();
$this->_data = null;
}
} }
<?php
/**
* The PicaXmlReader class file.
*
* This file is part of PicaReader.
*
* PicaReader is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PicaReader is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PicaReader. If not, see <http://www.gnu.org/licenses/>.
*
* @package PicaReader
* @author David Maus <maus@hab.de>
* @copyright Copyright (c) 2012 by Herzog August Bibliothek Wolfenbüttel
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
*/
namespace HAB\Pica\Reader;
use XMLReader;
class PicaXmlReader extends Reader
{
/**
* @var string XML namespace URI of PicaXML
*/
const PICAXML_NAMESPACE_URI = 'info:srw/schema/5/picaXML-v1.0';
/**
* @var XMLReader XML Reader instance
*/
private $_xmlReader;
/**
* Constructor.
*
* @return void
*/
public function __construct ()
{
parent::__construct();
$this->_xmlReader = new XMLReader();
}
/**
* Prepare the reader for reading data.
*
* @param string|resource $input
* @return void
*/
public function open ($input)
{
if (is_resource($input)) {
$input = stream_get_contents($input);
}
$this->_xmlReader->XML($input);
parent::open($input);
}
/**
* Close current input data.
*
* @return void
*/
public function close ()
{
$this->_xmlReader->close();
parent::close();
}
/**
* {@inheritDoc}
*/
protected function next ()
{
if ($this->forwardTo('record', self::PICAXML_NAMESPACE_URI)) {
$record = array('fields' => array());
while (!$this->atElementEnd('record', self::PICAXML_NAMESPACE_URI) && $this->_xmlReader->read()) {
if ($this->atElement('datafield', self::PICAXML_NAMESPACE_URI)) {
$record['fields'] []= $this->readField();
}
}
} else {
$record = false;
}
return $record;
}
/**
* Return array representation of datafield at cursor.
*
* The cursor is expected to be positioned on the opening field element.
*
* @return array
*/
protected function readField ()
{
$field = array('tag' => $this->_xmlReader->getAttribute('tag'),
'occurrence' => $this->_xmlReader->getAttribute('occurrence'),
'subfields' => array());
while (!$this->atElementEnd('datafield', self::PICAXML_NAMESPACE_URI) && $this->_xmlReader->read()) {
if ($this->atElement('subfield', self::PICAXML_NAMESPACE_URI)) {
$subfield = array('code' => $this->_xmlReader->getAttribute('code'), 'value' => '');
while (!$this->atElementEnd('subfield', self::PICAXML_NAMESPACE_URI) && $this->_xmlReader->read()) {
switch ($this->_xmlReader->nodeType) {
case XMLReader::TEXT:
case XMLReader::SIGNIFICANT_WHITESPACE:
case XMLReader::CDATA:
$subfield['value'] .= $this->_xmlReader->value;
break;
}
}
$field['subfields'] []= $subfield;
}
}
return $field;
}
/**
* Move cursor forward to named element.
*
* The cursor is not moved if it is already positioned at the named
* element. Returns true if cursor is at specified element and false if
* cursor reached the end of the document
*
* @param string $name Element local name
* @param string $uri Namespace URI
* @return boolean
*/
protected function forwardTo ($name, $uri)
{
while (!$this->atElement($name, $uri) && $this->_xmlReader->read()) { }
return ($this->_xmlReader->nodeType === XMLReader::ELEMENT);
}
/**
* Return true if the cursor is positioned at the named element.
*
* @param string $name Element local name
* @param string $uri Namespace URI
* @return boolean
*/
protected function atElement ($name, $uri)
{
return ($this->_xmlReader->nodeType === XMLReader::ELEMENT &&
$this->_xmlReader->localName === $name &&
$this->_xmlReader->namespaceURI === $uri);
}
/**
* Return TRUE if the cursor is positioned at the end of the named element.
*
* @param string $name Element local name
* @param string $uri Namespace URI
* @return boolean
*/
protected function atElementEnd ($name, $uri)
{
return ($this->_xmlReader->nodeType === XMLReader::END_ELEMENT &&
$this->_xmlReader->localName === $name &&
$this->_xmlReader->namespaceURI === $uri);
}
}
<?php
/**
* The Reader class file.
*
* This file is part of PicaReader.
*
* PicaReader is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PicaReader is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PicaReader. If not, see <http://www.gnu.org/licenses/>.
*
* @package PicaReader
* @author David Maus <maus@hab.de>
* @copyright Copyright (c) 2012, 2013 by Herzog August Bibliothek Wolfenbüttel
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
*/
namespace HAB\Pica\Reader;
use Exception;
use RuntimeException;
use HAB\Pica\Record\Record;
abstract class Reader
{
/**
* TRUE if the reader was opened with input data.
*
* @var boolean
*/
protected $_isOpen = false;
/**
* Filter function or NULL if none set.
*
* @see Reader::setFilter()
*
* @var callback|null
*/
protected $_filter = null;
/**
* Constructor.
*
* @return void
*/
public function __construct ()
{}
/**
* Open the reader with input data.
*
* @return void
*/
public function open ($data)
{
if ($this->isOpen()) {
$this->close();
}
$this->_isOpen = true;
}
/**
* Return next record in input data or FALSE if no more records.
*
* This function uses the Record::factory() method to create a record and
* applies a possible filter function to the input data.
*
* @see Reader::setFilter()
* @see Record::factory()
*
* @throws RuntimeException Error creating a record instance via factory function
* @return Record|false
*/
public function read ()
{
$record = $this->next();
if (is_array($record)) {
$record = $this->applyFilter($record);
if (is_array($record)) {
try {
return Record::factory($record);
} catch (Exception $e) {
throw new RuntimeException("Error creating record instance in Record::factory()", -1, $e);
}
}
}
return false;
}
/**
* Set a filter function.
*
* A filter function is every valid callback function that takes the array
* representation of a record as only argument and returns a possibly
* modifed array or false to skip the record.
*
* @param callback $filter Filter function
* @return array|false
*/
public function setFilter ($filter)
{
$this->_filter = $filter;
}
/**
* Return current filter function.
*
* @return callback|null
*/
public function getFilter ()
{
return $this->_filter;
}
/**
* Unset the filter function.
*
* @return void
*/
public function unsetFilter ()
{
$this->_filter = null;
}
/**
* Close the reader.
*
* @return void
*/
public function close ()
{
$this->_isOpen = false;
}
/**
* Return true if the reader is open.
*
* @return boolean
*/
public function isOpen ()
{
return $this->_isOpen;
}
/**
* Read the next record in input data.
*
* Returns array representation of the record or false if no more records.
*
* @return array|false
*/
abstract protected function next ();
/**
* Return filtered record.
*
* Applies the filter function to the array representation of a record.
*
* @param array $record Array representation of record
* @return array|false
*/
protected function applyFilter (array $record)
{
$filter = $this->getFilter();
if ($filter) {
return call_user_func($filter, $record);
} else {
return $record;
}
}
}
\ No newline at end of file
Your src/ folder
================
This src/ folder is where you put all of your code for release. There's
a folder for each type of file that the PEAR Installer supports. You can
find out more about these file types online at:
http://blog.stuartherbert.com/php/2011/04/04/explaining-file-roles/
* bin/
If you're creating any command-line tools, this is where you'd put
them. Files in here get installed into /usr/bin on Linux et al.
There is more information available here: http://blog.stuartherbert.com/php/2011/04/06/php-components-shipping-a-command-line-program/
You can find an example here: https://github.com/stuartherbert/phix/tree/master/src/bin
* data/
If you have any data files (any files that aren't PHP code, and which
don't belong in the www/ folder), this is the folder to put them in.
There is more information available here: http://blog.stuartherbert.com/php/2011/04/11/php-components-shipping-data-files-with-your-components/
You can find an example here: https://github.com/stuartherbert/ComponentManagerPhpLibrary/tree/master/src/data
* php/
This is where your component's PHP code belongs. Everything that goes
into this folder must be PSR0-compliant, so that it works with the
supplied autoloader.
There is more information available here: http://blog.stuartherbert.com/php/2011/04/05/php-components-shipping-reusable-php-code/
You can find an example here: https://github.com/stuartherbert/ContractLib/tree/master/src/php
* tests/functional-tests/
Right now, this folder is just a placeholder for future functionality.
You're welcome to make use of it yourself.
* tests/integration-tests/
Right now, this folder is just a placeholder for future functionality.
You're welcome to make use of it yourself.
* tests/unit-tests/
This is where all of your PHPUnit tests go.
It needs to contain _exactly_ the same folder structure as the src/php/
folder. For each of your PHP classes in src/php/, there should be a
corresponding test file in test/unit-tests.
There is more information available here: http://blog.stuartherbert.com/php/2011/08/15/php-components-shipping-unit-tests-with-your-component/
You can find an example here: https://github.com/stuartherbert/ContractLib/tree/master/test/unit-tests
* www/
This folder is for any files that should be published in a web server's
DocRoot folder.
It's quite unusual for components to put anything in this folder, but
it is there just in case.
There is more information available here: http://blog.stuartherbert.com/php/2011/08/16/php-components-shipping-web-pages-with-your-components/
<?php
/**
* The PicaXmlReader class file.
*
* This file is part of PicaReader.
*
* PicaReader is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PicaReader is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PicaReader. If not, see <http://www.gnu.org/licenses/>.
*
* @package PicaReader
* @author David Maus <maus@hab.de>
* @copyright Copyright (c) 2012 by Herzog August Bibliothek Wolfenbüttel
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
*/
namespace HAB\Pica\Reader;
use \XMLReader;
/**
* Reader for Pica+ records encoded in PicaXML.
*
* @package PicaReader
* @author David Maus <maus@hab.de>
* @copyright Copyright (c) 2012 by Herzog August Bibliothek Wolfenbüttel
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
*/
class PicaXmlReader extends Reader {
/**
* @var string XML namespace URI of PicaXML
*/
const PICAXML_NAMESPACE_URI = 'info:srw/schema/5/picaXML-v1.0';
/**
* @var \XMLReader XML Reader instance
*/
private $_xmlReader;
/**
* Constructor.
*
* @return void
*/
public function __construct () {
parent::__construct();
$this->_xmlReader = new XMLReader();
}
/**
* Prepare the reader for reading data.
*
* @param string $input Data to read
* @return void
*/
public function open ($input) {
$this->_xmlReader->XML($input);
parent::open($input);
}
/**
* Close current input data.
*
* @return void
*/
public function close () {
$this->_xmlReader->close();
parent::close();
}
/**
* Return the array representation of the next record in current input data.
*
* @see ReaderAbstract::next()
*
* @return array|false Record or false if there are no more records
*/
protected function next () {
if ($this->forwardTo('record', self::PICAXML_NAMESPACE_URI)) {
$record = array('fields' => array());
while (!$this->atElementEnd('record', self::PICAXML_NAMESPACE_URI) && $this->_xmlReader->read()) {
if ($this->atElement('datafield', self::PICAXML_NAMESPACE_URI)) {
$record['fields'] []= $this->readField();
}
}
} else {
$record = false;
}
return $record;
}
/**
* Return array representation of datafield at cursor.
*
* The cursor is expected to be positioned on the opening field element.
*
* @return array Field
*/
protected function readField () {
$field = array('tag' => $this->_xmlReader->getAttribute('tag'),
'occurrence' => $this->_xmlReader->getAttribute('occurrence'),
'subfields' => array());
while (!$this->atElementEnd('datafield', self::PICAXML_NAMESPACE_URI) && $this->_xmlReader->read()) {
if ($this->atElement('subfield', self::PICAXML_NAMESPACE_URI)) {
$subfield = array('code' => $this->_xmlReader->getAttribute('code'), 'value' => '');
while (!$this->atElementEnd('subfield', self::PICAXML_NAMESPACE_URI) && $this->_xmlReader->read()) {
switch ($this->_xmlReader->nodeType) {
case XMLReader::TEXT:
case XMLReader::SIGNIFICANT_WHITESPACE:
case XMLReader::CDATA:
$subfield['value'] .= $this->_xmlReader->value;
break;
}
}
$field['subfields'] []= $subfield;
}
}
return $field;
}
/**
* Move cursor forward to named element.
*
* The cursor is not moved if it is already positioned at the named element.
*
* @param string $name Element local name
* @param string $uri Namespace URI
* @return boolean TRUE if cursor is at specified element or FALSE if cursor
* reached the end of the document
*/
protected function forwardTo ($name, $uri) {
while (!$this->atElement($name, $uri) && $this->_xmlReader->read()) { }
return ($this->_xmlReader->nodeType === XMLReader::ELEMENT);
}
/**
* Return TRUE if the cursor is positioned at the named element.
*
* @param string $name Element local name
* @param string $uri Namespace URI
* @return boolean TRUE if the cursor is positioned at the element
*/
protected function atElement ($name, $uri) {
return ($this->_xmlReader->nodeType === XMLReader::ELEMENT &&
$this->_xmlReader->localName === $name &&
$this->_xmlReader->namespaceURI === $uri);
}
/**
* Return TRUE if the cursor is positioned at the end of the named element.
*
* @param string $name Element local name
* @param string $uri Namespace URI
* @return boolean TRUE if the cursor is positioned at the end of the named
* element
*/
protected function atElementEnd ($name, $uri) {
return ($this->_xmlReader->nodeType === XMLReader::END_ELEMENT &&
$this->_xmlReader->localName === $name &&
$this->_xmlReader->namespaceURI === $uri);
}
}
<?php
/**
* The Reader class file.
*
* This file is part of PicaReader.
*
* PicaReader is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PicaReader is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PicaReader. If not, see <http://www.gnu.org/licenses/>.
*
* @package PicaReader
* @author David Maus <maus@hab.de>
* @copyright Copyright (c) 2012 by Herzog August Bibliothek Wolfenbüttel
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
*/
namespace HAB\Pica\Reader;
/**
* Abstract base class of Pica+ readers.
*
* @package PicaReader
* @author David Maus <maus@hab.de>
* @copyright Copyright (c) 2012 by Herzog August Bibliothek Wolfenbüttel
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
*/
abstract class Reader {
/**
* TRUE if the reader was opened with input data.
*
* @var boolean
*/
protected $_isOpen = false;
/**
* Filter function or NULL if none set.
*
* @see Reader::setFilter()
*
* @var callback|null
*/
protected $_filter = null;
/**
* Constructor.
*
* @return void
*/
public function __construct () {
}
/**
* Open the reader with input data.
*
* @param string $data Input data
* @return void
*/
public function open ($data) {
if ($this->isOpen()) {
$this->close();
}
$this->_isOpen = true;
}
/**
* Return next record in input data or FALSE if no more records.
*
* This function uses the \HAB\Pica\Record\Record::factory() method to create a record and
* applies a possible filter function to the input data.
*
* @see \HAB\Pica\Reader\Reader::setFilter()
* @see \HAB\Pica\Record\Record::factory()
*
* @throws \RuntimeException Error creating a record instance via factory function
* @return \HAB\Pica\Record\Record|FALSE Next record in input data
*/
public function read () {
$record = $this->next();
if (is_array($record)) {
$record = $this->applyFilter($record);
if (is_array($record)) {
try {
return \HAB\Pica\Record\Record::factory($record);
} catch (\Exception $e) {
throw new \RuntimeException("Error creating record instance in Record::factory()", -1, $e);
}
}
}
return false;
}
/**
* Read the next record in input data.
*
* @return array|FALSE Array representation of the record or FALSE if no more records
*/
abstract protected function next ();
/**
* Return filtered record.
*
* Applies the filter function to the array representation of a record.
*
* @param array $record Array representation of record
* @return array|false Filtered record or FALSE to skip the record
*/
protected function applyFilter (array $record) {
$filter = $this->getFilter();
if ($filter) {
return call_user_func($filter, $record);
} else {
return $record;
}
}
/**
* Set a filter function.
*
* A filter function is every valid callback function that takes the array
* representation of a record as only argument and returns a possibly
* modifed array or FALSE to skip the record.
*
* @param callback $filter Filter function
* @return array|FALSE Filtered record or FALSE if the record should be skipped
*/
public function setFilter ($filter) {
$this->_filter = $filter;
}
/**
* Return current filter function.
*
* @return callback|NULL Current filter function or NULL if not set
*/
public function getFilter () {
return $this->_filter;
}
/**
* Unset the filter filter function.
*
* @return void
*/
public function unsetFilter () {
$this->_filter = null;
}
/**
* Close the reader.
*
* @return void
*/
public function close () {
$this->_isOpen = false;
}
/**
* Return TRUE if the reader is open.
*
* @return boolean TRUE if the reader is open
*/
public function isOpen () {
return $this->_isOpen;
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment