This repository has been archived by the owner. It is now read-only.
An EasyRdf extension to support authentication, LDP server endpoints and more.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
library/BOTK/RDF
samples
test
.gitignore
.project
.scrutinizer.yml
.travis.yml
CHANGELOG.md
CONTRIBUTING.md
LICENSE
README.md
Vagrantfile
composer.json
phpunit.xml.dist

README.md

WARNING

The support to this project is now discontinued. Update your links.

Find the old version as tagged branch.

BOTK\Rdf

Build Status Code Coverage Latest Version Total Downloads License

This package is an EasyRDF extension to support authentication,reasoning, LDP server endpoints and more.

It extends the default httpclient of EasyRDF to support basic authentication and and provides two content negotiation policies to manage consistently representations for RDF graphs and for Sparql Results data models.

Beside this it contains an implementation of a simple end point to publish linked data supporting many serialization and html according Linked Data Platform Editor Draft specification

This package is available on Packagist.

You can install adding following dependances to composer.json file in your project root:

    {
      "require": {
        "botk/rdf": "*"
      }
    }

Documentation

HttpClient class

This class is a replacement forEasyRDF http client class. It adds the setAuth(string $user, string $password) method supporting basic http authentication type. HttpClient in turn it is a lightware alternative to Zend_Http_client or Guzzle libraries.

HttpClient is normally used as HTTP protocol wrapper for all EasyRDF specialized clients and for SparqlClient through EasyRdf_Http::setDefaultHttpClient() method, but it can be also used as a generic Web Resource client.

For example, to use simple client identity in accessing a remote sparql endpoint execute:

// define common properties of http client to use to access RDF web resources
$httpClient = new BOTK\RDF\HttpClient;
$httpClient->setAuth('username', 'password');
EasyRdf_Http::setDefaultHttpClient($httpClient);

// access a private sparql end-point that requires basic authentication
$sparql = new EasyRdf_Sparql_Client('https://private/sparql');
$result=$sparql->query('SELECT * WHERE {?s ?p ?o} LIMIT 10');

HttpClient interface is compatible with ZEND-Http_client library.

HttpClient provides a simple helper to create an authenticated HTTP client and use it in EasyRdf  with a single call of the static method HttpClient::useIdentity(string $usename = null, string $password=null, $timeout=null ) . If not specified the client will reuse the timeout of the calling script (if available) or 30 sec. otherwise. Using the helper, the previous code can be shorten as:

BOTK\RDF\HttpClient::useIdentity('username','password');

$sparql = new EasyRdf_Sparql_Client('https://private/sparql');
$result=$sparql->query('SELECT * WHERE {?s ?p ?o} LIMIT 10');

.

Content negotiation policies

RDF

This content negotiation policy is designed for applications that use  EasyRff_Graph data structure as Resource Model.

It provide following response and request representations:

  RDF class define following renderer functions: 
RDF::turtleRenderer(mixed $data, Standard::n3Renderer(mixed $data)
Serializes data structure as RDF text/turle
RDF::rdfxmlRenderer(mixed $data)
Serializes data structure as RDF application/xml+rdf.
RDF::jsonRenderer(mixed $data)
Serializes data structure using json
RDF::ntriplesRenderer(mixed $data)
serializes data structure RDF ntriples.
RDF::htmlRenderer(mixed $data)
serializes data structure as html.
RDF::serialphpRenderer(mixed $data)
serializes data structure as php.

SparqlClientResult

This content negotiation policy is designed for applications that use  EasyRdf_Sparql_Result data structure as Resource Model.

It provide following response and request representations:

Simple Linked Data Platform Server (SLDPS)

This set of classes allow you to implement a simple endpoint to publish linked data according last Linked Data Platform Woking Group Draft Specifications . The provided classes can be used to base  Linked Data Platform Server Implementations.

Here is a simple script that realizes an LDP PAGING server:

    class MyRouter extends EndPoint
    {  
        protected function setRoutes() 
        {
            $this->get('/', 'ProductsController')
                ->accept(RDF::renderers())
                ->through($this->representationCachingProcessor(Caching::SHORT));
        }
    }

    class ProductsController extends SparqlLDPController
    {
        protected 
            $pagesize       = 10,
            $pagingPolicy   = self::CONSERVATIVE,
            $endpoint       = 'http://linkedopencommerce.com/sparql/',
            $constructor    = '
                PREFIX gr:  <http://purl.org/goodrelations/v1#>
                DESCRIBE ?product WHERE {
                    ?product a gr:ProductOrServiceModel.  
                }
            ';
    }

    $errorManager = BOTK\Core\ErrorManager::getInstance()->registerErrorHandler();    
    try {                                                      
        echo BOTK\Core\EndPointFactory::make('MyRouter')->run();
    } catch ( Exception $e) {
        echo $errorManager->render($e); 
    }

LDPController class

This class provides an generic abstract implementation of a LDP paged controller. In order to get a working implementation you have to implement three methods:

  • detectIfHasNextPage(): that must return true if another linked data page is available. If it is not provided, paging features will be disabled.
  • linkData(): that populate the protected var resultGraph (an EasyRdf_Graph object) with linked resource
  • linkMetaData(): that optionally add metadata to resultGraph

It provides a simple template engine (from Core Package) populated with a set  of predefine variables placeholders:

  • {pagedResourceUri} :  the requested uri without page info;
  • {strippedUri} : the requested uri without query strings and fragment.
  • {requestUri} :  the requested uri as written by user (with or partial page info)

The protected context variable contains an instance of Core PagedResourceContext.

SparqlLDPController Class

This class extends LDPController and provides a generic  implementation of a Linked Data Platform Server that publish as Linked Data Resources some resources contained in a sparql Server.

You need to redefine following variables to override defaults :

$username
the username required to access sparql update endpoint, default is empty
$password
the password required to access sparql update endpoint. only Basic method supported, default is empty
$endpoint
the sparql endpoint uri. The default is empty.  Examples of valid open sparql endpoints are: http://dbpedia.org/sparqlhttp://lod.openlinksw.com/sparql, http://linkedopencommerce.com/sparql
$pagingPolicy
it is a string value that can be `AGGRESSIVE` or `CONSERVATIVE` to drive next page detection algorithm. The default is  AGGRESSIVE
$constructor
must contain a valid  sparq query template that build a graph with linked data. Do not include  LIMIT/OFFSET clause.The default is empty.
$metadata
optionally contains a turtle template with paged resource metadata. The default is empty

SparqlLDPController class implements LDPController abstract methods:

  • it  provides an implementation of detectIfHasNextPage() based on a parametric algorithm that use the $pagingPolicy variable. If $pagingPolicy=AGGRESSIVE than detectIfHasNextPage() method returns true when last query to sparqls server resulted in exactly $pagesize triples, false otherwise. If  $pagingPolicy=CONSERVATIVE returns true when last query to sparql server was not empty.
  • It provides an implementation of linkData() methods based on the sparql query in $selector variable.
  • It provides an implementation of linkMedtadata() methods based on the turtle template in in $metadata variable.

Beside this, SparqlLDPController class implements  :

  • get($resourceId=null): a default controller get methods with an optional argument that is set by router.

This class add following predefined variables placeholders to the simple template engine:

  • {endpoint}: the value of the variable of the same name.
  • {limit}: same value of PagedResouceContext::getPageSize()
  • {offset}: a calculated value as  PagedResouceContext::getPageNum() *  PagedResouceContext::getPageSize()
  • {username}: the value of the variable of the same name.
  • {containerUri}: the guessed uri of the container extracted from {strippedUri}
  • {resourceId}: the value of the router template var argument. If resouceId is an array, it is transformed in string with implode('/',$resourceId) php instruction.
  • {encodedResourceId}: same as {resourceId} but url encoded.

You can use these variables, plus the ones defined in LDPController, in $constructor and $metadata templates.

    Here is a full example of a contanainer/resource LDP-PAGING implementation using void and prov ontology to
    annotate resources:
    class MyRouter extends EndPoint
    {  
        protected function setRoutes()
        {
            $this->get('/', 'DatasetController');
            $this->get('/*','DataDumpController');

            $this->always('Accept', RDF::renderers() );
            $this->always('Through', $this->representationCachingProcessor(Caching::SHORT));
        }
    }

    class DataDumpController extends SparqlLDPController
    {
        protected $endpoint = 'http://lod.openlinksw.com/sparql';

        protected $constructor  = '
            PREFIX ld: <http://e-artspace.com/s/eCloud#>
            CONSTRUCT {
              ?ldpr ?p ?o . 
            } WHERE { 
                GRAPH <http://e-artspace.com/s/eCloud/> {
                    ?ldpr ?p ?o
                    FILTER (?ldpr = ld:{resourceId} )
                }
            } LIMIT {limit} OFFSET {offset}
        ';

        protected $metadata = '     
            @base <{pagedResourceUri}> .
            @prefix foaf: <http://xmlns.com/foaf/0.1/> .
            @prefix void: <http://rdfs.org/ns/void#> .
            @prefix prov: <http://www.w3.org/ns/prov#> .
            @prefix ldp:  <http://www.w3.org/ns/ldp#> .
            @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
            @prefix container:  <{containerUri}#> .
            @prefix ld: <http://e-artspace.com/s/eCloud#> .
            <> a ldp:Resource, foaf:Document, prov:Entity ;
                foaf:primaryTopic ld:{resourceId} ;
                void:inDataset container:dataset ;
                rdfs:seeAlso <{endpoint}?query=DESCRIBE%20%3Chttp%3A%2F%2Fe-artspace.com%2Fs%2FeCloud%23{encodedResourceId}%3E> ;
                prov:wasGeneratedBy [
                    a prov:Activity ;
                    prov:used <{queryResource}> ;
                    prov:wasAssociatedWith container:sparqlServerUser ;
               ]
            .    
         ';    
    }    

    class DatasetController extends SparqlLDPController
    {
        protected $type     = 'DirectContainer';
        protected $endpoint = 'http://lod.openlinksw.com/sparql';

        protected $constructor  = '
            PREFIX void: <http://rdfs.org/ns/void#>
            PREFIX ldp:  <http://www.w3.org/ns/ldp#>
            CONSTRUCT {
              <{pagedResourceUri}#dataset> void:dataDump ?ldpr .
            } WHERE {
                GRAPH <http://e-artspace.com/s/eCloud/> {
                    ?resource a ?type
                    FILTER(!isBlank(?resource))
                }        
                BIND( IRI(REPLACE(STR(?resource), "http://e-artspace.com/s/eCloud#","{strippedUri}")) AS ?ldpr)
            }
        ';

        protected $metadata = '     
            @base <{pagedResourceUri}> .
            @prefix foaf: <http://xmlns.com/foaf/0.1/> .
            @prefix void: <http://rdfs.org/ns/void#> .
            @prefix prov: <http://www.w3.org/ns/prov#> .
            @prefix ldp:  <http://www.w3.org/ns/ldp#> .
            @prefix : <#> .
            <>  a ldp:DirectContainer, foaf:Document ;
                foaf:primaryTopic :dataset ;
                ldp:membershipResource :dataset ;
                ldp:hasMemberRelation void:dataDump ;
                ldp:insertedContentRelation foaf:primaryTopic ;

            .
            :dataset a void:Dataset, prov:Entity ;
                prov:wasGeneratedBy [
                    a prov:Activity ;
                    prov:used <{queryResource}> ;
                    prov:wasAssociatedWith :sparqlServerUser
                ]
            .
            :sparqlServerUser a foaf:Agent;
                foaf:account [
                    a foaf:OnlineAccount ;
                    foaf:accountServiceHomepage <{endpoint}> ;
                    foaf:accountname "{username}" ;
                ]
            .
         ';
    }

    $errorManager = BOTK\Core\ErrorManager::getInstance()->registerErrorHandler();    
    try {                                                      
        echo BOTK\Core\EndPointFactory::make('MyRouter')->run();
    } catch ( Exception $e) {
        echo $errorManager->render($e); 
    }

License

Copyright © 2016 by Enrico Fagnoni at LinkedData.Center®

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.