diff --git a/.gitignore b/.gitignore index be84e34068bb9670f050015236af1a43541532b7..ac1c8a85dfcc5e9c20388b08d394924bbb65fa17 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,8 @@ -.build -dist -.tmp -nbproject -review -vendor -\#*# -.#*# +*~ +\#* +.\#* TAGS +ChangeLog +vendor +review +build diff --git a/.hgignore b/.hgignore deleted file mode 100644 index ac0b76556e639b12349b9b2ef786c2b4d2cc2bee..0000000000000000000000000000000000000000 --- a/.hgignore +++ /dev/null @@ -1,11 +0,0 @@ -syntax: glob - -.build -.dist -nbproject -review -tmp -vendor -\#*# -.#*# -TAGS diff --git a/build.local.xml b/build.local.xml deleted file mode 100644 index 90aa3bc92e323653b9ef5c828f07c987d84dd494..0000000000000000000000000000000000000000 --- a/build.local.xml +++ /dev/null @@ -1,6 +0,0 @@ -<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: --> diff --git a/build.properties b/build.properties deleted file mode 100644 index 7385faba6784ea2621503dbab703463619c7b9a5..0000000000000000000000000000000000000000 --- a/build.properties +++ /dev/null @@ -1,9 +0,0 @@ -project.name=PicaRecord -project.channel=hab20.hab.de/service/pear -project.majorVersion=0 -project.minorVersion=4 -project.patchLevel=0 -project.snapshot=false - -component.type=php-library -component.version=11 diff --git a/build.xml b/build.xml deleted file mode 100644 index 7db58a021fe0dcc74706941ce1a5ad992b1b2adb..0000000000000000000000000000000000000000 --- a/build.xml +++ /dev/null @@ -1,500 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- build file for phing --> -<project default="help" basedir="." name="${project.name}"> - <!-- Human-readable info about our component --> - <property file="build.properties" /> - <taskdef name="now" classname="Phix_Project.ComponentManager.Phing.NowTask" /> - <now name="date.now"/> - <if> - <and> - <isset property="project.snapshot"/> - <istrue value="${project.snapshot}"/> - </and> - <then> - <property name="project.version" value="${project.majorVersion}.${project.minorVersion}.${project.patchLevel}snapshot${date.now}" /> - <property name="project.stability" value="snapshot" /> - </then> - <else> - <property name="project.version" value="${project.majorVersion}.${project.minorVersion}.${project.patchLevel}" /> - <property name="project.stability" value="stable" /> - </else> - </if> - <property name="project.apiversion" value="${project.majorVersion}.${project.minorVersion}" /> - - <!-- Paths to the directories that we work with --> - <property name="project.srcdir" value="${project.basedir}/src" override="true" /> - <property name="project.src.phpdir" value="${project.srcdir}/php" override="true" /> - <property name="project.src.bindir" value="${project.srcdir}/bin" override="true" /> - <property name="project.src.datadir" value="${project.srcdir}/data" override="true" /> - <property name="project.src.docdir" value="${project.srcdir}/docs" override="true" /> - <property name="project.src.testdir" value="${project.srcdir}/tests" override="true" /> - <property name="project.src.wwwdir" value="${project.srcdir}/www" override="true" /> - <property name="project.src.testunitdir" value="${project.src.testdir}/unit-tests" override="true" /> - <property name="project.src.testintdir" value="${project.src.testdir}/integration-tests" override="true" /> - <property name="project.src.testfuncdir" value="${project.src.testdir}/functional-tests" override="true" /> - - <property name="project.reviewdir" value="${project.basedir}/review" override="true" /> - <property name="project.review.logsdir" value="${project.basedir}/review/logs" override="true" /> - <property name="project.review.docsdir" value="${project.reviewdir}/docs" override="true" /> - <property name="project.review.codebrowserdir" value="${project.reviewdir}/code-browser" override="true" /> - <property name="project.review.codecoveragedir" value="${project.reviewdir}/code-coverage" override="true" /> - - <property name="project.builddir" value="${project.basedir}/.build" override="true" /> - <property name="project.pkgdir" value="${project.builddir}/${project.name}-${project.version}" override="true" /> - <property name="project.tmpdir" value="${project.basedir}/.tmp" override="true" /> - - <property name="project.vendordir" value="${project.basedir}/vendor" override="true" /> - <property name="project.vendor.bindir" value="${project.vendordir}/bin" override="true" /> - <property name="project.vendor.datadir" value="${project.vendordir}/data" override="true" /> - <property name="project.vendor.phpdir" value="${project.vendordir}/php" override="true" /> - <property name="project.vendor.testdir" value="${project.vendordir}/tests" override="true" /> - <property name="project.vendor.docdir" value="${project.vendordir}/docs" override="true" /> - <property name="project.vendor.wwwdir" value="${project.vendordir}/www" override="true" /> - - <property name="project.distdir" value="${project.basedir}/dist" /> - <property name="project.distdir.lastBuilt" value="${project.basedir}/dist/lastBuilt" /> - <property name="project.tarfilename" value="${project.name}-${project.version}.tgz" /> - <property name="project.tarfile" value="${project.distdir}/${project.tarfilename}" /> - - <!-- what was the last PEAR package we created, if any? --> - <if> - <available file="${project.distdir.lastBuilt}"/> - <then> - <property file="${project.distdir.lastBuilt}"/> - </then> - <else> - <property name="project.lastBuiltTarfile" value="false"/> - </else> - </if> - - <!-- override this if you want to run additional PEAR commands --> - <property name="pear.cmd" value="" override="true" /> - - <!-- lists of the files that make up our package --> - <fileset dir="${project.src.bindir}" id="binfiles"> - <include name="**/**"/> - <exclude name="**/.DS_Store"/> - <exclude name="**/.empty"/> - <exclude name="**/.svn"/> - </fileset> - <fileset dir="${project.src.datadir}" id="datafiles"> - <include name="**/**"/> - <exclude name="**/.DS_Store"/> - <exclude name="**/.empty"/> - <exclude name="**/.svn"/> - </fileset> - <fileset dir="${project.src.phpdir}" id="phpfiles"> - <include name="**/**"/> - <exclude name="**/.DS_Store"/> - <exclude name="**/.empty"/> - <exclude name="**/.svn"/> - </fileset> - <fileset dir="${project.src.testunitdir}/php" id="testfiles"> - <include name="**/**"/> - <exclude name="**/.DS_Store"/> - <exclude name="**/.empty"/> - <exclude name="**/.svn"/> - </fileset> - <fileset dir="${project.src.wwwdir}" id="wwwfiles"> - <include name="**/**" /> - <exclude name="**/.DS_Store"/> - <exclude name="**/.empty"/> - <exclude name="**/.svn"/> - </fileset> - <fileset dir="${project.src.docdir}" id="docfiles"> - <include name="**/**" /> - <exclude name="**/.DS_Store"/> - <exclude name="**/.empty"/> - <exclude name="**/.svn"/> - </fileset> - <fileset dir="${project.basedir}" id="topleveldocfiles"> - <include name="*.txt" /> - <include name="*.md" /> - </fileset> - - <taskdef name="phingcallifexists" classname="Phix_Project.ComponentManager.Phing.PhingCallIfExistsTask" /> - <import file="build.local.xml"/> - - <!-- Tell the user what this build file supports --> - <target name="help"> - <echo message="${project.name} ${project.version}: build.xml targets:" /> - <echo message="" /> - <echo message="Setup your dev environment:" /> - <echo message="" /> - <echo message=" build-vendor" /> - <echo message=" Populate vendor/ with this package's dependencies" /> - <echo message=" vendor-pear" /> - <echo message=" Run additional PEAR commands inside the vendor folder" /> - <echo message="" /> - <echo message="Develop your code:" /> - <echo message="" /> - <echo message=" lint" /> - <echo message=" Check the PHP files for syntax errors" /> - <echo message=" test" /> - <echo message=" Run the component's PHPUnit tests" /> - <echo message=" code-review" /> - <echo message=" Run all of the code quality targets:" /> - <echo message="" /> - <echo message=" code-browser" /> - <echo message=" Run code quality tests for PHP_CodeBrowser" /> - <echo message=" phpcpd" /> - <echo message=" Check for cut and paste problems" /> - <echo message=" phploc" /> - <echo message=" Calculate the size of your PHP project" /> - <echo message=" phpdoc" /> - <echo message=" Create the PHP docs from source code" /> - <echo message="" /> - <echo message="Publish your component:" /> - <echo message="" /> - <echo message=" pear-package" /> - <echo message=" Create a PEAR-compatible package" /> - <echo message=" publish-local" /> - <echo message=" Publish your PEAR-compatible package into a local copy" /> - <echo message=" of your PEAR channel" /> - <echo message=" install-vendor" /> - <echo message=" Install this component from source into vendor/" /> - <echo message=" install-system" /> - <echo message=" Install this component from source for all local users" /> - <echo message=" You must be root to run this target on Linux!!" /> - <echo message=""/> - <echo message="Maintain your component:"/> - <echo message=""/> - <echo message=" upgrade-skeleton"/> - <echo message=" Upgrade the skeleton files for this component"/> - <echo message=""/> - <echo message="Additional targets:" /> - <echo message=""/> - <echo message=" clean" /> - <echo message=" Remove all temporary folders created by this build file" /> - <echo message=" version" /> - <echo message=" Show this component's version from build.properties" /> - <echo message="" /> - <phingcallifexists target="local.help" /> - </target> - - <!-- Show the current version, as set in build.properties --> - <!-- This is just to be a time-saver --> - <target name="version"> - <echo message="${project.version}" /> - </target> - - <!-- Run PHP lint on all of the source code --> - <target name="lint"> - <phplint> - <fileset dir="${project.src.phpdir}"> - <include name="**/*.php" /> - </fileset> - </phplint> - <phingcallifexists target="local.lint" /> - </target> - - <!-- Run the unit tests for this module --> - <target name="run-unittests" depends="lint"> - <!-- Make sure vendor/ folder exists --> - <if> - <not> - <available file="${project.vendordir}" type="dir"/> - </not> - <then> - <phingcall target="build-vendor"/> - </then> - </if> - - <!-- do we have any tests? --> - <!-- currently cannot think of a reliable way to test this in phing --> - - <!-- run the tests --> - <delete dir="${project.review.codecoveragedir}" /> - <mkdir dir="${project.review.codecoveragedir}" /> - <mkdir dir="${project.review.logsdir}" /> - <exec command="phpunit" checkreturn="true" logoutput="true"/> - <echo/> - <echo>The code coverage report is in file://${project.review.codecoveragedir}</echo> - <echo/> - </target> - - <!-- Run all the tests for this module --> - <target name="test" depends="run-unittests"> - <phingcallifexists target="local.test"/> - </target> - - <!-- Run the code review quality tests --> - <target name="code-review" depends="run-unittests, code-browser, phpcpd, pdepend, phploc"> - <phingcallifexists target="local.code-review"/> - </target> - - <!-- Run all of the targets for setting up the code browser --> - <target name="code-browser" depends="phpmd, phpcs, phpcb"> - <phingcallifexists target="local.code-browser"/> - </target> - - <target name="pdepend"> - <mkdir dir="${project.review.logsdir}" /> - <exec command="pdepend --phpunit-xml=${project.review.logsdir}/pdepend.xml --jdepend-xml=${project.review.logsdir}/jdepend.xml --jdepend-chart=${project.review.logsdir}/dependencies.svg --overview-pyramid=${project.review.logsdir}/overview-pyramid.svg ${project.src.phpdir}" logoutput="true"/> - </target> - - <!-- Generate package docs --> - <target name="phpdoc"> - <mkdir dir="${project.review.logsdir}" /> - <exec command="phpdoc -d ${project.src.phpdir} -t ${project.review.docsdir}" logoutput="true"/> - <echo message="You will find the PHPDoc for your project at: ${project.review.docsdir}/index.html"/> - <phingcallifexists target="local.phpdoc"/> - </target> - - <!-- Check code for code smells --> - <target name="phpmd"> - <mkdir dir="${project.review.logsdir}" /> - <exec command="phpmd ${project.src.phpdir} xml codesize,design,naming,unusedcode --reportfile ${project.review.logsdir}/phpmd.xml" logoutput="true" /> - </target> - - <target name="phpcpd"> - <mkdir dir="${project.review.logsdir}"/> - <exec command="phpcpd --log-pmd ${project.review.logsdir}/pmd-cpd.xml ${project.src.phpdir}" logoutput="true" /> - </target> - - <!-- Check the code for style violations --> - <target name="phpcs"> - <mkdir dir="${project.review.logsdir}" /> - <exec command="phpcs --report=xml --report-file=${project.review.logsdir}/checkstyle.xml --standard=${checkstyle.standard} --extensions=php ${project.src.phpdir}" logoutput="true"/> - </target> - - <!-- Build the code-browser files --> - <target name="phpcb" depends="phpmd"> - <delete dir="${project.review.codebrowserdir}" /> - <mkdir dir="${project.review.codebrowserdir}" /> - <exec command="phpcb --log ${project.review.logsdir} --source ${project.src.phpdir} --output ${project.review.codebrowserdir}" logoutput="true" /> - </target> - - <!-- Work out the size of the project --> - <target name="phploc"> - <mkdir dir="${project.review.logsdir}" /> - <exec command="phploc --log-xml ${project.review.logsdir}/phploc.xml --log-csv ${project.review.logsdir}/phploc.csv ${project.src.phpdir}" logoutput="true" /> - </target> - - <!-- Populate vendor with the dependencies for this component --> - <target name="build-vendor" depends="pear-package,setup-vendor"> - <echo>Populating vendor/ with dependencies</echo> - <exec command="phix pear:register-channels" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config install --alldeps ${project.tarfile}" logoutput="true" checkreturn="true"/> - <echo/> - <echo>Your vendor/ folder has been built.</echo> - <echo>You only need to run 'phing build-vendor' again if you change the</echo> - <echo>dependencies listed in your package.xml file.</echo> - <echo/> - <phingcallifexists target="local.buildvendor"/> - </target> - - <!-- Setup the vendor folder --> - <target name="setup-vendor"> - <echo>Creating vendor/ as a sandboxed PEAR install folder</echo> - <delete dir="${project.vendordir}" /> - <mkdir dir="${project.vendordir}" /> - <delete dir="${project.tmpdir}" /> - <mkdir dir="${project.tmpdir}" /> - <exec command="pear config-create ${project.tmpdir} ${project.tmpdir}/pear-config" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set preferred_state alpha" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set php_dir ${project.vendor.phpdir}" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set bin_dir ${project.vendor.bindir}" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set data_dir ${project.vendor.datadir}" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set doc_dir ${project.vendor.docdir}" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set test_dir ${project.vendor.testdir}" checkreturn="true" logoutput="true" /> - <exec command="pear -c ${project.tmpdir}/pear-config config-set www_dir ${project.vendor.wwwdir}" checkreturn="true" logoutput="true" /> - </target> - - <!-- Create the PEAR package, ready for release --> - <target name="pear-package"> - <echo>Building release directory</echo> - <delete dir="${project.builddir}" /> - <mkdir dir="${project.pkgdir}" /> - <if> - <available file="${project.src.bindir}"/> - <then> - <copy todir="${project.pkgdir}"> - <fileset refid="binfiles"/> - </copy> - </then> - </if> - <if> - <available file="${project.src.datadir}"/> - <then> - <copy todir="${project.pkgdir}"> - <fileset refid="datafiles"/> - </copy> - </then> - </if> - <if> - <available file="${project.src.docdir}"/> - <then> - <copy todir="${project.pkgdir}"> - <fileset refid="docfiles"/> - </copy> - </then> - </if> - <if> - <available file="${project.src.phpdir}"/> - <then> - <copy todir="${project.pkgdir}"> - <fileset refid="phpfiles"/> - </copy> - </then> - </if> - <if> - <available file="${project.src.testunitdir}"/> - <then> - <copy todir="${project.pkgdir}"> - <fileset refid="testfiles"/> - </copy> - </then> - </if> - <if> - <available file="${project.src.wwwdir}"/> - <then> - <copy todir="${project.pkgdir}"> - <fileset refid="wwwfiles"/> - </copy> - </then> - </if> - <copy todir="${project.pkgdir}"> - <fileset refid="topleveldocfiles"/> - </copy> - <copy todir="${project.builddir}"> - <fileset dir="."> - <include name="package.xml" /> - </fileset> - </copy> - - <exec command="phix pear:expand-package-xml" checkreturn="yes" logoutput="yes"/> - - <echo>Creating ${project.tarfile} PEAR package</echo> - - <mkdir dir="${project.distdir}" /> - <delete file="${project.tarfile}" /> - <tar destfile="${project.tarfile}" compression="gzip"> - <fileset dir="${project.builddir}"> - <include name="**/**" /> - </fileset> - </tar> - - <!-- remember the tarball we have just build --> - <property name="project.lastBuiltTarfile" value="${project.tarfile}" override="true"/> - <echo file="${project.distdir.lastBuilt}" append="false">project.lastBuiltTarfile=${project.tarfile}</echo> - - <!-- write a message to say which file we built last --> - <echo>Your PEAR package is in ${project.tarfile}</echo> - <phingcallifexists target="local.pear-package"/> - </target> - - <!-- Install the code --> - <target name="install-vendor"> - <if> - <not> - <contains string="${project.lastBuiltTarfile}" substring="${project.name}"/> - </not> - <then> - <fail message="Please run 'phing pear-package' first, then try again."/> - </then> - </if> - - <if> - <not> - <available file="${project.vendordir"/> - </not> - <then> - <phingcall target="build-vendor" /> - </then> - </if> - - <if> - <available file="${project.lastBuiltTarfile}"/> - <then> - <exec command="pear -c ${project.tmpdir}/pear-config install --alldeps -f ${project.lastBuiltTarfile}" logoutput="true" checkreturn="true"/> - <phingcallifexists target="local.install-vendor"/> - </then> - <else> - <echo>Cannot find PEAR package file ${project.lastBuiltTarfile}</echo> - <fail message="Run 'phing pear-package' to create a new PEAR package, then try again."/> - </else> - </if> - </target> - - <!-- install a package system-wide --> - <target name="install-system"> - <if> - <not> - <contains string="${project.lastBuiltTarfile}" substring="${project.name}"/> - </not> - <then> - <echo>Please run 'phing pear-package' first, then try again.</echo> - </then> - <elseif> - <available file="${project.lastBuiltTarfile}"/> - <then> - <exec command="pear install -f -a ${project.lastBuiltTarfile}" checkreturn="true" logoutput="true" /> - <phingcallifexists target="local.install-system"/> - </then> - </elseif> - <else> - <echo>Cannot find PEAR package file ${project.lastBuiltTarfile}</echo> - <echo>Run 'phing pear-package' to create a new PEAR package, then try again</echo> - </else> - </if> - </target> - - <!-- Publish to local copy of PEAR channel --> - <target name="publish-local" depends="pear-package"> - <if> - <not> - <contains string="${project.lastBuiltTarfile}" substring="${project.name}"/> - </not> - <then> - <echo>Please run 'phing pear-package' first, then try again.</echo> - </then> - <elseif> - <available file="${project.lastBuiltTarfile}"/> - <then> - <!-- get rid of any existing snapshots we may have published --> - <foreach param="packagefile" absparam="abspackagefile" target="pirum-remove-package"> - <fileset dir="${pear.local}/get"> - <include name="${project.name}*snapshot*.tgz" /> - </fileset> - </foreach> - - <!-- publish the new PEAR package --> - <exec command="pirum add ${pear.local} ${project.lastBuiltTarfile}" checkreturn="true" logoutput="true" /> - <phingcallifexists target="local.publish-local"/> - </then> - </elseif> - <else> - <echo>Cannot find PEAR package file ${project.lastBuiltTarfile}</echo> - <echo>Run 'phing pear-package' to create a new PEAR package, then try again</echo> - </else> - </if> - </target> - - <target name="pirum-remove-package"> - <exec command="pirum remove ${pear.local} ${packagefile}" logoutput="true" checkreturn="true" /> - </target> - - <!-- Run additional PEAR commands in the vendor folder --> - <target name="vendor-pear"> - <exec command="pear -c ${project.tmpdir}/pear-config ${pear.cmd}" logoutput="true" checkreturn="true" /> - </target> - - <!-- Upgrade the skeleton files here and now --> - <target name="upgrade-skeleton"> - <exec command="phix ${component.type}:upgrade ." logoutput="true" checkreturn="true" /> - <phingcallifexists target="local.upgrade-skeleton"/> - </target> - - <!-- Clean up the mess --> - <target name="clean"> - <delete dir="${project.builddir}" /> - <delete dir="${project.distdir}" /> - <delete dir="${project.reviewdir}" /> - <delete dir="${project.pkgdir}" /> - <delete dir="${project.distdir}" /> - <delete dir="${project.tmpdir}" /> - <phingcallifexists target="local.clean"/> - </target> -</project> -<!-- vim: set tabstop=2 shiftwidth=2 expandtab: --> diff --git a/composer.json b/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..1e4072b39fd5d2e10fb71ac60349c53695e067ab --- /dev/null +++ b/composer.json @@ -0,0 +1,16 @@ +{ + "name": "hab/pica-record", + "description": "Object oriented interface to Pica+ records, fields, and subfields", + "type": "library", + "license": "GPL-3.0+", + "authors": [ + { + "name": "David Maus", + "email": "maus@hab.de", + "role": "Developer" + } + ], + "support": { + "email": "maus@hab.de" + } +} diff --git a/package.xml b/package.xml deleted file mode 100644 index 8e8d98e886d77cb8dc138c812d29fe6fb2d9dae3..0000000000000000000000000000000000000000 --- a/package.xml +++ /dev/null @@ -1,154 +0,0 @@ -<?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>Object oriented interface to Pica+ records</summary> - <description> - PicaRecord provides an object oriented interface to Pica+ records, fields, and subfields. - </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> - The PicaRecord package does not provide the means to read or write Pica+ records. In order to do so you need to install the packages PicaReader and PicaWriter that are available via this PEAR channel, too. - </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> - </required> - </dependencies> - <phprelease /> - <changelog> - <release> - <version> - <release>0.4.0</release> - <api>0.4</api> - </version> - <stability> - <release>stable</release> - <api>stable</api> - </stability> - <date>2013-01-10</date> - <license>GNU General Public License v3</license> - <notes> - * allow empty subfield values (031N $6) - </notes> - </release> - <release> - <version> - <release>0.3.2</release> - <api>0.3</api> - </version> - <stability> - <release>stable</release> - <api>stable</api> - </stability> - <date>2013-01-10</date> - <license>GNU General Public License v3</license> - <notes> - * remove hard dependency to Autoloader - </notes> - </release> - <release> - <version> - <release>0.3.1</release> - <api>0.3</api> - </version> - <stability> - <release>stable</release> - <api>stable</api> - </stability> - <date>2012-04-17</date> - <license>GNU General Public License v3</license> - <notes> - * fix getFields() with selector in NestedRecord - </notes> - </release> - <release> - <version> - <release>0.3.0</release> - <api>0.3</api> - </version> - <stability> - <release>stable</release> - <api>stable</api> - </stability> - <date>2012-03-05</date> - <license>GNU General Public License v3</license> - <notes> - * PicaRecord is now E_STRICT compliant - * add Record::getFirstMatchingField(), return first field matching a selector - * add Field::getNthSubfield(), return the nth subfield with a specified code - </notes> - </release> - <release> - <version> - <release>0.2.0</release> - <api>0.2</api> - </version> - <stability> - <release>stable</release> - <api>stable</api> - </stability> - <date>2012-02-17</date> - <license>GNU General Public License v3</license> - <notes> - * add Record::getMaximumOccurrenceOf(), return maximum occurrence value of field identified by tag - * fix the inline documentation - </notes> - </release> - <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> - Initial release. - </notes> - </release> - </changelog> -</package> -<!-- vim: set tabstop=2 shiftwidth=2 expandtab: --> diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000000000000000000000000000000000000..16d058a388443b5bc7d54508aa1c8321d6314561 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,21 @@ +<?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> diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 100644 index 864f7f7890b1ac293fb5de9ae2bf1c90824915d5..0000000000000000000000000000000000000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1,28 +0,0 @@ -<?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: --> diff --git a/src/.empty b/src/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/HAB/Pica/Record/AuthorityRecord.php b/src/HAB/Pica/Record/AuthorityRecord.php new file mode 100644 index 0000000000000000000000000000000000000000..a62980c12cf13ae2f897c11e18ea2985d7a75724 --- /dev/null +++ b/src/HAB/Pica/Record/AuthorityRecord.php @@ -0,0 +1,147 @@ +<?php + +/** + * Pica+ AuthorityRecord. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use InvalidArgumentException; + +class AuthorityRecord extends Record +{ + + /** + * Append a field to the record. + * + * @see Record::append() + * + * @throws InvalidArgumentException Field level other than 0 + * @throws InvalidArgumentException Field already in record + * + * @param Field $field Field to append + * @return void + */ + public function append (Field $field) + { + if ($field->getLevel() !== 0) { + throw new InvalidArgumentException("Invalid field level {$field->getLevel()}"); + } + return parent::append($field); + } + + /** + * Return the Pica production number (record identifier). + * + * @return string|null Pica production number or NULL if none exists + */ + public function getPPN () + { + $ppnField = $this->getFirstMatchingField('003@/00'); + if ($ppnField) { + $ppnSubfield = $ppnField->getNthSubfield('0', 0); + if ($ppnSubfield) { + return $ppnSubfield->getValue(); + } + } + return null; + } + + /** + * Set the Pica production number. + * + * Create a field 003@/00 if necessary. + * + * @param string $ppn Pica production number + * @return void + */ + public function setPPN ($ppn) + { + $ppnField = $this->getFirstMatchingField('003@/00'); + if ($ppnField) { + $ppnSubfield = $ppnField->getNthSubfield('0', 0); + if ($ppnSubfield) { + $ppnSubfield->setValue($ppn); + } else { + $ppnField->append(new Subfield('0', $ppn)); + } + } else { + $this->append(new Field('003@', 0, array(new Subfield('0', $ppn)))); + } + } + + /** + * Return TRUE if the record is valid. + * + * A valid authority record MUST have exactly one valid PPN field + * (003@/00$0) and exactly one type field (002@/0$0) with a type indicator + * `T'. + * + * @see AuthorityRecord::checkPPN(); + * @see AuthorityRecord::checkType(); + * + * @return boolean TRUE if the record is valid + */ + public function isValid () + { + return parent::isValid() && $this->checkPPN() && $this->checkType(); + } + + /** + * Return true if the record has exactly one PPN field (003@/00) with a + * subfield $0. + * + * @return boolean True if the record has a valid PPN field + */ + protected function checkPPN () + { + $ppnField = $this->getFields('003@/00'); + if (count($ppnField) === 1) { + $ppnSubfield = reset($ppnField)->getNthSubfield('0', 0); + if ($ppnSubfield) { + return true; + } + } + return false; + } + + /** + * Return true if the record has exactly one type field (002@/00) with a + * subfield $0 whose first character is `T'. + * + * @return boolean True if the record has a valid type field + */ + protected function checkType () + { + $typeField = $this->getFields('002@/00'); + if (count($typeField) === 1) { + $typeSubfield = reset($typeField)->getNthSubfield('0', 0); + if ($typeSubfield) { + $typeCode = $typeSubfield->getValue(); + if ($typeCode === 'T') { + return true; + } + } + } + } +} \ No newline at end of file diff --git a/src/HAB/Pica/Record/CopyRecord.php b/src/HAB/Pica/Record/CopyRecord.php new file mode 100644 index 0000000000000000000000000000000000000000..d90bbd18fe585c8ea6676ffbcb7d8ee3be2bcb5f --- /dev/null +++ b/src/HAB/Pica/Record/CopyRecord.php @@ -0,0 +1,170 @@ +<?php + +/** + * Pica+ CopyRecord. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use InvalidArgumentException; + +class CopyRecord extends Record +{ + + /** + * The item number. + * + * @var integer + */ + protected $_itemNumber; + + /** + * Append a field to the copy record. + * + * You can only append field of level 2 to a copy record. + * + * @see Record::append() + * + * @throws InvalidArgumentException Field level other than 2 + * @throws InvalidArgumentException Item number mismatch + * @throws InvalidArgumentException Field already in record + * + * @param Field $field Field to append + * @return void + */ + public function append (Field $field) + { + if ($field->getLevel() !== 2) { + throw new InvalidArgumentException("Invalid field level: {$field->getLevel()}"); + } + if ($this->getItemNumber() === null) { + $this->setItemNumber($field->getOccurrence()); + } + If ($field->getOccurrence() != $this->getItemNumber()) { + throw new InvalidArgumentException("Item number mismatch: {$this->getItemNumber()}, {$field->getOccurrence()}"); + } + return parent::append($field); + } + + /** + * Return the item number. + * + * @return integer|null Item number + */ + public function getItemNumber () + { + return $this->_itemNumber; + } + + /** + * Set the item number. + * + * @param integer $itemNumber Item number + * @return void + */ + protected function setItemNumber ($itemNumber) + { + $this->_itemNumber = (int)$itemNumber; + } + + /** + * Return the exemplar production number (EPN). + * + * @return string Exemplar production number + */ + public function getEPN () + { + $epnField = $this->getFirstMatchingField('203@'); + if ($epnField) { + $epnSubfield = $epnField->getNthSubfield('0', 0); + if ($epnSubfield) { + return $epnSubfield->getValue(); + } + } + return null; + } + + /** + * Set the exemplar production number (EPN). + * + * Create a field 203@ if necessary. + * + * @param string $epn Exemplar production number + * @return void + */ + public function setEPN ($epn) + { + $epnField = $this->getFirstMatchingField('203@'); + if ($epnField) { + $epnSubfield = $epnField->getNthSubfield('0', 0); + if ($epnSubfield) { + $epnSubfield->setValue($epn); + } else { + $epnField->append(new Subfield('0', $epn)); + } + } else { + $this->append(new Field('203@', $this->getItemNumber(), array(new Subfield('0', $epn)))); + } + } + + /** + * Set the containing local record. + * + * @param LocalRecord $record Local record + * @return void + */ + public function setLocalRecord (LocalRecord $record) + { + $this->unsetLocalRecord(); + if (!$record->containsCopyRecord($this)) { + $record->addCopyRecord($this); + } + $this->_parent = $record; + } + + /** + * Unset the containing local record. + * + * @return void + */ + public function unsetLocalRecord () + { + if ($this->_parent) { + if ($this->_parent->containsCopyRecord($this)) { + $this->_parent->removeCopyRecord($this); + } + $this->_parent = null; + } + } + + /** + * Return the containing local record. + * + * @return LocalRecord|null + */ + public function getLocalRecord () + { + return $this->_parent; + } + +} \ No newline at end of file diff --git a/src/HAB/Pica/Record/Field.php b/src/HAB/Pica/Record/Field.php new file mode 100644 index 0000000000000000000000000000000000000000..4e3f4b9e8ed5edd26dff52cee8dc4cffcb486d1b --- /dev/null +++ b/src/HAB/Pica/Record/Field.php @@ -0,0 +1,337 @@ +<?php + +/** + * Pica+ Field. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use InvalidArgumentException; + +class Field +{ + + /** + * Regular expression matching a valid Pica+ field tag. + * + * @var string + */ + const TAG_RE = '|^[012][0-9]{2}[A-Z@]$|D'; + + /** + * Return TRUE if argument is a valid field tag. + * + * @param mixed $arg Variable to check + * @return boolean TRUE if argument is a valid field tag + */ + public static function isValidFieldTag ($arg) + { + return (bool)preg_match(self::TAG_RE, $arg); + } + + /** + * Return TRUE if argument is a valid field occurrence. + * + * Argument is casted to int iff it is either null or a numeric string. + * + * @param mixed $arg Variable to check + * @return boolean TRUE if argument is a valid field occurrence + */ + public static function isValidFieldOccurrence ($arg) + { + if ($arg === null || ctype_digit($arg)) { + $arg = (int)$arg; + } + return is_int($arg) && $arg >= 0 && $arg < 100; + } + + /** + * Return predicate that matches a field shorthand against a regular + * expression. + * + * @param string $reBody Body of regular expression + * @return callback Predicate + */ + public static function match ($reBody) + { + if (strpos($reBody, '#') !== false) { + $reBody = str_replace('#', '\#', $reBody); + } + $regexp = "#{$reBody}#D"; + return function (Field $field) use ($regexp) { + return (bool)preg_match($regexp, $field->getShorthand()); + }; + } + + /** + * Return a new field based on its array representation. + * + * @throws InvalidArgumentException Missing `tag', `occurrene', or `subfields' index + * @param array $field Array representation of a field + * @return \HAB\Pica\Record\Field A shiny new field + */ + public static function factory (array $field) + { + foreach (array('tag', 'occurrence', 'subfields') as $index) { + if (!array_key_exists($index, $field)) { + throw new InvalidArgumentException("Missing '{$index}' index in field array"); + } + } + return new Field($field['tag'], + $field['occurrence'], + array_map(array('HAB\Pica\Record\Subfield', 'factory'), $field['subfields'])); + } + + /// + + /** + * The field tag. + * + * @var string + */ + protected $_tag; + + /** + * The field level. + * + * @var integer + */ + protected $_level; + + /** + * The field occurrence. + * + * @var integer + */ + protected $_occurrence; + + /** + * The field shorthand. + * + * @var string + */ + protected $_shorthand; + + /** + * Constructor. + * + * @throws InvalidArgumentException Invalid field tag or occurrence + * @param string $tag Field tag + * @param integer $occurrence Field occurrence + * @param array $subfields Initial set of subfields + * @return void + */ + public function __construct ($tag, $occurrence, array $subfields = array()) + { + if (!self::isValidFieldTag($tag)) { + throw new InvalidArgumentException("Invalid field tag: $tag"); + } + if (!self::isValidFieldOccurrence($occurrence)) { + throw new InvalidArgumentException("Invalid field occurrence: $occurrence"); + } + $this->_tag = $tag; + $this->_occurrence = (int)$occurrence; + $this->_shorthand = sprintf('%4s/%02d', $tag, $occurrence); + $this->_level = (int)$tag[0]; + $this->setSubfields($subfields); + } + + /** + * Set the field subfields. + * + * Replaces the subfield list with subfields in argument. + * + * @param array $subfields Subfields + * @return void + */ + public function setSubfields (array $subfields) + { + $this->_subfields = array(); + foreach ($subfields as $subfield) { + $this->addSubfield($subfield); + } + } + + /** + * Add a subfield to the end of the subfield list. + * + * @throws InvalidArgumentException Subfield already present in subfield list + * @param \HAB\Pica\Record\Subfield $subfield Subfield to add + * @return void + */ + public function addSubfield (\HAB\Pica\Record\Subfield $subfield) + { + if (in_array($subfield, $this->getSubfields(), true)) { + throw new InvalidArgumentException("Cannot add subfield: Subfield already part of the subfield list"); + } + $this->_subfields []= $subfield; + } + + /** + * Remove a subfield. + * + * @throws InvalidArgumentException Subfield is not part of the subfield list + * @param \HAB\Pica\Record\Subfield $subfield Subfield to delete + * @return void + */ + public function removeSubfield (\HAB\Pica\Record\Subfield $subfield) + { + $index = array_search($subfield, $this->_subfields, true); + if ($index === false) { + throw new InvalidArgumentException("Cannot remove subfield: Subfield not part of the subfield list"); + } + unset($this->_subfields[$index]); + } + + /** + * Return the field's subfields. + * + * Returns all subfields when called with no arguments. + * + * Otherwise the returned array is constructed as follows: + * + * Each argument is interpreted as a subfield code. The nth element of the + * returned array maps to the nth argument in the function call and contains + * NULL if the field does not have a subfield with the selected code, or the + * subfield if it exists. In order to retrieve multiple subfields with an + * identical code you repeat the subfield code in the argument list. + * + * @return array Subfields + */ + public function getSubfields () + { + if (func_num_args() === 0) { + return $this->_subfields; + } else { + $selected = array(); + $codes = array(); + $subfields = $this->getSubfields(); + array_walk($subfields, function ($value, $index) use (&$codes) { $codes[$index] = $value->getCode(); }); + foreach (func_get_args() as $arg) { + $index = array_search($arg, $codes, true); + if ($index === false) { + $selected []= null; + } else { + $selected []= $subfields[$index]; + unset($codes[$index]); + } + } + return $selected; + } + } + + /** + * Return the nth occurrence of a subfield with specified code. + * + * @param string $code Subfield code + * @param integer $n Zero-based subfield index + * @return \HAB\Pica\record\Subfield|null The requested subfield or NULL if + * none exists + */ + public function getNthSubfield ($code, $n) + { + $count = 0; + foreach ($this->getSubfields() as $subfield) { + if ($subfield->getCode() == $code) { + if ($count == $n) { + return $subfield; + } + $count++; + } + } + return null; + } + + /** + * Return the field tag. + * + * @return string Field tag + */ + public function getTag () + { + return $this->_tag; + } + + /** + * Return the field occurrence. + * + * @return integer Field occurrence + */ + public function getOccurrence () + { + return $this->_occurrence; + } + + /** + * Return the field level. + * + * @return integer Field level + */ + public function getLevel () { + return $this->_level; + } + + /** + * Return the field shorthand. + * + * @return string Field shorthand + */ + public function getShorthand () + { + return $this->_shorthand; + } + + /** + * Return TRUE if the field is empty. + * + * A field is empty if it contains no subfields. + * + * @return boolean TRUE if the field is empty + */ + public function isEmpty () + { + return empty($this->_subfields); + } + + /** + * Finalize the clone() operation. + * + * @return void + */ + public function __clone () + { + $this->_subfields = Helper::mapClone($this->_subfields); + } + + /** + * Return a printable representation of the field. + * + * The printable representation of a field is its shorthand. + * + * @return string Printable representation of the field + */ + public function __toString () + { + return $this->getShorthand(); + } +} \ No newline at end of file diff --git a/src/HAB/Pica/Record/Helper.php b/src/HAB/Pica/Record/Helper.php new file mode 100644 index 0000000000000000000000000000000000000000..4b9dcc3298f4b95ffc2303d4f4380af047989e78 --- /dev/null +++ b/src/HAB/Pica/Record/Helper.php @@ -0,0 +1,131 @@ +<?php + +/** + * Helper functions. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +abstract class Helper +{ + + /** + * Return the complement of a function. + * + * The complement of a function is a function that takes the same arguments + * as the original function but returns a boolean with the opposite truth + * value. + * + * @param callback $function Original function + * @return callback Complement function + */ + public static function complement ($function) + { + return function () use ($function) { return !call_user_func_array($function, func_get_args()); }; + } + + /** + * Return an array of the results of calling a method for each element of a + * sequence. + * + * @param array $sequence Sequence of objects + * @param string $method Name of the method + * @param array $arguments Optional array of method arguments + * @return array Result of calling method on each element of sequence + */ + public static function mapMethod (array $sequence, $method, array $arguments = array()) + { + if (empty($arguments)) { + $f = function ($element) use ($method) { + return $element->$method(); + }; + } else { + $f = function ($element) use ($method, $arguments) { + return call_user_func_array(array($element, $method), $arguments); + }; + } + return array_map($f, $sequence); + } + + /** + * Return an array with clones of each element in sequence. + * + * @param array $sequence Sequence of objects + * @return array Sequence of clones + */ + public static function mapClone (array $sequence) + { + return array_map(function ($element) { return clone($element); }, $sequence); + } + + /** + * Return TRUE if at leat one element of sequence matches predicate. + * + * @todo Make FALSE and TRUE self-evaluating, maybe + * + * @param array $sequence Sequence + * @param callback $predicate Predicate + * @return boolean TRUE if at least one element matches predicate + */ + public static function some (array $sequence, $predicate) + { + foreach ($sequence as $element) { + if (call_user_func($predicate, $element)) { + return true; + } + } + return false; + } + + /** + * Return TRUE if every element of sequence fullfills predicate. + * + * @todo Make FALSE and TRUE self-evaluating, maybe + * + * @param array $sequence Sequence + * @param callback $predicate Predicate + * @return boolean TRUE if every element fullfills predicate + */ + public static function every (array $sequence, $predicate) + { + foreach ($sequence as $element) { + if (!call_user_func($predicate, $element)) { + return false; + } + } + return true; + } + + /** + * Flatten sequence. + * + * @param array $sequence Sequence + * @return array Flattend sequence + */ + public static function flatten (array $sequence) + { + $flat = array(); + array_walk_recursive($sequence, function ($element) use (&$flat) { $flat []= $element; }); + return $flat; + } +} \ No newline at end of file diff --git a/src/HAB/Pica/Record/LocalRecord.php b/src/HAB/Pica/Record/LocalRecord.php new file mode 100644 index 0000000000000000000000000000000000000000..ca94ecd479033d01a42ea19f9fb1c2fa870cfdde --- /dev/null +++ b/src/HAB/Pica/Record/LocalRecord.php @@ -0,0 +1,196 @@ +<?php + +/** + * Pica+ LocalRecord. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use InvalidArgumentException; + +class LocalRecord extends NestedRecord +{ + + /** + * Append a field to the local record. + * + * You can only append field with a level of 0 to a local record. + * + * @see Record::append() + * + * @throws InvalidArgumentException Field level invalid + * @throws InvalidArgumentException Field already in record + * + * @param Field $field Field to add + * @return void + */ + public function append (Field $field) + { + if ($field->getLevel() !== 1) { + throw new InvalidArgumentException("Invalid field level: {$field->getLevel()}"); + } + parent::append($field); + } + + /** + * Add a copy record. + * + * @throws InvalidArgumentException Record already contains the copy record + * @throws InvalidArgumentException Record already contains a copy record with the same item number + * + * @param CopyRecord $record Copy record to add + * @return void + */ + public function addCopyRecord (CopyRecord $record) + { + if ($this->getCopyRecordByItemNumber($record->getItemNumber())) { + throw new InvalidArgumentException("Cannot add copy record: Copy record with item number {$record->getItemNumber()} already present"); + } + $this->addRecord($record); + $record->setLocalRecord($this); + } + + /** + * Remove a copy record. + * + * @param CopyRecord $record Record to remove + * @return void + */ + public function removeCopyRecord (CopyRecord $record) + { + $this->removeRecord($record); + $record->unsetLocalRecord(); + } + + /** + * Return copy record by item number. + * + * @param integer $itemNumber Item number + * @return CopyRecord|null The copy record or null if none exists + */ + public function getCopyRecordByItemNumber ($itemNumber) + { + foreach ($this->_records as $record) { + if ($record->getItemNumber() === $itemNumber) { + return $record; + } + } + return null; + } + + /** + * Return all copy records. + * + * @return array Copy records + */ + public function getCopyRecords () + { + return $this->_records; + } + + /** + * Return the ILN (internal library number) of the local record. + * + * @return integer|null ILN of the local record or NULL if none set + */ + public function getILN () + { + $ilnField = $this->getFirstMatchingField('101@/00'); + if ($ilnField) { + $ilnSubfield = $ilnField->getNthSubfield('a', 0); + if ($ilnSubfield) { + return $ilnSubfield->getValue(); + } + } + return null; + } + + /** + * Return true if local record contains the copy record. + * + * @param CopyRecord $record Copy record + * @return boolean + */ + public function containsCopyRecord (CopyRecord $record) + { + return $this->containsRecord($record); + } + + /** + * Set the containing title record. + * + * @param TitleRecord $record Title record + * @return void + */ + public function setTitleRecord (TitleRecord $record) + { + $this->unsetTitleRecord(); + if (!$record->containsLocalRecord($this)) { + $record->addLocalRecord($this); + } + $this->_parent = $record; + } + + /** + * Unset the containing title record. + * + * @return void + */ + public function unsetTitleRecord () + { + if ($this->_parent) { + if ($this->_parent->containsLocalRecord($this)) { + $this->_parent->removeLocalRecord($this); + } + $this->_parent = null; + } + } + + /** + * Return the containing local record. + * + * @return TitleRecord|null + */ + public function getTitleRecord () + { + return $this->_parent; + } + + /** + * Compare two copy records. + * + * Copyrecords are compared by their item number. + * + * @see CopyRecord::getItemNumber() + * @see NestedRecord::compareRecords() + * + * @param Record $a First copy record + * @param Record $b Second copy record + * @return integer Comparism value + */ + protected function compareRecords (Record $a, Record $b) + { + return $a->getItemNumber() - $b->getItemNumber(); + } + +} \ No newline at end of file diff --git a/src/HAB/Pica/Record/NestedRecord.php b/src/HAB/Pica/Record/NestedRecord.php new file mode 100644 index 0000000000000000000000000000000000000000..d7ea6b2db2e3650de75fad77a8577e183ad0a922 --- /dev/null +++ b/src/HAB/Pica/Record/NestedRecord.php @@ -0,0 +1,192 @@ +<?php + +/** + * Abstract base class of nested records. + * + * A nested record is a record that contains zero or more other records. It is + * the base class of {@link TitleRecord title} and {@link LocalRecord local} + * records and implements internal accessors for the contained records and the + * propagation of field getters to the contained records. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use InvalidArgumentException; + +abstract class NestedRecord extends Record +{ + + /** + * Contained records. + * + * @var array + */ + protected $_records = array(); + + /** + * Delete fields matching predicate. + * + * The delete() is propagated down to all contained records. + * + * @see Record::delete() + * + * @param callback $where Predicate + * @return void + */ + public function delete ($where) + { + parent::delete($where); + Helper::mapMethod($this->_records, 'delete', array($where)); + } + + /** + * Sort fields and contained records. + * + * The sort() is propagated down to all contained records. In addition the + * nested records are sorted themselves using the implementing class' + * compareNestedRecords() function. + * + * @see Record::sort() + * @see NestedRecord::compareNestedRecords() + * + * @return void + */ + public function sort () + { + parent::sort(); + Helper::mapMethod($this->_records, 'sort'); + usort($this->_records, array($this, 'compareRecords')); + } + + /** + * Return true if the record is empty. + * + * A nested record is empty iff it contains no fields and no non-empty + * contained record. + * + * @return boolean + */ + public function isEmpty () + { + return parent::isEmpty() && Helper::every($this->_records, function (Record $record) { return $record->isEmpty(); }); + } + + /** + * Return true if the record is valid. + * + * A nested record is valid iff it and all contained records are valid. + * + * @see Record::isValid() + * + * @return boolean + */ + public function isValid () + { + return parent::isValid() && !Helper::every($this->_records, function (Record $record) { return $record->isValid(); }); + } + + /** + * Return fields of the record. + * + * @see Record::getFields() + * + * @param string $selector Body of regular expression + * @return array Fields + */ + public function getFields ($selector = null) + { + if ($selector === null) { + return array_merge($this->_fields, Helper::flatten(Helper::mapMethod($this->_records, 'getFields'))); + } else { + return $this->select(Field::match($selector)); + } + } + + /** + * Compare two contained records and return a comparism value suitable for + * usort(). + * + * @see http://www.php.net/manual/en/function.usort.php + * + * @param Record $a First record + * @param Record $b Second record + * @return integer Comparism value + */ + abstract protected function compareRecords (Record $a, Record $b); + + /** + * Add a record as a contained record. + * + * @throws InvalidArgumentException Record already contains the record + * + * @param Record $record Record to add + * @return void + */ + protected function addRecord (Record $record) + { + if ($this->containsRecord($record)) { + throw new InvalidArgumentException("{$this} already contains {$record}"); + } + $this->_records []= $record; + } + + /** + * Remove a contained record. + * + * @throws InvalidArgumentException Record does not contain the record + * + * @param Record $record Record to remove + * @return void + */ + protected function removeRecord (Record $record) + { + $index = array_search($record, $this->_records, true); + if ($index === false) { + throw new InvalidArgumentException("{$this} does not contain {$record}"); + } + unset($this->_records[$index]); + } + + /** + * Return true if this record contains the requested record. + * + * @param \HAB\Pica\Record\Record Record to check + * @return boolean + */ + protected function containsRecord (Record $record) + { + return in_array($record, $this->_records, true); + } + + /** + * Finalize the clone() operation. + * + * Clone all contained records. + * + * @return void + */ + public function __clone () + { + $this->_records = Helper::mapClone($this->_records); + } +} \ No newline at end of file diff --git a/src/HAB/Pica/Record/Record.php b/src/HAB/Pica/Record/Record.php new file mode 100644 index 0000000000000000000000000000000000000000..bd44ed878bc210844226eaa3fd50421e573d81c3 --- /dev/null +++ b/src/HAB/Pica/Record/Record.php @@ -0,0 +1,286 @@ +<?php + +/** + * Abstract base class of all record structures. + * + * The abstract base class defines and partially implements the interface to + * all record structures. This class is the direct parent of records that do + * not contain other records, i.e. {@link AuthorityRecord authority} and + * {@link CopyRecord copy} records. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use InvalidArgumentException; + +abstract class Record +{ + + /** + * Return a new record based on its array representation. + * + * Returns either a {@link TitleRecord} or a {@link AuthorityRecord} + * depending on the field 002@ which encodes the record type. + * + * @throws InvalidArgumentException Missing type field + * @throws InvalidArgumentException Missing `fields' index + * + * @param array $record Array representation of a record + * @return TitleRecord|AuthorityRecord New record instance + */ + public static function factory (array $record) + { + if (!array_key_exists('fields', $record)) { + throw new InvalidArgumentException("Missing 'fields' index in record array"); + } + $fields = array_map(array('HAB\Pica\Record\Field', 'factory'), $record['fields']); + $type = null; + $typePredicate = Field::match('002@/00'); + foreach ($fields as $field) { + if ($typePredicate($field)) { + $typeSubfield = $field->getNthSubfield('0', 0); + if ($typeSubfield) { + $type = $typeSubfield->getValue(); + break; + } + } + } + if ($type === null) { + throw new InvalidArgumentException("Missing type field (002@/00$0)"); + } + if ($type[0] === 'T') { + return new AuthorityRecord($fields); + } else { + return new TitleRecord($fields); + } + } + + /// + + /** + * The record fields. + * + * @var array + */ + protected $_fields = array(); + + /** + * The containing parent record, if any. + * + * @var \HAB\Pica\Record + */ + protected $_parent; + + /** + * Constructor. + * + * @param array $fields Initial set of fields + * @return void + */ + public function __construct (array $fields = array()) + { + $this->setFields($fields); + } + + /** + * Return array of fields matching predicate. + * + * @param callback $where Predicate + * @return array Matching fields + */ + public function select ($where) + { + return array_filter($this->getFields(), $where); + } + + /** + * Delete fields matching predicate. + * + * @param callback $where Predicate + * @return void + */ + public function delete ($where) + { + $complement = Helper::complement($where); + $this->_fields = array_filter($this->_fields, $complement); + } + + /** + * Append a field to the record. + * + * @throws InvalidArgumentException Field already in record + * + * @param \HAB\Pica\Record\Field $field Field to append + * @return void + */ + public function append (Field $field) + { + if (in_array($field, $this->_fields, true)) { + throw new InvalidArgumentException("{$this} already contains {$field}"); + } + $this->_fields []= $field; + } + + /** + * Sort the fields of the record. + * + * Fields are sorted by their shorthand. + * + * @see \HAB\Pica\Record\Field::getShorthand() + * + * @return void + */ + public function sort () + { + usort($this->_fields, + function (Field $fieldA, Field $fieldB) { + return strcmp($fieldA->getShorthand(), $fieldB->getShorthand()); + }); + } + + /** + * Set the record fields. + * + * Removes the current set of fields and replaces it with the fields in + * argument. + * + * @param array $fields Fields + * @return void + */ + public function setFields (array $fields) + { + $this->_fields = array(); + foreach ($fields as $field) { + $this->append($field); + } + } + + /** + * Return the maximum occurrence value of a field. + * + * @throws InvalidArgumentException Invalid field tag + * + * @param string $tag Field tag + * @return int|null Maximum occurrence of field or NULL if field does not + * exist + */ + public function getMaximumOccurrenceOf ($tag) + { + if (!preg_match(Field::TAG_RE, $tag)) { + throw new InvalidArgumentException("Invalid field tag: {$tag}"); + } + return array_reduce($this->getFields($tag), + function ($maxOccurrence, Field $field) { + if ($field->getOccurrence() > $maxOccurrence || $maxOccurrence === null) { + return $field->getOccurrence(); + } else { + return $maxOccurrence; + } + }, null); + } + + /** + * Return TRUE if the record is empty. + * + * A record is empty if it contains no fields. + * + * @return boolean TRUE if record is empty + */ + public function isEmpty () + { + return empty($this->_fields); + } + + /** + * Return true if the record is valid. + * + * The base implementation checks that record is not empty and does not + * contain an empty field. + * + * @return boolean + */ + public function isValid () + { + return !$this->isEmpty() && !Helper::some($this->getFields(), function (Field $field) { return $field->isEmpty(); }); + } + + /** + * Return fields of the record. + * + * Optional argument $selector is the body of a regular expression. If set, + * this function returns only fields whose shorthand is matched by the + * regular expression. + * + * @see Field::match() + * + * @param string $selector Body of regular expression + * @return array Fields + */ + public function getFields ($selector = null) + { + if ($selector === null) { + return $this->_fields; + } else { + return $this->select(Field::match($selector)); + } + } + + /** + * Return the first field that matches a selector. + * + * @param string $selector Body of regular expression + * @return Field|null The first matching field or NULL if no match + */ + public function getFirstMatchingField ($selector) + { + $fields = $this->getFields($selector); + if (empty($fields)) { + return null; + } else { + return reset($fields); + } + } + + /** + * Finalize the clone() operation. + * + * @return void + */ + public function __clone () + { + $this->_fields = Helper::mapClone($this->_fields); + } + + /** + * Return a printable representation of the record. + * + * The printable representation of a record is the object hash prefixed by + * the class name. + * + * @return string Printable representation of the record + */ + public function __toString () + { + return get_class($this) . ':' . spl_object_hash($this); + } +} \ No newline at end of file diff --git a/src/HAB/Pica/Record/Subfield.php b/src/HAB/Pica/Record/Subfield.php new file mode 100644 index 0000000000000000000000000000000000000000..9edc7a0f85c8f842d225f86fa30af143def5ee13 --- /dev/null +++ b/src/HAB/Pica/Record/Subfield.php @@ -0,0 +1,146 @@ +<?php + +/** + * Pica+ subfield. + * + * A subfield is a cons of an alphanumeric character and a possibly empty + * string value. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use InvalidArgumentException; + +class Subfield +{ + + /** + * Return true if argument is a valid subfield code. + * + * @param mixed $arg Variable to check + * @return boolean + */ + public static function isValidSubfieldCode ($arg) + { + return (bool)preg_match('/^[a-z0-9]$/Di', $arg); + } + + /** + * Return a new subfield based on its array representation. + * + * The array representation of a subfield is an associative array with the + * keys `code' and `value', holding the subfield code and value. + * + * @throws InvalidArgumentException Missing code or value index + * + * @param array $subfield Array representation of a subfield + * @return Subfield New subfield + */ + public static function factory (array $subfield) + { + if (!array_key_exists('code', $subfield)) { + throw new InvalidArgumentException("Missing 'code' index in subfield array"); + } + if (!array_key_exists('value', $subfield)) { + throw new InvalidArgumentException("Missing 'value' index in subfield array"); + } + return new Subfield($subfield['code'], $subfield['value']); + } + + /// + + /** + * The subfield code. + * + * @var string + */ + protected $_code; + + /** + * The subfield value. + * + * @var string Value + */ + protected $_value; + + /** + * Constructor. + * + * @throws InvalidArgumentException Invalid subfield code + * + * @param string $code Subfield code + * @param string $value Subfield value + * @return void + */ + public function __construct ($code, $value) + { + if (!self::isValidSubfieldCode($code)) { + throw new InvalidArgumentException("Invalid subfield code: {$code}"); + } + $this->_code = $code; + $this->setValue($value); + } + + /** + * Set the subfield value. + * + * @param string $value Subfield value + * @return void + */ + public function setValue ($value) + { + $this->_value = $value; + } + + /** + * Return the subfield value. + * + * @return string Subfield value + */ + public function getValue () + { + return $this->_value; + } + + /** + * Return the subfield code. + * + * @return string Subfield code + */ + public function getCode () + { + return $this->_code; + } + + /** + * Return printable representation of the subfield. + * + * The printable representation of a subfield is its value. + * + * @return string Subfield value + */ + public function __toString () + { + return $this->getValue(); + } +} \ No newline at end of file diff --git a/src/HAB/Pica/Record/TitleRecord.php b/src/HAB/Pica/Record/TitleRecord.php new file mode 100644 index 0000000000000000000000000000000000000000..94660b1ff0d546aaedad8f7bac9c5d6679e02bce --- /dev/null +++ b/src/HAB/Pica/Record/TitleRecord.php @@ -0,0 +1,214 @@ +<?php + +/** + * Pica+ title record. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use InvalidArgumentException; + +class TitleRecord extends NestedRecord +{ + + /** + * Append a field to the title record. + * + * @see Record::append() + * + * You can only directly add fields with a level of 0. + * + * @throws InvalidArgumentException Field level invalid + * @throws InvalidArgumentException Field already in record + * + * @param Field $field Field to append + * @return void + */ + public function append (Field $field) + { + if ($field->getLevel() !== 0) { + throw new InvalidArgumentException("Invalid field level: {$field->getLevel()}"); + } + parent::append($field); + } + + /** + * Set the record's fields. + * + * @todo Relocate to \HAB\Pica\Record\Record::factory(), maybe + * + * @param array $fields Field + * @return void + */ + public function setFields (array $fields) + { + $this->_fields = array(); + $this->_records = array(); + $prevLevel = null; + foreach ($fields as $field) { + $level = $field->getLevel(); + if ($level === 0) { + $this->append($field); + } else { + if ($level === 1 && $prevLevel !== 1) { + $localRecord = new LocalRecord(array($field)); + $this->addLocalRecord($localRecord); + } else { + $records = $this->getLocalRecords(); + $localRecord = end($records); + if ($level === 1) { + $localRecord->append($field); + } else { + $copyRecord = $localRecord->getCopyRecordByItemNumber($field->getOccurrence()); + if ($copyRecord) { + $copyRecord->append($field); + } else { + $localRecord->addCopyRecord(new CopyRecord(array($field))); + } + } + } + } + $prevLevel = $level; + } + } + + /** + * Add a local record. + * + * @throws InvalidArgumentException Record already contains the local record + * + * @param LocalRecord $record Local record + * @return void + */ + public function addLocalRecord (LocalRecord $record) + { + $this->addRecord($record); + $record->setTitleRecord($this); + } + + /** + * Remove a local record. + * + * @param LocalRecord $record Local record to remove + * @return void + */ + public function removeLocalRecord (LocalRecord $record) + { + $this->removeRecord($record); + $record->unsetTitleRecord(); + } + + /** + * Return array of all local records. + * + * @return array Local records + */ + public function getLocalRecords () + { + return $this->_records; + } + + /** + * Return a local record identified by its ILN. + * + * @param integer $iln Intenal library number + * @return LocalRecord|null + */ + public function getLocalRecordByILN ($iln) + { + foreach ($this->getLocalRecords() as $localRecord) { + if ($localRecord->getILN() == $iln) { + return $localRecord; + } + } + return null; + } + + /** + * Return the Pica production number (record identifier). + * + * @return string|null + */ + public function getPPN () + { + $ppnField = $this->getFirstMatchingField('003@/00'); + if ($ppnField) { + $ppnSubfield = $ppnField->getNthSubfield('0', 0); + if ($ppnSubfield) { + return $ppnSubfield->getValue(); + } + } + return null; + } + + /** + * Set the Pica production number. + * + * Create a field 003@/00 if necessary. + * + * @param string $ppn Pica production number + * @return void + */ + public function setPPN ($ppn) + { + $ppnField = $this->getFirstMatchingField('003@/00'); + if ($ppnField) { + $ppnSubfield = $ppnField->getNthSubfield('0', 0); + if ($ppnSubfield) { + $ppnSubfield->setValue($ppn); + } else { + $ppnField->append(new Subfield('0', $ppn)); + } + } else { + $this->append(new Field('003@', 0, array(new Subfield('0', $ppn)))); + } + } + + /** + * Return true if title record contains the local record. + * + * @param LocalRecord $record Local record + * @return boolean + */ + public function containsLocalRecord (LocalRecord $record) + { + return $this->containsRecord($record); + } + + /** + * Compare two local records. + * + * @see NestedRecord::compareRecords() + * + * Local records are compared by their ILN. + * + * @param Record $a First record + * @param Record $b Second record + * @return Comparism value + */ + protected function compareRecords (Record $a, Record $b) + { + return $a->getILN() - $b->getILN(); + } + +} \ No newline at end of file diff --git a/src/README.txt b/src/README.txt deleted file mode 100644 index 4074f38738f3847625a1a7e521e392a80fde11cd..0000000000000000000000000000000000000000 --- a/src/README.txt +++ /dev/null @@ -1,68 +0,0 @@ -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/ diff --git a/src/bin/.empty b/src/bin/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/data/.empty b/src/data/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/docs/.empty b/src/docs/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/php/.empty b/src/php/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/php/HAB/Pica/Record/AuthorityRecord.php b/src/php/HAB/Pica/Record/AuthorityRecord.php deleted file mode 100644 index 89e94e1e80b335da58202fcbafac3e019fcf18d9..0000000000000000000000000000000000000000 --- a/src/php/HAB/Pica/Record/AuthorityRecord.php +++ /dev/null @@ -1,145 +0,0 @@ -<?php - -/** - * The AuthorityRecord class file. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -/** - * The Pica+ authority record. - * - * @package PicaRecord - * @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 AuthorityRecord extends Record { - - /** - * Append a field to the record. - * - * @see Record::append() - * - * @throws \InvalidArgumentException Field level other than 0 - * @throws \InvalidArgumentException Field already in record - * @param Field $field Field to append - * @return void - */ - public function append (Field $field) { - if ($field->getLevel() !== 0) { - throw new \InvalidArgumentException("Invalid field level {$field->getLevel()}"); - } - return parent::append($field); - } - - /** - * Return the Pica production number (record identifier). - * - * @return string|null Pica production number or NULL if none exists - */ - public function getPPN () { - $ppnField = $this->getFirstMatchingField('003@/00'); - if ($ppnField) { - $ppnSubfield = $ppnField->getNthSubfield('0', 0); - if ($ppnSubfield) { - return $ppnSubfield->getValue(); - } - } - return null; - } - - /** - * Set the Pica production number. - * - * Create a field 003@/00 if necessary. - * - * @param string $ppn Pica production number - * @return void - */ - public function setPPN ($ppn) { - $ppnField = $this->getFirstMatchingField('003@/00'); - if ($ppnField) { - $ppnSubfield = $ppnField->getNthSubfield('0', 0); - if ($ppnSubfield) { - $ppnSubfield->setValue($ppn); - } else { - $ppnField->append(new Subfield('0', $ppn)); - } - } else { - $this->append(new Field('003@', 0, array(new Subfield('0', $ppn)))); - } - } - - /** - * Return TRUE if the record is valid. - * - * A valid authority record MUST have exactly one valid PPN field - * (003@/00$0) and exactly one type field (002@/0$0) with a type indicator - * `T'. - * - * @see \HAB\Pica\Record\AuthorityRecord::checkPPN(); - * @see \HAB\Pica\Record\AuthorityRecord::checkType(); - * - * @return boolean TRUE if the record is valid - */ - public function isValid () { - return parent::isValid() && $this->checkPPN() && $this->checkType(); - } - - /** - * Return TRUE if the record has exactly one PPN field (003@/00) with a - * subfield $0. - * - * @return boolean TRUE if the record has a valid PPN field - */ - protected function checkPPN () { - $ppnField = $this->getFields('003@/00'); - if (count($ppnField) === 1) { - $ppnSubfield = reset($ppnField)->getNthSubfield('0', 0); - if ($ppnSubfield) { - return true; - } - } - return false; - } - - /** - * Return TRUE if the record has exactly one type field (002@/00) with a - * subfield $0 whose first character is `T'. - * - * @return boolean TRUE if the record has a valid type field - */ - protected function checkType () { - $typeField = $this->getFields('002@/00'); - if (count($typeField) === 1) { - $typeSubfield = reset($typeField)->getNthSubfield('0', 0); - if ($typeSubfield) { - $typeCode = $typeSubfield->getValue(); - if ($typeCode === 'T') { - return true; - } - } - } - } -} \ No newline at end of file diff --git a/src/php/HAB/Pica/Record/CopyRecord.php b/src/php/HAB/Pica/Record/CopyRecord.php deleted file mode 100644 index b3ac3fd9dda1fed45716cef25854455e6d13d079..0000000000000000000000000000000000000000 --- a/src/php/HAB/Pica/Record/CopyRecord.php +++ /dev/null @@ -1,166 +0,0 @@ -<?php - -/** - * The CopyRecord class file. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -/** - * The Pica+ copy record. - * - * @package PicaRecord - * @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 CopyRecord extends Record { - - /** - * The item number. - * - * @var integer - */ - protected $_itemNumber; - - /** - * Append a field to the copy record. - * - * You can only append field of level 2 to a copy record. - * - * @see Record::append() - * - * @throws \InvalidArgumentException Field level other than 2 - * @throws \InvalidArgumentException Item number mismatch - * @throws \InvalidArgumentException Field already in record - * @param \HAB\Pica\Record\Field $field Field to append - * @return void - */ - public function append (\HAB\Pica\Record\Field $field) { - if ($field->getLevel() !== 2) { - throw new \InvalidArgumentException("Invalid field level: {$field->getLevel()}"); - } - if ($this->getItemNumber() === null) { - $this->setItemNumber($field->getOccurrence()); - } - If ($field->getOccurrence() != $this->getItemNumber()) { - throw new \InvalidArgumentException("Item number mismatch: {$this->getItemNumber()}, {$field->getOccurrence()}"); - } - return parent::append($field); - } - - /** - * Return the item number. - * - * @return integer|null Item number - */ - public function getItemNumber () { - return $this->_itemNumber; - } - - /** - * Set the item number. - * - * @param integer $itemNumber Item number - * @return void - */ - protected function setItemNumber ($itemNumber) { - $this->_itemNumber = (int)$itemNumber; - } - - /** - * Return the exemplar production number (EPN). - * - * @return string Exemplar production number - */ - public function getEPN () { - $epnField = $this->getFirstMatchingField('203@'); - if ($epnField) { - $epnSubfield = $epnField->getNthSubfield('0', 0); - if ($epnSubfield) { - return $epnSubfield->getValue(); - } - } - return null; - } - - /** - * Set the exemplar production number (EPN). - * - * Create a field 203@ if necessary. - * - * @param string $epn Exemplar production number - * @return void - */ - public function setEPN ($epn) { - $epnField = $this->getFirstMatchingField('203@'); - if ($epnField) { - $epnSubfield = $epnField->getNthSubfield('0', 0); - if ($epnSubfield) { - $epnSubfield->setValue($epn); - } else { - $epnField->append(new Subfield('0', $epn)); - } - } else { - $this->append(new Field('203@', $this->getItemNumber(), array(new Subfield('0', $epn)))); - } - } - - /** - * Set the containing local record. - * - * @param \HAB\Pica\Record\LocalRecord $record Local record - * @return void - */ - public function setLocalRecord (\HAB\Pica\Record\LocalRecord $record) { - $this->unsetLocalRecord(); - if (!$record->containsCopyRecord($this)) { - $record->addCopyRecord($this); - } - $this->_parent = $record; - } - - /** - * Unset the containing local record. - * - * @return void - */ - public function unsetLocalRecord () { - if ($this->_parent) { - if ($this->_parent->containsCopyRecord($this)) { - $this->_parent->removeCopyRecord($this); - } - $this->_parent = null; - } - } - - /** - * Return the containing local record. - * - * @return \HAB\Pica\Record\LocalRecord|null - */ - public function getLocalRecord () { - return $this->_parent; - } - -} \ No newline at end of file diff --git a/src/php/HAB/Pica/Record/Field.php b/src/php/HAB/Pica/Record/Field.php deleted file mode 100644 index eb0037fb5725fbbcfd7dcf2afc2592289fd9e276..0000000000000000000000000000000000000000 --- a/src/php/HAB/Pica/Record/Field.php +++ /dev/null @@ -1,326 +0,0 @@ -<?php - -/** - * The Field class file. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -/** - * The Pica+ field. - * - * @package PicaRecord - * @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 Field { - - /** - * Regular expression matching a valid Pica+ field tag. - * - * @var string - */ - const TAG_RE = '|^[012][0-9]{2}[A-Z@]$|D'; - - /** - * Return TRUE if argument is a valid field tag. - * - * @param mixed $arg Variable to check - * @return boolean TRUE if argument is a valid field tag - */ - public static function isValidFieldTag ($arg) { - return (bool)preg_match(self::TAG_RE, $arg); - } - - /** - * Return TRUE if argument is a valid field occurrence. - * - * Argument is casted to int iff it is either null or a numeric string. - * - * @param mixed $arg Variable to check - * @return boolean TRUE if argument is a valid field occurrence - */ - public static function isValidFieldOccurrence ($arg) { - if ($arg === null || ctype_digit($arg)) { - $arg = (int)$arg; - } - return is_int($arg) && $arg >= 0 && $arg < 100; - } - - /** - * Return predicate that matches a field shorthand against a regular - * expression. - * - * @param string $reBody Body of regular expression - * @return callback Predicate - */ - public static function match ($reBody) { - if (strpos($reBody, '#') !== false) { - $reBody = str_replace('#', '\#', $reBody); - } - $regexp = "#{$reBody}#D"; - return function (Field $field) use ($regexp) { - return (bool)preg_match($regexp, $field->getShorthand()); - }; - } - - /** - * Return a new field based on its array representation. - * - * @throws \InvalidArgumentException Missing `tag', `occurrene', or `subfields' index - * @param array $field Array representation of a field - * @return \HAB\Pica\Record\Field A shiny new field - */ - public static function factory (array $field) { - foreach (array('tag', 'occurrence', 'subfields') as $index) { - if (!array_key_exists($index, $field)) { - throw new \InvalidArgumentException("Missing '{$index}' index in field array"); - } - } - return new Field($field['tag'], - $field['occurrence'], - array_map(array('HAB\Pica\Record\Subfield', 'factory'), $field['subfields'])); - } - - /// - - /** - * The field tag. - * - * @var string - */ - protected $_tag; - - /** - * The field level. - * - * @var integer - */ - protected $_level; - - /** - * The field occurrence. - * - * @var integer - */ - protected $_occurrence; - - /** - * The field shorthand. - * - * @var string - */ - protected $_shorthand; - - /** - * Constructor. - * - * @throws \InvalidArgumentException Invalid field tag or occurrence - * @param string $tag Field tag - * @param integer $occurrence Field occurrence - * @param array $subfields Initial set of subfields - * @return void - */ - public function __construct ($tag, $occurrence, array $subfields = array()) { - if (!self::isValidFieldTag($tag)) { - throw new \InvalidArgumentException("Invalid field tag: $tag"); - } - if (!self::isValidFieldOccurrence($occurrence)) { - throw new \InvalidArgumentException("Invalid field occurrence: $occurrence"); - } - $this->_tag = $tag; - $this->_occurrence = (int)$occurrence; - $this->_shorthand = sprintf('%4s/%02d', $tag, $occurrence); - $this->_level = (int)$tag[0]; - $this->setSubfields($subfields); - } - - /** - * Set the field subfields. - * - * Replaces the subfield list with subfields in argument. - * - * @param array $subfields Subfields - * @return void - */ - public function setSubfields (array $subfields) { - $this->_subfields = array(); - foreach ($subfields as $subfield) { - $this->addSubfield($subfield); - } - } - - /** - * Add a subfield to the end of the subfield list. - * - * @throws \InvalidArgumentException Subfield already present in subfield list - * @param \HAB\Pica\Record\Subfield $subfield Subfield to add - * @return void - */ - public function addSubfield (\HAB\Pica\Record\Subfield $subfield) { - if (in_array($subfield, $this->getSubfields(), true)) { - throw new \InvalidArgumentException("Cannot add subfield: Subfield already part of the subfield list"); - } - $this->_subfields []= $subfield; - } - - /** - * Remove a subfield. - * - * @throws \InvalidArgumentException Subfield is not part of the subfield list - * @param \HAB\Pica\Record\Subfield $subfield Subfield to delete - * @return void - */ - public function removeSubfield (\HAB\Pica\Record\Subfield $subfield) { - $index = array_search($subfield, $this->_subfields, true); - if ($index === false) { - throw new \InvalidArgumentException("Cannot remove subfield: Subfield not part of the subfield list"); - } - unset($this->_subfields[$index]); - } - - /** - * Return the field's subfields. - * - * Returns all subfields when called with no arguments. - * - * Otherwise the returned array is constructed as follows: - * - * Each argument is interpreted as a subfield code. The nth element of the - * returned array maps to the nth argument in the function call and contains - * NULL if the field does not have a subfield with the selected code, or the - * subfield if it exists. In order to retrieve multiple subfields with an - * identical code you repeat the subfield code in the argument list. - * - * @return array Subfields - */ - public function getSubfields () { - if (func_num_args() === 0) { - return $this->_subfields; - } else { - $selected = array(); - $codes = array(); - $subfields = $this->getSubfields(); - array_walk($subfields, function ($value, $index) use (&$codes) { $codes[$index] = $value->getCode(); }); - foreach (func_get_args() as $arg) { - $index = array_search($arg, $codes, true); - if ($index === false) { - $selected []= null; - } else { - $selected []= $subfields[$index]; - unset($codes[$index]); - } - } - return $selected; - } - } - - /** - * Return the nth occurrence of a subfield with specified code. - * - * @param string $code Subfield code - * @param integer $n Zero-based subfield index - * @return \HAB\Pica\record\Subfield|null The requested subfield or NULL if - * none exists - */ - public function getNthSubfield ($code, $n) { - $count = 0; - foreach ($this->getSubfields() as $subfield) { - if ($subfield->getCode() == $code) { - if ($count == $n) { - return $subfield; - } - $count++; - } - } - return null; - } - - /** - * Return the field tag. - * - * @return string Field tag - */ - public function getTag () { - return $this->_tag; - } - - /** - * Return the field occurrence. - * - * @return integer Field occurrence - */ - public function getOccurrence () { - return $this->_occurrence; - } - - /** - * Return the field level. - * - * @return integer Field level - */ - public function getLevel () { - return $this->_level; - } - - /** - * Return the field shorthand. - * - * @return string Field shorthand - */ - public function getShorthand () { - return $this->_shorthand; - } - - /** - * Return TRUE if the field is empty. - * - * A field is empty if it contains no subfields. - * - * @return boolean TRUE if the field is empty - */ - public function isEmpty () { - return empty($this->_subfields); - } - - /** - * Finalize the clone() operation. - * - * @return void - */ - public function __clone () { - $this->_subfields = Helper::mapClone($this->_subfields); - } - - /** - * Return a printable representation of the field. - * - * The printable representation of a field is its shorthand. - * - * @return string Printable representation of the field - */ - public function __toString () { - return $this->getShorthand(); - } -} \ No newline at end of file diff --git a/src/php/HAB/Pica/Record/Helper.php b/src/php/HAB/Pica/Record/Helper.php deleted file mode 100644 index c1349b56d823fa0378056f62b5bfc0620d111a29..0000000000000000000000000000000000000000 --- a/src/php/HAB/Pica/Record/Helper.php +++ /dev/null @@ -1,132 +0,0 @@ -<?php - -/** - * The Helper class file. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -/** - * Abstract class to anchor helper functions. - * - * @package PicaRecord - * @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 Helper { - - /** - * Return the complement of a function. - * - * The complement of a function is a function that takes the same arguments - * as the original function but returns a boolean with the opposite truth - * value. - * - * @param callback $function Original function - * @return callback Complement function - */ - public static function complement ($function) { - return function () use ($function) { return !call_user_func_array($function, func_get_args()); }; - } - - /** - * Return an array of the results of calling a method for each element of a - * sequence. - * - * @param array $sequence Sequence of objects - * @param string $method Name of the method - * @param array $arguments Optional array of method arguments - * @return array Result of calling method on each element of sequence - */ - public static function mapMethod (array $sequence, $method, array $arguments = array()) { - if (empty($arguments)) { - $f = function ($element) use ($method) { - return $element->$method(); - }; - } else { - $f = function ($element) use ($method, $arguments) { - return call_user_func_array(array($element, $method), $arguments); - }; - } - return array_map($f, $sequence); - } - - /** - * Return an array with clones of each element in sequence. - * - * @param array $sequence Sequence of objects - * @return array Sequence of clones - */ - public static function mapClone (array $sequence) { - return array_map(function ($element) { return clone($element); }, $sequence); - } - - /** - * Return TRUE if at leat one element of sequence matches predicate. - * - * @todo Make FALSE and TRUE self-evaluating, maybe - * - * @param array $sequence Sequence - * @param callback $predicate Predicate - * @return boolean TRUE if at least one element matches predicate - */ - public static function some (array $sequence, $predicate) { - foreach ($sequence as $element) { - if (call_user_func($predicate, $element)) { - return true; - } - } - return false; - } - - /** - * Return TRUE if every element of sequence fullfills predicate. - * - * @todo Make FALSE and TRUE self-evaluating, maybe - * - * @param array $sequence Sequence - * @param callback $predicate Predicate - * @return boolean TRUE if every element fullfills predicate - */ - public static function every (array $sequence, $predicate) { - foreach ($sequence as $element) { - if (!call_user_func($predicate, $element)) { - return false; - } - } - return true; - } - - /** - * Flatten sequence. - * - * @param array $sequence Sequence - * @return array Flattend sequence - */ - public static function flatten (array $sequence) { - $flat = array(); - array_walk_recursive($sequence, function ($element) use (&$flat) { $flat []= $element; }); - return $flat; - } -} \ No newline at end of file diff --git a/src/php/HAB/Pica/Record/LocalRecord.php b/src/php/HAB/Pica/Record/LocalRecord.php deleted file mode 100644 index 48c4fed6f6479eef5ecb64f56208f8712d39a911..0000000000000000000000000000000000000000 --- a/src/php/HAB/Pica/Record/LocalRecord.php +++ /dev/null @@ -1,189 +0,0 @@ -<?php - -/** - * The LocalRecord class file. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -/** - * The Pica+ local record. - * - * @package PicaRecord - * @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 LocalRecord extends NestedRecord { - - /** - * Append a field to the local record. - * - * You can only append field with a level of 0 to a local record. - * - * @see \HAB\Pica\Record\Record::append() - * - * @throws \InvalidArgumentException Field level invalid - * @throws \InvalidArgumentException Field already in record - * @param \HAB\Pica\Record\Field $field Field to add - * @return void - */ - public function append (Field $field) { - if ($field->getLevel() !== 1) { - throw new \InvalidArgumentException("Invalid field level: {$field->getLevel()}"); - } - parent::append($field); - } - - /** - * Add a copy record. - * - * @throws \InvalidArgumentException Record already contains the copy record - * @throws \InvalidArgumentException Record already contains a copy record with the same item number - * @param \HAB\Pica\Record\CopyRecord $record Copy record to add - * @return void - */ - public function addCopyRecord (\HAB\Pica\Record\CopyRecord $record) { - if ($this->getCopyRecordByItemNumber($record->getItemNumber())) { - throw new \InvalidArgumentException("Cannot add copy record: Copy record with item number {$record->getItemNumber()} already present"); - } - $this->addRecord($record); - $record->setLocalRecord($this); - } - - /** - * Remove a copy record. - * - * @throws \HAB\Pica\Record\Exception Record does not contain the specified copy record - * @param \HAB\Pica\Record\CopyRecord $record Record to remove - * @return void - */ - public function removeCopyRecord (\HAB\Pica\Record\CopyRecord $record) { - $this->removeRecord($record); - $record->unsetLocalRecord(); - } - - /** - * Return copy record by item number. - * - * @param integer $itemNumber Item number - * @return \HAB\Pica\Record\CopyRecord|null The copy record or null if none exists - */ - public function getCopyRecordByItemNumber ($itemNumber) { - foreach ($this->_records as $record) { - if ($record->getItemNumber() === $itemNumber) { - return $record; - } - } - return null; - } - - /** - * Return all copy records. - * - * @return array Copy records - */ - public function getCopyRecords () { - return $this->_records; - } - - /** - * Return the ILN (internal library number) of the local record. - * - * @return integer|null ILN of the local record or NULL if none set - */ - public function getILN () { - $ilnField = $this->getFirstMatchingField('101@/00'); - if ($ilnField) { - $ilnSubfield = $ilnField->getNthSubfield('a', 0); - if ($ilnSubfield) { - return $ilnSubfield->getValue(); - } - } - return null; - } - - /** - * Return true if local record contains the copy record. - * - * @param \HAB\Pica\Record\CopyRecord $record Copy record - * @return boolean - */ - public function containsCopyRecord (\HAB\Pica\Record\CopyRecord $record) { - return $this->containsRecord($record); - } - - /** - * Set the containing title record. - * - * @param \HAB\Pica\Record\TitleRecord $record Title record - * @return void - */ - public function setTitleRecord (\HAB\Pica\Record\TitleRecord $record) { - $this->unsetTitleRecord(); - if (!$record->containsLocalRecord($this)) { - $record->addLocalRecord($this); - } - $this->_parent = $record; - } - - /** - * Unset the containing title record. - * - * @return void - */ - public function unsetTitleRecord () { - if ($this->_parent) { - if ($this->_parent->containsLocalRecord($this)) { - $this->_parent->removeLocalRecord($this); - } - $this->_parent = null; - } - } - - /** - * Return the containing local record. - * - * @return \HAB\Pica\Record\TitleRecord|null - */ - public function getTitleRecord () { - return $this->_parent; - } - - /** - * Compare two copy records. - * - * Copyrecords are compared by their item number. - * - * @see \HAB\Pica\Record\CopyRecord::getItemNumber() - * @see \HAB\Pica\Record\NestedRecord::compareRecords() - * - * @param \HAB\Pica\Record\Record $a First copy record - * @param \HAB\Pica\Record\Record $b Second copy record - * @return integer Comparism value - */ - protected function compareRecords (\HAB\Pica\Record\Record $a, \HAB\Pica\Record\Record $b) { - return $a->getItemNumber() - $b->getItemNumber(); - } - -} \ No newline at end of file diff --git a/src/php/HAB/Pica/Record/NestedRecord.php b/src/php/HAB/Pica/Record/NestedRecord.php deleted file mode 100644 index 5a8f1a5529f3552d72fee1ebb6880602ee3bc55b..0000000000000000000000000000000000000000 --- a/src/php/HAB/Pica/Record/NestedRecord.php +++ /dev/null @@ -1,186 +0,0 @@ -<?php - -/** - * The NestedRecord class file. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -/** - * Abstract base class of nested records. - * - * A nested record is a record that contains zero or more other records. It is - * the base class of {@link TitleRecord title} and {@link LocalRecord local} - * records and implements internal accessors for the contained records and the - * propagation of field getters to the contained records. - * - * @package PicaRecord - * @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 NestedRecord extends Record { - - /** - * Contained records. - * - * @var array - */ - protected $_records = array(); - - /** - * Delete fields matching predicate. - * - * The delete() is propagated down to all contained records. - * - * @see \HAB\Pica\Record\Record::delete() - * - * @param callback $where Predicate - * @return void - */ - public function delete ($where) { - parent::delete($where); - Helper::mapMethod($this->_records, 'delete', array($where)); - } - - /** - * Sort fields and contained records. - * - * The sort() is propagated down to all contained records. In addition the - * nested records are sorted themselves using the implementing class' - * compareNestedRecords() function. - * - * @see \HAB\Pica\Record\Record::sort() - * @see \HAB\Pica\Record\NestedRecord::compareNestedRecords() - * - * @return void - */ - public function sort () { - parent::sort(); - Helper::mapMethod($this->_records, 'sort'); - usort($this->_records, array($this, 'compareRecords')); - } - - /** - * Return TRUE if the record is empty. - * - * A nested record is empty iff it contains no fields and no non-empty - * contained record. - * - * @return boolean TRUE if the record is empty - */ - public function isEmpty () { - return parent::isEmpty() && Helper::every($this->_records, function (Record $record) { return $record->isEmpty(); }); - } - - /** - * Return TRUE if the record is valid. - * - * A nested record is valid iff it and all contained records are valid. - * - * @see \HAB\Pica\Record\Record::isValid() - * - * @return boolean True if the record is valid - */ - public function isValid () { - return parent::isValid() && !Helper::every($this->_records, function (Record $record) { return $record->isValid(); }); - } - - /** - * Return fields of the record. - * - * @see \HAB\Pica\Record\Record::getFields() - * - * @param string $selector Body of regular expression - * @return array Fields - */ - public function getFields ($selector = null) { - if ($selector === null) { - return array_merge($this->_fields, Helper::flatten(Helper::mapMethod($this->_records, 'getFields'))); - } else { - return $this->select(Field::match($selector)); - } - } - - /** - * Compare two contained records and return a comparism value suitable for - * usort(). - * - * @see http://www.php.net/manual/en/function.usort.php - * - * @param \HAB\Pica\Record\Record $a First record - * @param \HAB\Pica\Record\Record $b Second record - * @return integer Comparism value - */ - abstract protected function compareRecords (\HAB\Pica\Record\Record $a, \HAB\Pica\Record\Record $b); - - /** - * Add a record as a contained record. - * - * @throws \InvalidArgumentException Record already contains the record - * @param \HAB\Pica\Record\Record $record Record to add - * @return void - */ - protected function addRecord (\HAB\Pica\Record\Record $record) { - if ($this->containsRecord($record)) { - throw new \InvalidArgumentException("{$this} already contains {$record}"); - } - $this->_records []= $record; - } - - /** - * Remove a contained record. - * - * @throws \InvalidArgumentException Record does not contain the record - * @param \HAB\Pica\Record\Record $record Record to remove - * @return void - */ - protected function removeRecord (\HAB\Pica\Record\Record $record) { - $index = array_search($record, $this->_records, true); - if ($index === false) { - throw new \InvalidArgumentException("{$this} does not contain {$record}"); - } - unset($this->_records[$index]); - } - - /** - * Return true if this record contains the requested record. - * - * @param \HAB\Pica\Record\Record Record to check - * @return boolean - */ - protected function containsRecord (\HAB\Pica\Record\Record $record) { - return in_array($record, $this->_records, true); - } - - /** - * Finalize the clone() operation. - * - * Clone all contained records. - * - * @return void - */ - public function __clone () { - $this->_records = Helper::mapClone($this->_records); - } -} \ No newline at end of file diff --git a/src/php/HAB/Pica/Record/Record.php b/src/php/HAB/Pica/Record/Record.php deleted file mode 100644 index ab64f66d411519434384b02a6b8e1d245ec54e2c..0000000000000000000000000000000000000000 --- a/src/php/HAB/Pica/Record/Record.php +++ /dev/null @@ -1,277 +0,0 @@ -<?php - -/** - * The Record class file. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -/** - * Abstract base class of all record structures. - * - * The abstract base class defines and partially implements the interface to - * all record structures. This class is the direct parent of records that do - * not contain other records, i.e. {@link AuthorityRecord authority} and - * {@link CopyRecord copy} records. - * - * @package PicaRecord - * @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 Record { - - /** - * Return a new record based on its array representation. - * - * Returns either a {@link TitleRecord} or a {@link AuthorityRecord} - * depending on the field 002@ which encodes the record type. - * - * @throws \InvalidArgumentException Missing type field - * @throws \InvalidArgumentException Missing `fields' index - * @param array $record Array representation of a record - * @return \HAB\Pica\Record\TitleRecord|\HAB\Pica\Record\AuthorityRecord New record instance - */ - public static function factory (array $record) { - if (!array_key_exists('fields', $record)) { - throw new \InvalidArgumentException("Missing 'fields' index in record array"); - } - $fields = array_map(array('HAB\Pica\Record\Field', 'factory'), $record['fields']); - $type = null; - $typePredicate = Field::match('002@/00'); - foreach ($fields as $field) { - if ($typePredicate($field)) { - $typeSubfield = $field->getNthSubfield('0', 0); - if ($typeSubfield) { - $type = $typeSubfield->getValue(); - break; - } - } - } - if ($type === null) { - throw new \InvalidArgumentException("Missing type field (002@/00$0)"); - } - if ($type[0] === 'T') { - return new AuthorityRecord($fields); - } else { - return new TitleRecord($fields); - } - } - - /// - - /** - * The record fields. - * - * @var array - */ - protected $_fields = array(); - - /** - * The containing parent record, if any. - * - * @var \HAB\Pica\Record - */ - protected $_parent; - - /** - * Constructor. - * - * @param array $fields Initial set of fields - * @return void - */ - public function __construct (array $fields = array()) { - $this->setFields($fields); - } - - /** - * Return array of fields matching predicate. - * - * @param callback $where Predicate - * @return array Matching fields - */ - public function select ($where) { - return array_filter($this->getFields(), $where); - } - - /** - * Delete fields matching predicate. - * - * @param callback $where Predicate - * @return void - */ - public function delete ($where) { - $complement = Helper::complement($where); - $this->_fields = array_filter($this->_fields, $complement); - } - - /** - * Append a field to the record. - * - * @throws \InvalidArgumentException Field already in record - * @param \HAB\Pica\Record\Field $field Field to append - * @return void - */ - public function append (\HAB\Pica\Record\Field $field) { - if (in_array($field, $this->_fields, true)) { - throw new \InvalidArgumentException("{$this} already contains {$field}"); - } - $this->_fields []= $field; - } - - /** - * Sort the fields of the record. - * - * Fields are sorted by their shorthand. - * - * @see \HAB\Pica\Record\Field::getShorthand() - * - * @return void - */ - public function sort () { - usort($this->_fields, - function (Field $fieldA, Field $fieldB) { - return strcmp($fieldA->getShorthand(), $fieldB->getShorthand()); - }); - } - - /** - * Set the record fields. - * - * Removes the current set of fields and replaces it with the fields in - * argument. - * - * @param array $fields Fields - * @return void - */ - public function setFields (array $fields) { - $this->_fields = array(); - foreach ($fields as $field) { - $this->append($field); - } - } - - /** - * Return the maximum occurrence value of a field. - * - * @throws \InvalidArgumentException Invalid field tag - * @param string $tag Field tag - * @return int|null Maximum occurrence of field or NULL if field does not - * exist - */ - public function getMaximumOccurrenceOf ($tag) { - if (!preg_match(Field::TAG_RE, $tag)) { - throw new \InvalidArgumentException("Invalid field tag: {$tag}"); - } - return array_reduce($this->getFields($tag), - function ($maxOccurrence, Field $field) { - if ($field->getOccurrence() > $maxOccurrence || $maxOccurrence === null) { - return $field->getOccurrence(); - } else { - return $maxOccurrence; - } - }, null); - } - - /** - * Return TRUE if the record is empty. - * - * A record is empty if it contains no fields. - * - * @return boolean TRUE if record is empty - */ - public function isEmpty () { - return empty($this->_fields); - } - - /** - * Return TRUE if the record is valid. - * - * The base implementation checks that record is not empty and does not - * contain an empty field. - * - * @return boolean TRUE if the record is valid - */ - public function isValid () { - return !$this->isEmpty() && !Helper::some($this->getFields(), function (Field $field) { return $field->isEmpty(); }); - } - - /** - * Return fields of the record. - * - * Optional argument $selector is the body of a regular expression. If set, - * this function returns only fields whose shorthand is matched by the - * regular expression. - * - * @see \HAB\Pica\Record\Field::match() - * - * @param string $selector Body of regular expression - * @return array Fields - */ - public function getFields ($selector = null) { - if ($selector === null) { - return $this->_fields; - } else { - return $this->select(Field::match($selector)); - } - } - - /** - * Return the first field that matches a selector. - * - * @see \HAB\Pica\Record\getFields() - * - * @param string $selector Body of regular expression - * @return \HAB\Pica\Record\Field|null The first matching field or NULL if - * no match - */ - public function getFirstMatchingField ($selector) { - $fields = $this->getFields($selector); - if (empty($fields)) { - return null; - } else { - return reset($fields); - } - } - - /** - * Finalize the clone() operation. - * - * @return void - */ - public function __clone () { - $this->_fields = Helper::mapClone($this->_fields); - } - - /** - * Return a printable representation of the record. - * - * The printable representation of a record is the object hash prefixed by - * the class name. - * - * @return string Printable representation of the record - */ - public function __toString () { - return get_class($this) . ':' . spl_object_hash($this); - } -} \ No newline at end of file diff --git a/src/php/HAB/Pica/Record/Subfield.php b/src/php/HAB/Pica/Record/Subfield.php deleted file mode 100644 index 1d2889e41eaa4543070a051ed9f57a2f3e1df621..0000000000000000000000000000000000000000 --- a/src/php/HAB/Pica/Record/Subfield.php +++ /dev/null @@ -1,141 +0,0 @@ -<?php - -/** - * The Subfield class file. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -/** - * The Pica+ subfield. - * - * A subfield is a cons of a alphanumeric character and a non-empty value. - * - * @package PicaRecord - * @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 Subfield { - - /** - * Return TRUE if argument is a valid subfield code. - * - * @param mixed $arg Variable to check - * @return boolean TRUE if argument is a valid subfield code - */ - public static function isValidSubfieldCode ($arg) { - return (bool)preg_match('/^[a-z0-9]$/Di', $arg); - } - - /** - * Return a new subfield based on its array representation. - * - * The array representation of a subfield is an associative array with the - * keys `code' and `value', holding the subfield code and value. - * - * @throws \InvalidArgumentException Missing code or value index - * @param array $subfield Array representation of a subfield - * @return \HAB\Pica\Record\Subfield New subfield - */ - public static function factory (array $subfield) { - if (!array_key_exists('code', $subfield)) { - throw new \InvalidArgumentException("Missing 'code' index in subfield array"); - } - if (!array_key_exists('value', $subfield)) { - throw new \InvalidArgumentException("Missing 'value' index in subfield array"); - } - return new Subfield($subfield['code'], $subfield['value']); - } - - /// - - /** - * The subfield code. - * - * @var string - */ - protected $_code; - - /** - * The subfield value. - * - * @var string Value - */ - protected $_value; - - /** - * Constructor. - * - * @throws \InvalidArgumentException Invalid subfield code - * @param string $code Subfield code - * @param string $value Subfield value - * @return void - */ - public function __construct ($code, $value) { - if (!self::isValidSubfieldCode($code)) { - throw new \InvalidArgumentException("Invalid subfield code: {$code}"); - } - $this->_code = $code; - $this->setValue($value); - } - - /** - * Set the subfield value. - * - * @param string $value Subfield value - * @return void - */ - public function setValue ($value) { - $this->_value = $value; - } - - /** - * Return the subfield value. - * - * @return string Subfield value - */ - public function getValue () { - return $this->_value; - } - - /** - * Return the subfield code. - * - * @return string Subfield code - */ - public function getCode () { - return $this->_code; - } - - /** - * Return printable representation of the subfield. - * - * The printable representation of a subfield is its value. - * - * @return string Subfield value - */ - public function __toString () { - return $this->getValue(); - } -} \ No newline at end of file diff --git a/src/php/HAB/Pica/Record/TitleRecord.php b/src/php/HAB/Pica/Record/TitleRecord.php deleted file mode 100644 index 6dd7fe58b0c05f39f94143544bc6d48016658887..0000000000000000000000000000000000000000 --- a/src/php/HAB/Pica/Record/TitleRecord.php +++ /dev/null @@ -1,208 +0,0 @@ -<?php - -/** - * The TitleRecord class file. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -/** - * A Pica+ title record. - * - * @package PicaRecord - * @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 TitleRecord extends NestedRecord { - - /** - * Append a field to the title record. - * - * @see \HAB\Pica\Record\Record::append() - * - * You can only directly add fields with a level of 0. - * - * @throws \InvalidArgumentException Field level invalid - * @throws \InvalidArgumentException Field already in record - * @param \HAB\Pica\Record\Field $field Field to append - * @return void - */ - public function append (\HAB\Pica\Record\Field $field) { - if ($field->getLevel() !== 0) { - throw new \InvalidArgumentException("Invalid field level: {$field->getLevel()}"); - } - parent::append($field); - } - - /** - * Set the record's fields. - * - * @todo Relocate to \HAB\Pica\Record\Record::factory(), maybe - * - * @param array $fields Field - * @return void - */ - public function setFields (array $fields) { - $this->_fields = array(); - $this->_records = array(); - $prevLevel = null; - foreach ($fields as $field) { - $level = $field->getLevel(); - if ($level === 0) { - $this->append($field); - } else { - if ($level === 1 && $prevLevel !== 1) { - $localRecord = new LocalRecord(array($field)); - $this->addLocalRecord($localRecord); - } else { - $records = $this->getLocalRecords(); - $localRecord = end($records); - if ($level === 1) { - $localRecord->append($field); - } else { - $copyRecord = $localRecord->getCopyRecordByItemNumber($field->getOccurrence()); - if ($copyRecord) { - $copyRecord->append($field); - } else { - $localRecord->addCopyRecord(new CopyRecord(array($field))); - } - } - } - } - $prevLevel = $level; - } - } - - /** - * Add a local record. - * - * @throws \InvalidArgumentException Record already contains the local record - * @param \HAB\Pica\Record\LocalRecord $record Local record - * @return void - */ - public function addLocalRecord (\HAB\Pica\Record\LocalRecord $record) { - $this->addRecord($record); - $record->setTitleRecord($this); - } - - /** - * Remove a local record. - * - * @throws \HAB\Pica\Record\Exception Record does not contain the local record - * @param \HAB\Pica\Record\LocalRecord $record Local record to remove - * @return void - */ - public function removeLocalRecord (\HAB\Pica\Record\LocalRecord $record) { - $this->removeRecord($record); - $record->unsetTitleRecord(); - } - - /** - * Return array of all local records. - * - * @return array Local records - */ - public function getLocalRecords () { - return $this->_records; - } - - /** - * Return a local record identified by its ILN. - * - * @param integer $iln Intenal library number - * @return \HAB\Pica\Record\LocalRecord|null The local record or NULL if none exists - */ - public function getLocalRecordByILN ($iln) { - foreach ($this->getLocalRecords() as $localRecord) { - if ($localRecord->getILN() == $iln) { - return $localRecord; - } - } - return null; - } - - /** - * Return the Pica production number (record identifier). - * - * @return string|null Pica production number or NULL if none exists - */ - public function getPPN () { - $ppnField = $this->getFirstMatchingField('003@/00'); - if ($ppnField) { - $ppnSubfield = $ppnField->getNthSubfield('0', 0); - if ($ppnSubfield) { - return $ppnSubfield->getValue(); - } - } - return null; - } - - /** - * Set the Pica production number. - * - * Create a field 003@/00 if necessary. - * - * @param string $ppn Pica production number - * @return void - */ - public function setPPN ($ppn) { - $ppnField = $this->getFirstMatchingField('003@/00'); - if ($ppnField) { - $ppnSubfield = $ppnField->getNthSubfield('0', 0); - if ($ppnSubfield) { - $ppnSubfield->setValue($ppn); - } else { - $ppnField->append(new Subfield('0', $ppn)); - } - } else { - $this->append(new Field('003@', 0, array(new Subfield('0', $ppn)))); - } - } - - /** - * Return true if title record contains the local record. - * - * @param \HAB\Pica\Record\LocalRecord $record Local record - * @return boolean - */ - public function containsLocalRecord (\HAB\Pica\Record\LocalRecord $record) { - return $this->containsRecord($record); - } - - /** - * Compare two local records. - * - * @see \HAB\Pica\Record\NestedRecord::compareRecords() - * - * Local records are compared by their ILN. - * - * @param \HAB\Pica\Record\Record $a First record - * @param \HAB\Pica\Record\Record $b Second record - * @return Comparism value - */ - protected function compareRecords (\HAB\Pica\Record\Record $a, \HAB\Pica\Record\Record $b) { - return $a->getILN() - $b->getILN(); - } - -} \ No newline at end of file diff --git a/src/tests/.empty b/src/tests/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/tests/functional-tests/.empty b/src/tests/functional-tests/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/tests/integration-tests/.empty b/src/tests/integration-tests/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/tests/unit-tests/.empty b/src/tests/unit-tests/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/tests/unit-tests/bin/.empty b/src/tests/unit-tests/bin/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/tests/unit-tests/bootstrap.php b/src/tests/unit-tests/bootstrap.php deleted file mode 100644 index f13e5c87315bd5b1ffd466c78b48faf0fc6d4326..0000000000000000000000000000000000000000 --- a/src/tests/unit-tests/bootstrap.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php - -// ========================================================================= -// -// tests/bootstrap.php -// A helping hand for running our unit tests -// -// Author Stuart Herbert -// (stuart@stuartherbert.com) -// -// Copyright (c) 2011 Stuart Herbert -// Released under the New BSD license -// -// ========================================================================= - -// step 1: create the APP_TOPDIR constant that all components require -define('APP_TOPDIR', realpath(__DIR__ . '/../../php')); -define('APP_LIBDIR', realpath(__DIR__ . '/../../../vendor/php')); -define('APP_TESTDIR', realpath(__DIR__ . '/php')); - -// step 2: find the autoloader, and install it -require_once(APP_LIBDIR . '/psr0.autoloader.php'); - -// step 3: add the additional paths to the include path -psr0_autoloader_searchFirst(APP_LIBDIR); -psr0_autoloader_searchFirst(APP_TESTDIR); -psr0_autoloader_searchFirst(APP_TOPDIR); - -// step 4: enable ContractLib if it is available -if (class_exists('Phix_Project\ContractLib\Contract')) -{ - \Phix_Project\ContractLib\Contract::EnforceWrappedContracts(); -} - -// step 5: Set error level to include E_STRICT -\error_reporting(\E_ALL | \E_STRICT); \ No newline at end of file diff --git a/src/tests/unit-tests/php/.empty b/src/tests/unit-tests/php/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/tests/unit-tests/php/HAB/Pica/Record/AuthorityRecordTest.php b/src/tests/unit-tests/php/HAB/Pica/Record/AuthorityRecordTest.php deleted file mode 100644 index c93c1534ecfbd9b432129635398ae4410999479e..0000000000000000000000000000000000000000 --- a/src/tests/unit-tests/php/HAB/Pica/Record/AuthorityRecordTest.php +++ /dev/null @@ -1,147 +0,0 @@ -<?php - -/** - * Unit test for the AuthorityRecord class. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -class AuthorityRecordTest extends \PHPUnit_FrameWork_TestCase { - - /// - - public function testConstructor () { - return new AuthorityRecord(); - } - - /** - * @depends testConstructor - */ - public function testIsEmpty (AuthorityRecord $r) { - $this->assertTrue($r->isEmpty()); - } - - /** - * @depends testConstructor - */ - public function testAppend (AuthorityRecord $r) { - $r->append(new Field('000@', 0, array(new Subfield('0', 'valid')))); - $this->assertFalse($r->isEmpty()); - } - - /** - * @depends testConstructor - */ - public function testGetPPN (AuthorityRecord $r) { - $this->assertNull($r->getPPN()); - $r->append(new Field('003@', 0, array(new Subfield('0', 'valid')))); - $this->assertEquals('valid', $r->getPPN()); - } - - /** - * @depends testConstructor - */ - public function testDelete (AuthorityRecord $r) { - $this->assertFalse($r->isEmpty()); - $r->delete(Field::match('..../..')); - $this->assertTrue($r->isEmpty()); - } - - /// - - public function testSetPPN () { - $r = new AuthorityRecord(); - $this->assertNull($r->getPPN()); - $r->setPPN('something'); - $this->assertEquals('something', $r->getPPN()); - $r->setPPN('else'); - $this->assertEquals('else', $r->getPPN()); - $this->assertEquals(1, count($r->getFields('003@/00'))); - } - - public function testClone () { - $r = new AuthorityRecord(); - $f = new Field('003@', 0); - $r->append($f); - $c = clone($r); - $this->assertNotSame($r, $c); - $fields = $c->getFields(); - $this->assertNotSame($f, reset($fields)); - } - - public function testIsInvalidEmptyField () { - $r = new AuthorityRecord(array(new Field('003@', 0))); - $this->assertFalse($r->isValid()); - } - - public function testIsInvalidMissingPPN () { - $r = new AuthorityRecord(array(new Field('002@', 0, array(new Subfield('0', 'T'))))); - $this->assertFalse($r->isValid()); - } - - public function testIsInvalidMissingType () { - $r = new AuthorityRecord(array(new Field('003@', 0, array(new Subfield('0', 'something'))))); - $this->assertFalse($r->isValid()); - } - - public function testIsInvalidWrongType () { - $r = new AuthorityRecord(array(new Field('002@', 0, array(new Subfield('0', 'A'))))); - $this->assertFalse($r->isValid()); - } - - public function testIsValid () { - $r = new AuthorityRecord(array(new Field('002@', 0, array(new Subfield('0', 'T'))), - new Field('003@', 0, array(new Subfield('0', 'valid'))))); - $this->assertTrue($r->isValid()); - } - - public function testSort () { - $r = new AuthorityRecord(array(new Field('003@', 99, array(new Subfield('0', 'valid'))), - new Field('003@', 0, array(new Subfield('0', 'valid'))))); - $r->sort(); - $fields = $r->getFields('003@'); - $this->assertEquals('003@/00', reset($fields)->getShorthand()); - $this->assertEquals('003@/99', end($fields)->getShorthand()); - } - - /// - - /** - * @expectedException \InvalidArgumentException - */ - public function testAppendThrowsExceptionOnDuplicateField () { - $r = new AuthorityRecord(); - $f = new Field('003@', 0); - $r->append($f); - $r->append($f); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testAppendThrowsExceptionOnInvalidLevel () { - $r = new AuthorityRecord(); - $r->append(new Field('101@', 0)); - } - -} \ No newline at end of file diff --git a/src/tests/unit-tests/php/HAB/Pica/Record/CopyRecordTest.php b/src/tests/unit-tests/php/HAB/Pica/Record/CopyRecordTest.php deleted file mode 100644 index 86cf24aed3122bff58fc7dc8b3632daafae00832..0000000000000000000000000000000000000000 --- a/src/tests/unit-tests/php/HAB/Pica/Record/CopyRecordTest.php +++ /dev/null @@ -1,75 +0,0 @@ -<?php - -/** - * Unit test for the CopyRecord class. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -class CopyRecordTest extends \PHPUnit_FrameWork_TestCase { - - public function testGetEPN () { - $r = new CopyRecord(); - $this->assertNull($r->getEPN()); - $r->append(new Field('203@', 0, array(new Subfield('0', 'something')))); - $this->assertEquals('something', $r->getEPN()); - } - - public function testSetEPN () { - $r = new CopyRecord(array(new Field('203@', 0, array(new Subfield('0', 'something'))))); - $this->assertEquals('something', $r->getEPN()); - $r->setEPN('epn'); - $this->assertEquals('epn', $r->getEPN()); - } - - public function testLocalRecordReference () { - $l = new LocalRecord(); - $c = new CopyRecord(); - $this->assertNull($c->getLocalRecord()); - $l->addCopyRecord($c); - $this->assertSame($l, $c->getLocalRecord()); - $c->unsetLocalRecord(); - $this->assertNull($c->getLocalRecord()); - $this->assertFalse($l->containsCopyRecord($c)); - } - - /// - - /** - * @expectedException \InvalidArgumentException - */ - public function testAppendThrowsExceptionOnInvalidFieldLevel () { - $r = new CopyRecord(); - $r->append(new Field('003@', 0)); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testAppendThrowsExceptionOnNumberMismatch () { - $r = new CopyRecord(); - $r->append(new Field('201@', 0)); - $r->append(new Field('202@', 1)); - } - -} diff --git a/src/tests/unit-tests/php/HAB/Pica/Record/FieldTest.php b/src/tests/unit-tests/php/HAB/Pica/Record/FieldTest.php deleted file mode 100644 index fa3bad8fb1c88e89f43e3b5cb818f25cb8587672..0000000000000000000000000000000000000000 --- a/src/tests/unit-tests/php/HAB/Pica/Record/FieldTest.php +++ /dev/null @@ -1,225 +0,0 @@ -<?php - -/** - * Unit test for the Field class. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -class FieldTest extends \PHPUnit_FrameWork_TestCase { - - public function testValidFieldOccurrenceCastNull () { - $this->assertTrue(Field::isValidFieldOccurrence(null)); - } - - public function testValidFieldOccurrenceCastString () { - $this->assertTrue(Field::isValidFieldOccurrence('10')); - } - - public function testInvalidFieldOccurrenceCastString () { - $this->assertFalse(Field::isValidFieldOccurrence("10\n")); - } - - public function testInvalidFieldOccurrenceLowerBound () { - $this->assertFalse(Field::isValidFieldOccurrence(-1)); - } - - public function testInvalidFieldOccurrenceUpperBound () { - $this->assertFalse(Field::isValidFieldOccurrence(100)); - } - - public function testInvalidFieldTagTrailingNewline () { - $this->assertFalse(Field::isValidFieldTag("003@\n")); - } - - public function testMatch () { - $this->assertTrue(call_user_func(Field::match('003./..'), new Field('003@', 0))); - $this->assertTrue(call_user_func(Field::match('003./..'), new Field('003Z', 0))); - $this->assertTrue(call_user_func(Field::match('003./..'), new Field('003Z', 99))); - } - - public function testFactory () { - $f = Field::factory(array('tag' => '003@', 'occurrence' => 10, 'subfields' => array())); - $this->assertInstanceOf('HAB\Pica\Record\Field', $f); - $this->assertEquals('003@/10', $f->getShorthand()); - } - - /// - - public function testConstructor () { - return new Field('003@', 0); - } - - /** - * @depends testConstructor - */ - public function testIsEmpty (Field $f) { - $this->assertTrue($f->isEmpty()); - $s = new Subfield('a', 'valid'); - $f->addSubfield($s); - $this->assertFalse($f->isEmpty()); - $f->removeSubfield($s); - } - - /** - * @depends testConstructor - */ - public function testGetTag (Field $f) { - $this->assertEquals('003@', $f->getTag()); - } - - /** - * @depends testConstructor - */ - public function testGetOccurrence (Field $f) { - $this->assertEquals(0, $f->getOccurrence()); - } - - /** - * @depends testConstructor - */ - public function testGetLevel (Field $f) { - $this->assertEquals(0, $f->getLevel()); - } - - /** - * @depends testConstructor - */ - public function testGetShorthand (Field $f) { - $this->assertEquals('003@/00', $f->getShorthand()); - } - - /// - - public function testSetSubfields () { - $f = new Field('003@', 0); - $f->setSubfields(array(new Subfield('a', 'first a'), - new Subfield('d', 'first d'), - new Subfield('a', 'second a'))); - $this->assertFalse($f->isEmpty()); - return $f; - } - - public function testGetNthSubfield () { - $f = new Field('003@', 0, array(new Subfield('a', 'first a'), - new Subfield('b', 'first b'), - new Subfield('a', 'second a'))); - $s = $f->getNthSubfield('a', 0); - $this->assertInstanceOf('HAB\Pica\Record\Subfield', $s); - $this->assertEquals('first a', $s->getValue()); - $s = $f->getNthSubfield('a', 1); - $this->assertInstanceOf('HAB\Pica\Record\Subfield', $s); - $this->assertEquals('second a', $s->getValue()); - $s = $f->getNthSubfield('a', 2); - $this->assertNull($s); - } - - /** - * @depends testSetSubfields - */ - public function testGetSubfields (Field $f) { - $this->assertEquals(3, count($f->getSubfields())); - return $f; - } - - /** - * @depends testGetSubfields - */ - public function testGetSubfieldsWithCode (Field $f) { - $this->assertEquals(5, count($f->getSubfields('x', 'x', 'x', 'x', 'x'))); - $s = $f->getSubfields('d'); - $this->assertEquals('first d', reset($s)); - $s = $f->getSubfields('a'); - $this->assertEquals('first a', reset($s)); - $s = $f->getSubfields('a', 'd', 'a'); - $this->assertEquals('second a', end($s));; - return $f; - } - - /// - - public function testClone () { - $f = new Field('003@', 0); - $s = new Subfield('a', 'valid'); - $f->addSubfield($s); - $c = clone($f); - $this->assertNotSame($c, $f); - $this->assertNotSame($s, $c->getNthSubfield('a', 0)); - } - - /// - - /** - * @expectedException \InvalidArgumentException - */ - public function testFactoryThrowsExceptionOnMissingTagIndex () { - Field::factory(array('occurrence' => 10, 'subfields' => array())); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testFactoryThrowsExceptionOnMissingOccurrenceIndex () { - Field::factory(array('tag' => '003@', 'subfields' => array())); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testFactoryThrowsExceptionOnMissingSubfieldIndex () { - Field::factory(array('tag' => '003@', 'occurrence' => 10)); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testContructorThrowsExceptionOnInvalidTag () { - new Field('invalid', 0); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testConstructorThrowsExceptionOnInvalidOccurrence () { - new Field('003@', 1000); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testAddSubfieldThrowsExceptionOnDuplicateSubfield () { - $f = new Field('003@', 0); - $s = new Subfield('a', 'valid'); - $f->addSubfield($s); - $f->addSubfield($s); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testRemoveSubfieldThrowsExceptionOnNonExistentField () { - $f = new Field('003@', 0); - $s = new Subfield('a', 'valid'); - $f->removeSubfield($s); - } -} \ No newline at end of file diff --git a/src/tests/unit-tests/php/HAB/Pica/Record/LocalRecordTest.php b/src/tests/unit-tests/php/HAB/Pica/Record/LocalRecordTest.php deleted file mode 100644 index 3e864474e93e8eff86e5b8a76bb96b766744137f..0000000000000000000000000000000000000000 --- a/src/tests/unit-tests/php/HAB/Pica/Record/LocalRecordTest.php +++ /dev/null @@ -1,170 +0,0 @@ -<?php - -/** - * Unit test for the LocalRecord class. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -class LocalRecordTest extends \PHPUnit_FrameWork_TestCase { - - public function testAddCopyRecord () { - $r = new LocalRecord(); - $r->addCopyRecord(new CopyRecord()); - } - - public function testClone () { - $r = new LocalRecord(); - $c = new CopyRecord(array(new Field('200@', 11))); - $r->addCopyRecord($c); - $clone = clone($r); - $this->assertNotSame($clone, $r); - $this->assertNotSame($c, $clone->getCopyRecordByItemNumber(11)); - } - - public function testRemoveCopyRecord () { - $r = new LocalRecord(); - $r->addCopyRecord(new CopyRecord(array(new Field('200@', 11)))); - $this->assertEquals(1, count($r->getCopyRecords())); - $r->removeCopyRecord($r->getCopyRecordByItemNumber(11)); - } - - public function testSort () { - $r = new LocalRecord(); - $a = new CopyRecord(array(new Field('200@', 11))); - $b = new CopyRecord(array(new Field('200@', 99))); - $r->addCopyRecord($b); - $r->addCopyRecord($a); - $c = $r->getCopyRecords(); - $this->assertSame($b, reset($c)); - $r->sort(); - $c = $r->getCopyRecords(); - $this->assertSame($a, reset($c)); - } - - public function testGetILN () { - $r = new LocalRecord(); - $this->assertNull($r->getILN()); - $r->append(new Field('101@', 0, array(new Subfield('a', '50')))); - $this->assertEquals(50, $r->getILN()); - } - - public function testSelectPropagatesDown () { - $r = new LocalRecord(); - $c = new CopyRecord(array(new Field('200@', 11))); - $r->addCopyRecord($c); - $this->assertEquals(1, count($r->select(Field::match('200@/11')))); - } - - public function testDeletePropagatesDown () { - $r = new LocalRecord(); - $c = new CopyRecord(array(new Field('200@', 11))); - $r->addCopyRecord($c); - $this->assertFalse($c->isEmpty()); - $r->delete(Field::match('200@/11')); - $this->assertTrue($c->isEmpty()); - } - - public function testIsEmpty () { - $r = new LocalRecord(); - $this->assertTrue($r->isEmpty()); - $r->addCopyRecord(new CopyRecord()); - $this->assertTrue($r->isEmpty()); - $r->addCopyRecord(new CopyRecord(array(new Field('200@', 11)))); - $this->assertFalse($r->isEmpty()); - } - - public function testGetMaximumOccurrenceOf () { - $r = new LocalRecord(); - $this->assertNull($r->getMaximumOccurrenceOf('144Z')); - $r->append(new Field('144Z', 0)); - $this->assertEquals(0, $r->getMaximumOccurrenceOf('144Z')); - $r->append(new Field('144Z', 10)); - $this->assertEquals(10, $r->getMaximumOccurrenceOf('144Z')); - } - - public function testContainsCopyRecord () { - $r = new LocalRecord(); - $c = new CopyRecord(); - $this->assertFalse($r->containsCopyRecord($c)); - $r->addCopyRecord($c); - $this->assertTrue($r->containsCopyRecord($c)); - } - - public function testTitleRecordReference () { - $t = new TitleRecord(); - $l = new LocalRecord(); - $this->assertNull($l->getTitleRecord()); - $t->addLocalRecord($l); - $this->assertSame($t, $l->getTitleRecord()); - $l->unsetTitleRecord(); - $this->assertNull($l->getTitleRecord()); - $this->assertFalse($t->containsLocalRecord($l)); - } - - /// - - /** - * @expectedException \InvalidArgumentException - */ - public function testAddCopyRecordThrowsExceptionOnItemNumberCollision () { - $r = new LocalRecord(); - $r->addCopyRecord(new CopyRecord(array(new Field('200@', 11)))); - $r->addCopyRecord(new CopyRecord(array(new Field('200@', 11)))); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testAddCopyRecordThrowsExceptionOnDuplicateCopyRecord () { - $r = new LocalRecord(); - $c = new CopyRecord(); - $r->addCopyRecord($c); - $r->addCopyRecord($c); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testRemoveCopyRecordThrowsExceptionOnCopyRecordNotContainedInRecord () { - $r = new LocalRecord(); - $c = new CopyRecord(); - $r->removeCopyRecord($c); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testAppendThrowsExceptionOnInvalidLevel () { - $r = new LocalRecord(); - $r->append(new Field('003@', 0)); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testGetMaximumOccurrenceOfThrowsExceptionOnInvalidFieldTag () { - $r = new LocalRecord(); - $r->getMaximumOccurrenceOf('@@@@'); - } -} \ No newline at end of file diff --git a/src/tests/unit-tests/php/HAB/Pica/Record/RecordTest.php b/src/tests/unit-tests/php/HAB/Pica/Record/RecordTest.php deleted file mode 100644 index 4c7d03842a8c7d7ecba725142ed52114a9300830..0000000000000000000000000000000000000000 --- a/src/tests/unit-tests/php/HAB/Pica/Record/RecordTest.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php - -/** - * Unit test for the AuthorityRecord class. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -class RecordTest extends \PHPUnit_FrameWork_TestCase { - - public function testFactoryCreatesAuthorityRecord () { - $record = Record::factory(array('fields' => array( - array('tag' => '002@', - 'occurrence' => 0, - 'subfields' => array( - array('code' => '0', - 'value' => 'T')))))); - $this->assertInstanceOf('HAB\Pica\Record\AuthorityRecord', $record); - } - - public function testGetFirstMatchingField () { - $record = new AuthorityRecord(array(new Field('001@', 0), - new Field('001@', 1))); - $this->assertNull($record->getFirstMatchingField('002@/00')); - $this->assertInstanceOf('HAB\Pica\Record\Field', $record->getFirstMatchingField('001@')); - } - - /// - - /** - * @expectedException \InvalidArgumentException - */ - public function testFactoryThrowsExceptionOnMissingFieldsIndex () { - Record::factory(array()); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testFactoryThrowsExceptionOnMissingTypeField () { - $record = Record::factory(array('fields' => array())); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testFactoryThrowsExceptionOnMissingTypeSubfield () { - $record = Record::factory(array('fields' => array( - array('tag' => '002@', - 'occurrence' => 0, - 'subfields' => array())))); - } -} \ No newline at end of file diff --git a/src/tests/unit-tests/php/HAB/Pica/Record/SubfieldTest.php b/src/tests/unit-tests/php/HAB/Pica/Record/SubfieldTest.php deleted file mode 100644 index 461eb09b2c91af84f257c0f42f695f491afb8e97..0000000000000000000000000000000000000000 --- a/src/tests/unit-tests/php/HAB/Pica/Record/SubfieldTest.php +++ /dev/null @@ -1,96 +0,0 @@ -<?php - -/** - * Unit test for the Subfield class. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -class SubfieldTest extends \PHPUnit_FrameWork_TestCase { - - public function testValidSubfieldCodeZero () { - $this->assertTrue(Subfield::isValidSubfieldCode('0')); - } - - public function testInvalidSubfieldCodeTrailingNewline () { - $this->assertFalse(Subfield::isValidSubfieldCode("a\n")); - } - - public function testFactory () { - $s = Subfield::factory(array('code' => 'a', 'value' => 'valid')); - $this->assertInstanceOf('HAB\Pica\Record\Subfield', $s); - $this->assertEquals('a', $s->getCode()); - $this->assertEquals('valid', $s->getValue()); - } - - /// - - public function testConstructor () { - return new Subfield('a', 'valid'); - } - - /** - * @depends testConstructor - */ - public function testGetValue (Subfield $s) { - $this->assertEquals('valid', $s->getValue()); - } - - /** - * @depends testConstructor - */ - public function testGetCode (Subfield $s) { - $this->assertEquals('a', $s->getCode()); - } - - /** - * @depends testConstructor - */ - public function testToString (Subfield $s) { - $this->assertEquals('valid', (string)$s); - } - - /// - - /** - * @expectedException \InvalidArgumentException - */ - public function testConstructorThrowsExceptionOnInvalidCode () { - new Subfield(null, 'valid'); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testFactoryThrowsExceptionOnMissingCodeIndex () { - Subfield::factory(array('value' => 'valid')); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testFactoryThrowsExceptionOnMissingValueIndex () { - Subfield::factory(array('code' => 'a')); - } - -} \ No newline at end of file diff --git a/src/tests/unit-tests/php/HAB/Pica/Record/TitleRecordTest.php b/src/tests/unit-tests/php/HAB/Pica/Record/TitleRecordTest.php deleted file mode 100644 index 10159be24d02ca5028994c44e4c5481cd047cf0f..0000000000000000000000000000000000000000 --- a/src/tests/unit-tests/php/HAB/Pica/Record/TitleRecordTest.php +++ /dev/null @@ -1,112 +0,0 @@ -<?php - -/** - * Unit test for the TitleRecord class. - * - * This file is part of PicaRecord. - * - * PicaRecord 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. - * - * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. - * - * @package PicaRecord - * @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\Record; - -class TitleRecordTest extends \PHPUnit_FrameWork_TestCase { - - public function testAppend () { - $r = new TitleRecord(); - $r->append(new Field('003@', 0)); - $this->assertEquals(1, count($r->getFields())); - } - - public function testAddLocalRecord () { - $r = new TitleRecord(); - $l = new LocalRecord(); - $this->assertEquals(0, count($r->getLocalRecords())); - $r->addLocalRecord($l); - $this->assertEquals(1, count($r->getLocalRecords())); - return $r; - } - - /** - * @depends testAddLocalRecord - */ - public function testRemoveLocalRecord (TitleRecord $r) { - $l = $r->getLocalRecords(); - $l = end($l); - $r->removeLocalRecord($l); - $this->assertEquals(0, count($r->getLocalRecords())); - } - - public function testSetFields () { - $r = new TitleRecord(); - $r->append(new Field('003@', 0)); - $this->assertEquals(1, count($r->getFields())); - } - - public function testSetFieldsCreatesNewLocalRecord () { - $r = new TitleRecord(); - $fields = array(); - $fields []= new Field('003@', 0); - $r->setFields($fields); - $this->assertEquals(0, count($r->getLocalRecords())); - $fields []= new Field('101@', 0, array(new Subfield('a', 1))); - $r->setFields($fields); - $this->assertEquals(1, count($r->getLocalRecords())); - $fields [] = new Field('200@', 0); - $r->setFields($fields); - $this->assertEquals(1, count($r->getLocalRecords())); - $fields []= new Field('101@', 0, array(new Subfield('a', 2))); - $r->setFields($fields); - $this->assertEquals(2, count($r->getLocalRecords())); - } - - public function testGetLocalRecordByILN () { - $r = new TitleRecord(); - $r->addLocalRecord(new LocalRecord(array(new Field('101@', 0, array(new Subfield('a', 11)))))); - $r->addLocalRecord(new LocalRecord(array(new Field('101@', 0, array(new Subfield('a', 99)))))); - $l = $r->getLocalRecordByILN(11); - $this->assertInstanceOf('HAB\\Pica\\Record\\LocalRecord', $l); - $this->assertEquals(11, $l->getILN()); - $l = $r->getLocalRecordByILN(33); - $this->assertNull($l); - } - - public function testGetPPN () { - $r = new TitleRecord(); - $this->assertNull($r->getPPN()); - $r->append(new Field('003@', 0, array(new Subfield('0', 'something')))); - $this->assertEquals('something', $r->getPPN()); - } - - public function testSetPPN () { - $r = new TitleRecord(); - $r->setPPN('something'); - $this->assertEquals(1, count($r->getFields('003@/00'))); - $r->setPPN('something else'); - $this->assertEquals('something else', $r->getPPN()); - } - - public function testContainsLocalRecord () { - $r = new TitleRecord(); - $l = new LocalRecord(); - $this->assertFalse($r->containsLocalRecord($l)); - $r->addLocalRecord($l); - $this->assertTrue($r->containsLocalRecord($l)); - } -} diff --git a/src/tests/unit-tests/www/.empty b/src/tests/unit-tests/www/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/www/.empty b/src/www/.empty deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000000000000000000000000000000000000..ba07c30f3cfa27bd999d0d5bcdda38cd3ef0dcd7 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,31 @@ +<?php + +/** + * This file is part of PicaRecord. + * + * OAI-PMH-Server 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. + * + * OAI-PMH-Server 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 OAI-PMH-Server. If not, see <http://www.gnu.org/licenses/>. + * + * @author David Maus <maus@hab.de> + * @copyright Copyright (c) 2013 by Herzog August Bibliothek Wolfenbüttel + * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 + */ + +require_once realpath(__DIR__ . '/../vendor/autoload.php'); + +define('PHPUNIT_FIXTURES', realpath(__DIR__ . '/fixtures')); + +$loader = new Composer\Autoload\ClassLoader(); +$loader->add('HAB', realpath(__DIR__ . '/../src')); +$loader->add('HAB', realpath(__DIR__ . '/src')); +$loader->register(); diff --git a/tests/src/HAB/Pica/Record/AuthorityRecordTest.php b/tests/src/HAB/Pica/Record/AuthorityRecordTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4d1f732885913130069086a4871f2761007f59c3 --- /dev/null +++ b/tests/src/HAB/Pica/Record/AuthorityRecordTest.php @@ -0,0 +1,153 @@ +<?php + +/** + * Unit test for the AuthorityRecord class. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use PHPUnit_FrameWork_TestCase; + +class AuthorityRecordTest extends PHPUnit_FrameWork_TestCase +{ + + /// + + public function testIsEmpty () + { + $r = new AuthorityRecord(); + $this->assertTrue($r->isEmpty()); + } + + public function testAppend () + { + $r = new AuthorityRecord(); + $r->append(new Field('000@', 0, array(new Subfield('0', 'valid')))); + $this->assertFalse($r->isEmpty()); + } + + public function testGetPPN () + { + $r = new AuthorityRecord(); + $this->assertNull($r->getPPN()); + $r->append(new Field('003@', 0, array(new Subfield('0', 'valid')))); + $this->assertEquals('valid', $r->getPPN()); + } + + public function testDelete () + { + $r = new AuthorityRecord(); + $r->append(new Field('003@', 0, array(new Subfield('0', 'valid')))); + $this->assertFalse($r->isEmpty()); + $r->delete(Field::match('..../..')); + $this->assertTrue($r->isEmpty()); + } + + /// + + public function testSetPPN () + { + $r = new AuthorityRecord(); + $this->assertNull($r->getPPN()); + $r->setPPN('something'); + $this->assertEquals('something', $r->getPPN()); + $r->setPPN('else'); + $this->assertEquals('else', $r->getPPN()); + $this->assertEquals(1, count($r->getFields('003@/00'))); + } + + public function testClone () + { + $r = new AuthorityRecord(); + $f = new Field('003@', 0); + $r->append($f); + $c = clone($r); + $this->assertNotSame($r, $c); + $fields = $c->getFields(); + $this->assertNotSame($f, reset($fields)); + } + + public function testIsInvalidEmptyField () + { + $r = new AuthorityRecord(array(new Field('003@', 0))); + $this->assertFalse($r->isValid()); + } + + public function testIsInvalidMissingPPN () + { + $r = new AuthorityRecord(array(new Field('002@', 0, array(new Subfield('0', 'T'))))); + $this->assertFalse($r->isValid()); + } + + public function testIsInvalidMissingType () + { + $r = new AuthorityRecord(array(new Field('003@', 0, array(new Subfield('0', 'something'))))); + $this->assertFalse($r->isValid()); + } + + public function testIsInvalidWrongType () + { + $r = new AuthorityRecord(array(new Field('002@', 0, array(new Subfield('0', 'A'))))); + $this->assertFalse($r->isValid()); + } + + public function testIsValid () + { + $r = new AuthorityRecord(array(new Field('002@', 0, array(new Subfield('0', 'T'))), + new Field('003@', 0, array(new Subfield('0', 'valid'))))); + $this->assertTrue($r->isValid()); + } + + public function testSort () + { + $r = new AuthorityRecord(array(new Field('003@', 99, array(new Subfield('0', 'valid'))), + new Field('003@', 0, array(new Subfield('0', 'valid'))))); + $r->sort(); + $fields = $r->getFields('003@'); + $this->assertEquals('003@/00', reset($fields)->getShorthand()); + $this->assertEquals('003@/99', end($fields)->getShorthand()); + } + + /// + + /** + * @expectedException InvalidArgumentException + */ + public function testAppendThrowsExceptionOnDuplicateField () + { + $r = new AuthorityRecord(); + $f = new Field('003@', 0); + $r->append($f); + $r->append($f); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testAppendThrowsExceptionOnInvalidLevel () + { + $r = new AuthorityRecord(); + $r->append(new Field('101@', 0)); + } + +} \ No newline at end of file diff --git a/tests/src/HAB/Pica/Record/CopyRecordTest.php b/tests/src/HAB/Pica/Record/CopyRecordTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7f2ad1e5180f59752cc278a0d58e32c4e21b48eb --- /dev/null +++ b/tests/src/HAB/Pica/Record/CopyRecordTest.php @@ -0,0 +1,82 @@ +<?php + +/** + * Unit test for the CopyRecord class. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use PHPUnit_FrameWork_TestCase; + +class CopyRecordTest extends PHPUnit_FrameWork_TestCase { + + public function testGetEPN () + { + $r = new CopyRecord(); + $this->assertNull($r->getEPN()); + $r->append(new Field('203@', 0, array(new Subfield('0', 'something')))); + $this->assertEquals('something', $r->getEPN()); + } + + public function testSetEPN () + { + $r = new CopyRecord(array(new Field('203@', 0, array(new Subfield('0', 'something'))))); + $this->assertEquals('something', $r->getEPN()); + $r->setEPN('epn'); + $this->assertEquals('epn', $r->getEPN()); + } + + public function testLocalRecordReference () + { + $l = new LocalRecord(); + $c = new CopyRecord(); + $this->assertNull($c->getLocalRecord()); + $l->addCopyRecord($c); + $this->assertSame($l, $c->getLocalRecord()); + $c->unsetLocalRecord(); + $this->assertNull($c->getLocalRecord()); + $this->assertFalse($l->containsCopyRecord($c)); + } + + /// + + /** + * @expectedException InvalidArgumentException + */ + public function testAppendThrowsExceptionOnInvalidFieldLevel () + { + $r = new CopyRecord(); + $r->append(new Field('003@', 0)); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testAppendThrowsExceptionOnNumberMismatch () + { + $r = new CopyRecord(); + $r->append(new Field('201@', 0)); + $r->append(new Field('202@', 1)); + } + +} diff --git a/tests/src/HAB/Pica/Record/FieldTest.php b/tests/src/HAB/Pica/Record/FieldTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ab9fde887251d09c3c34228ee5b6c498c3c1b9a9 --- /dev/null +++ b/tests/src/HAB/Pica/Record/FieldTest.php @@ -0,0 +1,231 @@ +<?php + +/** + * Unit test for the Field class. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use PHPUnit_FrameWork_TestCase; + +class FieldTest extends PHPUnit_FrameWork_TestCase +{ + + public function testValidFieldOccurrenceCastNull () { + $this->assertTrue(Field::isValidFieldOccurrence(null)); + } + + public function testValidFieldOccurrenceCastString () { + $this->assertTrue(Field::isValidFieldOccurrence('10')); + } + + public function testInvalidFieldOccurrenceCastString () { + $this->assertFalse(Field::isValidFieldOccurrence("10\n")); + } + + public function testInvalidFieldOccurrenceLowerBound () { + $this->assertFalse(Field::isValidFieldOccurrence(-1)); + } + + public function testInvalidFieldOccurrenceUpperBound () { + $this->assertFalse(Field::isValidFieldOccurrence(100)); + } + + public function testInvalidFieldTagTrailingNewline () { + $this->assertFalse(Field::isValidFieldTag("003@\n")); + } + + public function testMatch () { + $this->assertTrue(call_user_func(Field::match('003./..'), new Field('003@', 0))); + $this->assertTrue(call_user_func(Field::match('003./..'), new Field('003Z', 0))); + $this->assertTrue(call_user_func(Field::match('003./..'), new Field('003Z', 99))); + } + + public function testFactory () { + $f = Field::factory(array('tag' => '003@', 'occurrence' => 10, 'subfields' => array())); + $this->assertInstanceOf('HAB\Pica\Record\Field', $f); + $this->assertEquals('003@/10', $f->getShorthand()); + } + + /// + + public function testIsEmpty () + { + $f = new Field('003@', 0); + $this->assertTrue($f->isEmpty()); + $s = new Subfield('a', 'valid'); + $f->addSubfield($s); + $this->assertFalse($f->isEmpty()); + $f->removeSubfield($s); + } + + public function testGetTag () + { + $f = new Field('003@', 0); + $this->assertEquals('003@', $f->getTag()); + } + + public function testGetOccurrence () + { + $f = new Field('003@', 0); + $this->assertEquals(0, $f->getOccurrence()); + } + + public function testGetLevel () + { + $f = new Field('003@', 0); + $this->assertEquals(0, $f->getLevel()); + } + + public function testGetShorthand () + { + $f = new Field('003@', 0); + $this->assertEquals('003@/00', $f->getShorthand()); + } + + /// + + public function testSetSubfields () + { + $f = new Field('003@', 0); + $f->setSubfields(array(new Subfield('a', 'first a'), + new Subfield('d', 'first d'), + new Subfield('a', 'second a'))); + $this->assertFalse($f->isEmpty()); + return $f; + } + + public function testGetNthSubfield () + { + $f = new Field('003@', 0, array(new Subfield('a', 'first a'), + new Subfield('b', 'first b'), + new Subfield('a', 'second a'))); + $s = $f->getNthSubfield('a', 0); + $this->assertInstanceOf('HAB\Pica\Record\Subfield', $s); + $this->assertEquals('first a', $s->getValue()); + $s = $f->getNthSubfield('a', 1); + $this->assertInstanceOf('HAB\Pica\Record\Subfield', $s); + $this->assertEquals('second a', $s->getValue()); + $s = $f->getNthSubfield('a', 2); + $this->assertNull($s); + } + + /** + * @depends testSetSubfields + */ + public function testGetSubfields (Field $f) + { + $this->assertEquals(3, count($f->getSubfields())); + return $f; + } + + /** + * @depends testGetSubfields + */ + public function testGetSubfieldsWithCode (Field $f) + { + $this->assertEquals(5, count($f->getSubfields('x', 'x', 'x', 'x', 'x'))); + $s = $f->getSubfields('d'); + $this->assertEquals('first d', reset($s)); + $s = $f->getSubfields('a'); + $this->assertEquals('first a', reset($s)); + $s = $f->getSubfields('a', 'd', 'a'); + $this->assertEquals('second a', end($s));; + return $f; + } + + /// + + public function testClone () + { + $f = new Field('003@', 0); + $s = new Subfield('a', 'valid'); + $f->addSubfield($s); + $c = clone($f); + $this->assertNotSame($c, $f); + $this->assertNotSame($s, $c->getNthSubfield('a', 0)); + } + + /// + + /** + * @expectedException InvalidArgumentException + */ + public function testFactoryThrowsExceptionOnMissingTagIndex () + { + Field::factory(array('occurrence' => 10, 'subfields' => array())); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testFactoryThrowsExceptionOnMissingOccurrenceIndex () + { + Field::factory(array('tag' => '003@', 'subfields' => array())); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testFactoryThrowsExceptionOnMissingSubfieldIndex () + { + Field::factory(array('tag' => '003@', 'occurrence' => 10)); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testContructorThrowsExceptionOnInvalidTag () + { + new Field('invalid', 0); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testConstructorThrowsExceptionOnInvalidOccurrence () + { + new Field('003@', 1000); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testAddSubfieldThrowsExceptionOnDuplicateSubfield () + { + $f = new Field('003@', 0); + $s = new Subfield('a', 'valid'); + $f->addSubfield($s); + $f->addSubfield($s); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testRemoveSubfieldThrowsExceptionOnNonExistentField () + { + $f = new Field('003@', 0); + $s = new Subfield('a', 'valid'); + $f->removeSubfield($s); + } +} \ No newline at end of file diff --git a/tests/src/HAB/Pica/Record/LocalRecordTest.php b/tests/src/HAB/Pica/Record/LocalRecordTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c26199a3e661b8693fdd0a106f6a374aa4ba9fb2 --- /dev/null +++ b/tests/src/HAB/Pica/Record/LocalRecordTest.php @@ -0,0 +1,183 @@ +<?php + +/** + * Unit test for the LocalRecord class. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use PHPUnit_FrameWork_TestCase; + +class LocalRecordTest extends PHPUnit_FrameWork_TestCase +{ + + public function testClone () + { + $r = new LocalRecord(); + $c = new CopyRecord(array(new Field('200@', 11))); + $r->addCopyRecord($c); + $clone = clone($r); + $this->assertNotSame($clone, $r); + $this->assertNotSame($c, $clone->getCopyRecordByItemNumber(11)); + } + + public function testRemoveCopyRecord () + { + $r = new LocalRecord(); + $r->addCopyRecord(new CopyRecord(array(new Field('200@', 11)))); + $this->assertEquals(1, count($r->getCopyRecords())); + $r->removeCopyRecord($r->getCopyRecordByItemNumber(11)); + } + + public function testSort () + { + $r = new LocalRecord(); + $a = new CopyRecord(array(new Field('200@', 11))); + $b = new CopyRecord(array(new Field('200@', 99))); + $r->addCopyRecord($b); + $r->addCopyRecord($a); + $c = $r->getCopyRecords(); + $this->assertSame($b, reset($c)); + $r->sort(); + $c = $r->getCopyRecords(); + $this->assertSame($a, reset($c)); + } + + public function testGetILN () + { + $r = new LocalRecord(); + $this->assertNull($r->getILN()); + $r->append(new Field('101@', 0, array(new Subfield('a', '50')))); + $this->assertEquals(50, $r->getILN()); + } + + public function testSelectPropagatesDown () + { + $r = new LocalRecord(); + $c = new CopyRecord(array(new Field('200@', 11))); + $r->addCopyRecord($c); + $this->assertEquals(1, count($r->select(Field::match('200@/11')))); + } + + public function testDeletePropagatesDown () + { + $r = new LocalRecord(); + $c = new CopyRecord(array(new Field('200@', 11))); + $r->addCopyRecord($c); + $this->assertFalse($c->isEmpty()); + $r->delete(Field::match('200@/11')); + $this->assertTrue($c->isEmpty()); + } + + public function testIsEmpty () + { + $r = new LocalRecord(); + $this->assertTrue($r->isEmpty()); + $r->addCopyRecord(new CopyRecord()); + $this->assertTrue($r->isEmpty()); + $r->addCopyRecord(new CopyRecord(array(new Field('200@', 11)))); + $this->assertFalse($r->isEmpty()); + } + + public function testGetMaximumOccurrenceOf () + { + $r = new LocalRecord(); + $this->assertNull($r->getMaximumOccurrenceOf('144Z')); + $r->append(new Field('144Z', 0)); + $this->assertEquals(0, $r->getMaximumOccurrenceOf('144Z')); + $r->append(new Field('144Z', 10)); + $this->assertEquals(10, $r->getMaximumOccurrenceOf('144Z')); + } + + public function testContainsCopyRecord () + { + $r = new LocalRecord(); + $c = new CopyRecord(); + $this->assertFalse($r->containsCopyRecord($c)); + $r->addCopyRecord($c); + $this->assertTrue($r->containsCopyRecord($c)); + } + + public function testTitleRecordReference () + { + $t = new TitleRecord(); + $l = new LocalRecord(); + $this->assertNull($l->getTitleRecord()); + $t->addLocalRecord($l); + $this->assertSame($t, $l->getTitleRecord()); + $l->unsetTitleRecord(); + $this->assertNull($l->getTitleRecord()); + $this->assertFalse($t->containsLocalRecord($l)); + } + + /// + + /** + * @expectedException InvalidArgumentException + */ + public function testAddCopyRecordThrowsExceptionOnItemNumberCollision () + { + $r = new LocalRecord(); + $r->addCopyRecord(new CopyRecord(array(new Field('200@', 11)))); + $r->addCopyRecord(new CopyRecord(array(new Field('200@', 11)))); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testAddCopyRecordThrowsExceptionOnDuplicateCopyRecord () + { + $r = new LocalRecord(); + $c = new CopyRecord(); + $r->addCopyRecord($c); + $r->addCopyRecord($c); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testRemoveCopyRecordThrowsExceptionOnCopyRecordNotContainedInRecord () + { + $r = new LocalRecord(); + $c = new CopyRecord(); + $r->removeCopyRecord($c); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testAppendThrowsExceptionOnInvalidLevel () + { + $r = new LocalRecord(); + $r->append(new Field('003@', 0)); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testGetMaximumOccurrenceOfThrowsExceptionOnInvalidFieldTag () + { + $r = new LocalRecord(); + $r->getMaximumOccurrenceOf('@@@@'); + } +} \ No newline at end of file diff --git a/tests/src/HAB/Pica/Record/RecordTest.php b/tests/src/HAB/Pica/Record/RecordTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a1d0db3833fd34773d165d872a998cd7407ce0b9 --- /dev/null +++ b/tests/src/HAB/Pica/Record/RecordTest.php @@ -0,0 +1,81 @@ +<?php + +/** + * Unit test for the AuthorityRecord class. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use PHPUnit_FrameWork_TestCase; + +class RecordTest extends PHPUnit_FrameWork_TestCase +{ + + public function testFactoryCreatesAuthorityRecord () + { + $record = Record::factory(array('fields' => array( + array('tag' => '002@', + 'occurrence' => 0, + 'subfields' => array( + array('code' => '0', + 'value' => 'T')))))); + $this->assertInstanceOf('HAB\Pica\Record\AuthorityRecord', $record); + } + + public function testGetFirstMatchingField () + { + $record = new AuthorityRecord(array(new Field('001@', 0), + new Field('001@', 1))); + $this->assertNull($record->getFirstMatchingField('002@/00')); + $this->assertInstanceOf('HAB\Pica\Record\Field', $record->getFirstMatchingField('001@')); + } + + /// + + /** + * @expectedException InvalidArgumentException + */ + public function testFactoryThrowsExceptionOnMissingFieldsIndex () + { + Record::factory(array()); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testFactoryThrowsExceptionOnMissingTypeField () + { + $record = Record::factory(array('fields' => array())); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testFactoryThrowsExceptionOnMissingTypeSubfield () + { + $record = Record::factory(array('fields' => array( + array('tag' => '002@', + 'occurrence' => 0, + 'subfields' => array())))); + } +} \ No newline at end of file diff --git a/tests/src/HAB/Pica/Record/SubfieldTest.php b/tests/src/HAB/Pica/Record/SubfieldTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d398b391639a07bd4288f38190025d79569474a1 --- /dev/null +++ b/tests/src/HAB/Pica/Record/SubfieldTest.php @@ -0,0 +1,97 @@ +<?php + +/** + * Unit test for the Subfield class. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use PHPUnit_FrameWork_TestCase; + +class SubfieldTest extends PHPUnit_FrameWork_TestCase +{ + + public function testValidSubfieldCodeZero () + { + $this->assertTrue(Subfield::isValidSubfieldCode('0')); + } + + public function testInvalidSubfieldCodeTrailingNewline () + { + $this->assertFalse(Subfield::isValidSubfieldCode("a\n")); + } + + public function testFactory () + { + $s = Subfield::factory(array('code' => 'a', 'value' => 'valid')); + $this->assertInstanceOf('HAB\Pica\Record\Subfield', $s); + $this->assertEquals('a', $s->getCode()); + $this->assertEquals('valid', $s->getValue()); + } + + /// + + public function testGetValue () + { + $s = new Subfield('a', 'valid'); + $this->assertEquals('valid', $s->getValue()); + } + + public function testGetCode () + { + $s = new Subfield('a', 'valid'); + $this->assertEquals('a', $s->getCode()); + } + + public function testToString () { + $s = new Subfield('a', 'valid'); + $this->assertEquals('valid', (string)$s); + } + + /// + + /** + * @expectedException InvalidArgumentException + */ + public function testConstructorThrowsExceptionOnInvalidCode () + { + new Subfield(null, 'valid'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testFactoryThrowsExceptionOnMissingCodeIndex () + { + Subfield::factory(array('value' => 'valid')); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testFactoryThrowsExceptionOnMissingValueIndex () + { + Subfield::factory(array('code' => 'a')); + } + +} \ No newline at end of file diff --git a/tests/src/HAB/Pica/Record/TitleRecordTest.php b/tests/src/HAB/Pica/Record/TitleRecordTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9753e11996a94f59186db8584335629468a6a22c --- /dev/null +++ b/tests/src/HAB/Pica/Record/TitleRecordTest.php @@ -0,0 +1,124 @@ +<?php + +/** + * Unit test for the TitleRecord class. + * + * This file is part of PicaRecord. + * + * PicaRecord 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. + * + * PicaRecord 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 PicaRecord. If not, see <http://www.gnu.org/licenses/>. + * + * @package PicaRecord + * @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\Record; + +use PHPUnit_FrameWork_TestCase; + +class TitleRecordTest extends PHPUnit_FrameWork_TestCase +{ + + public function testAppend () + { + $r = new TitleRecord(); + $r->append(new Field('003@', 0)); + $this->assertEquals(1, count($r->getFields())); + } + + public function testAddLocalRecord () + { + $r = new TitleRecord(); + $l = new LocalRecord(); + $this->assertEquals(0, count($r->getLocalRecords())); + $r->addLocalRecord($l); + $this->assertEquals(1, count($r->getLocalRecords())); + return $r; + } + + /** + * @depends testAddLocalRecord + */ + public function testRemoveLocalRecord (TitleRecord $r) + { + $l = $r->getLocalRecords(); + $l = end($l); + $r->removeLocalRecord($l); + $this->assertEquals(0, count($r->getLocalRecords())); + } + + public function testSetFields () + { + $r = new TitleRecord(); + $r->append(new Field('003@', 0)); + $this->assertEquals(1, count($r->getFields())); + } + + public function testSetFieldsCreatesNewLocalRecord () + { + $r = new TitleRecord(); + $fields = array(); + $fields []= new Field('003@', 0); + $r->setFields($fields); + $this->assertEquals(0, count($r->getLocalRecords())); + $fields []= new Field('101@', 0, array(new Subfield('a', 1))); + $r->setFields($fields); + $this->assertEquals(1, count($r->getLocalRecords())); + $fields [] = new Field('200@', 0); + $r->setFields($fields); + $this->assertEquals(1, count($r->getLocalRecords())); + $fields []= new Field('101@', 0, array(new Subfield('a', 2))); + $r->setFields($fields); + $this->assertEquals(2, count($r->getLocalRecords())); + } + + public function testGetLocalRecordByILN () + { + $r = new TitleRecord(); + $r->addLocalRecord(new LocalRecord(array(new Field('101@', 0, array(new Subfield('a', 11)))))); + $r->addLocalRecord(new LocalRecord(array(new Field('101@', 0, array(new Subfield('a', 99)))))); + $l = $r->getLocalRecordByILN(11); + $this->assertInstanceOf('HAB\\Pica\\Record\\LocalRecord', $l); + $this->assertEquals(11, $l->getILN()); + $l = $r->getLocalRecordByILN(33); + $this->assertNull($l); + } + + public function testGetPPN () + { + $r = new TitleRecord(); + $this->assertNull($r->getPPN()); + $r->append(new Field('003@', 0, array(new Subfield('0', 'something')))); + $this->assertEquals('something', $r->getPPN()); + } + + public function testSetPPN () + { + $r = new TitleRecord(); + $r->setPPN('something'); + $this->assertEquals(1, count($r->getFields('003@/00'))); + $r->setPPN('something else'); + $this->assertEquals('something else', $r->getPPN()); + } + + public function testContainsLocalRecord () + { + $r = new TitleRecord(); + $l = new LocalRecord(); + $this->assertFalse($r->containsLocalRecord($l)); + $r->addLocalRecord($l); + $this->assertTrue($r->containsLocalRecord($l)); + } +}