--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/CHANGELOG.md Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,256 @@
+EasyRdf 0.8.0
+=============
+
+API changes
+-----------
+* is_a() has been renamed to isA()
+* isBnode() has been renamed to isBNode()
+* getNodeId() has been renamed to getBNodeId()
+
+Major new features
+------------------
+* Now PSR-2 compliant
+* Added RDFa parser
+
+Enhancements
+------------
+
+Bug Fixes
+---------
+
+
+
+EasyRdf 0.7.2
+=============
+
+Enhancements
+------------
+* Removed automatic registration of ARC2 and librdf parsers and serialisers
+** You must now specifically choose the parser or serialiser
+* Refactored `EasyRdf_Literal` with datatypes so that it preserves exact value
+* Changed Turtle serialiser to not escape Unicode characters unnecessarily
+* Fix for escaping literals objects in Turtle serialiser
+* Added a new static function `newAndLoad()` to `EasyRdf_Graph`
+* Added setters for each of the components of the URI to the class `EasyRdf_ParsedUri`
+* Added option to the converter example, to allow raw output, without any HTML
+
+Bug Fixes
+---------
+* Fixed broken Redland parser (thanks to Jon Phipps)
+* Fix for serialising two bnodes that reference each other in Turtle
+* Added support for parsing literals with single quotes in Turtle
+* Removed require for EasyRdf/Exception.php
+* Fix for serialising `EasyRdf_Literal_DateTime` to Turtle
+* Fix for serialising Turtle literals with a shorthand syntax
+* Several typo fixes and minor corrections
+
+
+EasyRdf 0.7.1
+=============
+
+Enhancements
+------------
+* Changed minimum version of PHPUnit to 3.5.15
+* Added RDFa namespace
+* Added Open Graph Protocol namespace
+* Made improvements to formatting of the Turtle serialiser
+* Added new splitUri() function to EasyRdf_Namespace
+* Made improvements to format guessing
+
+Bug Fixes
+---------
+* Fix for RDF/XML parser not returning the number of triples
+* Added re-mapping of b-nodes to N-Triples and Redland parsers
+
+
+EasyRdf 0.7.0
+=============
+
+API Changes
+-----------
+* You must now wrap full property URIs in angle brackets
+
+Major new features
+------------------
+* Added a new pure-PHP Turtle parser
+* Added basic property-path support for traversing graphs
+* Added support for serialising to the GraphViz dot format (and generating images)
+* Added a new class `EasyRdf_ParsedUri` - a RFC3986 compliant URI parser
+
+Enhancements
+------------
+* The load() function in `EasyRdf_Graph` no-longer takes a $data argument
+* The parse() and load() methods, now return the number of triples parsed
+* Added count() method to `EasyRdf_Resource` and `EasyRdf_Graph`
+* Added localName() method to `EasyRdf_Resource`
+* Added htmlLink() method to `EasyRdf_Resource`
+* Added methods deleteResource() and deleteLiteral() to `EasyRdf_Graph`
+* Added support for guessing the file format based on the file extension
+* Performance improvements to built-in serialisers
+
+Environment changes
+-------------------
+* Added PHP Composer description to the project
+* Now properly PSR-0 autoloader compatible
+* New minimum version of PHP is 5.2.8
+* Changed test suite to require PHPUnit 3.6
+* Changed from Phing to GNU Make based build system
+* Added automated testing of the examples
+
+Bug Fixes
+---------
+* Fix for loading https:// URLs
+* Fix for storing the value 0 in a `EasyRdf_Graph`
+* Fix for HTTP servers that return relative URIs in the Location header
+* Fix for Literals with languages in the SPARQL Query Results XML Format
+* Fix for SPARQL servers that put extra whitespace into the XML result
+* Fix for the httpget.php example in PHP 5.4+
+
+
+EasyRdf 0.6.3
+=============
+* Added $graph->parseFile() method.
+* Added support for SSL (https) to the built-in HTTP client
+* Fixes for HTTP responses with a charset parameter in the Content Type.
+* Improved error handling and empty documents in JSON and rapper parsers.
+* Added connivence class for xsd:hexBinary literals:
+ - `EasyRdf_Literal_HexBinary`
+* Made EasyRdf more tolerant of 'badly serialised bnodes'
+* Fix for SPARQL servers that return charset in the MIME Type.
+* Fix for using xml:lang in SPARQL 1.1 Query Results JSON Format
+* Changed datetime ISO formatting to use 'Z' instead of +0000 for UTC dateTimes
+* Added the namespace for 'The Cert Ontology' to EasyRdf.
+
+
+EasyRdf 0.6.2
+=============
+* Bug fix for missing triples in the RDF/XML serialiser.
+* Added countTriples() method to `EasyRdf_Graph`.
+* Re-factored the mechanism for mapping RDF datatypes to PHP classes.
+* Added subclasses of `EasyRdf_Literal` for various XSD datatypes:
+ - `EasyRdf_Literal_Boolean`
+ - `EasyRdf_Literal_Date`
+ - `EasyRdf_Literal_DateTime`
+ - `EasyRdf_Literal_Decimal`
+ - `EasyRdf_Literal_Integer`
+* Made the Redland based parser write triples directly to `EasyRdf_Graph`
+* Added support for datatypes and languages in the `EasyRdf_Parser_Ntriples` parser.
+* Fix for parsing XML Literals in RDF/XML
+
+
+EasyRdf 0.6.1
+=============
+* Updated API documentation for new classes and methods added in 0.6.0
+* Added a description to the top of the source code for each example.
+* Changed the generated bnode identifier names from eidXXX to genidXXX.
+* Implemented inlining of resources in the RDF/XML serialiser.
+* Added new reversePropertyUris() method to `EasyRdf_Graph` and `EasyRdf_Resource`.
+* Added addType() and setType() to `EasyRdf_Resource`.
+* Added a textarea to the converter example.
+* Added support for parsing the json-triples format.
+* Renamed `EasyRdf_SparqlClient` to `EasyRdf_Sparql_Client`
+* Renamed `EasyRdf_SparqlResult` to `EasyRdf_Sparql_Result`
+* Fix for $graph->isEmpty() failing after adding and deleting some triples
+* Added new `EasyRdf_DatatypeMapper` class that allows you to map RDF datatypes to PHP classes.
+* Renamed guessDatatype() to getDatatypeForValue() in `EasyRdf_Literal`.
+* Added getResource() and allResources() to `EasyRdf_Graph` and `EasyRdf_Resource`
+* Implemented value casting in literals based on the datatype.
+
+
+EasyRdf 0.6.0
+=============
+* Major re-factor of the way data is stored internally in `EasyRdf_Graph`.
+* Parsing and serialising is now much faster and will enable further optimisations.
+* API is mostly backwards-compatible apart from:
+ - Changed inverse property operator from - to ^ to match Sparql 1.1 property paths.
+ - New `EasyRdf_Graphs` will not automatically be loaded on creation
+ You must now call $graph->load();
+ - Setting the default HTTP client is now part of a new `EasyRdf_Http` class
+ - It is no-longer possible to add multiple properties at once using an associative array.
+* Added methods to `EasyRdf_Graph` for direct manipulation of triples.
+* Added new `EasyRdf_GraphStore` - class for fetching, saving and deleting graphs to a Graph Store over HTTP.
+* Added new `EasyRdf_SparqlClient` and `EasyRdf_SparqlResult` - class for querying a SPARQL endpoint over HTTP.
+* Added q values for each Mime-Type associated with an `EasyRdf_Format`.
+* New example demonstrating integration with the Zend Framework.
+* New `EasyRdf_HTTP_MockClient` class makes testing easier.
+
+
+EasyRdf 0.5.2
+=============
+* Added a built-in RDF/XML parser
+* Made the RDF/XML serialiser use the rdf:type to open tags
+* Added support for comments in the N-Triples parser
+* Added new resolveUriReference() function to `EasyRdf_Utils`
+* Added the application/rdf+json and text/rdf+n3 mime types
+
+
+EasyRdf 0.5.1
+=============
+* Bug fixes for PHP 5.2
+
+
+EasyRdf 0.5.0
+=============
+* Added support for inverse properties.
+* Updated RDF/XML and Turtle serialisers to create new namespaces if possible.
+* Added new is_a($type) method to `EasyRdf_Resource`.
+* Added support for passing an array of properties to the get() method.
+* Added primaryTopic() method to `EasyRdf_Resource`.
+* The function label() in `EasyRdf_Resource` will no longer attempted to shorten the URI,
+ if there is no label available.
+* Resource types are now stored as resources, instead of shortened URIs.
+* Added support for deleting a specific value for property to `EasyRdf_Resource`.
+* Properties and datatypes are now stored as full URIs and not
+ converted to qnames during import.
+* Change the TypeMapper to store full URIs internally.
+* Added bibo and geo to the set of default namespaces.
+* Improved bnode links in dump format
+* Fix for converting non-string `EasyRdf_Literal` to string.
+* Created an example that resolves UK postcodes using uk-postcodes.com.
+
+
+EasyRdf 0.4.0
+=============
+* Moved source code to Github
+* Added an `EasyRdf_Literal` class
+* Added proper support for Datatypes and Languages
+* Added built-in RDF/XML serialiser
+* Added built-in Turtle serialiser
+* Added a new `EasyRdf_Format` class to deal with mime types etc.
+* finished a major refactoring of the Parser/Serialiser registration
+* removed all parsing related code from `EasyRdf_Graph`
+* Added a basic serialisation example
+* Added additional common namespaces
+* Test fixes
+
+
+EasyRdf 0.3.0
+=============
+* Generated Wiki pages from phpdoc
+* Filtering of literals by language
+* Moved parsers into `EasyRdf_Parser_XXX` namespace
+* Added support for serialisation
+* Wrote RDF generation example (foafmaker.php)
+* Added built-in ntriples parser/generator
+* Added built-in RDF/PHP serialiser
+* Added built-in RDF/JSON serialiser
+* Added SKOS and RSS to the set of default namespaces.
+
+
+EasyRdf 0.2.0
+=============
+* Added support for Redland PHP bindings
+* Added support for n-triples document type.
+* Improved blank node handing and added newBNode() method to `EasyRdf_Graph`.
+* Add option to `EasyRdf_RapperParser` to choose location of rapper command
+* Added Rails style HTML tag helpers to examples to make them simpler
+
+
+EasyRdf 0.1.0
+=============
+* First public release
+* Support for ARC2 and Rapper
+* Built-in HTTP Client
+* API Documentation
+* PHP Unit tests for every class.
+* Several usage examples
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/LICENSE.md Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,23 @@
+LICENSE
+=======
+
+Copyright (c) 2009-2011 Nicholas J Humfrey. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * The name of the author 'Nicholas J Humfrey" may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/Makefile Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,152 @@
+PACKAGE = easyrdf
+VERSION = $(shell php -r "print json_decode(file_get_contents('composer.json'))->version;")
+distdir = $(PACKAGE)-$(VERSION)
+PHP = $(shell which php)
+COMPOSER_FLAGS=--no-ansi --no-interaction
+PHPUNIT = vendor/bin/phpunit
+PHPUNIT_FLAGS = -c config/phpunit.xml
+PHPCS = vendor/bin/phpcs
+PHPCS_FLAGS = --standard=./config/phpcs_ruleset.xml --encoding=utf8 --extensions=php
+SAMI = vendor/bin/sami.php
+
+# Composer doesn't work with bsdtar - try and use GNU tar
+TAR = $(shell which gtar || which gnutar || which tar)
+
+# Disable copying extended attributes and resource forks on Mac OS X
+export COPYFILE_DISABLE=true
+
+EXAMPLE_FILES = examples/*.php
+SOURCE_FILES = lib/EasyRdf.php \
+ lib/EasyRdf/*.php \
+ lib/EasyRdf/*/*.php
+TEST_FILES = test/*/*Test.php \
+ test/*/*/*Test.php
+TEST_SUPPORT = Makefile test/cli_example_wrapper.php \
+ test/TestHelper.php \
+ test/EasyRdf/TestCase.php \
+ test/EasyRdf/Http/MockClient.php \
+ test/EasyRdf/Serialiser/NtriplesArray.php \
+ test/fixtures/*
+DOC_FILES = docs/*.md \
+ docs/api
+INFO_FILES = composer.json \
+ doap.rdf \
+ README.md \
+ LICENSE.md \
+ CHANGELOG.md
+
+DISTFILES = $(EXAMPLE_FILES) $(SOURCE_FILES) $(TEST_FILES) \
+ $(TEST_SUPPORT) $(INFO_FILES) $(DOC_FILES)
+
+
+.DEFAULT: help
+all: help
+
+# TARGET:test Run all the PHPUnit tests
+.PHONY: test
+test: $(PHPUNIT)
+ mkdir -p reports
+ $(PHP) $(PHPUNIT) $(PHPUNIT_FLAGS)
+
+# TARGET:test-examples Run PHPUnit tests for each of the examples
+.PHONY: test-examples
+test-examples: $(PHPUNIT)
+ mkdir -p reports
+ $(PHP) $(PHPUNIT) $(PHPUNIT_FLAGS) --testsuite "EasyRdf Examples"
+
+# TARGET:test-lib Run PHPUnit tests for the library
+.PHONY: test-lib
+test-lib: $(PHPUNIT)
+ mkdir -p reports
+ $(PHP) $(PHPUNIT) $(PHPUNIT_FLAGS) --testsuite "EasyRdf Library"
+
+# TARGET:coverage Run library tests and generate coverage report
+.PHONY: coverage
+coverage: $(PHPUNIT)
+ mkdir -p reports/coverage
+ $(PHP) $(PHPUNIT) $(PHPUNIT_FLAGS) --coverage-html ./reports/coverage --testsuite "EasyRdf Library"
+
+# TARGET:apidocs Generate HTML API documentation
+.PHONY: apidocs
+apidocs: $(SAMI)
+ $(PHP) $(SAMI) update config/sami.php -n -v --force
+
+docs/api: apidocs
+
+doap.rdf: doap.php composer.json vendor/autoload.php
+ $(PHP) doap.php > doap.rdf
+
+# TARGET:cs Check the code style of the PHP source code
+.PHONY: cs
+cs: $(PHPCS)
+ $(PHPCS) $(PHPCS_FLAGS) lib test
+
+# TARGET:lint Perform basic PHP syntax check on all files
+.PHONY: lint
+lint: $(EXAMPLE_FILES) $(SOURCE_FILES) $(TEST_FILES)
+ @for file in $^; do \
+ $(PHP) -l $$file || exit -1; \
+ done
+
+# TARGET:dist Build archives for distribution
+.PHONY: dist
+dist: $(distdir).tar.gz
+ rm -Rf $(distdir)
+ @echo "Done."
+
+%.tar.gz: %
+ $(TAR) zcf $@ $^
+
+$(distdir): $(DISTFILES)
+ $(gatherfiles)
+
+define gatherfiles
+ @for file in $^; do \
+ dir=$@/`dirname "$$file"`; \
+ test -d "$$dir" || mkdir -p "$$dir" || exit -1; \
+ cp -Rfp "$$file" "$@/$$file" || exit -1; \
+ done
+endef
+
+# TARGET:clean Delete any temporary and generated files
+.PHONY: clean
+clean:
+ find . -name '.DS_Store' -type f -delete
+ -rm -Rf $(distdir) reports vendor
+ -rm -Rf docs/api samicache
+ -rm -f composer.phar composer.lock
+ -rm -f doap.rdf
+
+# TARGET:check-fixme Scan for files containing the words TODO or FIXME
+.PHONY: check-fixme
+check-fixme:
+ @git grep -n -E 'FIXME|TODO' || echo "No FIXME or TODO lines found."
+
+# TARGET:help You're looking at it!
+.PHONY: help
+help:
+ # Usage:
+ # make <target> [OPTION=value]
+ #
+ # Targets:
+ @egrep "^# TARGET:" [Mm]akefile | sed 's/^# TARGET:/# /'
+ #
+ # Options:
+ # PHP Path to php
+
+
+
+# Composer rules
+composer.phar:
+ curl -s -z composer.phar -o composer.phar http://getcomposer.org/composer.phar
+
+composer-install: composer.phar
+ $(PHP) composer.phar $(COMPOSER_FLAGS) install --dev
+
+composer-update: clean composer.phar
+ $(PHP) composer.phar $(COMPOSER_FLAGS) update --dev
+
+vendor/autoload.php: composer-install
+vendor/bin/phpunit: composer-install
+vendor/bin/phpcs: composer-install
+vendor/bin/sami.php: composer-install
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/README.md Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,111 @@
+EasyRdf
+=======
+EasyRdf is a PHP library designed to make it easy to consume and produce [RDF].
+It was designed for use in mixed teams of experienced and inexperienced RDF
+developers. It is written in Object Oriented PHP and has been tested
+extensively using PHPUnit.
+
+After parsing EasyRdf builds up a graph of PHP objects that can then be walked
+around to get the data to be placed on the page. Dump methods are available to
+inspect what data is available during development.
+
+Data is typically loaded into a [EasyRdf_Graph] object from source RDF
+documents, loaded from the web via HTTP. The [EasyRdf_GraphStore] class
+simplifies loading and saving data to a SPARQL 1.1 Graph Store.
+
+SPARQL queries can be made over HTTP to a Triplestore using the
+[EasyRdf_Sparql_Client] class. SELECT and ASK queries will return an
+[EasyRdf_Sparql_Result] object and CONSTRUCT and DESCRIBE queries will return
+an [EasyRdf_Graph] object.
+
+### Example ###
+
+ $foaf = new EasyRdf_Graph("http://njh.me/foaf.rdf");
+ $foaf->load();
+ $me = $foaf->primaryTopic();
+ echo "My name is: ".$me->get('foaf:name')."\n";
+
+
+Downloads
+---------
+
+The latest _stable_ version of EasyRdf can be [downloaded from the EasyRdf website].
+
+
+Links
+-----
+
+* [EasyRdf Homepage](http://www.easyrdf.org/)
+* [API documentation](http://www.easyrdf.org/docs/api)
+* [Change Log](http://github.com/njh/easyrdf/blob/master/CHANGELOG.md)
+* Source Code: <http://github.com/njh/easyrdf>
+* Issue Tracker: <http://github.com/njh/easyrdf/issues>
+
+
+Requirements
+------------
+
+* PHP 5.2.8 or higher
+
+
+Features
+--------
+
+* API documentation written in phpdoc
+* Extensive unit tests written using phpunit
+ * Automated testing against PHP 5.2, 5.3 and 5.4
+* Built-in parsers and serialisers: RDF/JSON, N-Triples, RDF/XML, Turtle
+* Optional parsing support for: [ARC2], [Redland Bindings], [rapper]
+* Optional support for [Zend_Http_Client]
+* No required external dependancies upon other libraries (PEAR, Zend, etc...)
+* Complies with Zend Framework coding style.
+* Type mapper - resources of type foaf:Person can be mapped into PHP object of class Foaf_Person
+* Support for visualisation of graphs using [GraphViz]
+* Comes with a number of examples
+
+
+More Examples
+-------------
+
+* [artistinfo.php](https://github.com/njh/easyrdf/blob/master/examples/artistinfo.php#slider) - Example of mapping an RDF class type to a PHP Class
+* [basic.php](https://github.com/njh/easyrdf/blob/master/examples/basic.php#slider) - Basic "Hello World" type example
+* [basic_sparql.php](https://github.com/njh/easyrdf/blob/master/examples/basic_sparql.php#slider) - Example of making a SPARQL SELECT query
+* [converter.php](https://github.com/njh/easyrdf/blob/master/examples/converter.php#slider) - Convert RDF from one format to another
+* [dump.php](https://github.com/njh/easyrdf/blob/master/examples/dump.php#slider) - Display the contents of a graph
+* [foafinfo.php](https://github.com/njh/easyrdf/blob/master/examples/foafinfo.php#slider) - Display the basic information in a FOAF document
+* [foafmaker.php](https://github.com/njh/easyrdf/blob/master/examples/foafmaker.php#slider) - Construct a FOAF document with a choice of serialisations
+* [graph_direct.php](https://github.com/njh/easyrdf/blob/master/examples/graph_direct.php#slider) - Example of using EasyRdf_Graph directly without EasyRdf_Resource
+* [graphstore.php](https://github.com/njh/easyrdf/blob/master/examples/graphstore.php#slider) - Store and retrieve data from a SPARQL 1.1 Graph Store
+* [graphviz.php](https://github.com/njh/easyrdf/blob/master/examples/graphviz.php#slider) - GraphViz rendering example
+* [html_tag_helpers.php](https://github.com/njh/easyrdf/blob/master/examples/html_tag_helpers.php#slider) - Rails Style html tag helpers to make the EasyRdf examples simplier
+* [httpget.php](https://github.com/njh/easyrdf/blob/master/examples/httpget.php#slider) - No RDF, just test EasyRdf_Http_Client
+* [serialise.php](https://github.com/njh/easyrdf/blob/master/examples/serialise.php#slider) - Basic serialisation example
+* [sparql_queryform.php](https://github.com/njh/easyrdf/blob/master/examples/sparql_queryform.php#slider) - Form to submit SPARQL queries and display the result
+* [uk_postcode.php](https://github.com/njh/easyrdf/blob/master/examples/uk_postcode.php#slider) - Example of resolving UK postcodes using uk-postcodes.com
+* [villages.php](https://github.com/njh/easyrdf/blob/master/examples/villages.php#slider) - Fetch and information about villages in Fife from dbpedialite.org
+* [zend_framework.php](https://github.com/njh/easyrdf/blob/master/examples/zend_framework.php#slider) - Example of using Zend_Http_Client and Zend_Loader_Autoloader with EasyRdf
+
+
+Licensing
+---------
+
+The EasyRdf library and tests are licensed under the [BSD-3-Clause] license.
+The examples are in the public domain, for more information see [UNLICENSE].
+
+
+
+[EasyRdf_Graph]:http://www.easyrdf.org/docs/api/EasyRdf_Graph.html
+[EasyRdf_GraphStore]:http://www.easyrdf.org/docs/api/EasyRdf_GraphStore.html
+[EasyRdf_Sparql_Client]:http://www.easyrdf.org/docs/api/EasyRdf_Sparql_Client.html
+[EasyRdf_Sparql_Result]:http://www.easyrdf.org/docs/api/EasyRdf_Sparql_Result.html
+
+[ARC2]:http://github.com/semsol/arc2/
+[BSD-3-Clause]:http://www.opensource.org/licenses/BSD-3-Clause
+[downloaded from the EasyRdf website]:http://www.easyrdf.org/downloads
+[GraphViz]:http://www.graphviz.org/
+[rapper]:http://librdf.org/raptor/rapper.html
+[RDF]:http://en.wikipedia.org/wiki/Resource_Description_Framework
+[Redland Bindings]:http://librdf.org/bindings/
+[SPARQL 1.1 query language]:http://www.w3.org/TR/sparql11-query/
+[UNLICENSE]:http://unlicense.org/
+[Zend_Http_Client]:http://framework.zend.com/manual/en/zend.http.client.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/composer.json Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,40 @@
+{
+ "name": "easyrdf/easyrdf",
+ "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.",
+ "version": "0.8.0-beta.2",
+ "type": "library",
+ "keywords": ["RDF", "Semantic Web", "Linked Data", "Turtle", "RDFa", "SPARQL"],
+ "homepage": "http://www.easyrdf.org/",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Nicholas Humfrey",
+ "email": "njh@aelius.com",
+ "homepage": "http://www.aelius.com/njh/",
+ "role": "Developer"
+ }
+ ],
+ "support": {
+ "forum": "http://groups.google.com/group/easyrdf/",
+ "issues": "http://github.com/njh/easyrdf/issues",
+ "irc": "irc://chat.freenode.net/easyrdf"
+ },
+ "require": {
+ "php": ">=5.2.8"
+ },
+ "suggest": {
+ "ml/json-ld": "dev-master"
+ },
+ "require-dev": {
+ "phpunit/PHPUnit": ">=3.5.15",
+ "squizlabs/php_codesniffer": ">=1.4.3",
+ "sami/sami": "dev-master",
+ "ml/json-ld": "dev-master"
+ },
+ "replace": {
+ "njh/easyrdf": "self.version"
+ },
+ "autoload": {
+ "psr-0": { "EasyRdf_": "lib/" }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/config/phpcs_ruleset.xml Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<ruleset name="EasyRdf">
+ <description>Extensions to the PSR-2 coding standard.</description>
+
+ <!-- Include the PSR-2 standard -->
+ <rule ref="PSR2">
+ <!--
+ These two sniffs doesn't detect PHP 5.2 namespaces / class names correctly
+ See: https://pear.php.net/bugs/bug.php?id=19774
+ -->
+ <exclude name="PSR1.Classes.ClassDeclaration.MissingNamespace"/>
+ <exclude name="Squiz.Classes.ValidClassName"/>
+
+ <!-- FIXME: We currently use side-effects to register classes -->
+ <exclude name="PSR1.Files.SideEffects.FoundWithSymbols" />
+ </rule>
+
+</ruleset>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/config/phpunit.xml Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit
+ backupGlobals="false"
+ backupStaticAttributes="false"
+ colors="false"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ strict="true"
+ syntaxCheck="false"
+ verbose="false">
+
+ <php>
+ <!--
+ Fix for coverage report causing Seg Fault
+ (see https://bugs.php.net/bug.php?id=53976)
+ -->
+ <ini name="zend.enable_gc" value="0" />
+ </php>
+
+ <testsuites>
+ <testsuite name="EasyRdf Library">
+ <directory suffix="Test.php">../test/EasyRdf/</directory>
+ </testsuite>
+ <testsuite name="EasyRdf Examples">
+ <directory suffix="Test.php">../test/examples/</directory>
+ </testsuite>
+ </testsuites>
+
+ <!-- Files to be included in the coverage report -->
+ <filter>
+ <whitelist addUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">../lib/EasyRdf/</directory>
+ </whitelist>
+ </filter>
+
+ <logging>
+ <log type="text" target="php://stdout" />
+ <log type="junit" target="../reports/test-results.xml" />
+ </logging>
+</phpunit>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/config/sami.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,22 @@
+<?php
+
+use Sami\Sami;
+use Symfony\Component\Finder\Finder;
+
+$root = realpath(__DIR__ . "/..");
+$iterator = Finder::create()
+ ->files()
+ ->name('*.php')
+ ->exclude('arc')
+ ->in($root.'/lib')
+;
+
+return new Sami($iterator, array(
+ 'title' => 'EasyRdf API Documentation',
+ 'theme' => 'enhanced',
+ 'build_dir' => "$root/docs/api",
+ 'cache_dir' => "$root/samicache",
+ 'include_parent_data' => true,
+ 'simulate_namespaces' => true,
+ 'default_opened_level' => 1,
+));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/doap.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,45 @@
+<?php
+ require_once "vendor/autoload.php";
+
+ // Load some properties from the composer file
+ $composer = json_decode(file_get_contents(__DIR__."/composer.json"));
+
+ // Start building up a RDF graph
+ $doap = new EasyRdf_Graph($composer->homepage.'doap.rdf');
+ $easyrdf = $doap->resource('#easyrdf', 'doap:Project', 'foaf:Project');
+ $easyrdf->addLiteral('doap:name', 'EasyRDF');
+ $easyrdf->addLiteral('doap:shortname', 'easyrdf');
+ $easyrdf->addLiteral('doap:revision', $composer->version);
+ $easyrdf->addLiteral('doap:shortdesc', $composer->description, 'en');
+ $easyrdf->addResource('doap:homepage', $composer->homepage);
+
+ $easyrdf->addLiteral('doap:programming-language', 'PHP');
+ $easyrdf->addLiteral(
+ 'doap:description', 'EasyRdf is a PHP library designed to make it easy to consume and produce RDF. '.
+ 'It was designed for use in mixed teams of experienced and inexperienced RDF developers. '.
+ 'It is written in Object Oriented PHP and has been tested extensively using PHPUnit.', 'en'
+ );
+ $easyrdf->addResource('doap:license', 'http://usefulinc.com/doap/licenses/bsd');
+ $easyrdf->addResource('doap:download-page', 'http://github.com/njh/easyrdf/downloads');
+ $easyrdf->addResource('doap:download-page', 'http://github.com/njh/easyrdf/downloads');
+ $easyrdf->addResource('doap:bug-database', 'http://github.com/njh/easyrdf/issues');
+ $easyrdf->addResource('doap:mailing-list', 'http://groups.google.com/group/easyrdf');
+
+ $easyrdf->addResource('doap:category', 'http://dbpedia.org/resource/Resource_Description_Framework');
+ $easyrdf->addResource('doap:category', 'http://dbpedia.org/resource/PHP');
+ $easyrdf->addResource('doap:category', 'http://dbpedialite.org/things/24131#id');
+ $easyrdf->addResource('doap:category', 'http://dbpedialite.org/things/53847#id');
+
+ $repository = $doap->newBNode('doap:GitRepository');
+ $repository->addResource('doap:browse', 'http://github.com/njh/easyrdf');
+ $repository->addResource('doap:location', 'git://github.com/njh/easyrdf.git');
+ $easyrdf->addResource('doap:repository', $repository);
+
+ $njh = $doap->resource('http://njh.me/', 'foaf:Person');
+ $njh->addLiteral('foaf:name', 'Nicholas J Humfrey');
+ $njh->addResource('foaf:homepage', 'http://www.aelius.com/njh/');
+ $easyrdf->add('doap:maintainer', $njh);
+ $easyrdf->add('doap:developer', $njh);
+ $easyrdf->add('foaf:maker', $njh);
+
+ print $doap->serialise('rdfxml');
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/docs/01-getting-started.md Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,47 @@
+Getting Started
+===============
+
+The preferred method of downloading and installing EasyRdf, is to use
+[Composer], a dependency manager that tracks all dependencies of your project.
+
+
+First, install composer in your project:
+
+ curl -s https://getcomposer.org/installer | php
+
+
+Create a composer.json file in your project root:
+
+ {
+ "require": {
+ "easyrdf/easyrdf": "*"
+ }
+ }
+
+
+Install EasyRdf (and any other dependencies) using:
+
+ php composer.phar install
+
+
+Then to start using EasyRdf in your project, add this to the top of your file:
+
+ <?php
+ require 'vendor/autoload.php';
+
+This will load composer's autoloader and make the EasyRdf classes available to your
+programme.
+
+
+A full basic example looks like this:
+
+ <?php
+ require 'vendor/autoload.php';
+
+ $foaf = new EasyRdf_Graph("http://njh.me/foaf.rdf");
+ $foaf->load();
+ $me = $foaf->primaryTopic();
+ echo "My name is: ".$me->get('foaf:name')."\n";
+
+
+[Composer]:http://getcomposer.org/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/docs/02-property-paths.md Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,26 @@
+Property Paths
+==============
+
+EasyRdf supports querying the data in a graph using basic property paths.
+This is a small subset of the property paths described in [SPARQL 1.1 query language].
+
+
+You may use the caret character (^) to get an inverse property, for example:
+
+ $person = $homepage->get('^foaf:homepage');
+
+You can use the pipe character (|) to get alternate properties, for example:
+
+ $title = $document->get('dc:title|dc11:title');
+
+You can use a forward slash (/) to follow a property sequence, for example to get
+the names of all my friends:
+
+ $names = $me->all('foaf:knows/foaf:name');
+
+Finally, in order to use a full property URI, enclose it in angle brackets:
+
+ $name = $me->get('<http://xmlns.com/foaf/0.1/name>');
+
+
+[SPARQL 1.1 query language]:http://www.w3.org/TR/sparql11-query/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/artistinfo.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,91 @@
+<?php
+ /**
+ * Mapping an RDF class type to a PHP Class
+ *
+ * This example fetches and displays artist information from the
+ * BBC Music website. The artist object is an instance of the
+ * Model_MusicArtist class, so it is possible to call custom PHP
+ * methods on the object.
+ *
+ * It also demonstrates setting new namespaces.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+ require_once "html_tag_helpers.php";
+
+
+ class Model_MusicArtist extends EasyRdf_Resource
+ {
+ function birthEvent()
+ {
+ foreach ($this->all('bio:event') as $event) {
+ if (in_array('bio:Birth', $event->types())) {
+ return $event;
+ }
+ }
+ return null;
+ }
+
+ function age()
+ {
+ $birth = $this->birthEvent();
+ if ($birth) {
+ $year = substr($birth->get('bio:date'), 0, 4);
+ if ($year) {
+ return date('Y') - $year;
+ }
+ }
+ return 'unknown';
+ }
+ }
+
+ ## Add namespaces
+ EasyRdf_Namespace::set('mo', 'http://purl.org/ontology/mo/');
+ EasyRdf_Namespace::set('bio', 'http://purl.org/vocab/bio/0.1/');
+ EasyRdf_TypeMapper::set('mo:MusicArtist', 'Model_MusicArtist');
+?>
+<html>
+<head><title>EasyRdf Artist Info Example</title></head>
+<body>
+<h1>EasyRdf Artist Info Example</h1>
+
+<?= form_tag() ?>
+<?= text_field_tag('uri', 'http://www.bbc.co.uk/music/artists/70248960-cb53-4ea4-943a-edb18f7d336f.rdf', array('size'=>50)) ?>
+<?= submit_tag() ?>
+<?= form_end_tag() ?>
+
+<?php
+ if (isset($_REQUEST['uri'])) {
+ $graph = EasyRdf_Graph::newAndLoad($_REQUEST['uri']);
+ $artist = $graph->primaryTopic();
+ }
+
+ if (isset($artist)) {
+?>
+
+<dl>
+ <dt>Artist Name:</dt><dd><?= $artist->get('foaf:name') ?></dd>
+ <dt>Type:</dt><dd><?= join(', ', $artist->types()) ?></dd>
+ <dt>Homepage:</dt><dd><?= link_to($artist->get('foaf:homepage')) ?></dd>
+ <dt>Wikipedia page:</dt><dd><?= link_to($artist->get('mo:wikipedia')) ?></dd>
+ <?php
+ if ($artist->isA('mo:SoloMusicArtist')) {
+ echo " <dt>Age:</dt>";
+ echo " <dd>".$artist->age()."</dd>\n";
+ }
+ ?>
+</dl>
+<?php
+ }
+
+ if (isset($graph)) {
+ echo $graph->dump();
+ }
+?>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/basic.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,34 @@
+<?php
+ /**
+ * Basic "Hello World" type example
+ *
+ * A new EasyRdf_Graph object is created and then the contents
+ * of my FOAF profile is loaded from the web. An EasyRdf_Resource for
+ * the primary topic of the document (me, Nicholas Humfrey) is returned
+ * and then used to display my name.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+?>
+<html>
+<head>
+ <title>Basic FOAF example</title>
+</head>
+<body>
+
+<?php
+ $foaf = EasyRdf_Graph::newAndLoad('http://njh.me/foaf.rdf');
+ $me = $foaf->primaryTopic();
+?>
+
+<p>
+ My name is: <?= $me->get('foaf:name') ?>
+</p>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/basic_sparql.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,57 @@
+<?php
+ /**
+ * Making a SPARQL SELECT query
+ *
+ * This example creates a new SPARQL client, pointing at the
+ * dbpedia.org endpoint. It then makes a SELECT query that
+ * returns all of the countries in DBpedia along with an
+ * english label.
+ *
+ * Note how the namespace prefix declarations are automatically
+ * added to the query.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+ require_once "html_tag_helpers.php";
+
+ // Setup some additional prefixes for DBpedia
+ EasyRdf_Namespace::set('category', 'http://dbpedia.org/resource/Category:');
+ EasyRdf_Namespace::set('dbpedia', 'http://dbpedia.org/resource/');
+ EasyRdf_Namespace::set('dbo', 'http://dbpedia.org/ontology/');
+ EasyRdf_Namespace::set('dbp', 'http://dbpedia.org/property/');
+
+ $sparql = new EasyRdf_Sparql_Client('http://dbpedia.org/sparql');
+?>
+<html>
+<head>
+ <title>EasyRdf Basic Sparql Example</title>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+</head>
+<body>
+<h1>EasyRdf Basic Sparql Example</h1>
+
+<h2>List of countries</h2>
+<ul>
+<?php
+ $result = $sparql->query(
+ 'SELECT * WHERE {'.
+ ' ?country rdf:type dbo:Country .'.
+ ' ?country rdfs:label ?label .'.
+ ' ?country dc:subject category:Member_states_of_the_United_Nations .'.
+ ' FILTER ( lang(?label) = "en" )'.
+ '} ORDER BY ?label'
+ );
+ foreach ($result as $row) {
+ echo "<li>".link_to($row->label, $row->country)."</li>\n";
+ }
+?>
+</ul>
+<p>Total number of countries: <?= $result->numRows() ?></p>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/converter.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,97 @@
+<?php
+ /**
+ * Convert RDF from one format to another
+ *
+ * The source RDF data can either be fetched from the web
+ * or typed into the Input box.
+ *
+ * The first thing that this script does is make a list the names of the
+ * supported input and output formats. These options are then
+ * displayed on the HTML form.
+ *
+ * The input data is loaded or parsed into an EasyRdf_Graph.
+ * That graph is than outputted again in the desired output format.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+ require_once "html_tag_helpers.php";
+
+ $input_format_options = array('Guess' => 'guess');
+ $output_format_options = array();
+ foreach (EasyRdf_Format::getFormats() as $format) {
+ if ($format->getSerialiserClass()) {
+ $output_format_options[$format->getLabel()] = $format->getName();
+ }
+ if ($format->getParserClass()) {
+ $input_format_options[$format->getLabel()] = $format->getName();
+ }
+ }
+
+ // Stupid PHP :(
+ if (get_magic_quotes_gpc() and isset($_REQUEST['data'])) {
+ $_REQUEST['data'] = stripslashes($_REQUEST['data']);
+ }
+
+ // Default to Guess input and Turtle output
+ if (!isset($_REQUEST['output_format'])) {
+ $_REQUEST['output_format'] = 'turtle';
+ }
+ if (!isset($_REQUEST['input_format'])) {
+ $_REQUEST['input_format'] = 'guess';
+ }
+
+ // Display the form, if raw option isn't set
+ if (!isset($_REQUEST['raw'])) {
+ print "<html>\n";
+ print "<head><title>EasyRdf Converter</title></head>\n";
+ print "<body>\n";
+ print "<h1>EasyRdf Converter</h1>\n";
+
+ print "<div style='margin: 10px'>\n";
+ print form_tag();
+ print label_tag('data', 'Input Data: ').'<br />'.text_area_tag('data', '', array('cols'=>80, 'rows'=>10)) . "<br />\n";
+ print label_tag('uri', 'or Uri: ').text_field_tag('uri', 'http://www.dajobe.org/foaf.rdf', array('size'=>80)) . "<br />\n";
+ print label_tag('input_format', 'Input Format: ').select_tag('input_format', $input_format_options) . "<br />\n";
+ print label_tag('output_format', 'Output Format: ').select_tag('output_format', $output_format_options) . "<br />\n";
+ print label_tag('raw', 'Raw Output: ').check_box_tag('raw') . "<br />\n";
+ print reset_tag() . submit_tag();
+ print form_end_tag();
+ print "</div>\n";
+ }
+
+ if (isset($_REQUEST['uri']) or isset($_REQUEST['data'])) {
+ // Parse the input
+ $graph = new EasyRdf_Graph($_REQUEST['uri']);
+ if (empty($_REQUEST['data'])) {
+ $graph->load($_REQUEST['uri'], $_REQUEST['input_format']);
+ } else {
+ $graph->parse($_REQUEST['data'], $_REQUEST['input_format'], $_REQUEST['uri']);
+ }
+
+ // Lookup the output format
+ $format = EasyRdf_Format::getFormat($_REQUEST['output_format']);
+
+ // Serialise to the new output format
+ $output = $graph->serialise($format);
+ if (!is_scalar($output)) {
+ $output = var_export($output, true);
+ }
+
+ // Send the output back to the client
+ if (isset($_REQUEST['raw'])) {
+ header('Content-Type: '.$format->getDefaultMimeType());
+ print $output;
+ } else {
+ print '<pre>'.htmlspecialchars($output).'</pre>';
+ }
+ }
+
+ if (!isset($_REQUEST['raw'])) {
+ print "</body>\n";
+ print "</html>\n";
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/dump.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,60 @@
+<?php
+ /**
+ * Display the contents of a graph
+ *
+ * Data from the chosen URI is loaded into an EasyRdf_Graph object.
+ * Then the graph is dumped and printed to the page using the
+ * $graph->dump() method.
+ *
+ * The call to preg_replace() replaces links in the page with
+ * links back to this dump script.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+ require_once "html_tag_helpers.php";
+
+?>
+<html>
+<head><title>EasyRdf Graph Dumper</title></head>
+<body>
+<h1>EasyRdf Graph Dumper</h1>
+
+<div style="margin: 10px">
+ <?= form_tag() ?>
+ URI: <?= text_field_tag('uri', 'http://mmt.me.uk/foaf.rdf', array('size'=>80)) ?><br />
+ Format: <?= label_tag('format_html', 'HTML').' '.radio_button_tag('format', 'html', true) ?>
+ <?= label_tag('format_text', 'Text').' '.radio_button_tag('format', 'text') ?><br />
+
+ <?= submit_tag() ?>
+ <?= form_end_tag() ?>
+</div>
+
+<?php
+ if (isset($_REQUEST['uri'])) {
+ $graph = EasyRdf_Graph::newAndLoad($_REQUEST['uri']);
+ if ($graph) {
+ if (isset($_REQUEST['format']) && $_REQUEST['format'] == 'text') {
+ print "<pre>".$graph->dump('text')."</pre>";
+ } else {
+ $dump = $graph->dump('html');
+ print preg_replace_callback("/ href='([^#][^']*)'/", 'makeLinkLocal', $dump);
+ }
+ } else {
+ print "<p>Failed to create graph.</p>";
+ }
+ }
+
+ # Callback function to re-write links in the dump to point back to this script
+ function makeLinkLocal($matches)
+ {
+ $href = $matches[1];
+ return " href='?uri=".urlencode($href)."#$href'";
+ }
+?>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/foafinfo.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,88 @@
+<?php
+ /**
+ * Display the basic information in a FOAF document
+ *
+ * The example starts by loading the requested FOAF document
+ * from the web. It then tries to work out if the URI given
+ * was for the person or the document about the person.
+ *
+ * If a person is found, then the person's name, homepage
+ * and description are shown, along with a list of the
+ * person's friends.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+ require_once "html_tag_helpers.php";
+?>
+<html>
+<head><title>EasyRdf FOAF Info Example</title></head>
+<body>
+<h1>EasyRdf FOAF Info Example</h1>
+
+<?= form_tag() ?>
+<?= text_field_tag('uri', 'http://njh.me/foaf.rdf', array('size'=>50)) ?>
+<?= submit_tag() ?>
+<?= form_end_tag() ?>
+
+<?php
+ if (isset($_REQUEST['uri'])) {
+ $graph = EasyRdf_Graph::newAndLoad($_REQUEST['uri']);
+ if ($graph->type() == 'foaf:PersonalProfileDocument') {
+ $person = $graph->primaryTopic();
+ } elseif ($graph->type() == 'foaf:Person') {
+ $person = $graph->resource();
+ }
+ }
+
+ if (isset($person)) {
+?>
+
+<dl>
+ <dt>Name:</dt><dd><?= $person->get('foaf:name') ?></dd>
+ <dt>Homepage:</dt><dd><?= link_to($person->get('foaf:homepage')) ?></dd>
+</dl>
+
+<?php
+ echo "<h2>Known Persons</h2>\n";
+ echo "<ul>\n";
+ foreach ($person->all('foaf:knows') as $friend) {
+ $label = $friend->label();
+ if (!$label) {
+ $label = $friend->getUri();
+ }
+
+ if ($friend->isBNode()) {
+ echo "<li>$label</li>";
+ } else {
+ echo "<li>".link_to_self($label, 'uri='.urlencode($friend))."</li>";
+ }
+ }
+ echo "</ul>\n";
+
+ echo "<h2>Interests</h2>\n";
+ echo "<ul>\n";
+ foreach ($person->all('foaf:interest') as $interest) {
+ $label = $interest->label();
+ if ($label) {
+ if ($interest->isBNode()) {
+ echo "<li>$label</li>";
+ } else {
+ echo "<li>".$interest->htmlLink($label)."</li>";
+ }
+ }
+ }
+ echo "</ul>\n";
+ }
+
+ if (isset($graph)) {
+ echo "<br />";
+ echo $graph->dump();
+ }
+?>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/foafmaker.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,115 @@
+<?php
+ /**
+ * Construct a FOAF document with a choice of serialisations
+ *
+ * This example is similar in concept to Leigh Dodds' FOAF-a-Matic.
+ * The fields in the HTML form are inserted into an empty
+ * EasyRdf_Graph and then serialised to the chosen format.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+ require_once "html_tag_helpers.php";
+
+ if (isset($_REQUEST['enable_arc']) && $_REQUEST['enable_arc']) {
+ require_once "EasyRdf/Serialiser/Arc.php";
+ EasyRdf_Format::registerSerialiser('ntriples', 'EasyRdf_Serialiser_Arc');
+ EasyRdf_Format::registerSerialiser('posh', 'EasyRdf_Serialiser_Arc');
+ EasyRdf_Format::registerSerialiser('rdfxml', 'EasyRdf_Serialiser_Arc');
+ EasyRdf_Format::registerSerialiser('turtle', 'EasyRdf_Serialiser_Arc');
+ }
+
+ if (isset($_REQUEST['enable_rapper']) && $_REQUEST['enable_rapper']) {
+ require_once "EasyRdf/Serialiser/Rapper.php";
+ EasyRdf_Format::registerSerialiser('dot', 'EasyRdf_Serialiser_Rapper');
+ EasyRdf_Format::registerSerialiser('rdfxml', 'EasyRdf_Serialiser_Rapper');
+ EasyRdf_Format::registerSerialiser('turtle', 'EasyRdf_Serialiser_Rapper');
+ }
+
+ $format_options = array();
+ foreach (EasyRdf_Format::getFormats() as $format) {
+ if ($format->getSerialiserClass()) {
+ $format_options[$format->getLabel()] = $format->getName();
+ }
+ }
+?>
+<html>
+<head><title>EasyRdf FOAF Maker Example</title></head>
+<body>
+<h1>EasyRdf FOAF Maker Example</h1>
+
+<?= form_tag(null, array('method' => 'POST')) ?>
+
+<h2>Your Identifier</h2>
+<?= labeled_text_field_tag('uri', 'http://www.example.com/joe#me', array('size'=>40)) ?><br />
+
+<h2>Your details</h2>
+<?= labeled_text_field_tag('title', 'Mr', array('size'=>8)) ?><br />
+<?= labeled_text_field_tag('given_name', 'Joseph') ?><br />
+<?= labeled_text_field_tag('family_name', 'Bloggs') ?><br />
+<?= labeled_text_field_tag('nickname', 'Joe') ?><br />
+<?= labeled_text_field_tag('email', 'joe@example.com') ?><br />
+<?= labeled_text_field_tag('homepage', 'http://www.example.com/', array('size'=>40)) ?><br />
+
+<h2>People you know</h2>
+<?= labeled_text_field_tag('person_1', 'http://www.example.com/dave#me', array('size'=>40)) ?><br />
+<?= labeled_text_field_tag('person_2', '', array('size'=>40)) ?><br />
+<?= labeled_text_field_tag('person_3', '', array('size'=>40)) ?><br />
+<?= labeled_text_field_tag('person_4', '', array('size'=>40)) ?><br />
+
+<h2>Output</h2>
+Enable Arc 2? <?= check_box_tag('enable_arc') ?><br />
+Enable Rapper? <?= check_box_tag('enable_rapper') ?><br />
+<?= label_tag('format').select_tag('format', $format_options, 'rdfxml') ?><br />
+
+<?= submit_tag() ?>
+<?= form_end_tag() ?>
+
+
+<?php
+ if (isset($_REQUEST['uri'])) {
+
+ $graph = new EasyRdf_Graph();
+
+ # 1st Technique
+ $me = $graph->resource($_REQUEST['uri'], 'foaf:Person');
+ $me->set('foaf:name', $_REQUEST['title'].' '.$_REQUEST['given_name'].' '.$_REQUEST['family_name']);
+ if ($_REQUEST['email']) {
+ $email = $graph->resource("mailto:".$_REQUEST['email']);
+ $me->add('foaf:mbox', $email);
+ }
+ if ($_REQUEST['homepage']) {
+ $homepage = $graph->resource($_REQUEST['homepage']);
+ $me->add('foaf:homepage', $homepage);
+ }
+
+ # 2nd Technique
+ $graph->addLiteral($_REQUEST['uri'], 'foaf:title', $_REQUEST['title']);
+ $graph->addLiteral($_REQUEST['uri'], 'foaf:givenname', $_REQUEST['given_name']);
+ $graph->addLiteral($_REQUEST['uri'], 'foaf:family_name', $_REQUEST['family_name']);
+ $graph->addLiteral($_REQUEST['uri'], 'foaf:nick', $_REQUEST['nickname']);
+
+ # Add friends
+ for($i=1; $i<=4; $i++) {
+ if ($_REQUEST["person_$i"]) {
+ $person = $graph->resource($_REQUEST["person_$i"]);
+ $graph->add($me, 'foaf:knows', $person);
+ }
+ }
+
+ # Finally output the graph
+ $data = $graph->serialise($_REQUEST['format']);
+ if (!is_scalar($data)) {
+ $data = var_export($data, true);
+ }
+ print "<pre>".htmlspecialchars($data)."</pre>";
+ }
+
+?>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/graph_direct.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,49 @@
+<?php
+ /**
+ * Using EasyRdf_Graph directly without EasyRdf_Resource
+ *
+ * Triple data is inserted and retrieved directly from a graph object,
+ * where it is stored internally as an associative array.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+?>
+<html>
+<head>
+ <title>Example of using EasyRdf_Graph directly</title>
+</head>
+<body>
+
+<?php
+ $graph = new EasyRdf_Graph();
+ $graph->addResource("http://example.com/joe", "rdf:type", "foaf:Person");
+ $graph->addLiteral("http://example.com/joe", "foaf:name", "Joe Bloggs");
+ $graph->addLiteral("http://example.com/joe", "foaf:name", "Joseph Bloggs");
+ $graph->add("http://example.com/joe", "rdfs:label", "Joe");
+
+ $graph->setType("http://njh.me/", "foaf:Person");
+ $graph->add("http://njh.me/", "rdfs:label", "Nick");
+ $graph->addLiteral("http://njh.me/", "foaf:name", "Nicholas Humfrey");
+ $graph->addResource("http://njh.me/", "foaf:homepage", "http://www.aelius.com/njh/");
+?>
+
+<p>
+ <b>Name:</b> <?= $graph->get("http://example.com/joe", "foaf:name") ?> <br />
+ <b>Names:</b> <?= $graph->join("http://example.com/joe", "foaf:name") ?> <br />
+
+ <b>Label:</b> <?= $graph->label("http://njh.me/") ?> <br />
+ <b>Properties:</b> <?= join(', ', $graph->properties("http://example.com/joe")) ?> <br />
+ <b>PropertyUris:</b> <?= join(', ', $graph->propertyUris("http://example.com/joe")) ?> <br />
+ <b>People:</b> <?= join(', ', $graph->allOfType('foaf:Person')) ?> <br />
+ <b>Unknown:</b> <?= $graph->get("http://example.com/joe", "unknown:property") ?> <br />
+</p>
+
+<?= $graph->dump() ?>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/graphstore.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,42 @@
+<?php
+ /**
+ * Store and retrieve data from a SPARQL 1.1 Graph Store
+ *
+ * This example adds a triple containing the current time into
+ * a local graph store. It then fetches the whole graph out
+ * and displays the contents.
+ *
+ * Note that you will need a graph store, for example RedStore,
+ * running on your local machine in order to test this example.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+?>
+<html>
+<head>
+ <title>GraphStore example</title>
+</head>
+<body>
+
+<?php
+ // Use a local SPARQL 1.1 Graph Store (eg RedStore)
+ $gs = new EasyRdf_GraphStore('http://localhost:8080/data/');
+
+ // Add the current time in a graph
+ $graph1 = new EasyRdf_Graph();
+ $graph1->add('http://example.com/test', 'rdfs:label', 'Test');
+ $graph1->add('http://example.com/test', 'dc:date', time());
+ $gs->insert($graph1, 'time.rdf');
+
+ // Get the graph back out of the graph store and display it
+ $graph2 = $gs->get('time.rdf');
+ print $graph2->dump();
+?>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/graphviz.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,86 @@
+<?php
+ /**
+ * GraphViz rendering example
+ *
+ * This example demonstrates converting an EasyRdf_Graph into the
+ * GraphViz graph file language. Using the 'Use Labels' option, you
+ * can have resource URIs replaced with text based labels and using
+ * 'Only Labelled' option, only the resources and properties with
+ * a label will be displayed.
+ *
+ * Rending a graph to an image will only work if you have the
+ * GraphViz 'dot' command installed.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2012-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+ require_once "html_tag_helpers.php";
+
+ $formats = array(
+ 'PNG' => 'png',
+ 'GIF' => 'gif',
+ 'SVG' => 'svg'
+ );
+
+ $format = EasyRdf_Format::getFormat(
+ isset($_REQUEST['format']) ? $_REQUEST['format'] : 'png'
+ );
+
+ // Construct a graph of three people
+ $graph = new EasyRdf_Graph();
+ $graph->set('foaf:knows', 'rdfs:label', 'knows');
+ $bob = $graph->resource('http://www.example.com/bob', 'foaf:Person');
+ $alice = $graph->resource('http://www.example.com/alice', 'foaf:Person');
+ $carol = $graph->resource('http://www.example.com/carol', 'foaf:Person');
+ $bob->set('foaf:name', 'Bob');
+ $alice->set('foaf:name', 'Alice');
+ $carol->set('foaf:name', 'Carol');
+ $bob->add('foaf:knows', $alice);
+ $bob->add('foaf:knows', $carol);
+ $alice->add('foaf:knows', $bob);
+ $alice->add('foaf:knows', $carol);
+
+ // Create a GraphViz serialiser
+ $gv = new EasyRdf_Serialiser_GraphViz();
+ $gv->setUseLabels(isset($_REQUEST['ul']));
+ $gv->setOnlyLabelled(isset($_REQUEST['ol']));
+
+ // If this is a request for the image, just render it and exit
+ if (isset($_REQUEST['image'])) {
+ header("Content-Type: ".$format->getDefaultMimeType());
+ echo $gv->renderImage($graph, $format);
+ exit;
+ }
+?>
+<html>
+<head><title>EasyRdf GraphViz Example</title></head>
+<body>
+<h1>EasyRdf GraphViz Example</h1>
+
+<form action='' method='get'>
+<?php
+ echo label_tag('format').' '.select_tag('format', $formats).tag('br');
+ echo label_tag('ul', 'Use labels:').' '.check_box_tag('ul').tag('br');
+ echo label_tag('ol', 'Only labelled:').' '.check_box_tag('ol').tag('br');
+ echo submit_tag();
+?>
+</form>
+
+<div>
+ <img src='?image&<?=$_SERVER["QUERY_STRING"]?>' />
+</div>
+
+<pre style="margin: 0.5em; padding:0.5em; background-color:#eee; border:dashed 1px grey;">
+<?php
+ print htmlspecialchars(
+ $gv->serialise($graph, 'dot')
+ );
+?>
+</pre>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/html_tag_helpers.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,218 @@
+<?php
+
+/**
+ * Rails Style html tag helpers
+ *
+ * These are used by the other examples to make the code
+ * more concise and simpler to read.
+ *
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+/* Examples:
+
+echo content_tag('p','Paragraph Tag', array('class'=>'foo'));
+
+echo tag('br');
+echo link_to('Hyperlink', 'http://www.example.com/?a=1&b=2');
+echo tag('br');
+
+echo form_tag();
+
+ echo label_tag('first_name').text_field_tag('first_name', 'Joe').tag('br');
+ echo label_tag('password').password_field_tag().tag('br');
+
+ echo label_tag('radio1_value1', 'Radio 1').radio_button_tag('radio1', 'value1').tag('br');
+ echo label_tag('radio1_value2', 'Radio 2').radio_button_tag('radio1', 'value2', true).tag('br');
+ echo label_tag('radio1_value3', 'Radio 3').radio_button_tag('radio1', 'value3').tag('br');
+
+ echo label_tag('check1', 'Check 1').check_box_tag('check1', 'value1').tag('br');
+ echo label_tag('check2', 'Check 2').check_box_tag('check2', 'value2', true).tag('br');
+ echo label_tag('check3', 'Check 3').check_box_tag('check3', 'value3').tag('br');
+
+ $options = array('Label 1' => 'value1', 'Label 2' => 'value2', 'Label 3' => 'value3');
+ echo label_tag('select1', 'Select Something:');
+ echo select_tag('select1', $options, 'value2').tag('br');
+
+ echo label_tag('textarea1', 'Type Something:');
+ echo text_area_tag('textarea1', "Hello World!").tag('br');
+
+ echo submit_tag();
+
+echo form_end_tag();
+
+*/
+
+
+function tag_options($options)
+{
+ $html = "";
+ foreach ($options as $key => $value) {
+ if ($key and $value) {
+ $html .= " ".htmlspecialchars($key)."=\"".
+ htmlspecialchars($value)."\"";
+ }
+ }
+ return $html;
+}
+
+function tag($name, $options = array(), $open = false)
+{
+ return "<$name".tag_options($options).($open ? ">" : " />");
+}
+
+function content_tag($name, $content = null, $options = array())
+{
+ return "<$name".tag_options($options).">".
+ htmlspecialchars($content)."</$name>";
+}
+
+function link_to($text, $uri = null, $options = array())
+{
+ if ($uri == null) $uri = $text;
+ $options = array_merge(array('href' => $uri), $options);
+ return content_tag('a', $text, $options);
+}
+
+function link_to_self($text, $query_string, $options = array())
+{
+ return link_to($text, $_SERVER['PHP_SELF'].'?'.$query_string, $options);
+}
+
+function image_tag($src, $options = array())
+{
+ $options = array_merge(array('src' => $src), $options);
+ return tag('img', $options);
+}
+
+function input_tag($type, $name, $value = null, $options = array())
+{
+ $options = array_merge(
+ array(
+ 'type' => $type,
+ 'name' => $name,
+ 'id' => $name,
+ 'value' => $value
+ ),
+ $options
+ );
+ return tag('input', $options);
+}
+
+function text_field_tag($name, $default = null, $options = array())
+{
+ $value = isset($_REQUEST[$name]) ? $_REQUEST[$name] : $default;
+ return input_tag('text', $name, $value, $options);
+}
+
+function text_area_tag($name, $default = null, $options = array())
+{
+ $content = isset($_REQUEST[$name]) ? $_REQUEST[$name] : $default;
+ $options = array_merge(
+ array(
+ 'name' => $name,
+ 'id' => $name,
+ 'cols' => 60,
+ 'rows' => 5
+ ),
+ $options
+ );
+ return content_tag('textarea', $content, $options);
+}
+
+function hidden_field_tag($name, $default = null, $options = array())
+{
+ $value = isset($_REQUEST[$name]) ? $_REQUEST[$name] : $default;
+ return input_tag('hidden', $name, $value, $options);
+}
+
+function password_field_tag($name = 'password', $default = null, $options = array())
+{
+ $value = isset($_REQUEST[$name]) ? $_REQUEST[$name] : $default;
+ return input_tag('password', $name, $value, $options);
+}
+
+function radio_button_tag($name, $value, $default = false, $options = array())
+{
+ if ((isset($_REQUEST[$name]) and $_REQUEST[$name] == $value) or
+ (!isset($_REQUEST[$name]) and $default))
+ {
+ $options = array_merge(array('checked' => 'checked'), $options);
+ }
+ $options = array_merge(array('id' => $name.'_'.$value), $options);
+ return input_tag('radio', $name, $value, $options);
+}
+
+function check_box_tag($name, $value = '1', $default = false, $options = array())
+{
+ if ((isset($_REQUEST[$name]) and $_REQUEST[$name] == $value) or
+ (!isset($_REQUEST['submit']) and $default))
+ {
+ $options = array_merge(array('checked' => 'checked'),$options);
+ }
+ return input_tag('checkbox', $name, $value, $options);
+}
+
+function submit_tag($name = '', $value = 'Submit', $options = array())
+{
+ return input_tag('submit', $name, $value, $options);
+}
+
+function reset_tag($name = '', $value = 'Reset', $options = array())
+{
+ return input_tag('reset', $name, $value, $options);
+}
+
+function label_tag($name, $text = null, $options = array())
+{
+ if ($text == null) {
+ $text = ucwords(str_replace('_', ' ', $name)).': ';
+ }
+ $options = array_merge(
+ array('for' => $name, 'id' => "label_for_$name"),
+ $options
+ );
+ return content_tag('label', $text, $options);
+}
+
+function labeled_text_field_tag($name, $default = null, $options = array())
+{
+ return label_tag($name).text_field_tag($name, $default, $options);
+}
+
+function select_tag($name, $options, $default = null, $html_options = array())
+{
+ $opts = '';
+ foreach ($options as $key => $value) {
+ $arr = array('value' => $value);
+ if ((isset($_REQUEST[$name]) and $_REQUEST[$name] == $value) or
+ (!isset($_REQUEST[$name]) and $default == $value))
+ {
+ $arr = array_merge(array('selected' => 'selected'),$arr);
+ }
+ $opts .= content_tag('option', $key, $arr);
+ }
+ $html_options = array_merge(
+ array('name' => $name, 'id' => $name),
+ $html_options
+ );
+ return "<select".tag_options($html_options).">$opts</select>";
+}
+
+function form_tag($uri = null, $options = array())
+{
+ if ($uri == null) {
+ $uri = $_SERVER['PHP_SELF'];
+ }
+ $options = array_merge(
+ array('method' => 'get', 'action' => $uri),
+ $options
+ );
+ return tag('form', $options, true);
+}
+
+function form_end_tag()
+{
+ return "</form>";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/httpget.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,84 @@
+<?php
+ /**
+ * No RDF, just test EasyRdf_Http_Client
+ *
+ * This example does nothing but test EasyRdf's build in HTTP client.
+ * It demonstrates setting Accept headers and displays the response
+ * headers and body.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+ require_once "html_tag_helpers.php";
+
+ $accept_options = array(
+ 'text/html' => 'text/html',
+ 'application/rdf+xml' => 'application/rdf+xml',
+ 'application/xhtml+xml' => 'application/xhtml+xml',
+ 'application/json' => 'application/json',
+ 'text/turtle' => 'text/turtle',
+ );
+?>
+<html>
+<head>
+ <title>Test EasyRdf_HTTP_Client Get</title>
+ <style type="text/css">
+ .body
+ {
+ width: 800px;
+ font-family: monospace;
+ font-size: 0.8em;
+ }
+ </style>
+</head>
+<body>
+<h1>Test EasyRdf_HTTP_Client Get</h1>
+<?= form_tag() ?>
+<?= text_field_tag('uri', 'http://tomheath.com/id/me', array('size'=>50)) ?><br />
+<?= label_tag('accept', 'Accept Header: ').select_tag('accept',$accept_options) ?>
+<?= submit_tag() ?>
+<?= form_end_tag() ?>
+
+<?php
+ if (isset($_REQUEST['uri'])) {
+ $client = new EasyRdf_Http_Client($_REQUEST['uri']);
+ $client->setHeaders('Accept',$_REQUEST['accept']);
+ $response = $client->request();
+
+?>
+
+ <p class="status">
+ <b>Status</b>: <?= $response->getStatus() ?><br />
+ <b>Message</b>: <?= $response->getMessage() ?><br />
+ <b>Version</b>: HTTP/<?= $response->getVersion() ?><br />
+ </p>
+
+ <p class="headers">
+ <?php
+ foreach ($response->getHeaders() as $name => $value) {
+ echo "<b>$name</b>: $value<br />\n";
+ }
+ ?>
+ </p>
+
+ <p class="body">
+ <?php
+ if (defined('ENT_SUBSTITUTE')) {
+ // This is needed for PHP 5.4+
+ print nl2br(htmlentities($response->getBody(), ENT_SUBSTITUTE | ENT_QUOTES));
+ } else {
+ print nl2br(htmlentities($response->getBody()));
+ }
+ ?>
+ </p>
+
+<?php
+ }
+?>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/parse_rss.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,56 @@
+<?php
+ /**
+ * Parse an RSS 1.0 feed and display titles
+ *
+ * The example demonstrates fetching an RSS 1.0 feed from the
+ * web and then parsing as RDF/XML. The channel is found by getting
+ * the first object of type rss:channel (a file should only contain
+ * a single RSS channel).
+ *
+ * In RSS 1.0, the list of items in the feed are listed by relating
+ * the rss:channel to the rss:items using an rdf:Seq. In EasyRdf
+ * this maps into an EasyRdf_Container object, which can be
+ * iterated over using a foreach() loop.
+ *
+ * Note that this example only works with RSS 1.0 and no
+ * other version (0.90, 1.1 and 2.0) as they are not RDF.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+ require_once "html_tag_helpers.php";
+?>
+<html>
+<head>
+ <title>EasyRdf RSS 1.0 Parsing example</title>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+</head>
+<body>
+<h1>EasyRdf RSS 1.0 Parsing example</h1>
+
+<?= form_tag() ?>
+<?= text_field_tag('uri', 'http://planetrdf.com/index.rdf', array('size'=>50)) ?>
+<?= submit_tag() ?>
+<?= form_end_tag() ?>
+
+<?php
+ if (isset($_REQUEST['uri'])) {
+ $graph = EasyRdf_Graph::newAndLoad($_REQUEST['uri'], 'rdfxml');
+ $channel = $graph->get('rss:channel', '^rdf:type');
+
+ print "<p>Channel: ".link_to($channel->label(), $channel->get('rss:link'))."</p>\n";
+ print "<p>Description: ".$channel->get('rss:description')."</p>\n";
+
+ print "<ol>\n";
+ foreach($channel->get('rss:items') as $item) {
+ print "<li>".link_to($item->get('rss:title'), $item)."</li>\n";
+ }
+ print "</ol>\n";
+ }
+?>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/serialise.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,68 @@
+<?php
+ /**
+ * Basic serialisation example
+ *
+ * This example create a simple FOAF graph in memory and then
+ * serialises it to the page in the format of choice.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+
+ $graph = new EasyRdf_Graph();
+ $me = $graph->resource('http://www.example.com/joe#me', 'foaf:Person');
+ $me->set('foaf:name', 'Joseph Bloggs');
+ $me->set('foaf:title', 'Mr');
+ $me->set('foaf:nick', 'Joe');
+ $me->add('foaf:homepage', $graph->resource('http://example.com/joe/'));
+
+ // I made these up; they are not officially part of FOAF
+ $me->set('foaf:dateOfBirth', new EasyRdf_Literal_Date('1980-09-08'));
+ $me->set('foaf:height', 1.82);
+
+ $project = $graph->newBnode('foaf:Project');
+ $project->set('foaf:name', "Joe's current project");
+ $me->set('foaf:currentProject', $project);
+
+ if (isset($_REQUEST['format'])) {
+ $format = preg_replace("/[^\w\-]+/", '', strtolower($_REQUEST['format']));
+ } else {
+ $format = 'ntriples';
+ }
+?>
+<html>
+<head><title>EasyRdf Serialiser Example</title></head>
+<body>
+<h1>EasyRdf Serialiser Example</h1>
+
+<ul>
+<?php
+ foreach (EasyRdf_Format::getFormats() as $f) {
+ if ($f->getSerialiserClass()) {
+ if ($f->getName() == $format) {
+ print "<li><b>".$f->getLabel()."</b></li>\n";
+ } else {
+ print "<li><a href='?format=$f'>";
+ print $f->getLabel()."</a></li>\n";
+ }
+ }
+ }
+?>
+</ul>
+
+<pre style="margin: 0.5em; padding:0.5em; background-color:#eee; border:dashed 1px grey;">
+<?php
+ $data = $graph->serialise($format);
+ if (!is_scalar($data)) {
+ $data = var_export($data, true);
+ }
+ print htmlspecialchars($data);
+?>
+</pre>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/sparql_queryform.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,79 @@
+<?php
+ /**
+ * Form to submit and display SPARQL queries
+ *
+ * This example presents a form that you can enter the URI
+ * of a a SPARQL endpoint and a SPARQL query into. The
+ * results are displayed using a call to dump() on what will be
+ * either a EasyRdf_Sparql_Result or EasyRdf_Graph object.
+ *
+ * A list of registered namespaces is displayed above the query
+ * box - any of these namespaces can be used in the query and PREFIX
+ * statements will automatically be added to the start of the query
+ * string.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+ require_once "html_tag_helpers.php";
+
+ // Stupid PHP :(
+ if (get_magic_quotes_gpc() and isset($_REQUEST['query'])) {
+ $_REQUEST['query'] = stripslashes($_REQUEST['query']);
+ }
+?>
+<html>
+<head>
+ <title>EasyRdf SPARQL Query Form</title>
+ <style type="text/css">
+ .error {
+ width: 35em;
+ border: 2px red solid;
+ padding: 1em;
+ margin: 0.5em;
+ background-color: #E6E6E6;
+ }
+ </style>
+</head>
+<body>
+<h1>EasyRdf SPARQL Query Form</h1>
+
+<div style="margin: 0.5em">
+ <?php
+ print form_tag();
+ print label_tag('endpoint');
+ print text_field_tag('endpoint', "http://dbpedia.org/sparql", array('size'=>80)).'<br />';
+ print "<code>";
+ foreach(EasyRdf_Namespace::namespaces() as $prefix => $uri) {
+ print "PREFIX $prefix: <".htmlspecialchars($uri)."><br />\n";
+ }
+ print "</code>";
+ print text_area_tag('query', "SELECT * WHERE {\n ?s ?p ?o\n}\nLIMIT 10", array('rows' => 10, 'cols' => 80)).'<br />';
+ print check_box_tag('text') . label_tag('text', 'Plain text results').'<br />';
+ print reset_tag() . submit_tag();
+ print form_end_tag();
+ ?>
+</div>
+
+<?php
+ if (isset($_REQUEST['endpoint']) and isset($_REQUEST['query'])) {
+ $sparql = new EasyRdf_Sparql_Client($_REQUEST['endpoint']);
+ try {
+ $results = $sparql->query($_REQUEST['query']);
+ if (isset($_REQUEST['text'])) {
+ print "<pre>".htmlspecialchars($results->dump('text'))."</pre>";
+ } else {
+ print $results->dump('html');
+ }
+ } catch (Exception $e) {
+ print "<div class='error'>".$e->getMessage()."</div>\n";
+ }
+ }
+?>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/uk_postcode.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,74 @@
+<?php
+ /**
+ * Resolving UK postcodes using uk-postcodes.com
+ *
+ * Another basic example that demonstrates registering namespaces,
+ * loading RDF data from the web and then directly displaying
+ * literals from the graph on the page.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+ require_once "html_tag_helpers.php";
+
+ EasyRdf_Namespace::set('postcode', 'http://data.ordnancesurvey.co.uk/ontology/postcode/');
+ EasyRdf_Namespace::set('sr', 'http://data.ordnancesurvey.co.uk/ontology/spatialrelations/');
+ EasyRdf_Namespace::set('eg', 'http://statistics.data.gov.uk/def/electoral-geography/');
+ EasyRdf_Namespace::set('ag', 'http://statistics.data.gov.uk/def/administrative-geography/');
+ EasyRdf_Namespace::set('osag', 'http://data.ordnancesurvey.co.uk/ontology/admingeo/');
+?>
+<html>
+<head>
+ <title>EasyRdf UK Postcode Resolver</title>
+ <style type="text/css" media="all">
+ #map
+ {
+ border: 1px gray solid;
+ float: right;
+ margin: 0 0 20px 20px;
+ }
+ th { text-align: right }
+ td { padding: 5px; }
+ </style>
+</head>
+<body>
+<h1>EasyRdf UK Postcode Resolver</h1>
+
+<?= form_tag() ?>
+ <?= text_field_tag('postcode', 'W1A 1AA', array('size'=>10)) ?>
+ <?= submit_tag() ?>
+<?= form_end_tag() ?>
+
+<?php
+ if (isset($_REQUEST['postcode'])) {
+ $postcode = str_replace(' ', '', strtoupper($_REQUEST['postcode']));
+ $docuri = "http://www.uk-postcodes.com/postcode/$postcode.rdf";
+ $graph = EasyRdf_Graph::newAndLoad($docuri);
+
+
+ // Get the first resource of type PostcodeUnit
+ $res = $graph->get('postcode:PostcodeUnit', '^rdf:type');
+ if ($res) {
+ $ll = $res->get('geo:lat').','.$res->get('geo:long');
+ print "<iframe id='map' width='500' height='250' frameborder='0' scrolling='no' src='http://maps.google.com/maps?f=q&ll=$ll&output=embed'></iframe>";
+ print "<table id='facts'>\n";
+ print "<tr><th>Easting:</th><td>" . $res->get('sr:easting') . "</td></tr>\n";
+ print "<tr><th>Northing:</th><td>" . $res->get('sr:northing') . "</td></tr>\n";
+ print "<tr><th>Longitude:</th><td>" . $res->get('geo:long') . "</td></tr>\n";
+ print "<tr><th>Latitude:</th><td>" . $res->get('geo:lat') . "</td></tr>\n";
+ print "<tr><th>Local Authority:</th><td>" . $res->get('ag:localAuthority')->label() . "</td></tr>\n";
+ print "<tr><th>Electoral Ward:</th><td>" . $res->get('eg:ward')->label() . "</td></tr>\n";
+ print "</table>\n";
+
+ print "<div style='clear: both'></div>\n";
+ }
+
+ print $graph->dump();
+ }
+?>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/villages.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,67 @@
+<?php
+ /**
+ * Consuming Linked Data from dbpedialite.org
+ *
+ * This example demonstrates fetching information about villages in Fife
+ * from dbpedialite.org.
+ *
+ * First it fetches a list of villages that are members of the
+ * Wikipedia category 'Villages in Fife' and displays them as a list.
+ *
+ * If you click on an village, then it displays a page about that village
+ * with a title, synopsis and Google Map.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+ require_once "EasyRdf.php";
+ require_once "html_tag_helpers.php";
+
+ $CATEGORY_ID = 4309010;
+?>
+<html>
+<head><title>EasyRdf Village Info Example</title></head>
+<body>
+<h1>EasyRdf Village Info Example</h1>
+
+<?php
+ if (isset($_REQUEST['id'])) {
+ $graph = EasyRdf_Graph::newAndLoad("http://dbpedialite.org/things/".$_REQUEST['id']);
+
+ $village = $graph->primaryTopic();
+ print content_tag('h2',$village->label());
+
+ if ($village->get('foaf:depiction')) {
+ print image_tag(
+ $village->get('foaf:depiction'),
+ array('style'=>'max-width:400px;max-height:250px;')
+ );
+ }
+
+ print content_tag('p',$village->get('rdfs:comment'));
+
+ if ($village->get('geo:long')) {
+ $ll = $village->get('geo:lat').','.$village->get('geo:long');
+ print "<iframe width='425' height='350' frameborder='0' scrolling='no' marginheight='0' marginwidth='0' src='http://maps.google.com/maps?f=q&ll=$ll&output=embed'></iframe>";
+ }
+
+ echo "<br /><br />";
+ echo $graph->dump();
+ } else {
+ $graph = EasyRdf_Graph::newAndLoad("http://dbpedialite.org/categories/".$CATEGORY_ID);
+ $category = $graph->primaryTopic();
+
+ print "<ul>\n";
+ foreach ($category->all('^rdf:type') as $resource) {
+ if (preg_match("|http://dbpedialite.org/things/(\d+)#id|", $resource, $matches)) {
+ print '<li>'.link_to_self($resource->label(), "id=".$matches[1])."</li>\n";
+ }
+ }
+ print "</ul>\n";
+ }
+?>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/examples/zend_framework.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,61 @@
+<?php
+ /**
+ * Using EasyRdf with the Zend Framework
+ *
+ * This example demonstrates using Zend_Http_Client and
+ * Zend_Loader_Autoloader with EasyRdf.
+ *
+ * It creates a simple graph in memory, saves it to a local graphstore
+ * and then fetches the data back using a SPARQL SELECT query.
+ * Zend's curl HTTP client adaptor is used to perform the HTTP requests.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://unlicense.org/
+ */
+
+ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib/');
+
+ // require the Zend Autoloader
+ require_once 'Zend/Loader/Autoloader.php';
+ $autoloader = Zend_Loader_Autoloader::getInstance();
+ $autoloader->setFallbackAutoloader(true);
+
+ // use the CURL based HTTP client adaptor
+ $client = new Zend_Http_Client(
+ null,
+ array(
+ 'adapter' => 'Zend_Http_Client_Adapter_Curl',
+ 'keepalive' => true,
+ 'useragent' => "EasyRdf/zendtest"
+ )
+ );
+ EasyRdf_Http::setDefaultHttpClient($client);
+?>
+
+<html>
+<head>
+ <title>Zend Framework Example</title>
+</head>
+<body>
+<h1>Zend Framework Example</h1>
+
+<?php
+ # Load some sample data into a graph
+ $graph = new EasyRdf_Graph('http://example.com/joe');
+ $joe = $graph->resource('http://example.com/joe#me', 'foaf:Person');
+ $joe->add('foaf:name', 'Joe Bloggs');
+ $joe->addResource('foaf:homepage', 'http://example.com/joe/');
+
+ # Store it in a local graphstore
+ $store = new EasyRdf_GraphStore('http://localhost:8080/data/');
+ $store->replace($graph);
+
+ # Now make a query to the graphstore
+ $sparql = new EasyRdf_Sparql_Client('http://localhost:8080/sparql/');
+ $result = $sparql->query('SELECT * WHERE {<http://example.com/joe#me> ?p ?o}');
+ echo $result->dump();
+?>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,239 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * Use this file to load the core of EasyRdf, if you don't have an autoloader.
+ *
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2011-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * @see EasyRdf_Exception
+ */
+require_once "EasyRdf/Exception.php";
+
+/**
+ * @see EasyRdf_Format
+ */
+require_once "EasyRdf/Format.php";
+
+/**
+ * @see EasyRdf_Graph
+ */
+require_once "EasyRdf/Graph.php";
+
+/**
+ * @see EasyRdf_GraphStore
+ */
+require_once "EasyRdf/GraphStore.php";
+
+/**
+ * @see EasyRdf_Http
+ */
+require_once "EasyRdf/Http.php";
+
+/**
+ * @see EasyRdf_Http_Client
+ */
+require_once "EasyRdf/Http/Client.php";
+
+/**
+ * @see EasyRdf_Http_Response
+ */
+require_once "EasyRdf/Http/Response.php";
+
+/**
+ * @see EasyRdf_Namespace
+ */
+require_once "EasyRdf/Namespace.php";
+
+/**
+ * @see EasyRdf_Literal
+ */
+require_once "EasyRdf/Literal.php";
+
+/**
+ * @see EasyRdf_Literal_Boolean
+ */
+require_once "EasyRdf/Literal/Boolean.php";
+
+/**
+ * @see EasyRdf_Literal_Date
+ */
+require_once "EasyRdf/Literal/Date.php";
+
+/**
+ * @see EasyRdf_Literal_DateTime
+ */
+require_once "EasyRdf/Literal/DateTime.php";
+
+/**
+ * @see EasyRdf_Literal_Decimal
+ */
+require_once "EasyRdf/Literal/Decimal.php";
+
+/**
+ * @see EasyRdf_Literal_HexBinary
+ */
+require_once "EasyRdf/Literal/HexBinary.php";
+
+/**
+ * @see EasyRdf_Literal_HTML
+ */
+require_once "EasyRdf/Literal/HTML.php";
+
+/**
+ * @see EasyRdf_Literal_Integer
+ */
+require_once "EasyRdf/Literal/Integer.php";
+
+/**
+ * @see EasyRdf_Literal_XML
+ */
+require_once "EasyRdf/Literal/XML.php";
+
+/**
+ * @see EasyRdf_ParsedUri
+ */
+require_once "EasyRdf/ParsedUri.php";
+
+/**
+ * @see EasyRdf_Parser
+ */
+require_once "EasyRdf/Parser.php";
+
+/**
+ * @see EasyRdf_Parser_Exception
+ */
+require_once "EasyRdf/Parser/Exception.php";
+
+/**
+ * @see EasyRdf_Parser_RdfPhp
+ */
+require_once "EasyRdf/Parser/RdfPhp.php";
+
+/**
+ * @see EasyRdf_Parser_Ntriples
+ */
+require_once "EasyRdf/Parser/Ntriples.php";
+
+/**
+ * @see EasyRdf_Parser_Json
+ */
+require_once "EasyRdf/Parser/Json.php";
+
+/**
+ * @see EasyRdf_Parser_Rdfa
+ */
+require_once "EasyRdf/Parser/Rdfa.php";
+
+/**
+ * @see EasyRdf_Parser_RdfXml
+ */
+require_once "EasyRdf/Parser/RdfXml.php";
+
+/**
+ * @see EasyRdf_Parser_Turtle
+ */
+require_once "EasyRdf/Parser/Turtle.php";
+
+/**
+ * @see EasyRdf_Resource
+ */
+require_once "EasyRdf/Resource.php";
+
+/**
+ * @see EasyRdf_Collection
+ */
+require_once "EasyRdf/Collection.php";
+
+/**
+ * @see EasyRdf_Container
+ */
+require_once "EasyRdf/Container.php";
+
+/**
+ * @see EasyRdf_Serialiser
+ */
+require_once "EasyRdf/Serialiser.php";
+
+/**
+ * @see EasyRdf_Serialiser_GraphViz
+ */
+require_once "EasyRdf/Serialiser/GraphViz.php";
+
+/**
+ * @see EasyRdf_Serialiser_RdfPhp
+ */
+require_once "EasyRdf/Serialiser/RdfPhp.php";
+
+/**
+ * @see EasyRdf_Serialiser_Ntriples
+ */
+require_once "EasyRdf/Serialiser/Ntriples.php";
+
+/**
+ * @see EasyRdf_Serialiser_Json
+ */
+require_once "EasyRdf/Serialiser/Json.php";
+
+/**
+ * @see EasyRdf_Serialiser_RdfXml
+ */
+require_once "EasyRdf/Serialiser/RdfXml.php";
+
+/**
+ * @see EasyRdf_Serialiser_Turtle
+ */
+require_once "EasyRdf/Serialiser/Turtle.php";
+
+/**
+ * @see EasyRdf_Sparql_Client
+ */
+require_once "EasyRdf/Sparql/Client.php";
+
+/**
+ * @see EasyRdf_Sparql_Result
+ */
+require_once "EasyRdf/Sparql/Result.php";
+
+/**
+ * @see EasyRdf_TypeMapper
+ */
+require_once "EasyRdf/TypeMapper.php";
+
+/**
+ * @see EasyRdf_Utils
+ */
+require_once "EasyRdf/Utils.php";
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Collection.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,333 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Sub-class of EasyRdf_Resource that represents an RDF collection (rdf:List)
+ *
+ * This class can be used to iterate through a collection of items.
+ *
+ * Note that items are numbered from 1 (not 0) for consistency with RDF Containers.
+ *
+ * @package EasyRdf
+ * @link http://www.w3.org/TR/xmlschema-2/#date
+ * @copyright Copyright (c) 2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Collection extends EasyRdf_Resource implements ArrayAccess, Countable, SeekableIterator
+{
+ private $position;
+ private $current;
+
+ /** Create a new collection - do not use this directly
+ *
+ * @ignore
+ */
+ public function __construct($uri, $graph)
+ {
+ $this->position = 1;
+ $this->current = null;
+ parent::__construct($uri, $graph);
+ }
+
+ /** Seek to a specific position in the container
+ *
+ * The first item is postion 1
+ *
+ * @param integer $position The position in the container to seek to
+ * @throws OutOfBoundsException
+ */
+ public function seek($position)
+ {
+ if (is_int($position) and $position > 0) {
+ list($node, $actual) = $this->getCollectionNode($position);
+ if ($actual === $position) {
+ $this->position = $actual;
+ $this->current = $node;
+ } else {
+ throw new OutOfBoundsException(
+ "Unable to seek to position $position in the collection"
+ );
+ }
+ } else {
+ throw new InvalidArgumentException(
+ "Collection position must be a positive integer"
+ );
+ }
+ }
+
+ /** Rewind the iterator back to the start of the collection
+ *
+ */
+ public function rewind()
+ {
+ $this->position = 1;
+ $this->current = null;
+ }
+
+ /** Return the current item in the collection
+ *
+ * @return mixed The current item
+ */
+ public function current()
+ {
+ if ($this->position === 1) {
+ return $this->get('rdf:first');
+ } elseif ($this->current) {
+ return $this->current->get('rdf:first');
+ }
+ }
+
+ /** Return the key / current position in the collection
+ *
+ * Note: the first item is number 1
+ *
+ * @return int The current position
+ */
+ public function key()
+ {
+ return $this->position;
+ }
+
+ /** Move forward to next item in the collection
+ *
+ */
+ public function next()
+ {
+ if ($this->position === 1) {
+ $this->current = $this->get('rdf:rest');
+ } elseif ($this->current) {
+ $this->current = $this->current->get('rdf:rest');
+ }
+ $this->position++;
+ }
+
+ /** Checks if current position is valid
+ *
+ * @return bool True if the current position is valid
+ */
+ public function valid()
+ {
+ if ($this->position === 1 and $this->hasProperty('rdf:first')) {
+ return true;
+ } elseif ($this->current !== null and $this->current->hasProperty('rdf:first')) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /** Get a node for a particular offset into the collection
+ *
+ * This function may not return the item you requested, if
+ * it does not exist. Please check the $postion parameter
+ * returned.
+ *
+ * If the offset is null, then the last node in the
+ * collection (before rdf:nil) will be returned.
+ *
+ * @param integer $offset The offset into the collection (or null)
+ * @return array $node, $postion The node object and postion of the node
+ */
+ public function getCollectionNode($offset)
+ {
+ $position = 1;
+ $node = $this;
+ $nil = $this->graph->resource('rdf:nil');
+ while (($rest = $node->get('rdf:rest')) and $rest !== $nil and (is_null($offset) or ($position < $offset))) {
+ $node = $rest;
+ $position++;
+ }
+ return array($node, $position);
+ }
+
+ /** Counts the number of items in the collection
+ *
+ * Note that this is an slow method - it is more efficient to use
+ * the iterator interface, if you can.
+ *
+ * @return integer The number of items in the collection
+ */
+ public function count()
+ {
+ // Find the end of the collection
+ list($node, $position) = $this->getCollectionNode(null);
+ if (!$node->hasProperty('rdf:first')) {
+ return 0;
+ } else {
+ return $position;
+ }
+ }
+
+ /** Append an item to the end of the collection
+ *
+ * @param mixed $value The value to append
+ * @return integer The number of values appended (1 or 0)
+ */
+ public function append($value)
+ {
+ // Find the end of the collection
+ list($node, $position) = $this->getCollectionNode(null);
+ $rest = $node->get('rdf:rest');
+
+ if ($node === $this and is_null($rest)) {
+ $node->set('rdf:first', $value);
+ $node->addResource('rdf:rest', 'rdf:nil');
+ } else {
+ $new = $this->graph->newBnode();
+ $node->set('rdf:rest', $new);
+ $new->add('rdf:first', $value);
+ $new->addResource('rdf:rest', 'rdf:nil');
+ }
+
+ return 1;
+ }
+
+ /** Array Access: check if a position exists in collection using array syntax
+ *
+ * Example: isset($list[2])
+ */
+ public function offsetExists($offset)
+ {
+ if (is_int($offset) and $offset > 0) {
+ list($node, $position) = $this->getCollectionNode($offset);
+ return ($node and $position === $offset and $node->hasProperty('rdf:first'));
+ } else {
+ throw new InvalidArgumentException(
+ "Collection offset must be a positive integer"
+ );
+ }
+ }
+
+ /** Array Access: get an item at a specified position in collection using array syntax
+ *
+ * Example: $item = $list[2];
+ */
+ public function offsetGet($offset)
+ {
+ if (is_int($offset) and $offset > 0) {
+ list($node, $position) = $this->getCollectionNode($offset);
+ if ($node and $position === $offset) {
+ return $node->get('rdf:first');
+ }
+ } else {
+ throw new InvalidArgumentException(
+ "Collection offset must be a positive integer"
+ );
+ }
+ }
+
+ /**
+ * Array Access: set an item at a positon in collection using array syntax
+ *
+ * Example: $list[2] = $item;
+ */
+ public function offsetSet($offset, $value)
+ {
+ if (is_null($offset)) {
+ // No offset - append to end of collection
+ $this->append($value);
+ } elseif (is_int($offset) and $offset > 0) {
+ list($node, $position) = $this->getCollectionNode($offset);
+
+ // Create nodes, if they are missing
+ while ($position < $offset) {
+ $new = $this->graph->newBnode();
+ $node->set('rdf:rest', $new);
+ $new->addResource('rdf:rest', 'rdf:nil');
+ $node = $new;
+ $position++;
+ }
+
+ // Terminate the list
+ if (!$node->hasProperty('rdf:rest')) {
+ $node->addResource('rdf:rest', 'rdf:nil');
+ }
+
+ return $node->set('rdf:first', $value);
+ } else {
+ throw new InvalidArgumentException(
+ "Collection offset must be a positive integer"
+ );
+ }
+ }
+
+ /**
+ * Array Access: delete an item at a specific postion using array syntax
+ *
+ * Example: unset($seq[2]);
+ */
+ public function offsetUnset($offset)
+ {
+ if (is_int($offset) and $offset > 0) {
+ list($node, $position) = $this->getCollectionNode($offset);
+ } else {
+ throw new InvalidArgumentException(
+ "Collection offset must be a positive integer"
+ );
+ }
+
+ // Does the item exist?
+ if ($node and $position === $offset) {
+ $nil = $this->graph->resource('rdf:nil');
+ if ($position === 1) {
+ $rest = $node->get('rdf:rest');
+ if ($rest and $rest !== $nil) {
+ // Move second value, so we can keep the head of list
+ $node->set('rdf:first', $rest->get('rdf:first'));
+ $node->set('rdf:rest', $rest->get('rdf:rest'));
+ $rest->delete('rdf:first');
+ $rest->delete('rdf:rest');
+ } else {
+ // Just remove the value
+ $node->delete('rdf:first');
+ $node->delete('rdf:rest');
+ }
+ } else {
+ // Remove the value and re-link the list
+ $node->delete('rdf:first');
+ $rest = $node->get('rdf:rest');
+ $previous = $node->get('^rdf:rest');
+ if (is_null($rest)) {
+ $rest = $nil;
+ }
+ if ($previous) {
+ $previous->set('rdf:rest', $rest);
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Container.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,230 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Sub-class of EasyRdf_Resource that represents an RDF container
+ * (rdf:Alt, rdf:Bag and rdf:Seq)
+ *
+ * This class can be used to iterate through a list of items.
+ *
+ * @package EasyRdf
+ * @link http://www.w3.org/TR/xmlschema-2/#date
+ * @copyright Copyright (c) 2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Container extends EasyRdf_Resource implements ArrayAccess, Countable, SeekableIterator
+{
+ private $position;
+
+ /** Create a new container - do not use this directly
+ *
+ * @ignore
+ */
+ public function __construct($uri, $graph)
+ {
+ $this->position = 1;
+ parent::__construct($uri, $graph);
+ }
+
+ /** Seek to a specific position in the container
+ *
+ * The first item is postion 1
+ *
+ * @param integer $position The position in the container to seek to
+ * @throws OutOfBoundsException
+ */
+ public function seek($position)
+ {
+ if (is_int($position) and $position > 0) {
+ if ($this->hasProperty('rdf:_'.$position)) {
+ $this->position = $position;
+ } else {
+ throw new OutOfBoundsException(
+ "Unable to seek to position $position in the container"
+ );
+ }
+ } else {
+ throw new InvalidArgumentException(
+ "Container position must be a positive integer"
+ );
+ }
+ }
+
+ /** Rewind the iterator back to the start of the container (item 1)
+ *
+ */
+ public function rewind()
+ {
+ $this->position = 1;
+ }
+
+ /** Return the current item in the container
+ *
+ * @return mixed The current item
+ */
+ public function current()
+ {
+ return $this->get('rdf:_'.$this->position);
+ }
+
+ /** Return the key / current position in the container
+ *
+ * @return int The current position
+ */
+ public function key()
+ {
+ return $this->position;
+ }
+
+ /** Move forward to next item in the container
+ *
+ */
+ public function next()
+ {
+ $this->position++;
+ }
+
+ /** Checks if current position is valid
+ *
+ * @return bool True if the current position is valid
+ */
+ public function valid()
+ {
+ return $this->hasProperty('rdf:_'.$this->position);
+ }
+
+ /** Counts the number of items in the container
+ *
+ * Note that this is an slow method - it is more efficient to use
+ * the iterator interface, if you can.
+ *
+ * @return integer The number of items in the container
+ */
+ public function count()
+ {
+ $pos = 1;
+ while ($this->hasProperty('rdf:_'.$pos)) {
+ $pos++;
+ }
+ return $pos - 1;
+ }
+
+ /** Append an item to the end of the container
+ *
+ * @param mixed $value The value to append
+ * @return integer The number of values appended (1 or 0)
+ */
+ public function append($value)
+ {
+ // Find the end of the list
+ $pos = 1;
+ while ($this->hasProperty('rdf:_'.$pos)) {
+ $pos++;
+ }
+
+ // Add the item
+ return $this->add('rdf:_'.$pos, $value);
+ }
+
+ /** Array Access: check if a position exists in container using array syntax
+ *
+ * Example: isset($seq[2])
+ */
+ public function offsetExists($offset)
+ {
+ if (is_int($offset) and $offset > 0) {
+ return $this->hasProperty('rdf:_'.$offset);
+ } else {
+ throw new InvalidArgumentException(
+ "Container position must be a positive integer"
+ );
+ }
+ }
+
+ /** Array Access: get an item at a specified position in container using array syntax
+ *
+ * Example: $item = $seq[2];
+ */
+ public function offsetGet($offset)
+ {
+ if (is_int($offset) and $offset > 0) {
+ return $this->get('rdf:_'.$offset);
+ } else {
+ throw new InvalidArgumentException(
+ "Container position must be a positive integer"
+ );
+ }
+ }
+
+ /**
+ * Array Access: set an item at a positon in container using array syntax
+ *
+ * Example: $seq[2] = $item;
+ *
+ * Warning: creating gaps in the sequence will result in unexpected behavior
+ */
+ public function offsetSet($offset, $value)
+ {
+ if (is_int($offset) and $offset > 0) {
+ return $this->set('rdf:_'.$offset, $value);
+ } elseif (is_null($offset)) {
+ return $this->append($value);
+ } else {
+ throw new InvalidArgumentException(
+ "Container position must be a positive integer"
+ );
+ }
+ }
+
+ /**
+ * Array Access: delete an item at a specific postion using array syntax
+ *
+ * Example: unset($seq[2]);
+ *
+ * Warning: creating gaps in the sequence will result in unexpected behavior
+ */
+ public function offsetUnset($offset)
+ {
+ if (is_int($offset) and $offset > 0) {
+ return $this->delete('rdf:_'.$offset);
+ } else {
+ throw new InvalidArgumentException(
+ "Container position must be a positive integer"
+ );
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Exception.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * EasyRdf Exception class
+ *
+ * All exceptions thrown by EasyRdf are an instance of this class.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Exception extends Exception
+{
+ // Comment to make PHP CodeSniffer happy
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Format.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,687 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class the represents an RDF file format.
+ *
+ * For each format, the name, label, URIs and associated MIME Types are
+ * stored. A single parser and serialiser can also be registered to each
+ * format.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Format
+{
+ private static $formats = array();
+
+ private $name = array();
+ private $label = null;
+ private $uri = null;
+ private $mimeTypes = array();
+ private $extensions = array();
+ private $parserClass = null;
+ private $serialiserClass = null;
+
+ /** Get a list of format names
+ *
+ * @return array An array of formats name
+ */
+ public static function getNames()
+ {
+ return array_keys(self::$formats);
+ }
+
+ /** Get a list of all the registered formats
+ *
+ * @return array An array of format objects
+ */
+ public static function getFormats()
+ {
+ return self::$formats;
+ }
+
+ /** Generates an HTTP Accept header string
+ *
+ * The string will contain all of the MIME Types that we
+ * are able to parse.
+ *
+ * It is also possible to specify additional MIME types
+ * in the form array('text/plain' => 0.5) where 0.5 is the
+ * q value for that type. The types are sorted by q value
+ * before constructing the string.
+ *
+ * @param array $extraTypes extra MIME types to add
+ * @return string list of supported MIME types
+ */
+ public static function getHttpAcceptHeader($extraTypes = array())
+ {
+ $accept = $extraTypes;
+ foreach (self::$formats as $format) {
+ if ($format->parserClass and count($format->mimeTypes) > 0) {
+ $accept = array_merge($accept, $format->mimeTypes);
+ }
+ }
+ arsort($accept, SORT_NUMERIC);
+
+ $acceptStr='';
+ foreach ($accept as $type => $q) {
+ if ($acceptStr) {
+ $acceptStr .= ',';
+ }
+ if ($q == 1.0) {
+ $acceptStr .= $type;
+ } else {
+ $acceptStr .= sprintf("%s;q=%1.1f", $type, $q);
+ }
+ }
+ return $acceptStr;
+ }
+
+ /** Check if a named graph exists
+ *
+ * @param string $name the name of the format
+ * @return boolean true if the format exists
+ */
+ public static function formatExists($name)
+ {
+ return array_key_exists($name, self::$formats);
+ }
+
+ /** Get a EasyRdf_Format from a name, uri or mime type
+ *
+ * @param string $query a query string to search for
+ * @return object the first EasyRdf_Format that matches the query
+ * @throws EasyRdf_Exception if no format is found
+ */
+ public static function getFormat($query)
+ {
+ if (!is_string($query) or $query == null or $query == '') {
+ throw new InvalidArgumentException(
+ "\$query should be a string and cannot be null or empty"
+ );
+ }
+
+ foreach (self::$formats as $format) {
+ if ($query == $format->name or
+ $query == $format->uri or
+ array_key_exists($query, $format->mimeTypes) or
+ in_array($query, $format->extensions)) {
+ return $format;
+ }
+ }
+
+ # No match
+ throw new EasyRdf_Exception(
+ "Format is not recognised: $query"
+ );
+ }
+
+ /** Register a new format
+ *
+ * @param string $name The name of the format (e.g. ntriples)
+ * @param string $label The label for the format (e.g. N-Triples)
+ * @param string $uri The URI for the format
+ * @param string $mimeTypes One or more mime types for the format
+ * @param string $extensions One or more extensions (file suffix)
+ * @return object The new EasyRdf_Format object
+ */
+ public static function register(
+ $name,
+ $label = null,
+ $uri = null,
+ $mimeTypes = array(),
+ $extensions = array()
+ ) {
+ if (!is_string($name) or $name == null or $name == '') {
+ throw new InvalidArgumentException(
+ "\$name should be a string and cannot be null or empty"
+ );
+ }
+
+ if (!array_key_exists($name, self::$formats)) {
+ self::$formats[$name] = new EasyRdf_Format($name);
+ }
+
+ self::$formats[$name]->setLabel($label);
+ self::$formats[$name]->setUri($uri);
+ self::$formats[$name]->setMimeTypes($mimeTypes);
+ self::$formats[$name]->setExtensions($extensions);
+ return self::$formats[$name];
+ }
+
+ /** Remove a format from the registry
+ *
+ * @param string $name The name of the format (e.g. ntriples)
+ */
+ public static function unregister($name)
+ {
+ unset(self::$formats[$name]);
+ }
+
+ /** Class method to register a parser class to a format name
+ *
+ * @param string $name The name of the format (e.g. ntriples)
+ * @param string $class The name of the class (e.g. EasyRdf_Parser_Ntriples)
+ */
+ public static function registerParser($name, $class)
+ {
+ if (!self::formatExists($name)) {
+ self::register($name);
+ }
+ self::getFormat($name)->setParserClass($class);
+ }
+
+ /** Class method to register a serialiser class to a format name
+ *
+ * @param string $name The name of the format (e.g. ntriples)
+ * @param string $class The name of the class (e.g. EasyRdf_Serialiser_Ntriples)
+ */
+ public static function registerSerialiser($name, $class)
+ {
+ if (!self::formatExists($name)) {
+ self::register($name);
+ }
+ self::getFormat($name)->setSerialiserClass($class);
+ }
+
+ /** Attempt to guess the document format from some content.
+ *
+ * If $filename is given, then the suffix is first used to guess the format.
+ *
+ * If the document format is not recognised, null is returned.
+ *
+ * @param string $data The document data
+ * @param string $filename Optional filename
+ * @return object EasyRdf_Format The format object
+ */
+ public static function guessFormat($data, $filename = null)
+ {
+ if (is_array($data)) {
+ # Data has already been parsed into RDF/PHP
+ return self::getFormat('php');
+ }
+
+ // First try and identify by the filename
+ if ($filename and preg_match("/\.(\w+)$/", $filename, $matches)) {
+ foreach (self::$formats as $format) {
+ if (in_array($matches[1], $format->extensions)) {
+ return $format;
+ }
+ }
+ }
+
+ // Then try and guess by the first 1024 bytes of content
+ $short = substr($data, 0, 1024);
+ if (preg_match("/^\s*\{/", $short)) {
+ return self::getFormat('json');
+ } elseif (preg_match("/<rdf:/i", $short)) {
+ return self::getFormat('rdfxml');
+ } elseif (preg_match("/@prefix\s|@base\s/", $short)) {
+ return self::getFormat('turtle');
+ } elseif (preg_match("/^\s*<.+> <.+>/m", $short)) {
+ return self::getFormat('ntriples');
+ } elseif (preg_match("|http://www.w3.org/2005/sparql-results|", $short)) {
+ return self::getFormat('sparql-xml');
+ } elseif (preg_match("/\WRDFa\W/i", $short)) {
+ return self::getFormat('rdfa');
+ } elseif (preg_match("/<!DOCTYPE html|<html/i", $short)) {
+ # We don't support any other microformats embedded in HTML
+ return self::getFormat('rdfa');
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * This constructor is for internal use only.
+ * To create a new format, use the register method.
+ *
+ * @param string $name The name of the format
+ * @see EasyRdf_Format::register()
+ * @ignore
+ */
+ public function __construct($name)
+ {
+ $this->name = $name;
+ $this->label = $name; # Only a default
+ }
+
+ /** Get the name of a format object
+ *
+ * @return string The name of the format (e.g. rdfxml)
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /** Get the label for a format object
+ *
+ * @return string The format label (e.g. RDF/XML)
+ */
+ public function getLabel()
+ {
+ return $this->label;
+ }
+
+ /** Set the label for a format object
+ *
+ * @param string $label The new label for the format
+ */
+ public function setLabel($label)
+ {
+ if ($label) {
+ if (!is_string($label)) {
+ throw new InvalidArgumentException(
+ "\$label should be a string"
+ );
+ }
+ return $this->label = $label;
+ } else {
+ return $this->label = null;
+ }
+ }
+
+ /** Get the URI for a format object
+ *
+ * @return string The format URI
+ */
+ public function getUri()
+ {
+ return $this->uri;
+ }
+
+ /** Set the URI for a format object
+ *
+ * @param string $uri The new URI for the format
+ */
+ public function setUri($uri)
+ {
+ if ($uri) {
+ if (!is_string($uri)) {
+ throw new InvalidArgumentException(
+ "\$uri should be a string"
+ );
+ }
+ return $this->uri = $uri;
+ } else {
+ return $this->uri = null;
+ }
+ }
+
+ /** Get the default registered mime type for a format object
+ *
+ * @return string The default mime type as a string.
+ */
+ public function getDefaultMimeType()
+ {
+ $types = array_keys($this->mimeTypes);
+ if (isset($types[0])) {
+ return $types[0];
+ }
+ }
+
+ /** Get all the registered mime types for a format object
+ *
+ * @return array One or more MIME types in an array with
+ * the mime type as the key and q value as the value
+ */
+ public function getMimeTypes()
+ {
+ return $this->mimeTypes;
+ }
+
+ /** Set the MIME Types for a format object
+ *
+ * @param array $mimeTypes One or more mime types
+ */
+ public function setMimeTypes($mimeTypes)
+ {
+ if ($mimeTypes) {
+ if (!is_array($mimeTypes)) {
+ $mimeTypes = array($mimeTypes);
+ }
+ $this->mimeTypes = $mimeTypes;
+ } else {
+ $this->mimeTypes = array();
+ }
+ }
+
+ /** Get the default registered file extension (filename suffix) for a format object
+ *
+ * @return string The default extension as a string.
+ */
+ public function getDefaultExtension()
+ {
+ if (isset($this->extensions[0])) {
+ return $this->extensions[0];
+ }
+ }
+
+ /** Get all the registered file extensions (filename suffix) for a format object
+ *
+ * @return array One or more extensions as an array
+ */
+ public function getExtensions()
+ {
+ return $this->extensions;
+ }
+
+ /** Set the file format extensions (filename suffix) for a format object
+ *
+ * @param mixed $extensions One or more file extensions
+ */
+ public function setExtensions($extensions)
+ {
+ if ($extensions) {
+ if (!is_array($extensions)) {
+ $extensions = array($extensions);
+ }
+ $this->extensions = $extensions;
+ } else {
+ $this->extensions = array();
+ }
+ }
+
+ /** Set the parser to use for a format
+ *
+ * @param string $class The name of the class
+ */
+ public function setParserClass($class)
+ {
+ if ($class) {
+ if (!is_string($class)) {
+ throw new InvalidArgumentException(
+ "\$class should be a string"
+ );
+ }
+ $this->parserClass = $class;
+ } else {
+ $this->parserClass = null;
+ }
+ }
+
+ /** Get the name of the class to use to parse the format
+ *
+ * @return string The name of the class
+ */
+ public function getParserClass()
+ {
+ return $this->parserClass;
+ }
+
+ /** Create a new parser to parse this format
+ *
+ * @return object The new parser object
+ */
+ public function newParser()
+ {
+ $parserClass = $this->parserClass;
+ if (!$parserClass) {
+ throw new EasyRdf_Exception(
+ "No parser class available for format: ".$this->getName()
+ );
+ }
+ return (new $parserClass());
+ }
+
+ /** Set the serialiser to use for a format
+ *
+ * @param string $class The name of the class
+ */
+ public function setSerialiserClass($class)
+ {
+ if ($class) {
+ if (!is_string($class)) {
+ throw new InvalidArgumentException(
+ "\$class should be a string"
+ );
+ }
+ $this->serialiserClass = $class;
+ } else {
+ $this->serialiserClass = null;
+ }
+ }
+
+ /** Get the name of the class to use to serialise the format
+ *
+ * @return string The name of the class
+ */
+ public function getSerialiserClass()
+ {
+ return $this->serialiserClass;
+ }
+
+ /** Create a new serialiser to parse this format
+ *
+ * @return object The new serialiser object
+ */
+ public function newSerialiser()
+ {
+ $serialiserClass = $this->serialiserClass;
+ if (!$serialiserClass) {
+ throw new EasyRdf_Exception(
+ "No serialiser class available for format: ".$this->getName()
+ );
+ }
+ return (new $serialiserClass());
+ }
+
+ /** Magic method to return the name of the format when casted to string
+ *
+ * @return string The name of the format
+ */
+ public function __toString()
+ {
+ return $this->name;
+ }
+}
+
+
+/*
+ Register default set of supported formats
+ NOTE: they are ordered by preference
+*/
+
+EasyRdf_Format::register(
+ 'php',
+ 'RDF/PHP',
+ 'http://n2.talis.com/wiki/RDF_PHP_Specification',
+ array(
+ 'application/x-httpd-php-source' => 1.0
+ ),
+ array('phps')
+);
+
+EasyRdf_Format::register(
+ 'json',
+ 'RDF/JSON Resource-Centric',
+ 'http://n2.talis.com/wiki/RDF_JSON_Specification',
+ array(
+ 'application/json' => 1.0,
+ 'text/json' => 0.9,
+ 'application/rdf+json' => 0.9
+ ),
+ array('json')
+);
+
+EasyRdf_Format::register(
+ 'ntriples',
+ 'N-Triples',
+ 'http://www.w3.org/TR/n-triples/',
+ array(
+ 'application/n-triples' => 1.0,
+ 'text/plain' => 0.9,
+ 'text/ntriples' => 0.9,
+ 'application/ntriples' => 0.9,
+ 'application/x-ntriples' => 0.9
+ ),
+ array('nt')
+);
+
+EasyRdf_Format::register(
+ 'turtle',
+ 'Turtle Terse RDF Triple Language',
+ 'http://www.dajobe.org/2004/01/turtle',
+ array(
+ 'text/turtle' => 0.8,
+ 'application/turtle' => 0.7,
+ 'application/x-turtle' => 0.7
+ ),
+ array('ttl')
+);
+
+EasyRdf_Format::register(
+ 'rdfxml',
+ 'RDF/XML',
+ 'http://www.w3.org/TR/rdf-syntax-grammar',
+ array(
+ 'application/rdf+xml' => 0.8
+ ),
+ array('rdf', 'xrdf')
+);
+
+EasyRdf_Format::register(
+ 'dot',
+ 'Graphviz',
+ 'http://www.graphviz.org/doc/info/lang.html',
+ array(
+ 'text/vnd.graphviz' => 0.8
+ ),
+ array('gv', 'dot')
+);
+
+EasyRdf_Format::register(
+ 'json-triples',
+ 'RDF/JSON Triples'
+);
+
+EasyRdf_Format::register(
+ 'n3',
+ 'Notation3',
+ 'http://www.w3.org/2000/10/swap/grammar/n3#',
+ array(
+ 'text/n3' => 0.5,
+ 'text/rdf+n3' => 0.5
+ ),
+ array('n3')
+);
+
+EasyRdf_Format::register(
+ 'rdfa',
+ 'RDFa',
+ 'http://www.w3.org/TR/rdfa-core/',
+ array(
+ 'text/html' => 0.4,
+ 'application/xhtml+xml' => 0.4
+ ),
+ array('html')
+);
+
+EasyRdf_Format::register(
+ 'sparql-xml',
+ 'SPARQL XML Query Results',
+ 'http://www.w3.org/TR/rdf-sparql-XMLres/',
+ array(
+ 'application/sparql-results+xml' => 1.0
+ )
+);
+
+EasyRdf_Format::register(
+ 'sparql-json',
+ 'SPARQL JSON Query Results',
+ 'http://www.w3.org/TR/rdf-sparql-json-res/',
+ array(
+ 'application/sparql-results+json' => 1.0
+ )
+);
+
+EasyRdf_Format::register(
+ 'png',
+ 'Portable Network Graphics (PNG)',
+ 'http://www.w3.org/TR/PNG/',
+ array(
+ 'image/png' => 0.3
+ ),
+ array('png')
+);
+
+EasyRdf_Format::register(
+ 'gif',
+ 'Graphics Interchange Format (GIF)',
+ 'http://www.w3.org/Graphics/GIF/spec-gif89a.txt',
+ array(
+ 'image/gif' => 0.2
+ ),
+ array('gif')
+);
+
+EasyRdf_Format::register(
+ 'svg',
+ 'Scalable Vector Graphics (SVG)',
+ 'http://www.w3.org/TR/SVG/',
+ array(
+ 'image/svg+xml' => 0.3
+ ),
+ array('svg')
+);
+
+
+/*
+ Register default set of parsers and serialisers
+*/
+
+EasyRdf_Format::registerParser('json', 'EasyRdf_Parser_Json');
+EasyRdf_Format::registerParser('ntriples', 'EasyRdf_Parser_Ntriples');
+EasyRdf_Format::registerParser('php', 'EasyRdf_Parser_RdfPhp');
+EasyRdf_Format::registerParser('rdfxml', 'EasyRdf_Parser_RdfXml');
+EasyRdf_Format::registerParser('turtle', 'EasyRdf_Parser_Turtle');
+EasyRdf_Format::registerParser('rdfa', 'EasyRdf_Parser_Rdfa');
+
+EasyRdf_Format::registerSerialiser('json', 'EasyRdf_Serialiser_Json');
+EasyRdf_Format::registerSerialiser('n3', 'EasyRdf_Serialiser_Turtle');
+EasyRdf_Format::registerSerialiser('ntriples', 'EasyRdf_Serialiser_Ntriples');
+EasyRdf_Format::registerSerialiser('php', 'EasyRdf_Serialiser_RdfPhp');
+EasyRdf_Format::registerSerialiser('rdfxml', 'EasyRdf_Serialiser_RdfXml');
+EasyRdf_Format::registerSerialiser('turtle', 'EasyRdf_Serialiser_Turtle');
+
+EasyRdf_Format::registerSerialiser('dot', 'EasyRdf_Serialiser_GraphViz');
+EasyRdf_Format::registerSerialiser('gif', 'EasyRdf_Serialiser_GraphViz');
+EasyRdf_Format::registerSerialiser('png', 'EasyRdf_Serialiser_GraphViz');
+EasyRdf_Format::registerSerialiser('svg', 'EasyRdf_Serialiser_GraphViz');
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Graph.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,1648 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Container for collection of EasyRdf_Resources.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Graph
+{
+ /** The URI of the graph */
+ private $uri = null;
+ private $parsedUri = null;
+
+ /** Array of resources contained in the graph */
+ private $resources = array();
+
+ private $index = array();
+ private $revIndex = array();
+
+ /** Counter for the number of bnodes */
+ private $bNodeCount = 0;
+
+ /** Array of URLs that have been loaded into the graph */
+ private $loaded = array();
+
+ private $maxRedirects = 10;
+
+
+ /**
+ * Constructor
+ *
+ * If no URI is given then an unnamed graph is created.
+ *
+ * The $data parameter is optional and will be parsed into
+ * the graph if given.
+ *
+ * The data format is optional and should be specified if it
+ * can't be guessed by EasyRdf.
+ *
+ * @param string $uri The URI of the graph
+ * @param string $data Data for the graph
+ * @param string $format The document type of the data (e.g. rdfxml)
+ * @return object EasyRdf_Graph
+ */
+ public function __construct($uri = null, $data = null, $format = null)
+ {
+ $this->checkResourceParam($uri, true);
+
+ if ($uri) {
+ $this->uri = $uri;
+ $this->parsedUri = new EasyRdf_ParsedUri($uri);
+ if ($data) {
+ $this->parse($data, $format, $this->uri);
+ }
+ }
+ }
+
+ /**
+ * Create a new graph and load RDF data from a URI into it
+ *
+ * This static function is shorthand for:
+ * $graph = new EasyRdf_Graph($uri);
+ * $graph->load($uri, $format);
+ *
+ * The document type is optional but should be specified if it
+ * can't be guessed or got from the HTTP headers.
+ *
+ * @param string $uri The URI of the data to load
+ * @param string $format Optional format of the data (eg. rdfxml)
+ * @return object EasyRdf_Graph The new the graph object
+ */
+ public static function newAndLoad($uri, $format = null)
+ {
+ $graph = new self($uri);
+ $graph->load($uri, $format);
+ return $graph;
+ }
+
+ /** Get or create a resource stored in a graph
+ *
+ * If the resource did not previously exist, then a new resource will
+ * be created. If you provide an RDF type and that type is registered
+ * with the EasyRdf_TypeMapper, then the resource will be an instance
+ * of the class registered.
+ *
+ * If URI is null, then the URI of the graph is used.
+ *
+ * @param string $uri The URI of the resource
+ * @param mixed $types RDF type of a new resource (e.g. foaf:Person)
+ * @return object EasyRdf_Resource
+ */
+ public function resource($uri = null, $types = array())
+ {
+ $this->checkResourceParam($uri, true);
+ if (!$uri) {
+ throw new InvalidArgumentException(
+ '$uri is null and EasyRdf_Graph object has no URI either.'
+ );
+ }
+
+ // Resolve relative URIs
+ if ($this->parsedUri) {
+ $uri = $this->parsedUri->resolve($uri)->toString();
+ }
+
+ // Add the types
+ $this->addType($uri, $types);
+
+ // Create resource object if it doesn't already exist
+ if (!isset($this->resources[$uri])) {
+ $resClass = $this->classForResource($uri);
+ $this->resources[$uri] = new $resClass($uri, $this);
+ }
+
+ return $this->resources[$uri];
+ }
+
+ /** Work out the class to instantiate a resource as
+ * @ignore
+ */
+ protected function classForResource($uri)
+ {
+ $rdfType = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type';
+ if (isset($this->index[$uri][$rdfType])) {
+ foreach ($this->index[$uri][$rdfType] as $type) {
+ if ($type['type'] == 'uri' or $type['type'] == 'bnode') {
+ $class = EasyRdf_TypeMapper::get($type['value']);
+ if ($class != null) {
+ return $class;
+ }
+ }
+ }
+ }
+
+ // Parsers don't typically add a rdf:type to rdf:List, so we have to
+ // do a bit of 'inference' here using properties.
+ if ($uri == 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil' or
+ isset($this->index[$uri]['http://www.w3.org/1999/02/22-rdf-syntax-ns#first']) or
+ isset($this->index[$uri]['http://www.w3.org/1999/02/22-rdf-syntax-ns#rest'])
+ ) {
+ return 'EasyRdf_Collection';
+ }
+ return 'EasyRdf_Resource';
+ }
+
+ /**
+ * Create a new blank node in the graph and return it.
+ *
+ * If you provide an RDF type and that type is registered
+ * with the EasyRdf_TypeMapper, then the resource will be an instance
+ * of the class registered.
+ *
+ * @param mixed $types RDF type of a new blank node (e.g. foaf:Person)
+ * @return object EasyRdf_Resource The new blank node
+ */
+ public function newBNode($types = array())
+ {
+ return $this->resource($this->newBNodeId(), $types);
+ }
+
+ /**
+ * Create a new unique blank node identifier and return it.
+ *
+ * @return string The new blank node identifier (e.g. _:genid1)
+ */
+ public function newBNodeId()
+ {
+ return "_:genid".(++$this->bNodeCount);
+ }
+
+ /**
+ * Parse some RDF data into the graph object.
+ *
+ * @param string $data Data to parse for the graph
+ * @param string $format Optional format of the data
+ * @param string $uri The URI of the data to load
+ * @return integer The number of triples added to the graph
+ */
+ public function parse($data, $format = null, $uri = null)
+ {
+ $this->checkResourceParam($uri, true);
+
+ if (empty($format) or $format == 'guess') {
+ // Guess the format if it is Unknown
+ $format = EasyRdf_Format::guessFormat($data, $uri);
+ } else {
+ $format = EasyRdf_Format::getFormat($format);
+ }
+
+ if (!$format) {
+ throw new EasyRdf_Exception(
+ "Unable to parse data of an unknown format."
+ );
+ }
+
+ $parser = $format->newParser();
+ return $parser->parse($this, $data, $format, $uri);
+ }
+
+ /**
+ * Parse a file containing RDF data into the graph object.
+ *
+ * @param string $filename The path of the file to load
+ * @param string $format Optional format of the file
+ * @param string $uri The URI of the file to load
+ * @return integer The number of triples added to the graph
+ */
+ public function parseFile($filename, $format = null, $uri = null)
+ {
+ if ($uri === null) {
+ $uri = "file://$filename";
+ }
+
+ return $this->parse(
+ file_get_contents($filename),
+ $format,
+ $uri
+ );
+ }
+
+ /**
+ * Load RDF data into the graph from a URI.
+ *
+ * If no URI is given, then the URI of the graph will be used.
+ *
+ * The document type is optional but should be specified if it
+ * can't be guessed or got from the HTTP headers.
+ *
+ * @param string $uri The URI of the data to load
+ * @param string $format Optional format of the data (eg. rdfxml)
+ * @return integer The number of triples added to the graph
+ */
+ public function load($uri = null, $format = null)
+ {
+ $this->checkResourceParam($uri, true);
+
+ if (!$uri) {
+ throw new EasyRdf_Exception(
+ "No URI given to load() and the graph does not have a URI."
+ );
+ }
+
+ // Setup the HTTP client
+ $client = EasyRdf_Http::getDefaultHttpClient();
+ $client->resetParameters(true);
+ $client->setConfig(array('maxredirects' => 0));
+ $client->setMethod('GET');
+ $client->setHeaders('Accept', EasyRdf_Format::getHttpAcceptHeader());
+
+ $requestUrl = $uri;
+ $response = null;
+ $redirectCounter = 0;
+ do {
+ // Have we already loaded it into the graph?
+ $requestUrl = EasyRdf_Utils::removeFragmentFromUri($requestUrl);
+ if (in_array($requestUrl, $this->loaded)) {
+ return 0;
+ }
+
+ // Make the HTTP request
+ $client->setHeaders('host', null);
+ $client->setUri($requestUrl);
+ $response = $client->request();
+
+ // Add the URL to the list of URLs loaded
+ $this->loaded[] = $requestUrl;
+
+ if ($response->isRedirect() and $location = $response->getHeader('location')) {
+ // Avoid problems with buggy servers that add whitespace
+ $location = trim($location);
+
+ // Some servers return relative URLs in the location header
+ // resolve it in relation to previous request
+ $baseUri = new EasyRdf_ParsedUri($requestUrl);
+ $requestUrl = $baseUri->resolve($location)->toString();
+ $requestUrl = EasyRdf_Utils::removeFragmentFromUri($requestUrl);
+
+ // If it is a 303 then drop the parameters
+ if ($response->getStatus() == 303) {
+ $client->resetParameters();
+ }
+
+ ++$redirectCounter;
+ } elseif ($response->isSuccessful()) {
+ // If we didn't get any location, stop redirecting
+ break;
+ } else {
+ throw new EasyRdf_Exception(
+ "HTTP request for $requestUrl failed: ".$response->getMessage()
+ );
+ }
+ } while ($redirectCounter < $this->maxRedirects);
+
+ if (!$format or $format == 'guess') {
+ list($format, $params) = EasyRdf_Utils::parseMimeType(
+ $response->getHeader('Content-Type')
+ );
+ }
+
+ // Parse the data
+ return $this->parse($response->getBody(), $format, $uri);
+ }
+
+ /** Get an associative array of all the resources stored in the graph.
+ * The keys of the array is the URI of the EasyRdf_Resource.
+ *
+ * @return array Array of EasyRdf_Resource
+ */
+ public function resources()
+ {
+ foreach ($this->index as $subject => $properties) {
+ if (!isset($this->resources[$subject])) {
+ $this->resource($subject);
+ }
+ }
+
+ foreach ($this->revIndex as $object => $properties) {
+ if (!isset($this->resources[$object])) {
+ $this->resource($object);
+ }
+ }
+
+ return $this->resources;
+ }
+
+ /** Get an arry of resources matching a certain property and optional value.
+ *
+ * For example this routine could be used as a way of getting
+ * everyone who has name:
+ * $people = $graph->resourcesMatching('foaf:name')
+ *
+ * Or everyone who is male:
+ * $people = $graph->resourcesMatching('foaf:gender', 'male');
+ *
+ * Or all homepages:
+ * $people = $graph->resourcesMatching('^foaf:homepage');
+ *
+ * @param string $property The property to check.
+ * @param mixed $value Optional, the value of the propery to check for.
+ * @return array Array of EasyRdf_Resource
+ */
+ public function resourcesMatching($property, $value = null)
+ {
+ $this->checkSinglePropertyParam($property, $inverse);
+ $this->checkValueParam($value);
+
+ // Use the reverse index if it is an inverse property
+ if ($inverse) {
+ $index = &$this->revIndex;
+ } else {
+ $index = &$this->index;
+ }
+
+ $matched = array();
+ foreach ($index as $subject => $props) {
+ if (isset($index[$subject][$property])) {
+ if (isset($value)) {
+ foreach ($this->index[$subject][$property] as $v) {
+ if ($v['type'] == $value['type'] and
+ $v['value'] == $value['value']) {
+ $matched[] = $this->resource($subject);
+ break;
+ }
+ }
+ } else {
+ $matched[] = $this->resource($subject);
+ }
+ }
+ }
+ return $matched;
+ }
+
+ /** Get the URI of the graph
+ *
+ * @return string The URI of the graph
+ */
+ public function getUri()
+ {
+ return $this->uri;
+ }
+
+ /** Check that a URI/resource parameter is valid, and convert it to a string
+ * @ignore
+ */
+ protected function checkResourceParam(&$resource, $allowNull = false)
+ {
+ if ($allowNull == true) {
+ if ($resource === null) {
+ if ($this->uri) {
+ $resource = $this->uri;
+ } else {
+ return;
+ }
+ }
+ } elseif ($resource === null) {
+ throw new InvalidArgumentException(
+ "\$resource cannot be null"
+ );
+ }
+
+ if (is_object($resource) and $resource instanceof EasyRdf_Resource) {
+ $resource = $resource->getUri();
+ } elseif (is_object($resource) and $resource instanceof EasyRdf_ParsedUri) {
+ $resource = strval($resource);
+ } elseif (is_string($resource)) {
+ if ($resource == '') {
+ throw new InvalidArgumentException(
+ "\$resource cannot be an empty string"
+ );
+ } elseif (preg_match("|^<(.+)>$|", $resource, $matches)) {
+ $resource = $matches[1];
+ } else {
+ $resource = EasyRdf_Namespace::expand($resource);
+ }
+ } else {
+ throw new InvalidArgumentException(
+ "\$resource should be a string or an EasyRdf_Resource"
+ );
+ }
+ }
+
+ /** Check that a single URI/property parameter (not a property path)
+ * is valid, and expand it if required
+ * @ignore
+ */
+ protected function checkSinglePropertyParam(&$property, &$inverse)
+ {
+ if (is_object($property) and $property instanceof EasyRdf_Resource) {
+ $property = $property->getUri();
+ } elseif (is_object($property) and $property instanceof EasyRdf_ParsedUri) {
+ $property = strval($property);
+ } elseif (is_string($property)) {
+ if ($property == '') {
+ throw new InvalidArgumentException(
+ "\$property cannot be an empty string"
+ );
+ } elseif (substr($property, 0, 1) == '^') {
+ $inverse = true;
+ $property = EasyRdf_Namespace::expand(substr($property, 1));
+ } elseif (substr($property, 0, 2) == '_:') {
+ throw new InvalidArgumentException(
+ "\$property cannot be a blank node"
+ );
+ } else {
+ $inverse = false;
+ $property = EasyRdf_Namespace::expand($property);
+ }
+ }
+
+ if ($property === null or !is_string($property)) {
+ throw new InvalidArgumentException(
+ "\$property should be a string or EasyRdf_Resource and cannot be null"
+ );
+ }
+ }
+
+ /** Check that a value parameter is valid, and convert it to an associative array if needed
+ * @ignore
+ */
+ protected function checkValueParam(&$value)
+ {
+ if (isset($value)) {
+ if (is_object($value)) {
+ if (!method_exists($value, 'toRdfPhp')) {
+ // Convert to a literal object
+ $value = EasyRdf_Literal::create($value);
+ }
+ $value = $value->toRdfPhp();
+ } elseif (is_array($value)) {
+ if (!isset($value['type'])) {
+ throw new InvalidArgumentException(
+ "\$value is missing a 'type' key"
+ );
+ }
+
+ if (!isset($value['value'])) {
+ throw new InvalidArgumentException(
+ "\$value is missing a 'value' key"
+ );
+ }
+
+ // Fix ordering and remove unknown keys
+ $value = array(
+ 'type' => strval($value['type']),
+ 'value' => strval($value['value']),
+ 'lang' => isset($value['lang']) ? strval($value['lang']) : null,
+ 'datatype' => isset($value['datatype']) ? strval($value['datatype']) : null
+ );
+ } else {
+ $value = array(
+ 'type' => 'literal',
+ 'value' => strval($value),
+ 'datatype' => EasyRdf_Literal::getDatatypeForValue($value)
+ );
+ }
+ if (!in_array($value['type'], array('uri', 'bnode', 'literal'), true)) {
+ throw new InvalidArgumentException(
+ "\$value does not have a valid type (".$value['type'].")"
+ );
+ }
+ if (empty($value['datatype'])) {
+ unset($value['datatype']);
+ }
+ if (empty($value['lang'])) {
+ unset($value['lang']);
+ }
+ if (isset($value['lang']) and isset($value['datatype'])) {
+ throw new InvalidArgumentException(
+ "\$value cannot have both and language and a datatype"
+ );
+ }
+ }
+ }
+
+ /** Get a single value for a property of a resource
+ *
+ * If multiple values are set for a property then the value returned
+ * may be arbitrary.
+ *
+ * If $property is an array, then the first item in the array that matches
+ * a property that exists is returned.
+ *
+ * This method will return null if the property does not exist.
+ *
+ * @param string $resource The URI of the resource (e.g. http://example.com/joe#me)
+ * @param string $propertyPath A valid property path
+ * @param string $type The type of value to filter by (e.g. literal or resource)
+ * @param string $lang The language to filter by (e.g. en)
+ * @return mixed A value associated with the property
+ */
+ public function get($resource, $propertyPath, $type = null, $lang = null)
+ {
+ $this->checkResourceParam($resource);
+
+ if (is_object($propertyPath) and $propertyPath instanceof EasyRdf_Resource) {
+ return $this->getSingleProperty($resource, $propertyPath->getUri(), $type, $lang);
+ } elseif (is_string($propertyPath) and preg_match('|^(\^?)<(.+)>|', $propertyPath, $matches)) {
+ return $this->getSingleProperty($resource, "$matches[1]$matches[2]", $type, $lang);
+ } elseif ($propertyPath === null or !is_string($propertyPath)) {
+ throw new InvalidArgumentException(
+ "\$propertyPath should be a string or EasyRdf_Resource and cannot be null"
+ );
+ } elseif ($propertyPath === '') {
+ throw new InvalidArgumentException(
+ "\$propertyPath cannot be an empty string"
+ );
+ }
+
+ // Loop through each component in the path
+ foreach (explode('/', $propertyPath) as $part) {
+ // Stop if we come to a literal
+ if ($resource instanceof EasyRdf_Literal) {
+ return null;
+ }
+
+ // Try each of the alternative paths
+ foreach (explode('|', $part) as $p) {
+ $res = $this->getSingleProperty($resource, $p, $type, $lang);
+ if ($res) {
+ break;
+ }
+ }
+
+ // Stop if nothing was found
+ $resource = $res;
+ if (!$resource) {
+ break;
+ }
+ }
+
+ return $resource;
+ }
+
+ /** Get a single value for a property of a resource
+ *
+ * @param string $resource The URI of the resource (e.g. http://example.com/joe#me)
+ * @param string $property The name of the property (e.g. foaf:name)
+ * @param string $type The type of value to filter by (e.g. literal or resource)
+ * @param string $lang The language to filter by (e.g. en)
+ * @return mixed A value associated with the property
+ *
+ * @ignore
+ */
+ protected function getSingleProperty($resource, $property, $type = null, $lang = null)
+ {
+ $this->checkResourceParam($resource);
+ $this->checkSinglePropertyParam($property, $inverse);
+
+ // Get an array of values for the property
+ $values = $this->propertyValuesArray($resource, $property, $inverse);
+ if (!isset($values)) {
+ return null;
+ }
+
+ // Filter the results
+ $result = null;
+ if ($type) {
+ foreach ($values as $value) {
+ if ($type == 'literal' and $value['type'] == 'literal') {
+ if ($lang == null or (isset($value['lang']) and $value['lang'] == $lang)) {
+ $result = $value;
+ break;
+ }
+ } elseif ($type == 'resource') {
+ if ($value['type'] == 'uri' or $value['type'] == 'bnode') {
+ $result = $value;
+ break;
+ }
+ }
+ }
+ } else {
+ $result = $values[0];
+ }
+
+ // Convert the internal data structure into a PHP object
+ return $this->arrayToObject($result);
+ }
+
+ /** Get a single literal value for a property of a resource
+ *
+ * If multiple values are set for a property then the value returned
+ * may be arbitrary.
+ *
+ * This method will return null if there is not literal value for the
+ * property.
+ *
+ * @param string $resource The URI of the resource (e.g. http://example.com/joe#me)
+ * @param string|array $property The name of the property (e.g. foaf:name)
+ * @param string $lang The language to filter by (e.g. en)
+ * @return object EasyRdf_Literal Literal value associated with the property
+ */
+ public function getLiteral($resource, $property, $lang = null)
+ {
+ return $this->get($resource, $property, 'literal', $lang);
+ }
+
+ /** Get a single resource value for a property of a resource
+ *
+ * If multiple values are set for a property then the value returned
+ * may be arbitrary.
+ *
+ * This method will return null if there is not resource for the
+ * property.
+ *
+ * @param string $resource The URI of the resource (e.g. http://example.com/joe#me)
+ * @param string|array $property The name of the property (e.g. foaf:name)
+ * @return object EasyRdf_Resource Resource associated with the property
+ */
+ public function getResource($resource, $property)
+ {
+ return $this->get($resource, $property, 'resource');
+ }
+
+ /** Return all the values for a particular property of a resource
+ * @ignore
+ */
+ protected function propertyValuesArray($resource, $property, $inverse = false)
+ {
+ // Is an inverse property being requested?
+ if ($inverse) {
+ if (isset($this->revIndex[$resource])) {
+ $properties = &$this->revIndex[$resource];
+ }
+ } else {
+ if (isset($this->index[$resource])) {
+ $properties = &$this->index[$resource];
+ }
+ }
+
+ if (isset($properties[$property])) {
+ return $properties[$property];
+ } else {
+ return null;
+ }
+ }
+
+ /** Get an EasyRdf_Resource or EasyRdf_Literal object from an associative array.
+ * @ignore
+ */
+ protected function arrayToObject($data)
+ {
+ if ($data) {
+ if ($data['type'] == 'uri' or $data['type'] == 'bnode') {
+ return $this->resource($data['value']);
+ } else {
+ return EasyRdf_Literal::create($data);
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /** Get all values for a property path
+ *
+ * This method will return an empty array if the property does not exist.
+ *
+ * @param string $resource The URI of the resource (e.g. http://example.com/joe#me)
+ * @param string $propertyPath A valid property path
+ * @param string $type The type of value to filter by (e.g. literal)
+ * @param string $lang The language to filter by (e.g. en)
+ * @return array An array of values associated with the property
+ */
+ public function all($resource, $propertyPath, $type = null, $lang = null)
+ {
+ $this->checkResourceParam($resource);
+
+ if (is_object($propertyPath) and $propertyPath instanceof EasyRdf_Resource) {
+ return $this->allForSingleProperty($resource, $propertyPath->getUri(), $type, $lang);
+ } elseif (is_string($propertyPath) and preg_match('|^(\^?)<(.+)>|', $propertyPath, $matches)) {
+ return $this->allForSingleProperty($resource, "$matches[1]$matches[2]", $type, $lang);
+ } elseif ($propertyPath === null or !is_string($propertyPath)) {
+ throw new InvalidArgumentException(
+ "\$propertyPath should be a string or EasyRdf_Resource and cannot be null"
+ );
+ } elseif ($propertyPath === '') {
+ throw new InvalidArgumentException(
+ "\$propertyPath cannot be an empty string"
+ );
+ }
+
+ $objects = array($resource);
+
+ // Loop through each component in the path
+ foreach (explode('/', $propertyPath) as $part) {
+
+ $results = array();
+ foreach (explode('|', $part) as $p) {
+ foreach ($objects as $o) {
+ // Ignore literals found earlier in path
+ if ($o instanceof EasyRdf_Literal) {
+ continue;
+ }
+
+ $results = array_merge(
+ $results,
+ $this->allForSingleProperty($o, $p, $type, $lang)
+ );
+ }
+ }
+
+ // Stop if we don't have anything
+ if (empty($objects)) {
+ break;
+ }
+
+ // Use the results as the input to the next iteration
+ $objects = $results;
+ }
+
+ return $results;
+ }
+
+ /** Get all values for a single property of a resource
+ *
+ * @param string $resource The URI of the resource (e.g. http://example.com/joe#me)
+ * @param string $property The name of the property (e.g. foaf:name)
+ * @param string $type The type of value to filter by (e.g. literal)
+ * @param string $lang The language to filter by (e.g. en)
+ * @return array An array of values associated with the property
+ *
+ * @ignore
+ */
+ protected function allForSingleProperty($resource, $property, $type = null, $lang = null)
+ {
+ $this->checkResourceParam($resource);
+ $this->checkSinglePropertyParam($property, $inverse);
+
+ // Get an array of values for the property
+ $values = $this->propertyValuesArray($resource, $property, $inverse);
+ if (!isset($values)) {
+ return array();
+ }
+
+ $objects = array();
+ if ($type) {
+ foreach ($values as $value) {
+ if ($type == 'literal' and $value['type'] == 'literal') {
+ if ($lang == null or (isset($value['lang']) and $value['lang'] == $lang)) {
+ $objects[] = $this->arrayToObject($value);
+ }
+ } elseif ($type == 'resource') {
+ if ($value['type'] == 'uri' or $value['type'] == 'bnode') {
+ $objects[] = $this->arrayToObject($value);
+ }
+ }
+ }
+ } else {
+ foreach ($values as $value) {
+ $objects[] = $this->arrayToObject($value);
+ }
+ }
+ return $objects;
+ }
+
+ /** Get all literal values for a property of a resource
+ *
+ * This method will return an empty array if the resource does not
+ * has any literal values for that property.
+ *
+ * @param string $resource The URI of the resource (e.g. http://example.com/joe#me)
+ * @param string $property The name of the property (e.g. foaf:name)
+ * @param string $lang The language to filter by (e.g. en)
+ * @return array An array of values associated with the property
+ */
+ public function allLiterals($resource, $property, $lang = null)
+ {
+ return $this->all($resource, $property, 'literal', $lang);
+ }
+
+ /** Get all resources for a property of a resource
+ *
+ * This method will return an empty array if the resource does not
+ * has any resources for that property.
+ *
+ * @param string $resource The URI of the resource (e.g. http://example.com/joe#me)
+ * @param string $property The name of the property (e.g. foaf:name)
+ * @return array An array of values associated with the property
+ */
+ public function allResources($resource, $property)
+ {
+ return $this->all($resource, $property, 'resource');
+ }
+
+ /** Get all the resources in the graph of a certain type
+ *
+ * If no resources of the type are available and empty
+ * array is returned.
+ *
+ * @param string $type The type of the resource (e.g. foaf:Person)
+ * @return array The array of resources
+ */
+ public function allOfType($type)
+ {
+ return $this->all($type, '^rdf:type');
+ }
+
+ /** Count the number of values for a property of a resource
+ *
+ * @param string $resource The URI of the resource (e.g. http://example.com/joe#me)
+ * @param string $property The name of the property (e.g. foaf:name)
+ * @param string $type The type of value to filter by (e.g. literal)
+ * @param string $lang The language to filter by (e.g. en)
+ * @return integer The number of values for this property
+ */
+ public function countValues($resource, $property, $type = null, $lang = null)
+ {
+ return count($this->all($resource, $property, $type, $lang));
+ }
+
+ /** Concatenate all values for a property of a resource into a string.
+ *
+ * The default is to join the values together with a space character.
+ * This method will return an empty string if the property does not exist.
+ *
+ * @param mixed $resource The resource to get the property on
+ * @param string $property The name of the property (e.g. foaf:name)
+ * @param string $glue The string to glue the values together with.
+ * @param string $lang The language to filter by (e.g. en)
+ * @return string Concatenation of all the values.
+ */
+ public function join($resource, $property, $glue = ' ', $lang = null)
+ {
+ return join($glue, $this->all($resource, $property, 'literal', $lang));
+ }
+
+ /** Add data to the graph
+ *
+ * The resource can either be a resource or the URI of a resource.
+ *
+ * Example:
+ * $graph->add("http://www.example.com", 'dc:title', 'Title of Page');
+ *
+ * @param mixed $resource The resource to add data to
+ * @param mixed $property The property name
+ * @param mixed $value The new value for the property
+ * @return integer The number of values added (1 or 0)
+ */
+ public function add($resource, $property, $value)
+ {
+ $this->checkResourceParam($resource);
+ $this->checkSinglePropertyParam($property, $inverse);
+ $this->checkValueParam($value);
+
+ // No value given?
+ if ($value === null) {
+ return 0;
+ }
+
+ // Check that the value doesn't already exist
+ if (isset($this->index[$resource][$property])) {
+ foreach ($this->index[$resource][$property] as $v) {
+ if ($v == $value) {
+ return 0;
+ }
+ }
+ }
+ $this->index[$resource][$property][] = $value;
+
+ // Add to the reverse index if it is a resource
+ if ($value['type'] == 'uri' or $value['type'] == 'bnode') {
+ $uri = $value['value'];
+ $this->revIndex[$uri][$property][] = array(
+ 'type' => substr($resource, 0, 2) == '_:' ? 'bnode' : 'uri',
+ 'value' => $resource
+ );
+ }
+
+ // Success
+ return 1;
+ }
+
+ /** Add a literal value as a property of a resource
+ *
+ * The resource can either be a resource or the URI of a resource.
+ * The value can either be a single value or an array of values.
+ *
+ * Example:
+ * $graph->add("http://www.example.com", 'dc:title', 'Title of Page');
+ *
+ * @param mixed $resource The resource to add data to
+ * @param mixed $property The property name
+ * @param mixed $value The value or values for the property
+ * @param string $lang The language of the literal
+ * @return integer The number of values added
+ */
+ public function addLiteral($resource, $property, $value, $lang = null)
+ {
+ $this->checkResourceParam($resource);
+ $this->checkSinglePropertyParam($property, $inverse);
+
+ if (is_array($value)) {
+ $added = 0;
+ foreach ($value as $v) {
+ $added += $this->addLiteral($resource, $property, $v, $lang);
+ }
+ return $added;
+ } elseif (!is_object($value) or !$value instanceof EasyRdf_Literal) {
+ $value = EasyRdf_Literal::create($value, $lang);
+ }
+ return $this->add($resource, $property, $value);
+ }
+
+ /** Add a resource as a property of another resource
+ *
+ * The resource can either be a resource or the URI of a resource.
+ *
+ * Example:
+ * $graph->add("http://example.com/bob", 'foaf:knows', 'http://example.com/alice');
+ *
+ * @param mixed $resource The resource to add data to
+ * @param mixed $property The property name
+ * @param mixed $resource2 The resource to be value of the property
+ * @return integer The number of values added
+ */
+ public function addResource($resource, $property, $resource2)
+ {
+ $this->checkResourceParam($resource);
+ $this->checkSinglePropertyParam($property, $inverse);
+ $this->checkResourceParam($resource2);
+
+ return $this->add(
+ $resource,
+ $property,
+ array(
+ 'type' => substr($resource2, 0, 2) == '_:' ? 'bnode' : 'uri',
+ 'value' => $resource2
+ )
+ );
+ }
+
+ /** Set a value for a property
+ *
+ * The new value will replace the existing values for the property.
+ *
+ * @param string $resource The resource to set the property on
+ * @param string $property The name of the property (e.g. foaf:name)
+ * @param mixed $value The value for the property
+ * @return integer The number of values added (1 or 0)
+ */
+ public function set($resource, $property, $value)
+ {
+ $this->checkResourceParam($resource);
+ $this->checkSinglePropertyParam($property, $inverse);
+ $this->checkValueParam($value);
+
+ // Delete the old values
+ $this->delete($resource, $property);
+
+ // Add the new values
+ return $this->add($resource, $property, $value);
+ }
+
+ /** Delete a property (or optionally just a specific value)
+ *
+ * @param mixed $resource The resource to delete the property from
+ * @param string $property The name of the property (e.g. foaf:name)
+ * @param mixed $value The value to delete (null to delete all values)
+ * @return integer The number of values deleted
+ */
+ public function delete($resource, $property, $value = null)
+ {
+ $this->checkResourceParam($resource);
+
+ if (is_object($property) and $property instanceof EasyRdf_Resource) {
+ return $this->deleteSingleProperty($resource, $property->getUri(), $value);
+ } elseif (is_string($property) and preg_match('|^(\^?)<(.+)>|', $property, $matches)) {
+ return $this->deleteSingleProperty($resource, "$matches[1]$matches[2]", $value);
+ } elseif ($property === null or !is_string($property)) {
+ throw new InvalidArgumentException(
+ "\$property should be a string or EasyRdf_Resource and cannot be null"
+ );
+ } elseif ($property === '') {
+ throw new InvalidArgumentException(
+ "\$property cannot be an empty string"
+ );
+ }
+
+ // FIXME: finish implementing property paths for delete
+ return $this->deleteSingleProperty($resource, $property, $value);
+ }
+
+
+ /** Delete a property (or optionally just a specific value)
+ *
+ * @param mixed $resource The resource to delete the property from
+ * @param string $property The name of the property (e.g. foaf:name)
+ * @param mixed $value The value to delete (null to delete all values)
+ * @return integer The number of values deleted
+ *
+ * @ignore
+ */
+ public function deleteSingleProperty($resource, $property, $value = null)
+ {
+ $this->checkResourceParam($resource);
+ $this->checkSinglePropertyParam($property, $inverse);
+ $this->checkValueParam($value);
+
+ $count = 0;
+ if (isset($this->index[$resource][$property])) {
+ foreach ($this->index[$resource][$property] as $k => $v) {
+ if (!$value or $v == $value) {
+ unset($this->index[$resource][$property][$k]);
+ $count++;
+ if ($v['type'] == 'uri' or $v['type'] == 'bnode') {
+ $this->deleteInverse($v['value'], $property, $resource);
+ }
+ }
+ }
+
+ // Clean up the indexes - remove empty properties and resources
+ if ($count) {
+ if (count($this->index[$resource][$property]) == 0) {
+ unset($this->index[$resource][$property]);
+ }
+ if (count($this->index[$resource]) == 0) {
+ unset($this->index[$resource]);
+ }
+ }
+ }
+
+ return $count;
+ }
+
+ /** Delete a resource from a property of another resource
+ *
+ * The resource can either be a resource or the URI of a resource.
+ *
+ * Example:
+ * $graph->delete("http://example.com/bob", 'foaf:knows', 'http://example.com/alice');
+ *
+ * @param mixed $resource The resource to delete data from
+ * @param mixed $property The property name
+ * @param mixed $resource2 The resource value of the property to be deleted
+ */
+ public function deleteResource($resource, $property, $resource2)
+ {
+ $this->checkResourceParam($resource);
+ $this->checkSinglePropertyParam($property, $inverse);
+ $this->checkResourceParam($resource2);
+
+ return $this->delete(
+ $resource,
+ $property,
+ array(
+ 'type' => substr($resource2, 0, 2) == '_:' ? 'bnode' : 'uri',
+ 'value' => $resource2
+ )
+ );
+ }
+
+ /** Delete a literal value from a property of a resource
+ *
+ * Example:
+ * $graph->delete("http://www.example.com", 'dc:title', 'Title of Page');
+ *
+ * @param mixed $resource The resource to add data to
+ * @param mixed $property The property name
+ * @param mixed $value The value of the property
+ * @param string $lang The language of the literal
+ */
+ public function deleteLiteral($resource, $property, $value, $lang = null)
+ {
+ $this->checkResourceParam($resource);
+ $this->checkSinglePropertyParam($property, $inverse);
+ $this->checkValueParam($value);
+
+ if ($lang) {
+ $value['lang'] = $lang;
+ }
+
+ return $this->delete($resource, $property, $value);
+ }
+
+ /** This function is for internal use only.
+ *
+ * Deletes an inverse property from a resource.
+ *
+ * @ignore
+ */
+ protected function deleteInverse($resource, $property, $value)
+ {
+ if (isset($this->revIndex[$resource])) {
+ foreach ($this->revIndex[$resource][$property] as $k => $v) {
+ if ($v['value'] === $value) {
+ unset($this->revIndex[$resource][$property][$k]);
+ }
+ }
+ if (count($this->revIndex[$resource][$property]) == 0) {
+ unset($this->revIndex[$resource][$property]);
+ }
+ if (count($this->revIndex[$resource]) == 0) {
+ unset($this->revIndex[$resource]);
+ }
+ }
+ }
+
+ /** Check if the graph contains any statements
+ *
+ * @return boolean True if the graph contains no statements
+ */
+ public function isEmpty()
+ {
+ return count($this->index) == 0;
+ }
+
+ /** Get a list of all the shortened property names (qnames) for a resource.
+ *
+ * This method will return an empty array if the resource has no properties.
+ *
+ * @return array Array of shortened URIs
+ */
+ public function properties($resource)
+ {
+ $this->checkResourceParam($resource);
+
+ $properties = array();
+ if (isset($this->index[$resource])) {
+ foreach ($this->index[$resource] as $property => $value) {
+ $short = EasyRdf_Namespace::shorten($property);
+ if ($short) {
+ $properties[] = $short;
+ }
+ }
+ }
+ return $properties;
+ }
+
+ /** Get a list of the full URIs for the properties of a resource.
+ *
+ * This method will return an empty array if the resource has no properties.
+ *
+ * @return array Array of full URIs
+ */
+ public function propertyUris($resource)
+ {
+ $this->checkResourceParam($resource);
+
+ if (isset($this->index[$resource])) {
+ return array_keys($this->index[$resource]);
+ } else {
+ return array();
+ }
+ }
+
+ /** Get a list of the full URIs for the properties that point to a resource.
+ *
+ * @return array Array of full property URIs
+ */
+ public function reversePropertyUris($resource)
+ {
+ $this->checkResourceParam($resource);
+
+ if (isset($this->revIndex[$resource])) {
+ return array_keys($this->revIndex[$resource]);
+ } else {
+ return array();
+ }
+ }
+
+ /** Check to see if a property exists for a resource.
+ *
+ * This method will return true if the property exists.
+ * If the value parameter is given, then it will only return true
+ * if the value also exists for that property.
+ *
+ * By providing a value parameter you can use this function to check
+ * to see if a triple exists in the graph.
+ *
+ * @param mixed $resource The resource to check
+ * @param string $property The name of the property (e.g. foaf:name)
+ * @param mixed $value An optional value of the property
+ * @return boolean True if value the property exists.
+ */
+ public function hasProperty($resource, $property, $value = null)
+ {
+ $this->checkResourceParam($resource);
+ $this->checkSinglePropertyParam($property, $inverse);
+ $this->checkValueParam($value);
+
+ // Use the reverse index if it is an inverse property
+ if ($inverse) {
+ $index = &$this->revIndex;
+ } else {
+ $index = &$this->index;
+ }
+
+ if (isset($index[$resource][$property])) {
+ if (is_null($value)) {
+ return true;
+ } else {
+ foreach ($index[$resource][$property] as $v) {
+ if ($v == $value) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /** Serialise the graph into RDF
+ *
+ * The $format parameter can be an EasyRdf_Format object, a
+ * format name, a mime type or a file extension.
+ *
+ * Example:
+ * $turtle = $graph->serialise('turtle');
+ *
+ * @param mixed $format The format to serialise to
+ * @return mixed The serialised graph
+ */
+ public function serialise($format)
+ {
+ if (!$format instanceof EasyRdf_Format) {
+ $format = EasyRdf_Format::getFormat($format);
+ }
+ $serialiser = $format->newSerialiser();
+ return $serialiser->serialise($this, $format->getName());
+ }
+
+ /** Return a human readable view of all the resources in the graph
+ *
+ * This method is intended to be a debugging aid and will
+ * return a pretty-print view of all the resources and their
+ * properties.
+ *
+ * @param string $format Either 'html' or 'text'
+ * @return string
+ */
+ public function dump($format = 'html')
+ {
+ $result = '';
+ if ($format == 'html') {
+ $result .= "<div style='font-family:arial; font-weight: bold; padding:0.5em; ".
+ "color: black; background-color:lightgrey;border:dashed 1px grey;'>".
+ "Graph: ". $this->uri . "</div>\n";
+ } else {
+ $result .= "Graph: ". $this->uri . "\n";
+ }
+
+ foreach ($this->index as $resource => $properties) {
+ $result .= $this->dumpResource($resource, $format);
+ }
+ return $result;
+ }
+
+ /** Return a human readable view of a resource and its properties
+ *
+ * This method is intended to be a debugging aid and will
+ * print a resource and its properties.
+ *
+ * @param mixed $resource The resource to dump
+ * @param string $format Either 'html' or 'text'
+ * @return string
+ */
+ public function dumpResource($resource, $format = 'html')
+ {
+ $this->checkResourceParam($resource, true);
+
+ if (isset($this->index[$resource])) {
+ $properties = $this->index[$resource];
+ } else {
+ return '';
+ }
+
+ $plist = array();
+ foreach ($properties as $property => $values) {
+ $olist = array();
+ foreach ($values as $value) {
+ if ($value['type'] == 'literal') {
+ $olist []= EasyRdf_Utils::dumpLiteralValue($value, $format, 'black');
+ } else {
+ $olist []= EasyRdf_Utils::dumpResourceValue($value['value'], $format, 'blue');
+ }
+ }
+
+ $pstr = EasyRdf_Namespace::shorten($property);
+ if ($pstr == null) {
+ $pstr = $property;
+ }
+ if ($format == 'html') {
+ $plist []= "<span style='font-size:130%'>→</span> ".
+ "<span style='text-decoration:none;color:green'>".
+ htmlentities($pstr) . "</span> ".
+ "<span style='font-size:130%'>→</span> ".
+ join(", ", $olist);
+ } else {
+ $plist []= " -> $pstr -> " . join(", ", $olist);
+ }
+ }
+
+ if ($format == 'html') {
+ return "<div id='".htmlentities($resource, ENT_QUOTES)."' " .
+ "style='font-family:arial; padding:0.5em; ".
+ "background-color:lightgrey;border:dashed 1px grey;'>\n".
+ "<div>".EasyRdf_Utils::dumpResourceValue($resource, $format, 'blue')." ".
+ "<span style='font-size: 0.8em'>(".
+ $this->classForResource($resource).")</span></div>\n".
+ "<div style='padding-left: 3em'>\n".
+ "<div>".join("</div>\n<div>", $plist)."</div>".
+ "</div></div>\n";
+ } else {
+ return $resource." (".$this->classForResource($resource).")\n" .
+ join("\n", $plist) . "\n\n";
+ }
+ }
+
+ /** Get the resource type of the graph
+ *
+ * The type will be a shortened URI as a string.
+ * If the graph has multiple types then the type returned
+ * may be arbitrary.
+ * This method will return null if the resource has no type.
+ *
+ * @return string A type assocated with the resource (e.g. foaf:Document)
+ */
+ public function type($resource = null)
+ {
+ $this->checkResourceParam($resource, true);
+
+ if ($resource) {
+ $type = $this->get($resource, 'rdf:type', 'resource');
+ if ($type) {
+ return EasyRdf_Namespace::shorten($type);
+ }
+ }
+
+ return null;
+ }
+
+ /** Get the resource type of the graph as a EasyRdf_Resource
+ *
+ * If the graph has multiple types then the type returned
+ * may be arbitrary.
+ * This method will return null if the resource has no type.
+ *
+ * @return object EasyRdf_Resource A type assocated with the resource
+ */
+ public function typeAsResource($resource = null)
+ {
+ $this->checkResourceParam($resource, true);
+
+ if ($resource) {
+ return $this->get($resource, 'rdf:type', 'resource');
+ }
+
+ return null;
+ }
+
+ /** Get a list of types for a resource
+ *
+ * The types will each be a shortened URI as a string.
+ * This method will return an empty array if the resource has no types.
+ *
+ * If $resource is null, then it will get the types for the URI of the graph.
+ *
+ * @return array All types assocated with the resource (e.g. foaf:Person)
+ */
+ public function types($resource = null)
+ {
+ $this->checkResourceParam($resource, true);
+
+ $types = array();
+ if ($resource) {
+ foreach ($this->all($resource, 'rdf:type', 'resource') as $type) {
+ $types[] = EasyRdf_Namespace::shorten($type);
+ }
+ }
+
+ return $types;
+ }
+
+ /** Check if a resource is of the specified type
+ *
+ * @param string $resource The resource to check the type of
+ * @param string $type The type to check (e.g. foaf:Person)
+ * @return boolean True if resource is of specified type
+ */
+ public function isA($resource, $type)
+ {
+ $this->checkResourceParam($resource, true);
+
+ $type = EasyRdf_Namespace::expand($type);
+ foreach ($this->all($resource, 'rdf:type', 'resource') as $t) {
+ if ($t->getUri() == $type) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** Add one or more rdf:type properties to a resource
+ *
+ * @param string $resource The resource to add the type to
+ * @param string $types One or more types to add (e.g. foaf:Person)
+ * @return integer The number of types added
+ */
+ public function addType($resource, $types)
+ {
+ $this->checkResourceParam($resource, true);
+
+ if (!is_array($types)) {
+ $types = array($types);
+ }
+
+ $count = 0;
+ foreach ($types as $type) {
+ $type = EasyRdf_Namespace::expand($type);
+ $count += $this->add($resource, 'rdf:type', array('type' => 'uri', 'value' => $type));
+ }
+
+ return $count;
+ }
+
+ /** Change the rdf:type property for a resource
+ *
+ * Note that if the resource object has already previously
+ * been created, then the PHP class of the resource will not change.
+ *
+ * @param string $resource The resource to change the type of
+ * @param string $type The new type (e.g. foaf:Person)
+ * @return integer The number of types added
+ */
+ public function setType($resource, $type)
+ {
+ $this->checkResourceParam($resource, true);
+
+ $this->delete($resource, 'rdf:type');
+ return $this->addType($resource, $type);
+ }
+
+ /** Get a human readable label for a resource
+ *
+ * This method will check a number of properties for a resource
+ * (in the order: skos:prefLabel, rdfs:label, foaf:name, dc:title)
+ * and return an approriate first that is available. If no label
+ * is available then it will return null.
+ *
+ * @return string A label for the resource.
+ */
+ public function label($resource = null, $lang = null)
+ {
+ $this->checkResourceParam($resource, true);
+
+ if ($resource) {
+ return $this->get(
+ $resource,
+ 'skos:prefLabel|rdfs:label|foaf:name|rss:title|dc:title|dc11:title',
+ 'literal',
+ $lang
+ );
+ } else {
+ return null;
+ }
+ }
+
+ /** Get the primary topic of the graph
+ *
+ * @return EasyRdf_Resource The primary topic of the document.
+ */
+ public function primaryTopic($resource = null)
+ {
+ $this->checkResourceParam($resource, true);
+
+ if ($resource) {
+ return $this->get(
+ $resource,
+ 'foaf:primaryTopic|^foaf:isPrimaryTopicOf',
+ 'resource'
+ );
+ } else {
+ return null;
+ }
+ }
+
+ /** Returns the graph as a RDF/PHP associative array
+ *
+ * @return array The contents of the graph as an array.
+ */
+ public function toRdfPhp()
+ {
+ return $this->index;
+ }
+
+ /** Calculates the number of triples in the graph
+ *
+ * @return integer The number of triples in the graph.
+ */
+ public function countTriples()
+ {
+ $count = 0;
+ foreach ($this->index as $resource) {
+ foreach ($resource as $property => $values) {
+ $count += count($values);
+ }
+ }
+ return $count;
+ }
+
+ /** Magic method to return URI of resource when casted to string
+ *
+ * @return string The URI of the resource
+ */
+ public function __toString()
+ {
+ return $this->uri == null ? '' : $this->uri;
+ }
+
+ /** Magic method to get a property of the graph
+ *
+ * Note that only properties in the default namespace can be accessed in this way.
+ *
+ * Example:
+ * $value = $graph->title;
+ *
+ * @see EasyRdf_Namespace::setDefault()
+ * @param string $name The name of the property
+ * @return string A single value for the named property
+ */
+ public function __get($name)
+ {
+ return $this->get($this->uri, $name);
+ }
+
+ /** Magic method to set the value for a property of the graph
+ *
+ * Note that only properties in the default namespace can be accessed in this way.
+ *
+ * Example:
+ * $graph->title = 'Title';
+ *
+ * @see EasyRdf_Namespace::setDefault()
+ * @param string $name The name of the property
+ * @param string $value The value for the property
+ */
+ public function __set($name, $value)
+ {
+ return $this->set($this->uri, $name, $value);
+ }
+
+ /** Magic method to check if a property exists
+ *
+ * Note that only properties in the default namespace can be accessed in this way.
+ *
+ * Example:
+ * if (isset($graph->title)) { blah(); }
+ *
+ * @see EasyRdf_Namespace::setDefault()
+ * @param string $name The name of the property
+ */
+ public function __isset($name)
+ {
+ return $this->hasProperty($this->uri, $name);
+ }
+
+ /** Magic method to delete a property of the graph
+ *
+ * Note that only properties in the default namespace can be accessed in this way.
+ *
+ * Example:
+ * unset($graph->title);
+ *
+ * @see EasyRdf_Namespace::setDefault()
+ * @param string $name The name of the property
+ */
+ public function __unset($name)
+ {
+ return $this->delete($this->uri, $name);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/GraphStore.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,215 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * A class for fetching, saving and deleting graphs to a Graph Store.
+ * Implementation of the SPARQL 1.1 Graph Store HTTP Protocol.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_GraphStore
+{
+ /** The address of the GraphStore endpoint */
+ private $uri = null;
+ private $parsedUri = null;
+
+
+ /** Create a new SPARQL Graph Store client
+ *
+ * @param string $uri The address of the graph store endpoint
+ */
+ public function __construct($uri)
+ {
+ $this->uri = $uri;
+ $this->parsedUri = new EasyRdf_ParsedUri($uri);
+ }
+
+ /** Get the URI of the graph store
+ *
+ * @return string The URI of the graph store
+ */
+ public function getUri()
+ {
+ return $this->uri;
+ }
+
+ /** Fetch a named graph from the graph store
+ *
+ * The URI can either be a full absolute URI or
+ * a URI relative to the URI of the graph store.
+ *
+ * @param string $uriRef The URI of graph desired
+ * @return object EasyRdf_Graph The graph requested
+ */
+ public function get($uriRef)
+ {
+ $graphUri = $this->parsedUri->resolve($uriRef)->toString();
+ $dataUrl = $this->urlForGraph($graphUri);
+ $graph = new EasyRdf_Graph($graphUri);
+ $graph->load($dataUrl);
+ return $graph;
+ }
+
+ /** Send some graph data to the graph store
+ *
+ * This method is used by insert() and replace()
+ *
+ * @ignore
+ */
+ protected function sendGraph($method, $graph, $uriRef, $format)
+ {
+ if (is_object($graph) and $graph instanceof EasyRdf_Graph) {
+ if ($uriRef == null) {
+ $uriRef = $graph->getUri();
+ }
+ $data = $graph->serialise($format);
+ } else {
+ $data = $graph;
+ }
+
+ $formatObj = EasyRdf_Format::getFormat($format);
+ $mimeType = $formatObj->getDefaultMimeType();
+
+ $graphUri = $this->parsedUri->resolve($uriRef)->toString();
+ $dataUrl = $this->urlForGraph($graphUri);
+
+ $client = EasyRdf_Http::getDefaultHttpClient();
+ $client->resetParameters(true);
+ $client->setUri($dataUrl);
+ $client->setMethod($method);
+ $client->setRawData($data);
+ $client->setHeaders('Content-Type', $mimeType);
+ $response = $client->request();
+ if (!$response->isSuccessful()) {
+ throw new EasyRdf_Exception(
+ "HTTP request for $dataUrl failed: ".$response->getMessage()
+ );
+ }
+ return $response;
+ }
+
+ /** Replace the contents of a graph in the graph store with new data
+ *
+ * The $graph parameter is the EasyRdf_Graph object to be sent to the
+ * graph store. Alternatively it can be a string, already serialised.
+ *
+ * The URI can either be a full absolute URI or
+ * a URI relative to the URI of the graph store.
+ *
+ * The $format parameter can be given to specify the serialisation
+ * used to send the graph data to the graph store.
+ *
+ * @param object EasyRdfGraph $graph The URI of graph desired
+ * @param string $uriRef The URI of graph to be replaced
+ * @param string $format The format of the data to send to the graph store
+ * @return object EasyRdf_Http_Response The response from the graph store
+ */
+ public function replace($graph, $uriRef = null, $format = 'ntriples')
+ {
+ return $this->sendGraph('PUT', $graph, $uriRef, $format);
+ }
+
+ /** Add data to a graph in the graph store
+ *
+ * The $graph parameter is the EasyRdf_Graph object to be sent to the
+ * graph store. Alternatively it can be a string, already serialised.
+ *
+ * The URI can either be a full absolute URI or
+ * a URI relative to the URI of the graph store.
+ *
+ * The $format parameter can be given to specify the serialisation
+ * used to send the graph data to the graph store.
+ *
+ * @param object EasyRdfGraph $graph The URI of graph desired
+ * @param string $uriRef The URI of graph to be added to
+ * @param string $format The format of the data to send to the graph store
+ * @return object EasyRdf_Http_Response The response from the graph store
+ */
+ public function insert($graph, $uriRef = null, $format = 'ntriples')
+ {
+ return $this->sendGraph('POST', $graph, $uriRef, $format);
+ }
+
+ /** Delete a graph from the graph store
+ *
+ * The URI can either be a full absolute URI or
+ * a URI relative to the URI of the graph store.
+ *
+ * @param string $uriRef The URI of graph to be added to
+ * @return object EasyRdf_Http_Response The response from the graph store
+ */
+ public function delete($uriRef)
+ {
+ $graphUri = $this->parsedUri->resolve($uriRef)->toString();
+ $dataUrl = $this->urlForGraph($graphUri);
+
+ $client = EasyRdf_Http::getDefaultHttpClient();
+ $client->resetParameters(true);
+ $client->setUri($dataUrl);
+ $client->setMethod('DELETE');
+ $response = $client->request();
+ if (!$response->isSuccessful()) {
+ throw new EasyRdf_Exception(
+ "HTTP request to delete $dataUrl failed: ".$response->getMessage()
+ );
+ }
+ return $response;
+ }
+
+ /** Work out the full URL for a graph store request.
+ * by checking if if it is a direct or indirect request.
+ * @ignore
+ */
+ protected function urlForGraph($url)
+ {
+ if (strpos($url, $this->uri) === false) {
+ $url = $this->uri."?graph=".urlencode($url);
+ }
+ return $url;
+ }
+
+ /** Magic method to return URI of the graph store when casted to string
+ *
+ * @return string The URI of the graph store
+ */
+ public function __toString()
+ {
+ return empty($this->uri) ? '' : $this->uri;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Http.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+
+/**
+ * Static class to set the HTTP client used by EasyRdf
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Http
+{
+ /** The default HTTP Client object */
+ private static $defaultHttpClient = null;
+
+ /** Set the HTTP Client object used to fetch RDF data
+ *
+ * @param object mixed $httpClient The new HTTP client object
+ * @return object mixed The new HTTP client object
+ */
+ public static function setDefaultHttpClient($httpClient)
+ {
+ if (!is_object($httpClient) or
+ !($httpClient instanceof Zend_Http_Client or
+ $httpClient instanceof EasyRdf_Http_Client)) {
+ throw new InvalidArgumentException(
+ "\$httpClient should be an object of class Zend_Http_Client or EasyRdf_Http_Client"
+ );
+ }
+ return self::$defaultHttpClient = $httpClient;
+ }
+
+ /** Get the HTTP Client object used to fetch RDF data
+ *
+ * If no HTTP Client has previously been set, then a new
+ * default (EasyRdf_Http_Client) client will be created.
+ *
+ * @return object mixed The HTTP client object
+ */
+ public static function getDefaultHttpClient()
+ {
+ if (!isset(self::$defaultHttpClient)) {
+ self::$defaultHttpClient = new EasyRdf_Http_Client();
+ }
+ return self::$defaultHttpClient;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Http/Client.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,548 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ * Copyright (c) 2005-2009 Zend Technologies USA Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * Copyright (c) 2005-2009 Zend Technologies USA Inc.
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * This class is an implemetation of an HTTP client in PHP.
+ * It supports basic HTTP 1.0 and 1.1 requests. For a more complete
+ * implementation try Zend_Http_Client.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Http_Client
+{
+ /**
+ * Configuration array, set using the constructor or using ::setConfig()
+ *
+ * @var array
+ */
+ private $config = array(
+ 'maxredirects' => 5,
+ 'useragent' => 'EasyRdf_Http_Client',
+ 'timeout' => 10
+ );
+
+ /**
+ * Request URI
+ *
+ * @var string
+ */
+ private $uri = null;
+
+ /**
+ * Associative array of request headers
+ *
+ * @var array
+ */
+ private $headers = array();
+
+ /**
+ * HTTP request method
+ *
+ * @var string
+ */
+ private $method = 'GET';
+
+ /**
+ * Associative array of GET parameters
+ *
+ * @var array
+ */
+ private $paramsGet = array();
+
+ /**
+ * The raw post data to send. Could be set by setRawData($data).
+ *
+ * @var string
+ */
+ private $rawPostData = null;
+
+ /**
+ * Redirection counter
+ *
+ * @var int
+ */
+ private $redirectCounter = 0;
+
+ /**
+ * Constructor method. Will create a new HTTP client. Accepts the target
+ * URL and optionally configuration array.
+ *
+ * @param string $uri
+ * @param array $config Configuration key-value pairs.
+ */
+ public function __construct($uri = null, $config = null)
+ {
+ if ($uri !== null) {
+ $this->setUri($uri);
+ }
+ if ($config !== null) {
+ $this->setConfig($config);
+ }
+ }
+
+ /**
+ * Set the URI for the next request
+ *
+ * @param string $uri
+ * @return EasyRdf_Http_Client
+ */
+ public function setUri($uri)
+ {
+ if (!is_string($uri)) {
+ $uri = strval($uri);
+ }
+
+ if (!preg_match('/^http(s?):/', $uri)) {
+ throw new InvalidArgumentException(
+ "EasyRdf_Http_Client only supports the 'http' and 'https' schemes."
+ );
+ }
+
+ $this->uri = $uri;
+
+ return $this;
+ }
+
+ /**
+ * Get the URI for the next request
+ *
+ * @return string
+ */
+ public function getUri($asString = true)
+ {
+ return $this->uri;
+ }
+
+ /**
+ * Set configuration parameters for this HTTP client
+ *
+ * @param array $config
+ * @return EasyRdf_Http_Client
+ * @throws InvalidArgumentException
+ */
+ public function setConfig($config = array())
+ {
+ if ($config == null or !is_array($config)) {
+ throw new InvalidArgumentException(
+ "\$config should be an array and cannot be null"
+ );
+ }
+
+ foreach ($config as $k => $v) {
+ $this->config[strtolower($k)] = $v;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set a request header
+ *
+ * @param string $name Header name (e.g. 'Accept')
+ * @param string $value Header value or null
+ * @return EasyRdf_Http_Client
+ */
+ public function setHeaders($name, $value = null)
+ {
+ $normalizedName = strtolower($name);
+
+ // If $value is null or false, unset the header
+ if ($value === null || $value === false) {
+ unset($this->headers[$normalizedName]);
+ } else {
+ // Else, set the header
+ $this->headers[$normalizedName] = array($name, $value);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set the next request's method
+ *
+ * Validated the passed method and sets it.
+ *
+ * @param string $method
+ * @return EasyRdf_Http_Client
+ * @throws InvalidArgumentException
+ */
+ public function setMethod($method)
+ {
+ if (!is_string($method) or !preg_match('/^[A-Z]+$/', $method)) {
+ throw new InvalidArgumentException("Invalid HTTP request method.");
+ }
+
+ $this->method = $method;
+
+ return $this;
+ }
+
+ /**
+ * Get the method for the next request
+ *
+ * @return string
+ */
+ public function getMethod()
+ {
+ return $this->method;
+ }
+
+ /**
+ * Get the value of a specific header
+ *
+ * Note that if the header has more than one value, an array
+ * will be returned.
+ *
+ * @param string $key
+ * @return string|array|null The header value or null if it is not set
+ */
+ public function getHeader($key)
+ {
+ $key = strtolower($key);
+ if (isset($this->headers[$key])) {
+ return $this->headers[$key][1];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Set a GET parameter for the request.
+ *
+ * @param string $name
+ * @param string $value
+ * @return EasyRdf_Http_Client
+ */
+ public function setParameterGet($name, $value = null)
+ {
+ if ($value === null) {
+ if (isset($this->paramsGet[$name])) {
+ unset($this->paramsGet[$name]);
+ }
+ } else {
+ $this->paramsGet[$name] = $value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get a GET parameter for the request.
+ *
+ * @param string $name
+ * @return string value
+ */
+ public function getParameterGet($name)
+ {
+ if (isset($this->paramsGet[$name])) {
+ return $this->paramsGet[$name];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get all the GET parameters
+ *
+ * @return array
+ */
+ public function getParametersGet()
+ {
+ return $this->paramsGet;
+ }
+
+ /**
+ * Get the number of redirections done on the last request
+ *
+ * @return int
+ */
+ public function getRedirectionsCount()
+ {
+ return $this->redirectCounter;
+ }
+
+ /**
+ * Set the raw (already encoded) POST data.
+ *
+ * This function is here for two reasons:
+ * 1. For advanced user who would like to set their own data, already encoded
+ * 2. For backwards compatibilty: If someone uses the old post($data) method.
+ * this method will be used to set the encoded data.
+ *
+ * $data can also be stream (such as file) from which the data will be read.
+ *
+ * @param string|resource $data
+ * @return Zend_Http_Client
+ */
+ public function setRawData($data)
+ {
+ $this->rawPostData = $data;
+ return $this;
+ }
+
+ /**
+ * Get the raw (already encoded) POST data.
+ *
+ * @return string
+ */
+ public function getRawData()
+ {
+ return $this->rawPostData;
+ }
+
+ /**
+ * Clear all GET and POST parameters
+ *
+ * Should be used to reset the request parameters if the client is
+ * used for several concurrent requests.
+ *
+ * clearAll parameter controls if we clean just parameters or also
+ * headers
+ *
+ * @param bool $clearAll Should all data be cleared?
+ * @return EasyRdf_Http_Client
+ */
+ public function resetParameters($clearAll = false)
+ {
+ // Reset parameter data
+ $this->paramsGet = array();
+ $this->rawPostData = null;
+ $this->method = 'GET';
+
+ if ($clearAll) {
+ $this->headers = array();
+ } else {
+ // Clear outdated headers
+ if (isset($this->headers['content-type'])) {
+ unset($this->headers['content-type']);
+ }
+ if (isset($this->headers['content-length'])) {
+ unset($this->headers['content-length']);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Send the HTTP request and return an HTTP response object
+ *
+ * @return EasyRdf_Http_Response
+ * @throws EasyRdf_Exception
+ */
+ public function request($method = null)
+ {
+ if (!$this->uri) {
+ throw new EasyRdf_Exception(
+ "Set URI before calling EasyRdf_Http_Client->request()"
+ );
+ }
+
+ if ($method) {
+ $this->setMethod($method);
+ }
+ $this->redirectCounter = 0;
+ $response = null;
+
+ // Send the first request. If redirected, continue.
+ do {
+ // Clone the URI and add the additional GET parameters to it
+ $uri = parse_url($this->uri);
+ if ($uri['scheme'] === 'http') {
+ $host = $uri['host'];
+ } elseif ($uri['scheme'] === 'https') {
+ $host = 'ssl://'.$uri['host'];
+ } else {
+ throw new EasyRdf_Exception(
+ "Unsupported URI scheme: ".$uri['scheme']
+ );
+ }
+
+ if (isset($uri['port'])) {
+ $port = $uri['port'];
+ } else {
+ if ($uri['scheme'] === 'https') {
+ $port = 443;
+ } else {
+ $port = 80;
+ }
+ }
+
+ if (!empty($this->paramsGet)) {
+ if (!empty($uri['query'])) {
+ $uri['query'] .= '&';
+ } else {
+ $uri['query'] = '';
+ }
+ $uri['query'] .= http_build_query($this->paramsGet, null, '&');
+ }
+
+ $headers = $this->prepareHeaders($uri['host'], $port);
+
+ // Open socket to remote server
+ $socket = @fsockopen($host, $port, $errno, $errstr, $this->config['timeout']);
+ if (!$socket) {
+ throw new EasyRdf_Exception("Unable to connect to $host:$port ($errstr)");
+ }
+
+ // Write the request
+ $path = $uri['path'];
+ if (isset($uri['query'])) {
+ $path .= '?' . $uri['query'];
+ }
+ fwrite($socket, "{$this->method} {$path} HTTP/1.1\r\n");
+ foreach ($headers as $k => $v) {
+ if (is_string($k)) {
+ $v = ucfirst($k) . ": $v";
+ }
+ fwrite($socket, "$v\r\n");
+ }
+ fwrite($socket, "\r\n");
+
+ // Send the request body, if there is one set
+ if (isset($this->rawPostData)) {
+ fwrite($socket, $this->rawPostData);
+ }
+
+ // Read in the response
+ $content = '';
+ while (!feof($socket)) {
+ $content .= fgets($socket);
+ }
+
+ // FIXME: support HTTP/1.1 100 Continue
+
+ // Close the socket
+ @fclose($socket);
+
+ // Parse the response string
+ $response = EasyRdf_Http_Response::fromString($content);
+
+ // If we got redirected, look for the Location header
+ if ($response->isRedirect() &&
+ ($location = $response->getHeader('location'))
+ ) {
+
+ // Avoid problems with buggy servers that add whitespace at the
+ // end of some headers (See ZF-11283)
+ $location = trim($location);
+
+ // Some servers return relative URLs in the location header
+ // resolve it in relation to previous request
+ $baseUri = new EasyRdf_ParsedUri($this->uri);
+ $location = $baseUri->resolve($location)->toString();
+
+ // If it is a 303 then drop the parameters and send a GET request
+ if ($response->getStatus() == 303) {
+ $this->resetParameters();
+ $this->setMethod('GET');
+ }
+
+ // If we got a well formed absolute URI
+ if (parse_url($location)) {
+ $this->setHeaders('host', null);
+ $this->setUri($location);
+ } else {
+ throw new EasyRdf_Exception(
+ "Failed to parse Location header returned by ".
+ $this->uri
+ );
+ }
+ ++$this->redirectCounter;
+
+ } else {
+ // If we didn't get any location, stop redirecting
+ break;
+ }
+
+
+ } while ($this->redirectCounter < $this->config['maxredirects']);
+
+ return $response;
+ }
+
+ /**
+ * Prepare the request headers
+ *
+ * @ignore
+ * @return array
+ */
+ protected function prepareHeaders($host, $port)
+ {
+ $headers = array();
+
+ // Set the host header
+ if (! isset($this->headers['host'])) {
+ // If the port is not default, add it
+ if ($port !== 80 and $port !== 443) {
+ $host .= ':' . $port;
+ }
+ $headers[] = "Host: {$host}";
+ }
+
+ // Set the connection header
+ if (! isset($this->headers['connection'])) {
+ $headers[] = "Connection: close";
+ }
+
+ // Set the user agent header
+ if (! isset($this->headers['user-agent'])) {
+ $headers[] = "User-Agent: {$this->config['useragent']}";
+ }
+
+ // If we have rawPostData set, set the content-length header
+ if (isset($this->rawPostData)) {
+ $headers[] = "Content-Length: ".strlen($this->rawPostData);
+ }
+
+ // Add all other user defined headers
+ foreach ($this->headers as $header) {
+ list($name, $value) = $header;
+ if (is_array($value)) {
+ $value = implode(', ', $value);
+ }
+
+ $headers[] = "$name: $value";
+ }
+
+ return $headers;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Http/Response.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,360 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey.
+ * Copyright (c) 2005-2009 Zend Technologies USA Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc.
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class that represents an HTTP 1.0 / 1.1 response message.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * Copyright (c) 2005-2009 Zend Technologies USA Inc.
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Http_Response
+{
+
+ /**
+ * The HTTP response status code
+ *
+ * @var int
+ */
+ private $status;
+
+ /**
+ * The HTTP response code as string
+ * (e.g. 'Not Found' for 404 or 'Internal Server Error' for 500)
+ *
+ * @var string
+ */
+ private $message;
+
+ /**
+ * The HTTP response headers array
+ *
+ * @var array
+ */
+ private $headers = array();
+
+ /**
+ * The HTTP response body
+ *
+ * @var string
+ */
+ private $body;
+
+ /**
+ * Constructor.
+ *
+ * @param int $status HTTP Status code
+ * @param array $headers The HTTP response headers
+ * @param string $body The content of the response
+ * @param string $version The HTTP Version (1.0 or 1.1)
+ * @param string $message The HTTP response Message
+ * @return object EasyRdf_Http_Response
+ */
+ public function __construct(
+ $status,
+ $headers,
+ $body = null,
+ $version = '1.1',
+ $message = null
+ ) {
+ $this->status = intval($status);
+ $this->body = $body;
+ $this->version = $version;
+ $this->message = $message;
+
+ foreach ($headers as $k => $v) {
+ $k = ucwords(strtolower($k));
+ $this->headers[$k] = $v;
+ }
+ }
+
+ /**
+ * Check whether the response in successful
+ *
+ * @return boolean
+ */
+ public function isSuccessful()
+ {
+ return ($this->status >= 200 && $this->status < 300);
+ }
+
+ /**
+ * Check whether the response is an error
+ *
+ * @return boolean
+ */
+ public function isError()
+ {
+ return ($this->status >= 400 && $this->status < 600);
+ }
+
+ /**
+ * Check whether the response is a redirection
+ *
+ * @return boolean
+ */
+ public function isRedirect()
+ {
+ return ($this->status >= 300 && $this->status < 400);
+ }
+
+ /**
+ * Get the HTTP response status code
+ *
+ * @return int
+ */
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ /**
+ * Return a message describing the HTTP response code
+ * (Eg. "OK", "Not Found", "Moved Permanently")
+ *
+ * @return string
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * Get the response body as string
+ *
+ * @return string
+ */
+ public function getBody()
+ {
+ // Decode the body if it was transfer-encoded
+ switch (strtolower($this->getHeader('transfer-encoding'))) {
+ // Handle chunked body
+ case 'chunked':
+ return self::decodeChunkedBody($this->body);
+ break;
+
+ // No transfer encoding, or unknown encoding extension:
+ // return body as is
+ default:
+ return $this->body;
+ break;
+ }
+ }
+
+ /**
+ * Get the raw response body (as transfered "on wire") as string
+ *
+ * If the body is encoded (with Transfer-Encoding, not content-encoding -
+ * IE "chunked" body), gzip compressed, etc. it will not be decoded.
+ *
+ * @return string
+ */
+ public function getRawBody()
+ {
+ return $this->body;
+ }
+
+ /**
+ * Get the HTTP version of the response
+ *
+ * @return string
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Get the response headers
+ *
+ * @return array
+ */
+ public function getHeaders()
+ {
+ return $this->headers;
+ }
+
+ /**
+ * Get a specific header as string, or null if it is not set
+ *
+ * @param string$header
+ * @return string|array|null
+ */
+ public function getHeader($header)
+ {
+ $header = ucwords(strtolower($header));
+ if (array_key_exists($header, $this->headers)) {
+ return $this->headers[$header];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get all headers as string
+ *
+ * @param boolean $statusLine Whether to return the first status line (ie "HTTP 200 OK")
+ * @param string $br Line breaks (eg. "\n", "\r\n", "<br />")
+ * @return string
+ */
+ public function getHeadersAsString($statusLine = true, $br = "\n")
+ {
+ $str = '';
+
+ if ($statusLine) {
+ $str = "HTTP/{$this->version} {$this->status} {$this->message}{$br}";
+ }
+
+ // Iterate over the headers and stringify them
+ foreach ($this->headers as $name => $value) {
+ if (is_string($value)) {
+ $str .= "{$name}: {$value}{$br}";
+ } elseif (is_array($value)) {
+ foreach ($value as $subval) {
+ $str .= "{$name}: {$subval}{$br}";
+ }
+ }
+ }
+
+ return $str;
+ }
+
+ /**
+ * Create an EasyRdf_Http_Response object from a HTTP response string
+ *
+ * @param string $responseStr
+ * @return EasyRdf_Http_Response
+ */
+ public static function fromString($responseStr)
+ {
+ // First, split body and headers
+ $matches = preg_split('|(?:\r?\n){2}|m', $responseStr, 2);
+ if ($matches and sizeof($matches) == 2) {
+ list ($headerLines, $body) = $matches;
+ } else {
+ throw new EasyRdf_Exception(
+ "Failed to parse HTTP response."
+ );
+ }
+
+ // Split headers part to lines
+ $headerLines = preg_split('|[\r\n]+|m', $headerLines);
+ $status = array_shift($headerLines);
+ if (preg_match("|^HTTP/([\d\.x]+) (\d+) ([^\r\n]+)|", $status, $m)) {
+ $version = $m[1];
+ $status = $m[2];
+ $message = $m[3];
+ } else {
+ throw new EasyRdf_Exception(
+ "Failed to parse HTTP response status line."
+ );
+ }
+
+ // Process the rest of the header lines
+ $headers = array();
+ foreach ($headerLines as $line) {
+ if (preg_match("|^([\w-]+):\s+(.+)$|", $line, $m)) {
+ $hName = ucwords(strtolower($m[1]));
+ $hValue = $m[2];
+
+ if (isset($headers[$hName])) {
+ if (! is_array($headers[$hName])) {
+ $headers[$hName] = array($headers[$hName]);
+ }
+ $headers[$hName][] = $hValue;
+ } else {
+ $headers[$hName] = $hValue;
+ }
+ }
+ }
+
+ return new EasyRdf_Http_Response($status, $headers, $body, $version, $message);
+ }
+
+
+ /**
+ * Decode a "chunked" transfer-encoded body and return the decoded text
+ *
+ * @param string $body
+ * @return string
+ */
+ public static function decodeChunkedBody($body)
+ {
+ $decBody = '';
+
+ while (trim($body)) {
+ if (preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $body, $m)) {
+ $length = hexdec(trim($m[1]));
+ $cut = strlen($m[0]);
+ $decBody .= substr($body, $cut, $length);
+ $body = substr($body, $cut + $length + 2);
+ } else {
+ throw new EasyRdf_Exception(
+ "Failed to decode chunked body in HTTP response."
+ );
+ }
+ }
+
+ return $decBody;
+ }
+
+
+ /**
+ * Get the entire response as string
+ *
+ * @param string $br Line breaks (eg. "\n", "\r\n", "<br />")
+ * @return string
+ */
+ public function asString($br = "\n")
+ {
+ return $this->getHeadersAsString(true, $br) . $br . $this->getRawBody();
+ }
+
+ /**
+ * Implements magic __toString()
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->asString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Literal.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,327 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class that represents an RDF Literal
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Literal
+{
+ /** @ignore a mapping from datatype uri to class name */
+ private static $datatypeMap = array();
+
+ /** @ignore A mapping from class name to datatype URI */
+ private static $classMap = array();
+
+ /** @ignore The string value for this literal */
+ protected $value = null;
+
+ /** @ignore The language of the literal (e.g. 'en') */
+ protected $lang = null;
+
+ /** @ignore The datatype URI of the literal */
+ protected $datatype = null;
+
+
+ /** Create a new literal object
+ *
+ * PHP values of type bool, int or float, will automatically be converted
+ * to the corresponding datatype and PHP sub-class.
+ *
+ * If a registered datatype is given, then the registered subclass of EasyRdf_Literal
+ * will instantiated.
+ *
+ * Note that literals are not required to have a language or datatype.
+ * Literals cannot have both a language and a datatype.
+ *
+ * @param mixed $value The value of the literal or an associative array
+ * @param string $lang The natural language of the literal or null (e.g. 'en')
+ * @param string $datatype The datatype of the literal or null (e.g. 'xsd:integer')
+ * @return object EasyRdf_Literal (or subclass of EasyRdf_Literal)
+ */
+ public static function create($value, $lang = null, $datatype = null)
+ {
+ if (EasyRdf_Utils::isAssociativeArray($value)) {
+ if (isset($value['xml:lang'])) {
+ $lang = $value['xml:lang'];
+ } elseif (isset($value['lang'])) {
+ $lang = $value['lang'];
+ }
+ if (isset($value['datatype'])) {
+ $datatype = $value['datatype'];
+ }
+ $value = isset($value['value']) ? $value['value'] : null;
+ }
+
+ if (is_null($datatype) or $datatype === '') {
+ if (is_null($lang) or $lang === '') {
+ // Automatic datatype selection
+ $datatype = self::getDatatypeForValue($value);
+ }
+ } elseif (is_object($datatype)) {
+ $datatype = strval($datatype);
+ } else {
+ // Expand shortened URIs (qnames)
+ $datatype = EasyRdf_Namespace::expand($datatype);
+ }
+
+ // Work out what class to use for this datatype
+ if (isset(self::$datatypeMap[$datatype])) {
+ $class = self::$datatypeMap[$datatype];
+ } else {
+ $class = 'EasyRdf_Literal';
+ }
+ return new $class($value, $lang, $datatype);
+ }
+
+ /** Register an RDF datatype with a PHP class name
+ *
+ * When parsing registered class will be used whenever the datatype
+ * is seen.
+ *
+ * When serialising a registered class, the mapping will be used to
+ * set the datatype in the RDF.
+ *
+ * Example:
+ * EasyRdf_Literal::registerDatatype('xsd:dateTime', 'My_DateTime_Class');
+ *
+ * @param string $datatype The RDF datatype (e.g. xsd:dateTime)
+ * @param string $class The PHP class name (e.g. My_DateTime_Class)
+ */
+ public static function setDatatypeMapping($datatype, $class)
+ {
+ if (!is_string($datatype) or $datatype == null or $datatype == '') {
+ throw new InvalidArgumentException(
+ "\$datatype should be a string and cannot be null or empty"
+ );
+ }
+
+ if (!is_string($class) or $class == null or $class == '') {
+ throw new InvalidArgumentException(
+ "\$class should be a string and cannot be null or empty"
+ );
+ }
+
+ $datatype = EasyRdf_Namespace::expand($datatype);
+ self::$datatypeMap[$datatype] = $class;
+ self::$classMap[$class] = $datatype;
+ }
+
+ /** Remove the mapping between an RDF datatype and a PHP class name
+ *
+ * @param string $datatype The RDF datatype (e.g. xsd:dateTime)
+ */
+ public static function deleteDatatypeMapping($datatype)
+ {
+ if (!is_string($datatype) or $datatype == null or $datatype == '') {
+ throw new InvalidArgumentException(
+ "\$datatype should be a string and cannot be null or empty"
+ );
+ }
+
+ $datatype = EasyRdf_Namespace::expand($datatype);
+ if (isset(self::$datatypeMap[$datatype])) {
+ $class = self::$datatypeMap[$datatype];
+ unset(self::$datatypeMap[$datatype]);
+ unset(self::$classMap[$class]);
+ }
+ }
+
+ /** Get datatype URI for a PHP value.
+ *
+ * This static function is intended for internal use.
+ * Given a PHP value, it will return an XSD datatype
+ * URI for that value, for example:
+ * http://www.w3.org/2001/XMLSchema#integer
+ *
+ * @return string A URI for the datatype of $value.
+ */
+ public static function getDatatypeForValue($value)
+ {
+ if (is_float($value)) {
+ return 'http://www.w3.org/2001/XMLSchema#decimal';
+ } elseif (is_int($value)) {
+ return 'http://www.w3.org/2001/XMLSchema#integer';
+ } elseif (is_bool($value)) {
+ return 'http://www.w3.org/2001/XMLSchema#boolean';
+ } elseif (is_object($value) and $value instanceof DateTime) {
+ return 'http://www.w3.org/2001/XMLSchema#dateTime';
+ } else {
+ return null;
+ }
+ }
+
+
+
+ /** Constructor for creating a new literal
+ *
+ * @param string $value The value of the literal
+ * @param string $lang The natural language of the literal or null (e.g. 'en')
+ * @param string $datatype The datatype of the literal or null (e.g. 'xsd:string')
+ * @return object EasyRdf_Literal
+ */
+ public function __construct($value, $lang = null, $datatype = null)
+ {
+ $this->value = $value;
+ $this->lang = $lang ? $lang : null;
+ $this->datatype = $datatype ? $datatype : null;
+
+ if ($this->datatype) {
+ if (is_object($this->datatype)) {
+ // Convert objects to strings
+ $this->datatype = strval($this->datatype);
+ } else {
+ // Expand shortened URIs (CURIEs)
+ $this->datatype = EasyRdf_Namespace::expand($this->datatype);
+ }
+
+ // Literals can not have both a language and a datatype
+ $this->lang = null;
+ } else {
+ // Set the datatype based on the subclass
+ $class = get_class($this);
+ if (isset(self::$classMap[$class])) {
+ $this->datatype = self::$classMap[$class];
+ $this->lang = null;
+ }
+ }
+
+ // Cast value to string
+ settype($this->value, 'string');
+ }
+
+ /** Returns the value of the literal.
+ *
+ * @return string Value of this literal.
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /** Returns the full datatype URI of the literal.
+ *
+ * @return string Datatype URI of this literal.
+ */
+ public function getDatatypeUri()
+ {
+ return $this->datatype;
+ }
+
+ /** Returns the shortened datatype URI of the literal.
+ *
+ * @return string Datatype of this literal (e.g. xsd:integer).
+ */
+ public function getDatatype()
+ {
+ if ($this->datatype) {
+ return EasyRdf_Namespace::shorten($this->datatype);
+ } else {
+ return null;
+ }
+ }
+
+ /** Returns the language of the literal.
+ *
+ * @return string Language of this literal.
+ */
+ public function getLang()
+ {
+ return $this->lang;
+ }
+
+ /** Returns the properties of the literal as an associative array
+ *
+ * For example:
+ * array('type' => 'literal', 'value' => 'string value')
+ *
+ * @return array The properties of the literal
+ */
+ public function toRdfPhp()
+ {
+ $array = array(
+ 'type' => 'literal',
+ 'value' => $this->value
+ );
+
+ if ($this->datatype) {
+ $array['datatype'] = $this->datatype;
+ }
+
+ if ($this->lang) {
+ $array['lang'] = $this->lang;
+ }
+
+ return $array;
+ }
+
+ /** Magic method to return the value of a literal as a string
+ *
+ * @return string The value of the literal
+ */
+ public function __toString()
+ {
+ return isset($this->value) ? $this->value : '';
+ }
+
+ /** Return pretty-print view of the literal
+ *
+ * @param string $format Either 'html' or 'text'
+ * @param string $color The colour of the text
+ * @return string
+ */
+ public function dumpValue($format = 'html', $color = 'black')
+ {
+ return EasyRdf_Utils::dumpLiteralValue($this, $format, $color);
+ }
+}
+
+/*
+ Register default set of datatype classes
+*/
+
+EasyRdf_Literal::setDatatypeMapping('xsd:boolean', 'EasyRdf_Literal_Boolean');
+EasyRdf_Literal::setDatatypeMapping('xsd:date', 'EasyRdf_Literal_Date');
+EasyRdf_Literal::setDatatypeMapping('xsd:dateTime', 'EasyRdf_Literal_DateTime');
+EasyRdf_Literal::setDatatypeMapping('xsd:decimal', 'EasyRdf_Literal_Decimal');
+EasyRdf_Literal::setDatatypeMapping('xsd:hexBinary', 'EasyRdf_Literal_HexBinary');
+EasyRdf_Literal::setDatatypeMapping('rdf:HTML', 'EasyRdf_Literal_HTML');
+EasyRdf_Literal::setDatatypeMapping('xsd:integer', 'EasyRdf_Literal_Integer');
+EasyRdf_Literal::setDatatypeMapping('rdf:XMLLiteral', 'EasyRdf_Literal_XML');
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Literal/Boolean.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class that represents an RDF Literal of datatype xsd:boolean
+ *
+ * @package EasyRdf
+ * @link http://www.w3.org/TR/xmlschema-2/#boolean
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Literal_Boolean extends EasyRdf_Literal
+{
+ /** Constructor for creating a new boolean literal
+ *
+ * If the value is not a string, then it will be converted to 'true' or 'false'.
+ *
+ * @param mixed $value The value of the literal
+ * @param string $lang Should be null (literals with a datatype can't have a language)
+ * @param string $datatype Optional datatype (default 'xsd:boolean')
+ * @return object EasyRdf_Literal_Boolean
+ */
+ public function __construct($value, $lang = null, $datatype = null)
+ {
+ if (!is_string($value)) {
+ $value = $value ? 'true' : 'false';
+ }
+ parent::__construct($value, null, $datatype);
+ }
+
+ /** Return the value of the literal cast to a PHP bool
+ *
+ * If the value is 'true' or '1' return true, otherwise returns false.
+ *
+ * @return bool
+ */
+ public function getValue()
+ {
+ return strtolower($this->value) === 'true' or $this->value === '1';
+ }
+
+ /** Return true if the value of the literal is 'true' or '1'
+ *
+ * @return bool
+ */
+ public function isTrue()
+ {
+ return strtolower($this->value) === 'true' or $this->value === '1';
+ }
+
+ /** Return true if the value of the literal is 'false' or '0'
+ *
+ * @return bool
+ */
+ public function isFalse()
+ {
+ return strtolower($this->value) === 'false' or $this->value === '0';
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Literal/Date.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,137 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class that represents an RDF Literal of datatype xsd:date
+ *
+ * @package EasyRdf
+ * @link http://www.w3.org/TR/xmlschema-2/#date
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Literal_Date extends EasyRdf_Literal
+{
+ /** Constructor for creating a new date literal
+ *
+ * If the value is a DateTime object, then it will be converted to the xsd:date format.
+ * If no value is given or is is null, then the current date is used.
+ *
+ * @see DateTime
+ *
+ * @param mixed $value The value of the literal
+ * @param string $lang Should be null (literals with a datatype can't have a language)
+ * @param string $datatype Optional datatype (default 'xsd:date')
+ * @return object EasyRdf_Literal_Date
+ */
+ public function __construct($value = null, $lang = null, $datatype = null)
+ {
+ // If $value is null, use today's date
+ if (is_null($value)) {
+ $value = new DateTime('today');
+ }
+
+ // Convert DateTime object into string
+ if ($value instanceof DateTime) {
+ $value = $value->format('Y-m-d');
+ }
+
+ parent::__construct($value, null, $datatype);
+ }
+
+ /** Parses a string using DateTime and creates a new literal
+ *
+ * Example:
+ * $date = EasyRdf_Literal_Date::parse('1 January 2011');
+ *
+ * @see DateTime
+ * @param string $value The date to parse
+ * @return object EasyRdf_Literal_Date
+ */
+ public static function parse($value)
+ {
+ $value = new DateTime($value);
+ return new EasyRdf_Literal_Date($value);
+ }
+
+ /** Returns the date as a PHP DateTime object
+ *
+ * @see DateTime::format
+ * @return string
+ */
+ public function getValue()
+ {
+ return new DateTime($this->value);
+ }
+
+ /** Returns date formatted according to given format
+ *
+ * @see DateTime::format
+ * @param string $format
+ * @return string
+ */
+ public function format($format)
+ {
+ return $this->getValue()->format($format);
+ }
+
+ /** A full integer representation of the year, 4 digits
+ *
+ * @return integer
+ */
+ public function year()
+ {
+ return (int)$this->format('Y');
+ }
+
+ /** Integer representation of the month
+ *
+ * @return integer
+ */
+ public function month()
+ {
+ return (int)$this->format('m');
+ }
+
+ /** Integer representation of the day of the month
+ *
+ * @return integer
+ */
+ public function day()
+ {
+ return (int)$this->format('d');
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Literal/DateTime.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,117 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class that represents an RDF Literal of datatype xsd:dateTime
+ *
+ * @package EasyRdf
+ * @link http://www.w3.org/TR/xmlschema-2/#date
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Literal_DateTime extends EasyRdf_Literal_Date
+{
+ /** Constructor for creating a new date and time literal
+ *
+ * If the value is a DateTime object, then it will be converted to the xsd:dateTime format.
+ * If no value is given or is is null, then the current time is used.
+ *
+ * @see DateTime
+ *
+ * @param mixed $value The value of the literal
+ * @param string $lang Should be null (literals with a datatype can't have a language)
+ * @param string $datatype Optional datatype (default 'xsd:dateTime')
+ * @return object EasyRdf_Literal_DateTime
+ */
+ public function __construct($value = null, $lang = null, $datatype = null)
+ {
+ // If $value is null, use 'now'
+ if (is_null($value)) {
+ $value = new DateTime('now');
+ }
+
+ // Convert DateTime objects into string
+ if ($value instanceof DateTime) {
+ $atom = $value->format(DateTime::ATOM);
+ $value = preg_replace('/[\+\-]00(\:?)00$/', 'Z', $atom);
+ }
+
+ EasyRdf_Literal::__construct($value, null, $datatype);
+ }
+
+ /** Parses a string using DateTime and creates a new literal
+ *
+ * Example:
+ * $dt = EasyRdf_Literal_DateTime::parse('Mon 18 Jul 2011 18:45:43 BST');
+ *
+ * @see DateTime
+ * @param string $value The date and time to parse
+ * @return object EasyRdf_Literal_DateTime
+ */
+ public static function parse($value)
+ {
+ $value = new DateTime($value);
+ return new EasyRdf_Literal_DateTime($value);
+ }
+
+ /** 24-hour format of the hour as an integer
+ *
+ * @return integer
+ */
+ public function hour()
+ {
+ return (int)$this->format('H');
+ }
+
+ /** The minutes pasts the hour as an integer
+ *
+ * @return integer
+ */
+ public function min()
+ {
+ return (int)$this->format('i');
+ }
+
+ /** The seconds pasts the minute as an integer
+ *
+ * @return integer
+ */
+ public function sec()
+ {
+ return (int)$this->format('s');
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Literal/Decimal.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class that represents an RDF Literal of datatype xsd:decimal
+ *
+ * @package EasyRdf
+ * @link http://www.w3.org/TR/xmlschema-2/#decimal
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Literal_Decimal extends EasyRdf_Literal
+{
+ /** Constructor for creating a new decimal literal
+ *
+ * @param mixed $value The value of the literal
+ * @param string $lang Should be null (literals with a datatype can't have a language)
+ * @param string $datatype Optional datatype (default 'xsd:decimal')
+ * @return object EasyRdf_Literal_Decimal
+ */
+ public function __construct($value, $lang = null, $datatype = null)
+ {
+ parent::__construct($value, null, $datatype);
+ }
+
+ /** Return the value of the literal cast to a PHP double
+ *
+ * @return double
+ */
+ public function getValue()
+ {
+ return (double)$this->value;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Literal/HTML.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class that represents an RDF Literal of datatype rdf:HTML
+ *
+ * @package EasyRdf
+ * @link http://www.w3.org/TR/rdf11-concepts/#section-html
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Literal_HTML extends EasyRdf_Literal
+{
+ /** Constructor for creating a new rdf:HTML literal
+ *
+ * @param mixed $value The HTML fragment
+ * @param string $lang Should be null (literals with a datatype can't have a language)
+ * @param string $datatype Optional datatype (default 'rdf:HTML')
+ * @return object EasyRdf_Literal_HTML
+ */
+ public function __construct($value, $lang = null, $datatype = null)
+ {
+ parent::__construct($value, null, $datatype);
+ }
+
+ /** Strip the HTML tags from the literal
+ *
+ * @link http://php.net/manual/en/function.strip-tags.php
+ * @param string $allowableTags Optional allowed tag, not be be removed
+ * @return string The literal as plain text
+ */
+ public function stripTags($allowableTags = null)
+ {
+ return strip_tags($this->value, $allowableTags);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Literal/HexBinary.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class that represents an RDF Literal of datatype xsd:hexBinary
+ *
+ * @package EasyRdf
+ * @link http://www.w3.org/TR/xmlschema-2/#hexBinary
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Literal_HexBinary extends EasyRdf_Literal
+{
+ /** Constructor for creating a new xsd:hexBinary literal
+ *
+ * @param mixed $value The value of the literal (already encoded as hexadecimal)
+ * @param string $lang Should be null (literals with a datatype can't have a language)
+ * @param string $datatype Optional datatype (default 'xsd:hexBinary')
+ * @return object EasyRdf_Literal_HexBinary
+ */
+ public function __construct($value, $lang = null, $datatype = null)
+ {
+ // Normalise the canonical representation, as specified here:
+ // http://www.w3.org/TR/xmlschema-2/#hexBinary-canonical-repr
+ $value = strtoupper($value);
+
+ // Validate the data
+ if (preg_match("/[^A-F0-9]/", $value)) {
+ throw new InvalidArgumentException(
+ "Literal of type xsd:hexBinary contains non-hexadecimal characters"
+ );
+ }
+
+ parent::__construct(strtoupper($value), null, 'xsd:hexBinary');
+ }
+
+ /** Constructor for creating a new literal object from a binary blob
+ *
+ * @param string $binary The binary data
+ * @return object EasyRdf_Literal_HexBinary
+ */
+ public static function fromBinary($binary)
+ {
+ return new self( bin2hex($binary) );
+ }
+
+ /** Decode the hexadecimal string into a binary blob
+ *
+ * @return string The binary blob
+ */
+ public function toBinary()
+ {
+ return pack("H*", $this->value);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Literal/Integer.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class that represents an RDF Literal of datatype xsd:integer
+ *
+ * @package EasyRdf
+ * @link http://www.w3.org/TR/xmlschema-2/#integer
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Literal_Integer extends EasyRdf_Literal
+{
+ /** Constructor for creating a new integer literal
+ *
+ * @param mixed $value The value of the literal
+ * @param string $lang Should be null (literals with a datatype can't have a language)
+ * @param string $datatype Optional datatype (default 'xsd:integer')
+ * @return object EasyRdf_Literal_Integer
+ */
+ public function __construct($value, $lang = null, $datatype = null)
+ {
+ parent::__construct($value, null, $datatype);
+ }
+
+ /** Return the value of the literal cast to a PHP int
+ *
+ * @return double
+ */
+ public function getValue()
+ {
+ return (int)$this->value;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Literal/XML.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class that represents an RDF Literal of datatype rdf:XMLLiteral
+ *
+ * @package EasyRdf
+ * @link http://www.w3.org/TR/REC-rdf-syntax/#section-Syntax-XML-literals
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Literal_XML extends EasyRdf_Literal
+{
+ /** Constructor for creating a new rdf:XMLLiteral literal
+ *
+ * @param mixed $value The XML fragment
+ * @param string $lang Should be null (literals with a datatype can't have a language)
+ * @param string $datatype Optional datatype (default 'rdf:XMLLiteral')
+ * @return object EasyRdf_Literal_XML
+ */
+ public function __construct($value, $lang = null, $datatype = null)
+ {
+ parent::__construct($value, null, $datatype);
+ }
+
+ /** Parse the XML literal into a DOMDocument
+ *
+ * @link http://php.net/manual/en/domdocument.loadxml.php
+ * @return object DOMDocument
+ */
+ public function domParse()
+ {
+ $dom = new DOMDocument();
+ $dom->loadXML($this->value);
+ return $dom;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Namespace.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,350 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * A namespace registry and manipulation class.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Namespace
+{
+ /** Namespace registry
+ *
+ * List of default namespaces come from:
+ * - http://www.w3.org/2011/rdfa-context/rdfa-1.1
+ *
+ * With a few extras added.
+ *
+ */
+ private static $namespaces = array(
+ 'bibo' => 'http://purl.org/ontology/bibo/',
+ 'cc' => 'http://creativecommons.org/ns#',
+ 'cert' => 'http://www.w3.org/ns/auth/cert#',
+ 'ctag' => 'http://commontag.org/ns#',
+ 'dc' => 'http://purl.org/dc/terms/',
+ 'dc11' => 'http://purl.org/dc/elements/1.1/',
+ 'dcterms' => 'http://purl.org/dc/terms/',
+ 'doap' => 'http://usefulinc.com/ns/doap#',
+ 'exif' => 'http://www.w3.org/2003/12/exif/ns#',
+ 'foaf' => 'http://xmlns.com/foaf/0.1/',
+ 'geo' => 'http://www.w3.org/2003/01/geo/wgs84_pos#',
+ 'gr' => 'http://purl.org/goodrelations/v1#',
+ 'grddl' => 'http://www.w3.org/2003/g/data-view#',
+ 'ical' => 'http://www.w3.org/2002/12/cal/icaltzd#',
+ 'ma' => 'http://www.w3.org/ns/ma-ont#',
+ 'og' => 'http://ogp.me/ns#',
+ 'owl' => 'http://www.w3.org/2002/07/owl#',
+ 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
+ 'rdfa' => 'http://www.w3.org/ns/rdfa#',
+ 'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
+ 'rev' => 'http://purl.org/stuff/rev#',
+ 'rif' => 'http://www.w3.org/2007/rif#',
+ 'rss' => 'http://purl.org/rss/1.0/',
+ 'schema' => 'http://schema.org/',
+ 'sioc' => 'http://rdfs.org/sioc/ns#',
+ 'skos' => 'http://www.w3.org/2004/02/skos/core#',
+ 'skosxl' => 'http://www.w3.org/2008/05/skos-xl#',
+ 'synd' => 'http://purl.org/rss/1.0/modules/syndication/',
+ 'v' => 'http://rdf.data-vocabulary.org/#',
+ 'vcard' => 'http://www.w3.org/2006/vcard/ns#',
+ 'void' => 'http://rdfs.org/ns/void#',
+ 'wdr' => 'http://www.w3.org/2007/05/powder#',
+ 'wdrs' => 'http://www.w3.org/2007/05/powder-s#',
+ 'wot' => 'http://xmlns.com/wot/0.1/',
+ 'xhv' => 'http://www.w3.org/1999/xhtml/vocab#',
+ 'xml' => 'http://www.w3.org/XML/1998/namespace',
+ 'xsd' => 'http://www.w3.org/2001/XMLSchema#',
+ );
+
+ private static $default = null;
+
+ /** Counter for numbering anonymous namespaces */
+ private static $anonymousNamespaceCount = 0;
+
+ /**
+ * Return all the namespaces registered
+ *
+ * @return array Associative array of all the namespaces.
+ */
+ public static function namespaces()
+ {
+ return self::$namespaces;
+ }
+
+ /**
+ * Return a namespace given its prefix.
+ *
+ * @param string $prefix The namespace prefix (eg 'foaf')
+ * @return string The namespace URI (eg 'http://xmlns.com/foaf/0.1/')
+ */
+ public static function get($prefix)
+ {
+ if (!is_string($prefix) or $prefix === null or $prefix === '') {
+ throw new InvalidArgumentException(
+ "\$prefix should be a string and cannot be null or empty"
+ );
+ }
+
+ if (preg_match('/\W/', $prefix)) {
+ throw new InvalidArgumentException(
+ "\$prefix should only contain alpha-numeric characters"
+ );
+ }
+
+ $prefix = strtolower($prefix);
+ if (array_key_exists($prefix, self::$namespaces)) {
+ return self::$namespaces[$prefix];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Register a new namespace.
+ *
+ * @param string $prefix The namespace prefix (eg 'foaf')
+ * @param string $long The namespace URI (eg 'http://xmlns.com/foaf/0.1/')
+ */
+ public static function set($prefix, $long)
+ {
+ if (!is_string($prefix) or $prefix === null or $prefix === '') {
+ throw new InvalidArgumentException(
+ "\$prefix should be a string and cannot be null or empty"
+ );
+ }
+
+ if (preg_match('/\W/', $prefix)) {
+ throw new InvalidArgumentException(
+ "\$prefix should only contain alpha-numeric characters"
+ );
+ }
+
+ if (!is_string($long) or $long === null or $long === '') {
+ throw new InvalidArgumentException(
+ "\$long should be a string and cannot be null or empty"
+ );
+ }
+
+ $prefix = strtolower($prefix);
+ self::$namespaces[$prefix] = $long;
+ }
+
+ /**
+ * Get the default namespace
+ *
+ * Returns the URI of the default namespace or null
+ * if no default namespace is defined.
+ *
+ * @return string The URI of the default namespace
+ */
+ public static function getDefault()
+ {
+ return self::$default;
+ }
+
+ /**
+ * Set the default namespace
+ *
+ * Set the default namespace to either a URI or the prefix of
+ * an already defined namespace.
+ *
+ * Example:
+ * EasyRdf_Namespace::setDefault('http://schema.org/');
+ *
+ * @param string $namespace The URI or prefix of a namespace (eg 'og')
+ */
+ public static function setDefault($namespace)
+ {
+ if (is_null($namespace) or $namespace === '') {
+ self::$default = null;
+ } elseif (preg_match("/^\w+$/", $namespace)) {
+ if (isset(self::$namespaces[$namespace])) {
+ self::$default = self::$namespaces[$namespace];
+ } else {
+ throw new InvalidArgumentException(
+ "Unable to set default namespace to unknown prefix: $namespace"
+ );
+ }
+ } else {
+ self::$default = $namespace;
+ }
+ }
+
+ /**
+ * Delete an existing namespace.
+ *
+ * @param string $prefix The namespace prefix (eg 'foaf')
+ */
+ public static function delete($prefix)
+ {
+ if (!is_string($prefix) or $prefix === null or $prefix === '') {
+ throw new InvalidArgumentException(
+ "\$prefix should be a string and cannot be null or empty"
+ );
+ }
+
+ $prefix = strtolower($prefix);
+ if (isset(self::$namespaces[$prefix])) {
+ unset(self::$namespaces[$prefix]);
+ }
+ }
+
+ /**
+ * Delete the anonymous namespaces and reset the counter to 0
+ */
+ public static function reset()
+ {
+ while (self::$anonymousNamespaceCount > 0) {
+ self::delete('ns'.(self::$anonymousNamespaceCount-1));
+ self::$anonymousNamespaceCount--;
+ }
+ }
+
+ /**
+ * Try and breakup a URI into a prefix and local part
+ *
+ * If $createNamespace is true, and the URI isn't part of an existing
+ * namespace, then EasyRdf will attempt to create a new namespace and
+ * return the name of the new prefix (for example 'ns0', 'term').
+ *
+ * If it isn't possible to split the URI, then null will be returned.
+ *
+ * @param string $uri The full URI (eg 'http://xmlns.com/foaf/0.1/name')
+ * @param bool $createNamespace If true, a new namespace will be created
+ * @return array The split URI (eg 'foaf', 'name') or null
+ */
+ public static function splitUri($uri, $createNamespace = false)
+ {
+ if ($uri === null or $uri === '') {
+ throw new InvalidArgumentException(
+ "\$uri cannot be null or empty"
+ );
+ }
+
+ if (is_object($uri) and ($uri instanceof EasyRdf_Resource)) {
+ $uri = $uri->getUri();
+ } elseif (!is_string($uri)) {
+ throw new InvalidArgumentException(
+ "\$uri should be a string or EasyRdf_Resource"
+ );
+ }
+
+ foreach (self::$namespaces as $prefix => $long) {
+ if (substr($uri, 0, strlen($long)) == $long) {
+ return array($prefix, substr($uri, strlen($long)));
+ }
+ }
+
+ if ($createNamespace) {
+ // Try and create a new namespace
+ # FIXME: check the valid characters for an XML element name
+ if (preg_match("/^(.+?)([\w\-]+)$/", $uri, $matches)) {
+ $prefix = "ns".(self::$anonymousNamespaceCount++);
+ self::set($prefix, $matches[1]);
+ return array($prefix, $matches[2]);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the prefix namespace that a URI belongs to.
+ *
+ * @param string $uri A full URI (eg 'http://xmlns.com/foaf/0.1/name')
+ * @return string The prefix namespace that it is a part of(eg 'foaf')
+ */
+ public static function prefixOfUri($uri)
+ {
+ if ($parts = self::splitUri($uri)) {
+ return $parts[0];
+ }
+ }
+
+ /**
+ * Shorten a URI by substituting in the namespace prefix.
+ *
+ * If $createNamespace is true, and the URI isn't part of an existing
+ * namespace, then EasyRdf will attempt to create a new namespace and
+ * use that namespace to shorten the URI (for example ns0:term).
+ *
+ * If it isn't possible to shorten the URI, then null will be returned.
+ *
+ * @param string $uri The full URI (eg 'http://xmlns.com/foaf/0.1/name')
+ * @param bool $createNamespace If true, a new namespace will be created
+ * @return string The shortened URI (eg 'foaf:name') or null
+ */
+ public static function shorten($uri, $createNamespace = false)
+ {
+ if ($parts = self::splitUri($uri, $createNamespace)) {
+ return implode(':', $parts);
+ }
+ }
+
+ /**
+ * Expand a shortened URI (qname) back into a full URI.
+ *
+ * If it isn't possible to expand the qname, for example if the namespace
+ * isn't registered, then the original string will be returned.
+ *
+ * @param string $shortUri The short URI (eg 'foaf:name')
+ * @return string The full URI (eg 'http://xmlns.com/foaf/0.1/name')
+ */
+ public static function expand($shortUri)
+ {
+ if (!is_string($shortUri) or $shortUri === '') {
+ throw new InvalidArgumentException(
+ "\$shortUri should be a string and cannot be null or empty"
+ );
+ }
+
+ if ($shortUri === 'a') {
+ return self::$namespaces['rdf'] . 'type';
+ } elseif (preg_match("/^(\w+?):([\w\-]+)$/", $shortUri, $matches)) {
+ $long = self::get($matches[1]);
+ if ($long) {
+ return $long . $matches[2];
+ }
+ } elseif (preg_match("/^(\w+)$/", $shortUri) and isset(self::$default)) {
+ return self::$default . $shortUri;
+ }
+
+ return $shortUri;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/ParsedUri.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,340 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+
+/**
+ * A RFC3986 compliant URI parser
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ * @link http://www.ietf.org/rfc/rfc3986.txt
+ */
+class EasyRdf_ParsedUri
+{
+ // For all URIs:
+ private $scheme = null;
+ private $fragment = null;
+
+ // For hierarchical URIs:
+ private $authority = null;
+ private $path = null;
+ private $query = null;
+
+ const URI_REGEX = "|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|";
+
+ /** Constructor for creating a new parsed URI
+ *
+ * The $uri parameter can either be a string or an
+ * associative array with the following keys:
+ * scheme, authority, path, query, fragment
+ *
+ * @param mixed $uri The URI as a string or an array
+ * @return object EasyRdf_ParsedUri
+ */
+ public function __construct($uri = null)
+ {
+ if (is_string($uri)) {
+ if (preg_match(self::URI_REGEX, $uri, $matches)) {
+ if (!empty($matches[1])) {
+ $this->scheme = isset($matches[2]) ? $matches[2] : '';
+ }
+ if (!empty($matches[3])) {
+ $this->authority = isset($matches[4]) ? $matches[4] : '';
+ }
+ $this->path = isset($matches[5]) ? $matches[5] : '';
+ if (!empty($matches[6])) {
+ $this->query = isset($matches[7]) ? $matches[7] : '';
+ }
+ if (!empty($matches[8])) {
+ $this->fragment = isset($matches[9]) ? $matches[9] : '';
+ }
+ }
+ } elseif (is_array($uri)) {
+ $this->scheme = isset($uri['scheme']) ? $uri['scheme'] : null;
+ $this->authority = isset($uri['authority']) ? $uri['authority'] : null;
+ $this->path = isset($uri['path']) ? $uri['path'] : null;
+ $this->query = isset($uri['query']) ? $uri['query'] : null;
+ $this->fragment = isset($uri['fragment']) ? $uri['fragment'] : null;
+ }
+ }
+
+
+ /** Returns true if this is an absolute (complete) URI
+ * @return boolean
+ */
+ public function isAbsolute()
+ {
+ return $this->scheme !== null;
+ }
+
+ /** Returns true if this is an relative (partial) URI
+ * @return boolean
+ */
+ public function isRelative()
+ {
+ return $this->scheme === null;
+ }
+
+ /** Returns the scheme of the URI (e.g. http)
+ * @return string
+ */
+ public function getScheme()
+ {
+ return $this->scheme;
+ }
+
+ /** Sets the scheme of the URI (e.g. http)
+ * @param string $scheme The new value for the scheme of the URI
+ */
+ public function setScheme($scheme)
+ {
+ $this->scheme = $scheme;
+ }
+
+ /** Returns the authority of the URI (e.g. www.example.com:8080)
+ * @return string
+ */
+ public function getAuthority()
+ {
+ return $this->authority;
+ }
+
+ /** Sets the authority of the URI (e.g. www.example.com:8080)
+ * @param string $authority The new value for the authority component of the URI
+ */
+ public function setAuthority($authority)
+ {
+ $this->authority = $authority;
+ }
+
+ /** Returns the path of the URI (e.g. /foo/bar)
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /** Set the path of the URI (e.g. /foo/bar)
+ * @param string $path The new value for the path component of the URI
+ */
+ public function setPath($path)
+ {
+ $this->path = $path;
+ }
+
+ /** Returns the query string part of the URI (e.g. foo=bar)
+ * @return string
+ */
+ public function getQuery()
+ {
+ return $this->query;
+ }
+
+ /** Set the query string of the URI (e.g. foo=bar)
+ * @param string $query The new value for the query string component of the URI
+ */
+ public function setQuery($query)
+ {
+ $this->query = $query;
+ }
+
+ /** Returns the fragment part of the URI (i.e. after the #)
+ * @return string
+ */
+ public function getFragment()
+ {
+ return $this->fragment;
+ }
+
+ /** Set the fragment of the URI (i.e. after the #)
+ * @param string $fragment The new value for the fragment component of the URI
+ */
+ public function setFragment($fragment)
+ {
+ $this->fragment = $fragment;
+ }
+
+
+ /**
+ * Normalises the path of this URI if it has one. Normalising a path means
+ * that any unnecessary '.' and '..' segments are removed. For example, the
+ * URI http://example.com/a/b/../c/./d would be normalised to
+ * http://example.com/a/c/d
+ *
+ * @return object EasyRdf_ParsedUri
+ */
+ public function normalise()
+ {
+ if (empty($this->path)) {
+ return $this;
+ }
+
+ // Remove ./ from the start
+ if (substr($this->path, 0, 2) == './') {
+ // Remove both characters
+ $this->path = substr($this->path, 2);
+ }
+
+ // Remove /. from the end
+ if (substr($this->path, -2) == '/.') {
+ // Remove only the last dot, not the slash!
+ $this->path = substr($this->path, 0, -1);
+ }
+
+ if (substr($this->path, -3) == '/..') {
+ $this->path .= '/';
+ }
+
+ // Split the path into its segments
+ $segments = explode('/', $this->path);
+ $newSegments = array();
+
+ // Remove all unnecessary '.' and '..' segments
+ foreach ($segments as $segment) {
+ if ($segment == '..') {
+ // Remove the previous part of the path
+ $count = count($newSegments);
+ if ($count > 0 && $newSegments[$count-1]) {
+ array_pop($newSegments);
+ }
+ } elseif ($segment == '.') {
+ // Ignore
+ continue;
+ } else {
+ array_push($newSegments, $segment);
+ }
+ }
+
+ // Construct the new normalised path
+ $this->path = implode($newSegments, '/');
+
+ // Allow easy chaining of methods
+ return $this;
+ }
+
+ /**
+ * Resolves a relative URI using this URI as the base URI.
+ */
+ public function resolve($relUri)
+ {
+ // If it is a string, then convert it to a parsed object
+ if (is_string($relUri)) {
+ $relUri = new EasyRdf_ParsedUri($relUri);
+ }
+
+ // This code is based on the pseudocode in section 5.2.2 of RFC3986
+ $target = new EasyRdf_ParsedUri();
+ if ($relUri->scheme) {
+ $target->scheme = $relUri->scheme;
+ $target->authority = $relUri->authority;
+ $target->path = $relUri->path;
+ $target->query = $relUri->query;
+ } else {
+ if ($relUri->authority) {
+ $target->authority = $relUri->authority;
+ $target->path = $relUri->path;
+ $target->query = $relUri->query;
+ } else {
+ if (empty($relUri->path)) {
+ $target->path = $this->path;
+ if ($relUri->query) {
+ $target->query = $relUri->query;
+ } else {
+ $target->query = $this->query;
+ }
+ } else {
+ if (substr($relUri->path, 0, 1) == '/') {
+ $target->path = $relUri->path;
+ } else {
+ $path = $this->path;
+ $lastSlash = strrpos($path, '/');
+ if ($lastSlash !== false) {
+ $path = substr($path, 0, $lastSlash + 1);
+ } else {
+ $path = '/';
+ }
+
+ $target->path .= $path . $relUri->path;
+ }
+ $target->query = $relUri->query;
+ }
+ $target->authority = $this->authority;
+ }
+ $target->scheme = $this->scheme;
+ }
+
+ $target->fragment = $relUri->fragment;
+
+ $target->normalise();
+
+ return $target;
+ }
+
+ /** Convert the parsed URI back into a string
+ *
+ * @return string The URI as a string
+ */
+ public function toString()
+ {
+ $str = '';
+ if ($this->scheme !== null) {
+ $str .= $this->scheme . ':';
+ }
+ if ($this->authority !== null) {
+ $str .= '//' . $this->authority;
+ }
+ $str .= $this->path;
+ if ($this->query !== null) {
+ $str .= '?' . $this->query;
+ }
+ if ($this->fragment !== null) {
+ $str .= '#' . $this->fragment;
+ }
+ return $str;
+ }
+
+ /** Magic method to convert the URI, when casted, back to a string
+ *
+ * @return string The URI as a string
+ */
+ public function __toString()
+ {
+ return $this->toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Parser.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,149 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Parent class for the EasyRdf parsers
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Parser
+{
+ /** Mapping from source to graph bnode identifiers */
+ private $bnodeMap = array();
+
+ /** The current graph to insert triples into */
+ protected $graph = null;
+
+ /** The format of the document currently being parsed */
+ protected $format = null;
+
+ /** The base URI for the document currently being parsed */
+ protected $baseUri = null;
+
+ /**
+ * Create a new, unique bnode identifier from a source identifier.
+ * If the source identifier has previously been seen, the
+ * same new bnode identifier is returned.
+ * @ignore
+ */
+ protected function remapBnode($name)
+ {
+ if (!isset($this->bnodeMap[$name])) {
+ $this->bnodeMap[$name] = $this->graph->newBNodeId();
+ }
+ return $this->bnodeMap[$name];
+ }
+
+ /**
+ * Delete the bnode mapping - to be called at the start of a new parse
+ * @ignore
+ */
+ protected function resetBnodeMap()
+ {
+ $this->bnodeMap = array();
+ }
+
+ /**
+ * Check, cleanup parameters and prepare for parsing
+ * @ignore
+ */
+ protected function checkParseParams($graph, $data, $format, $baseUri)
+ {
+ if ($graph == null or !is_object($graph) or
+ !($graph instanceof EasyRdf_Graph)) {
+ throw new InvalidArgumentException(
+ "\$graph should be an EasyRdf_Graph object and cannot be null"
+ );
+ } else {
+ $this->graph = $graph;
+ }
+
+ if ($format == null or $format == '') {
+ throw new InvalidArgumentException(
+ "\$format cannot be null or empty"
+ );
+ } elseif (is_object($format) and $format instanceof EasyRdf_Format) {
+ $this->format = $format = $format->getName();
+ } elseif (!is_string($format)) {
+ throw new InvalidArgumentException(
+ "\$format should be a string or an EasyRdf_Format object"
+ );
+ } else {
+ $this->format = $format;
+ }
+
+ if ($baseUri) {
+ if (!is_string($baseUri)) {
+ throw new InvalidArgumentException(
+ "\$baseUri should be a string"
+ );
+ } else {
+ $this->baseUri = new EasyRdf_ParsedUri($baseUri);
+ }
+ } else {
+ $this->baseUri = null;
+ }
+
+ // Prepare for parsing
+ $this->resetBnodeMap();
+ $this->tripleCount = 0;
+ }
+
+ /**
+ * Sub-classes must follow this protocol
+ * @ignore
+ */
+ public function parse($graph, $data, $format, $baseUri)
+ {
+ throw new EasyRdf_Exception(
+ "This method should be overridden by sub-classes."
+ );
+ }
+
+ /**
+ * Add a triple to the current graph, and keep count of the number of triples
+ * @ignore
+ */
+ protected function addTriple($resource, $property, $value)
+ {
+ $count = $this->graph->add($resource, $property, $value);
+ $this->tripleCount += $count;
+ return $count;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Parser/Arc.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,96 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class to parse RDF using the ARC2 library.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Parser_Arc extends EasyRdf_Parser_RdfPhp
+{
+ private static $supportedTypes = array(
+ 'rdfxml' => 'RDFXML',
+ 'turtle' => 'Turtle',
+ 'ntriples' => 'Turtle',
+ 'rdfa' => 'SemHTML',
+ );
+
+ /**
+ * Constructor
+ *
+ * @return object EasyRdf_Parser_Arc
+ */
+ public function __construct()
+ {
+ require_once 'arc/ARC2.php';
+ }
+
+ /**
+ * Parse an RDF document into an EasyRdf_Graph
+ *
+ * @param object EasyRdf_Graph $graph the graph to load the data into
+ * @param string $data the RDF document data
+ * @param string $format the format of the input data
+ * @param string $baseUri the base URI of the data being parsed
+ * @return integer The number of triples added to the graph
+ */
+ public function parse($graph, $data, $format, $baseUri)
+ {
+ parent::checkParseParams($graph, $data, $format, $baseUri);
+
+ if (array_key_exists($format, self::$supportedTypes)) {
+ $className = self::$supportedTypes[$format];
+ } else {
+ throw new EasyRdf_Exception(
+ "EasyRdf_Parser_Arc does not support: $format"
+ );
+ }
+
+ $parser = ARC2::getParser($className);
+ if ($parser) {
+ $parser->parse($baseUri, $data);
+ $rdfphp = $parser->getSimpleIndex(false);
+ return parent::parse($graph, $rdfphp, 'php', $baseUri);
+ } else {
+ throw new EasyRdf_Exception(
+ "ARC2 failed to get a $className parser."
+ );
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Parser/Exception.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * EasyRdf Exception class
+ *
+ * All exceptions thrown by EasyRdf are an instance of this class.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Parser_Exception extends EasyRdf_Exception
+{
+ protected $parserLine;
+ protected $parserColumn;
+
+ public function __construct($message, $line = null, $column = null)
+ {
+ $this->parserLine = $line;
+ $this->parserColumn = $column;
+
+ if (!is_null($line)) {
+ $message .= " on line $line";
+ if (!is_null($column)) {
+ $message .= ", column $column";
+ }
+ }
+
+ parent::__construct($message);
+ }
+
+ public function getParserLine()
+ {
+ return $this->parserLine;
+ }
+
+ public function getParserColumn()
+ {
+ return $this->parserColumn;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Parser/Json.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,155 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * A pure-php class to parse RDF/JSON with no dependancies.
+ *
+ * http://n2.talis.com/wiki/RDF_JSON_Specification
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Parser_Json extends EasyRdf_Parser_RdfPhp
+{
+ private $jsonLastErrorExists = false;
+
+ /**
+ * Constructor
+ *
+ * @return object EasyRdf_Parser_Json
+ */
+ public function __construct()
+ {
+ $this->jsonLastErrorExists = function_exists('json_last_error');
+ }
+
+ /** Return the last JSON parser error as a string
+ *
+ * If json_last_error() is not available a generic message will be returned.
+ *
+ * @ignore
+ */
+ protected function jsonLastErrorString()
+ {
+ if ($this->jsonLastErrorExists) {
+ switch (json_last_error()) {
+ case JSON_ERROR_NONE:
+ return null;
+ case JSON_ERROR_DEPTH:
+ return "JSON Parse error: the maximum stack depth has been exceeded";
+ case JSON_ERROR_STATE_MISMATCH:
+ return "JSON Parse error: invalid or malformed JSON";
+ case JSON_ERROR_CTRL_CHAR:
+ return "JSON Parse error: control character error, possibly incorrectly encoded";
+ case JSON_ERROR_SYNTAX:
+ return "JSON Parse syntax error";
+ case JSON_ERROR_UTF8:
+ return "JSON Parse error: malformed UTF-8 characters, possibly incorrectly encoded";
+ default:
+ return "JSON Parse error: unknown";
+ }
+ } else {
+ return "JSON Parse error";
+ }
+ }
+
+ /** Parse the triple-centric JSON format, as output by libraptor
+ *
+ * http://librdf.org/raptor/api/serializer-json.html
+ *
+ * @ignore
+ */
+ protected function parseJsonTriples($data, $baseUri)
+ {
+ foreach ($data['triples'] as $triple) {
+ if ($triple['subject']['type'] == 'bnode') {
+ $subject = $this->remapBnode($triple['subject']['value']);
+ } else {
+ $subject = $triple['subject']['value'];
+ }
+
+ $predicate = $triple['predicate']['value'];
+
+ if ($triple['object']['type'] == 'bnode') {
+ $object = array(
+ 'type' => 'bnode',
+ 'value' => $this->remapBnode($triple['object']['value'])
+ );
+ } else {
+ $object = $triple['object'];
+ }
+
+ $this->addTriple($subject, $predicate, $object);
+ }
+
+ return $this->tripleCount;
+ }
+
+ /**
+ * Parse RDF/JSON into an EasyRdf_Graph
+ *
+ * @param object EasyRdf_Graph $graph the graph to load the data into
+ * @param string $data the RDF document data
+ * @param string $format the format of the input data
+ * @param string $baseUri the base URI of the data being parsed
+ * @return integer The number of triples added to the graph
+ */
+ public function parse($graph, $data, $format, $baseUri)
+ {
+ $this->checkParseParams($graph, $data, $format, $baseUri);
+
+ if ($format != 'json') {
+ throw new EasyRdf_Exception(
+ "EasyRdf_Parser_Json does not support: $format"
+ );
+ }
+
+ $decoded = @json_decode(strval($data), true);
+ if ($decoded === null) {
+ throw new EasyRdf_Parser_Exception(
+ $this->jsonLastErrorString()
+ );
+ }
+
+ if (array_key_exists('triples', $decoded)) {
+ return $this->parseJsonTriples($decoded, $baseUri);
+ } else {
+ return parent::parse($graph, $decoded, 'php', $baseUri);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Parser/Ntriples.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,211 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * A pure-php class to parse N-Triples with no dependancies.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Parser_Ntriples extends EasyRdf_Parser
+{
+ /**
+ * Decodes an encoded N-Triples string. Any \-escape sequences are substituted
+ * with their decoded value.
+ *
+ * @param string $str An encoded N-Triples string.
+ * @return The unencoded string.
+ **/
+ protected function unescapeString($str)
+ {
+ if (strpos($str, '\\') === false) {
+ return $str;
+ }
+
+ $mappings = array(
+ 't' => chr(0x09),
+ 'b' => chr(0x08),
+ 'n' => chr(0x0A),
+ 'r' => chr(0x0D),
+ 'f' => chr(0x0C),
+ '\"' => chr(0x22),
+ '\'' => chr(0x27)
+ );
+ foreach ($mappings as $in => $out) {
+ $str = preg_replace('/\x5c([' . $in . '])/', $out, $str);
+ }
+
+ if (stripos($str, '\u') === false) {
+ return $str;
+ }
+
+ while (preg_match('/\\\(U)([0-9A-F]{8})/', $str, $matches) ||
+ preg_match('/\\\(u)([0-9A-F]{4})/', $str, $matches)) {
+ $no = hexdec($matches[2]);
+ if ($no < 128) { // 0x80
+ $char = chr($no);
+ } elseif ($no < 2048) { // 0x800
+ $char = chr(($no >> 6) + 192) .
+ chr(($no & 63) + 128);
+ } elseif ($no < 65536) { // 0x10000
+ $char = chr(($no >> 12) + 224) .
+ chr((($no >> 6) & 63) + 128) .
+ chr(($no & 63) + 128);
+ } elseif ($no < 2097152) { // 0x200000
+ $char = chr(($no >> 18) + 240) .
+ chr((($no >> 12) & 63) + 128) .
+ chr((($no >> 6) & 63) + 128) .
+ chr(($no & 63) + 128);
+ } else {
+ # FIXME: throw an exception instead?
+ $char = '';
+ }
+ $str = str_replace('\\' . $matches[1] . $matches[2], $char, $str);
+ }
+ return $str;
+ }
+
+ /**
+ * @ignore
+ */
+ protected function parseNtriplesSubject($sub, $lineNum)
+ {
+ if (preg_match('/<([^<>]+)>/', $sub, $matches)) {
+ return $this->unescapeString($matches[1]);
+ } elseif (preg_match('/_:([A-Za-z0-9]*)/', $sub, $matches)) {
+ if (empty($matches[1])) {
+ return $this->graph->newBNodeId();
+ } else {
+ $nodeid = $this->unescapeString($matches[1]);
+ return $this->remapBnode($nodeid);
+ }
+ } else {
+ throw new EasyRdf_Parser_Exception(
+ "Failed to parse subject: $sub",
+ $lineNum
+ );
+ }
+ }
+
+ /**
+ * @ignore
+ */
+ protected function parseNtriplesObject($obj, $lineNum)
+ {
+ if (preg_match('/"(.+)"\^\^<([^<>]+)>/', $obj, $matches)) {
+ return array(
+ 'type' => 'literal',
+ 'value' => $this->unescapeString($matches[1]),
+ 'datatype' => $this->unescapeString($matches[2])
+ );
+ } elseif (preg_match('/"(.+)"@([\w\-]+)/', $obj, $matches)) {
+ return array(
+ 'type' => 'literal',
+ 'value' => $this->unescapeString($matches[1]),
+ 'lang' => $this->unescapeString($matches[2])
+ );
+ } elseif (preg_match('/"(.*)"/', $obj, $matches)) {
+ return array('type' => 'literal', 'value' => $this->unescapeString($matches[1]));
+ } elseif (preg_match('/<([^<>]+)>/', $obj, $matches)) {
+ return array('type' => 'uri', 'value' => $matches[1]);
+ } elseif (preg_match('/_:([A-Za-z0-9]*)/', $obj, $matches)) {
+ if (empty($matches[1])) {
+ return array(
+ 'type' => 'bnode',
+ 'value' => $this->graph->newBNodeId()
+ );
+ } else {
+ $nodeid = $this->unescapeString($matches[1]);
+ return array(
+ 'type' => 'bnode',
+ 'value' => $this->remapBnode($nodeid)
+ );
+ }
+ } else {
+ throw new EasyRdf_Parser_Exception(
+ "Failed to parse object: $obj",
+ $lineNum
+ );
+ }
+ }
+
+ /**
+ * Parse an N-Triples document into an EasyRdf_Graph
+ *
+ * @param object EasyRdf_Graph $graph the graph to load the data into
+ * @param string $data the RDF document data
+ * @param string $format the format of the input data
+ * @param string $baseUri the base URI of the data being parsed
+ * @return integer The number of triples added to the graph
+ */
+ public function parse($graph, $data, $format, $baseUri)
+ {
+ parent::checkParseParams($graph, $data, $format, $baseUri);
+
+ if ($format != 'ntriples') {
+ throw new EasyRdf_Exception(
+ "EasyRdf_Parser_Ntriples does not support: $format"
+ );
+ }
+
+ $lines = preg_split("/\x0D?\x0A/", strval($data));
+ foreach ($lines as $index => $line) {
+ $lineNum = $index + 1;
+ if (preg_match("/^\s*#/", $line)) {
+ # Comment
+ continue;
+ } elseif (preg_match("/^\s*(.+?)\s+<([^<>]+?)>\s+(.+?)\s*\.\s*$/", $line, $matches)) {
+ $this->addTriple(
+ $this->parseNtriplesSubject($matches[1], $lineNum),
+ $this->unescapeString($matches[2]),
+ $this->parseNtriplesObject($matches[3], $lineNum)
+ );
+ } elseif (preg_match("/^\s*$/", $line)) {
+ # Blank line
+ continue;
+ } else {
+ throw new EasyRdf_Parser_Exception(
+ "Failed to parse statement",
+ $lineNum
+ );
+ }
+ }
+
+ return $this->tripleCount;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/easyrdf/lib/EasyRdf/Parser/Rapper.php Mon Sep 09 21:02:53 2013 +0100
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package EasyRdf
+ * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class to parse RDF using the 'rapper' comma