├── .htaccess ├── COPYING ├── README ├── TODO ├── classes ├── LDP.php ├── LDP_Config.php └── SITE_Template.php ├── config.php ├── favicon.ico ├── index.php.sample ├── install.php ├── patches ├── README ├── moriarty │ └── simplegraph.class.php └── paget │ ├── paget_abstractresource.class.php │ ├── paget_resourcedescription.class.php │ ├── paget_storebackedurispace.class.php │ ├── paget_template.class.php │ └── paget_termwidget.class.php ├── scripts └── fuseki.importrdf.sh ├── templates ├── foot.html ├── footer.html ├── head.html ├── header.html ├── html.html ├── nav.html ├── page.about.html ├── page.class.html ├── page.default.html └── page.home.html └── theme ├── base └── css │ └── display.css └── default ├── css └── display.css └── images ├── icons ├── icon_diskette.gif ├── icon_loading.gif └── icon_processing.gif ├── illustrations ├── illu_node-connections-1.gif └── illu_node-connections-2.gif └── logos └── logo_270a-linked-data.png /.htaccess: -------------------------------------------------------------------------------- 1 | 2 | Order deny,allow 3 | Allow from all 4 | 5 | 6 | RewriteEngine on 7 | RewriteRule ^$ index.php [L] 8 | 9 | RewriteCond %{REQUEST_FILENAME} -d 10 | RewriteRule ^.*$ - [L] 11 | 12 | RewriteCond %{REQUEST_FILENAME} -f 13 | RewriteRule ^.*$ - [L] 14 | 15 | RewriteRule ^.*$ index.php [L] 16 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | == Overview == 2 | http://csarven.ca/statistical-linked-dataspaces#linked-data-pages 3 | 4 | == Package overview == 5 | Majority of what's discussed here is written as a how-to article at http://csarven.ca/how-to-create-a-linked-data-site . If you want to dive into this project using steps, I suggest reading that first. Naturally there is a lot of overlap with what's mentioned here. 6 | 7 | === Requirements === 8 | * Paget framework 9 | * Moriarty library 10 | * ARC2 library 11 | 12 | == Installation == 13 | This is an ongoing process to make installation and configuration of this framework. At the moment, you can use the initial install.php file to setup the directories for your setup. All you have to do is copy the install.php file to the directory that you want to setup your site at. For example, if you want to run your site from /var/www/site/, then make sure you to chmod a+w that directory (or at least the script that's running PHP has write access). Then go to http://example.org/install.php (replace example.org with whatever host you have /var/www/site/ pointing to. This only copies the necessary files and configures the index.php file for you. You'd still have to setup your SPARQL endpoint and all that... but, yea, stay tuned. 14 | 15 | 16 | === Directory/file structure for templating and themes === 17 | Templates go under the templates/ directory. Templates are used to render different requests made by the client. For example, if the client requests the resource http://site/geo/Montreal, we might want to serve the page.geo.html. Templates generally include layout sections like; html, head, header, nav, footer, foot. It is aimed to modularize common components. There is still a lot of flexibility for any template, hence one can include or exclude any component. 18 | $nano /var/www/site/index.php 19 | Themes go under the theme/ directory. A theme is assigned by $config['site']['theme']. See Site configuration below. The ones that are included in this package are base, default and cso. Base contains all layout and typographical rules, and common images like icons. Default imports base and extends it by including background images and colour rules. By default this package sets the theme to 'default', but you can set your own, in site configuration. 20 | 21 | Custom data processing for templates can be created in classes/SITE_Template.php 22 | 23 | For now, jQuery minimal library comes with this package. 24 | 25 |

 26 | favicon.ico
 27 | .htaccess                      #contains rules for paget's URL dispatching
 28 | index.php                      #main file that dispatches everything
 29 | js/
 30 | js/index.js                    #main script for the site
 31 | js/jquery.min.js               #jQuery JavaScript library
 32 | templates/
 33 | templates/page.about.html      #about template
 34 | templates/page.default.html    #default template that is used to output a resource. includes layout sections
 35 | templates/html.html            #starts the document
 36 | templates/head.html            #head element
 37 | templates/header.html          #header section (e.g., site address, global navigation)
 38 | templates/page.home.html       #home template
 39 | templates/footer.html          #footer section (e.g., global navigation)
 40 | templates/foot.html            #closes the document
 41 | templates/page.geo.html        #geo template that is used to output demographic stats about a particular location. Geared towards the CSO dataset
 42 | templates/nav.html             #local navigation (i.e., in context of the viewed page)
 43 | templates/page.property.html   #default template that is used for properties
 44 | 
 45 | theme/
 46 | theme/base/
 47 | theme/base/css/display.css              #layout, typography rules
 48 | theme/base/images/                      #common icons, illustrations
 49 | theme/base/icons/
 50 | theme/base/images/icons/icons-01.png    #main icons file (combined into a single file)
 51 | theme/base/illustrations/
 52 | theme/default/
 53 | theme/default/css/display.css           #imports base stylesheet, and contains background images and colour rules
 54 | theme/cso/
 55 | theme/cso/css/display.css               #imports default stylesheet and adds CSO specific styles
 56 | 
57 | 58 | 59 | === Configuration === 60 | ==== Server setup ==== 61 |
 62 | /**
 63 |  * XXX: Review each line before executing!
 64 |  * The following is tested under Debian/Linux kernel in an Apache and PHP5 environment.
 65 |  */
 66 | 
 67 | /* Essential requirements for Fuseki */
 68 | $sudo apt-get install maven2
 69 | $sudo apt-get install ruby
 70 | $sudo apt-get install subversion
 71 | 
 72 | /* Required to pull Moriarty, Paget, ARC2, and Linked Data Pages */
 73 | $sudo apt-get install git
 74 | 
 75 | /* Setting up Fuseki triple store */
 76 | $sudo svn co http://jena.svn.sourceforge.net/svnroot/jena/Fuseki/trunk /usr/lib/fuseki
 77 | $cd /usr/lib/fuseki
 78 | $sudo mvn clean package
 79 | 
 80 | /* Fuseki configuration for a DESCRIBE query for resources as subject and object. Optinal. */
 81 | $sudo cp src-dev/dev/BackwardForwardDescribeFactory.java src/main/java/org/openjena/fuseki/
 82 | $sudo nano src/main/java/org/openjena/fuseki/BackwardForwardDescribeFactory.java   #Use org.openjena.fuseki instead of dev for package
 83 | $sudo nano tdb2.ttl   #Use the same path for BackwardForwardDescribeFactory. Uncomment tdb:unionDefaultGraph true ;. Use <#site> instead of <#dataset>
 84 | $sudo mvn install
 85 | 
 86 | /* Starts the Fuseki server */
 87 | Default is read only, use --update to enable write
 88 | $sudo ./fuseki-server --desc tdb2.ttl /cso
 89 | 
 90 | /* Some tests to make sure the Fuseki server is up and running okay */
 91 | $sudo ./s-put http://localhost:3030/site/data default books.ttl
 92 | $sudo ./s-get http://localhost:3030/site/data default
 93 | $sudo ./s-query --service http://localhost:3030/site/query 'SELECT * WHERE {?s ?p ?o .}'
 94 | $sudo ./s-update --service http://localhost:3030/site/update 'CLEAR default'
 95 | 
 96 | 
 97 | 
 98 | /* If you already have Linked Data Pages, you can skip this. */
 99 | $cd /var/www
100 | $sudo mkdir site
101 | $chown -R csarven site
102 | $git clone git://github.com/csarven/Linked Data Pages.git site
103 | 
104 | /* Required libraries for Linked Data Pages */
105 | $svn checkout http://moriarty.googlecode.com/svn/trunk/ lib/moriarty
106 | $svn checkout http://paget.googlecode.com/svn/branches/2.0/ lib/paget
107 | $git clone git://github.com/semsol/arc2.git lib/arc2
108 | 
109 | /* Until some of the issues are fixed in Moriarty and Paget, we include the fixes in this package */
110 | $cp -R patches/moriarty/* lib/moriarty/
111 | $cp -R patches/paget/* lib/paget/
112 | 
113 | /* Configure paths to libraries and SPARQL endpoint URI */
114 | Either load install.php from your browser and submit the form or manually edit the directory configuration:
115 | $cp /var/www/site/index.php.sample /var/www/site/index.php
116 | $nano /var/www/site/index.php
117 | 
118 | 
119 | /* Site configuration (see below for details) */
120 | $nano /var/www/site/config.php
121 | 
122 | /* Take note of the details. Change as you see fit. */
123 | $nano /var/www/site/.htaccess
124 | 
125 | 126 | 127 | 128 | ==== Site configuration ==== 129 | * index.php contains general site settings 130 | * config.php contains URI mappings, entity URIs, query types and templates 131 | 132 | ===== Site settings ===== 133 | The settings extend the base LDP config site settings. These values are used throughout the site, therefore make sure to configure them for your own needs. 134 | 135 |
136 | $config['site']['name']   = 'My LDP site'; /*Name of your site. Appears in page title, address etc. */
137 | $config['site']['server'] = 'site';         /* 'site' in http://site */
138 | $config['site']['path']   = '';             /* 'foo' in http://site/foo */
139 | $config['site']['theme']  = 'default';      /* 'default' in /var/www/site/theme/default */
140 | $config['site']['logo']   = 'logo.png';  /* logo.png in /var/www/site/theme/default/images/logo.jpg */
141 | 
142 | 143 | ===== Server URI mapping ===== 144 | This setting is used to map server names that are found in the dataset to the ones that are requested by the client. For example, if the user requests http://site/resource/Montreal, you would look for http://dbpedia.org/resource/Montreal in your dataset. 145 | 146 |
147 | $config['server']['dbpedia.org'] = 'site';  /* URI maps e.g., http://dbpedia.org/resource/Montreal to http://site/resource/Montreal */
148 | 
149 | 150 | There is a default mapping of: 151 |
152 | $config['server']['site'] = 'site';
153 | 
154 | 155 | so, you don't have to repeat that. But you can add other ones as mentioned earlier. 156 | 157 | ===== Entity URIs, query types and templates ===== 158 | We use entity ids to determine how to respond back to the request. The entity set id is determined from the requested URI. The example below uses 'site_foo' as the entity set id. The entity set id is also reused in HTML templates < body = "site_foo" >. The path is assigned to '/foo', if there is a request for http://site/foo. The query is also assigned here. For the time being, we only set a query name here. We can set a custom SPARQL query to $config['sparql_query']['site_foo'] and use the index name 'site_foo' at $config['entity']['site_foo']['query'] = 'site_foo'; 159 | 160 |
161 | /* SPARQL query to use for this entity e.g., $config['sparql_query']['cso_home'] */
162 | $config['sparql_query']['site_foo'] = "
163 | DESCRIBE 
164 | "
165 | 
166 | /* URI path for this entity */
167 | $config['entity']['site_foo']['path']     = "/foo";
168 | /* SPARQL query to use for this entity e.g., $config['sparql_query']['site_foo'] */
169 | $config['entity']['site_foo']['query']    = 'site_foo';
170 | /* HTML template to use for this entity */
171 | $config['entity']['site_foo']['template'] = 'page.foo.html';
172 | 
173 | 174 | 175 | ===== PHP Classes ===== 176 | Classes are located in '/var/www/site/classes/': 177 | 178 | class LDP_Config 179 | * Main configuration 180 | * Contains base methods for working with the configuration values 181 | * Allows entity set configuration; entities are identified by id, and contain sub properties for URI path, querying, and the templating to be triggered. 182 | 183 | getCurrentRequest() 184 | * Figures out the URI pattern. 185 | 186 | getEntityId() 187 | * Returns the entity id from the current request. 188 | 189 | getEntityQuery() 190 | * Returns the query type based on the current request. 191 | 192 | getEntityPaths() 193 | * Returns all of the entity paths that was set in site (index.php) and LDP configuration (LDP_config.php). 194 | 195 | getRemoteURIFromCurrentRequest() 196 | * Transforms the current request URI to the URI found in the RDF store. 197 | 198 | getConfig() 199 | * Returns all of the configuration values that was set in site (index.php) and LDP configuration (LDP_config.php). 200 | 201 | getPrefix() 202 | * Returns a namespace of prefix or the whole LDP and SITE prefix set 203 | 204 | getURI() 205 | * Given QName, returns an URI from configured prefix list 206 | 207 | object() 208 | * Returns the object value for a property object pair based on property QName input 209 | 210 | 211 | 212 | 213 | 214 | class LDP_UriSpace extends PAGET_StoreBackedUriSpace 215 | * Primary class that figures out the request and prepares a response 216 | 217 | 218 | class LDP_ResourceDescription extends PAGET_ResourceDescription 219 | * Figures out how to respond; prepares a SPARQL query to be used, reads the triples from the response, maps the URIs, assigns a template to be used for the HTML response 220 | 221 | 222 | class LDP_StoreDescribeGenerator extends PAGET_StoreDescribeGenerator 223 | * Figures out how to add the RDF triples to the index from the SPARQL query result. 224 | 225 | 226 | class LDP_Template extends PAGET_Template 227 | * LDP specific templates 228 | ** function getTriples($subjects = null, $properties = null, $objects = null, $index = null) 229 | ** function renderProperty() 230 | 231 | class LDP_TableDataWidget extends PAGET_TableDataWidget 232 | * Outputs a layout for tables 233 | 234 | 235 | class LDP_Store extends Store 236 | * Overrides Moriarty's default store URI 237 | 238 | 239 | class LDP_SparqlServiceBase extends SparqlServiceBase 240 | * Controls which SPARQL query to use 241 | 242 | 243 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | == TODO == 2 | * Create query tests for better response handling 3 | * Serve static pages 4 | * Page title (non-URI) for non-DESCRIBE query 5 | * Percentile indicators for some columns (e.g., population) in tabular data 6 | * Maps for geo resources 7 | * Exclude some of the triples that are auto-included by Paget 8 | * Abstract a method to handle data with n-dimensions 9 | * Have a way to handle page cases (e.g., about) where there is no need 10 | to take a trip to the SPARQL endpoint 11 | -------------------------------------------------------------------------------- /classes/LDP.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | * @category Action 19 | * @package LDP 20 | * @author Sarven Capadisli 21 | * @copyright 2010 Digital Enterprise Research Institute 22 | * @license http://www.fsf.org/licensing/licenses/gpl-3.0.html GNU General Public License version 3.0 23 | * @link http://deri.org/ 24 | */ 25 | 26 | require_once PAGET_DIR . 'paget_urispace.class.php'; 27 | require_once PAGET_DIR . 'paget_simplepropertylabeller.class.php'; 28 | require_once PAGET_DIR . 'paget_storedescribegenerator.class.php'; 29 | require_once PAGET_DIR . 'paget_storebackedurispace.class.php'; 30 | 31 | /** 32 | * TODO: 33 | * Move these classes into their own files. 34 | */ 35 | 36 | 37 | /** 38 | * Primary class that figures out the request and prepares a response 39 | */ 40 | class LDP_UriSpace extends PAGET_StoreBackedUriSpace 41 | { 42 | var $sC; 43 | 44 | function __construct($sC) 45 | { 46 | $this->sC = $sC; 47 | 48 | parent::__construct(STORE_URI); 49 | } 50 | 51 | 52 | function get_resource($request) 53 | { 54 | $request_uri = $request->uri; 55 | 56 | if (preg_match('~^(.+)\.(html|rdf|json|ttl|csv)$~', $request->full_path, $m)) { 57 | $base_path = $m[1]; 58 | $type = $m[2]; 59 | 60 | if ($base_path == $this->_base_path.'~search') { 61 | $query = isset($request->data["query"]) ? $request->data["query"] : ''; 62 | $offset = isset($request->data["offset"]) ? $request->data["offset"] : '0'; 63 | 64 | $desc = new PAGET_StoreSearch($request_uri, $type, $this->_store_uri, $query, 30, $offset); 65 | $desc->set_template($this->_description_template); 66 | 67 | return $desc; 68 | } else if ($base_path == $this->_base_path. '~browse') { 69 | if (! defined('AUTH_USER') && ! defined('AUTH_PWD')) { 70 | return null; 71 | } 72 | 73 | $token = isset($request->data["token"]) ? $request->data["token"] : null; 74 | 75 | $desc = new PAGET_StoreOAI($request_uri, $type, $this->_store_uri, $token); 76 | $desc->set_template($this->_description_template); 77 | 78 | return $desc; 79 | } else { 80 | $resource_uri = $this->sC->getRemoteURIFromCurrentRequest(); 81 | 82 | if (isset($this->_static_data[$resource_uri])) { 83 | $desc = new PAGET_FileBackedResourceDescription($request_uri, $resource_uri, $type, $this->_static_data[$resource_uri], 'rdfxml'); 84 | } else { 85 | $desc = new LDP_ResourceDescription($request_uri, $resource_uri, $type, $this->_store_uri, $this->sC); 86 | } 87 | 88 | $desc->set_template($this->_description_template); 89 | 90 | foreach ($this->_ns as $short_name => $uri) { 91 | $desc->set_namespace_mapping($short_name, $uri); 92 | } 93 | 94 | if ($desc->is_valid()) { 95 | return $desc; 96 | } 97 | } 98 | } else { 99 | return new PAGET_AbstractResource($request_uri); 100 | } 101 | 102 | return null; 103 | } 104 | 105 | } 106 | 107 | 108 | 109 | /** 110 | * Figures out how to respond; prepares a SPARQL query to be used, 111 | * reads the triples from the response, maps the URIs, 112 | * assigns a template to be used for the HTML response 113 | */ 114 | class LDP_ResourceDescription extends PAGET_ResourceDescription 115 | { 116 | var $sC; 117 | 118 | function __construct($rt, $re, $te, $su, $sC) 119 | { 120 | $this->sC = $sC; 121 | parent::__construct($rt, $re, $te, $su); 122 | } 123 | 124 | 125 | /* 126 | * Seeds the triples in the description using provided Store URI and 127 | * bounded description type. 128 | * 129 | * @return array 130 | */ 131 | function get_generators() 132 | { 133 | $eQ = $this->sC->getEntityQuery(); 134 | 135 | return array(new LDP_StoreDescribeGenerator(STORE_URI, $eQ, $this->sC)); 136 | } 137 | 138 | 139 | 140 | /** 141 | * Prepares the template to be used based on entity configuration 142 | */ 143 | function get_html(&$urispace, &$request) 144 | { 145 | $tmpl = $this->_template; 146 | if ( null == $tmpl ) { 147 | $tmpl = $urispace->get_template($request); 148 | } 149 | if ( null == $tmpl ) { 150 | $c = $this->sC->getConfig(); 151 | 152 | $entitySetId = $this->sC->getEntitySetId(); 153 | 154 | $tmpl = SITE_DIR . 'templates/' . $c['entity'][$entitySetId]['template']; 155 | } 156 | 157 | $template = new SITE_Template($tmpl, $this, $urispace, $request, $this->sC); 158 | 159 | return $template->execute(); 160 | } 161 | 162 | 163 | /** 164 | * Takes the request URI and maps it to a local equivalent (in RDF store) 165 | * If there is no local equivalent (e.g., includes the bnode case), 166 | * it will return the same string. 167 | * 168 | * @return string 169 | */ 170 | function map_uri($uri) 171 | { 172 | if (isset($_SERVER["HTTP_HOST"])) { 173 | if (preg_match('#http://([^/]+)/#i', $uri, $m)) { 174 | $c = $this->sC->getConfig(); 175 | 176 | if ($_SERVER["HTTP_HOST"] != $m[1] && isset($c['server'][$m[1]])) { 177 | $r = str_replace($m[1], $c['server'][$m[1]], $uri); 178 | return $r; 179 | } else { 180 | return $uri; 181 | } 182 | } 183 | } 184 | 185 | return $uri; 186 | } 187 | 188 | 189 | /** 190 | * Initiates functions to get the requested resource results 191 | * into a local index. 192 | * 193 | * @return nothing 194 | */ 195 | function read_triples() { 196 | $resources_mapped = $resources = $this->get_resources(); 197 | 198 | foreach ($resources_mapped as $key => $value) { 199 | $resources_mapped[$key] = $this->map_uri($value); 200 | } 201 | 202 | if (count($resources) > 0) { 203 | $this->_primary_resource = $resources_mapped[0]; 204 | } 205 | 206 | $this->add_representation_triples(); 207 | 208 | $this->_is_valid = false; 209 | 210 | foreach ($resources as $key => $value) { 211 | $this->add_resource_triple($this->_uri, FOAF_TOPIC, $resources_mapped[$key]); 212 | 213 | $generators = $this->get_generators(); 214 | foreach ($generators as $generator) { 215 | $generator->add_triples($resources[$key], $this); 216 | } 217 | 218 | //XXX: Is this hackish? 219 | if (array_key_exists($resources_mapped[$key], $this->get_index()) 220 | || array_key_exists($resources_mapped[$key], $this->get_inverse_index())) { 221 | $this->_is_valid = true; 222 | } 223 | } 224 | 225 | # $augmentors = $this->get_augmentors(); 226 | # foreach ($augmentors as $augmentor) { 227 | # $augmentor->process($this); 228 | # } 229 | } 230 | } 231 | 232 | 233 | 234 | /** 235 | * Figures out how to add the RDF triples to the index from the SPARQL query result. 236 | * 237 | */ 238 | class LDP_StoreDescribeGenerator extends PAGET_StoreDescribeGenerator 239 | { 240 | var $sC; 241 | 242 | function __construct($su, $eQ, $sC) 243 | { 244 | $this->sC = $sC; 245 | parent::__construct($su, $eQ); 246 | } 247 | 248 | function add_triples($resource_uri, &$desc) 249 | { 250 | $store = new LDP_Store($this->_store_uri, $this->sC); 251 | 252 | // $type = $desc->_type; 253 | $type = '*/*'; 254 | 255 | $response = $store->describe($resource_uri, $this->_type, $type); 256 | 257 | if ($response->is_success()) { 258 | //XXX: This is sort of another place to map URIs. Revisit after paget issues 259 | 260 | $desc->add_rdf($response->body); 261 | } 262 | } 263 | } 264 | 265 | 266 | 267 | class LDP_SimplePropertyLabeller extends PAGET_SimplePropertyLabeller 268 | { 269 | function __construct() 270 | { 271 | parent::__construct(); 272 | } 273 | } 274 | 275 | 276 | /** 277 | * Used for LDP specific templates. 278 | * TODO: render() 279 | * 280 | */ 281 | class LDP_Template extends PAGET_Template 282 | { 283 | var $sC; 284 | 285 | function __construct($template_filename, $desc, $urispace, $request, $sC) 286 | { 287 | $this->sC = $sC; 288 | 289 | parent::__construct($template_filename, $desc, $urispace, $request); 290 | 291 | $this->table_widget = new LDP_TableDataWidget($this->desc, $this, $urispace); 292 | } 293 | 294 | 295 | /** 296 | * Finds triples in an index. If an index (a multi-dimensional array) is not provided, 297 | * it will use the internal query result. Null acts as a wildcard. 298 | * e.g., $subjects = array('a', 'b'); $properties = null; $objects = ('c', 'd'); 299 | * would try to find these triples: 300 | * a, *, c 301 | * a, *, d 302 | * b, *, c 303 | * b, *, d 304 | * 305 | * @return array 306 | */ 307 | function getTriples($subjects = null, $properties = null, $objects = null, $index = null) 308 | { 309 | $triples = $t = array(); 310 | 311 | if (is_null($index)) { 312 | $index = $this->desc->get_index(); 313 | } 314 | 315 | if (!is_null($subjects) && !is_array($subjects)) { 316 | $subjects = array($subjects); 317 | } 318 | if (!is_null($properties) && !is_array($properties)) { 319 | $properties = array($properties); 320 | } 321 | if (!is_null($objects) && !is_array($objects)) { 322 | $objects = array($objects); 323 | } 324 | 325 | foreach($index as $s => $po) { 326 | $s_candidate = null; 327 | 328 | /** 329 | * These ifs act as a wildcard or a match. Otherwise we skip 330 | */ 331 | if (empty($subjects) || in_array($s, $subjects)) { 332 | $s_candidate = $s; 333 | 334 | foreach($po as $p => $o) { 335 | $p_candidate = null; 336 | 337 | if (empty($properties) || in_array($p, $properties)) { 338 | $p_candidate = $p; 339 | 340 | foreach ($o as $o_key) { 341 | $o_candidate = null; 342 | 343 | if (empty($objects) || in_array($o_key['value'], $objects)) { 344 | $o_candidate = $o; 345 | 346 | $triples[$s_candidate][$p_candidate] = $o_candidate; 347 | } 348 | } 349 | } 350 | } 351 | } 352 | } 353 | 354 | //XXX: Is there simpler way to do this natural sort for mutli-dimensional array? 355 | $triples_keys = array_keys($triples); 356 | natsort($triples_keys); 357 | foreach($triples_keys as $key => $value) { 358 | $t[$value] = $triples[$value]; 359 | } 360 | 361 | return $t; 362 | } 363 | 364 | 365 | function getTriplesOfType ($object = null) 366 | { 367 | $c = $this->sC->getConfig(); 368 | 369 | //TODO: 370 | if (!is_null($object)) { 371 | } 372 | 373 | $subjects = null; 374 | $properties = $c['prefixes']['rdf'].'type'; 375 | $objects = array($object); 376 | $triples = $this->getTriples($subjects, $properties, $objects); 377 | 378 | $subjects = array_keys($triples); 379 | $properties = $c['prefixes']['skos'].'prefLabel'; 380 | $objects = null; 381 | $triples_propertyLabels = $this->getTriples($subjects, $properties, $objects); 382 | 383 | $triples = array_merge_recursive($triples, $triples_propertyLabels); 384 | 385 | return $triples; 386 | } 387 | 388 | 389 | /** 390 | * Returns a list of subject resources in given index of triples. 391 | * If no index given, returns index from query result. 392 | */ 393 | 394 | function getSubjects($i = null) 395 | { 396 | if (!is_null($i)) { 397 | return array_keys($i); 398 | } 399 | 400 | return $this->desc->get_subjects(); 401 | } 402 | 403 | 404 | function getProperties($i = null) 405 | { 406 | $properties = array(); 407 | 408 | if (is_null($i)) { 409 | $i = $this->desc->get_index(); 410 | } 411 | 412 | foreach($i as $s => $po) { 413 | $properties[] = array_keys($po); 414 | } 415 | 416 | return $properties; 417 | } 418 | 419 | 420 | function getObjects($i = null) 421 | { 422 | $objects = array(); 423 | 424 | if (is_null($i)) { 425 | $i = $this->desc->get_index(); 426 | } 427 | 428 | foreach($i as $s => $po) { 429 | foreach($po as $p => $o) { 430 | foreach($o as $o_key) { 431 | $objects[] = $o_key['value']; 432 | } 433 | } 434 | } 435 | 436 | return $objects; 437 | } 438 | 439 | 440 | /** 441 | * Returns object value given subject and property. 442 | * This method returns the first matching object from triple. 443 | * 444 | * @subject paramater value is a full URI 445 | * @property paramater is a qname 446 | * 447 | * @return string 448 | */ 449 | function getValue($subject, $property) 450 | { 451 | $c = $this->sC->getConfig(); 452 | $triples = array(); 453 | 454 | if (preg_match("#(.*):(.*)#", $property, $m)) { 455 | $prefixName = $c['prefixes'][$m[1]]; 456 | if (isset($prefixName)) { 457 | $triples = $this->getTriples($subject, $prefixName.$m[2]); 458 | 459 | if (count($triples) > 0) { 460 | return $triples[$subject][$prefixName.$m[2]][0]['value']; 461 | } 462 | } 463 | } 464 | 465 | return; 466 | } 467 | 468 | 469 | function render($resource_info = null, $inline = FALSE, $brief = FALSE) { 470 | if (is_null($resource_info)) { 471 | $widget = $this->table_widget; 472 | return $widget->render(); 473 | } 474 | else if (is_array(current($resource_info))) { 475 | $widget = $this->table_widget; 476 | return $widget->render($resource_info); 477 | } 478 | 479 | if ($resource_info['type'] == 'bnode' || $resource_info['type'] == 'uri') { 480 | $widget = $this->table_widget; 481 | } 482 | else { 483 | $widget = $this->literal_widget; 484 | } 485 | return $widget->render($resource_info, $inline, $brief); 486 | } 487 | 488 | 489 | 490 | function renderClear() 491 | { 492 | $this->table_widget->ignore_properties(array()); 493 | $this->excludes = array(); 494 | } 495 | 496 | 497 | /** 498 | * A generic method to render properties. 499 | * XXX: Status: testing. 500 | * TODO: Output at least 501 | * Ideally we want to render what the store knows about this property, and 502 | * make it more human friendly so the user can understand its purpose and 503 | * see example relationships (where it is used). 504 | */ 505 | function renderProperty() 506 | { 507 | $subjects = null; 508 | $properties = $this->desc->get_primary_resource_uri(); 509 | $objects = null; 510 | 511 | $triples = $this->getTriples($subjects, $properties, $objects); 512 | 513 | $r = ''; 514 | $r .= "\n".'
'; 515 | $r .= "\n".'
Some subjects with this property
'; 516 | $r .= "\n".'
'; 517 | $r .= "\n".'
    '; 518 | foreach($triples as $s => $po) { 519 | //TODO: Use rdfs:label if available. 520 | $r .= "\n".'
  • '.$s.'
  • '; 521 | } 522 | $r .= "\n".'
'; 523 | $r .= "\n".'
'; 524 | $r .= "\n".'
'; 525 | return $r; 526 | } 527 | 528 | 529 | /** 530 | * A generic output for resources that is an instance of a Class 531 | */ 532 | function renderClass() 533 | { 534 | $sC = $this->sC; 535 | $c = $this->sC->getConfig(); 536 | 537 | $resource_uri = $this->desc->get_primary_resource_uri(); 538 | $r = ''; 539 | 540 | //XXX: We first output what we know about the Class itself 541 | $subjects = $resource_uri; 542 | $properties = null; 543 | $objects = null; 544 | 545 | $triples = $this->getTriples($subjects, $properties, $objects); 546 | 547 | 548 | //TODO: Make this a bit more generic. Perhaps use LDP_TableDataWidget::format_table ? 549 | $r .= "\n".'
'; 550 | foreach($triples as $s => $po) { 551 | if ($sC->hasProperty('rdfs:label', $po)) { 552 | $r .= "\n".'
About
'; 553 | $r .= "\n".'
'.$po[$c['prefixes']['rdfs'].'label'][0]['value'].'
'; 554 | } 555 | 556 | if ($sC->hasProperty('rdfs:comment', $po)) { 557 | $r .= "\n".'
Comment
'; 558 | $r .= "\n".'
'.$po[$c['prefixes']['rdfs'].'comment'][0]['value'].'
'; 559 | } 560 | 561 | if ($sC->hasProperty('rdfs:subClassOf', $po)) { 562 | $r .= "\n".'
Semantics
'; 563 | $r .= "\n".'
Being a member of this class implies also being a member of '.$this->term_widget->link_uri($sC->object('rdfs:subClassOf', $po)).'
'; 564 | } 565 | } 566 | $r .= "\n".'
'; 567 | 568 | //XXX: We now output a list of resources that is a type of this Class 569 | $subjects = $this->desc->get_subjects_where_resource($c['prefixes']['rdf'].'type', $resource_uri); 570 | $properties = null; 571 | $objects = null; 572 | 573 | $triples = $this->getTriples($subjects, $properties, $objects); 574 | 575 | $r .= "\n".'
'; 576 | $r .= "\n".'
Things that are of this type
'; 577 | $r .= "\n".'
'; 578 | $r .= "\n".'
    '; 579 | foreach($triples as $s => $po) { 580 | //XXX: If there is no label, we should output the URI 581 | $prefLabel = ''; 582 | if ($sC->hasProperty('skos:prefLabel', $po)) { 583 | $prefLabel = $sC->object('skos:prefLabel', $po); 584 | } 585 | $r .= "\n".'
  • '.$prefLabel.'
  • '; 586 | } 587 | $r .= "\n".'
'; 588 | $r .= "\n".'
'; 589 | $r .= "\n".'
'; 590 | 591 | return $r; 592 | } 593 | 594 | 595 | /** 596 | * This method can be used if templates wants to use XSLT for RDF/XML. 597 | */ 598 | function indexToRDFXML() 599 | { 600 | return $this->desc->to_rdfxml(); 601 | } 602 | } 603 | 604 | 605 | 606 | /** 607 | * LDP's lean table for basic key value pair output 608 | * 609 | */ 610 | class LDP_TableDataWidget extends PAGET_TableDataWidget 611 | { 612 | function render($resource_info = null, $inline = FALSE, $brief = FALSE) { 613 | if ($brief) return $this->render_brief($resource_info, $inline); 614 | 615 | $index = $this->desc->get_index(); 616 | 617 | if (is_null($resource_info)) { 618 | $resource_uris = array_keys($index); 619 | } 620 | else { 621 | if (isset($resource_info['value'])) { 622 | $resource_uris = array($resource_info['value']); 623 | } 624 | else { 625 | $index = $resource_info; /* Works with given triples index instead */ 626 | $resource_uris = array_keys($resource_info); 627 | } 628 | } 629 | 630 | $r = ''; 631 | foreach($resource_uris as $resource_uri) { 632 | if (array_key_exists($resource_uri, $index)) { 633 | $used_properties = array_keys($index[$resource_uri]); 634 | $properties = array_diff(array_merge($this->property_order, array_diff($used_properties, $this->property_order)), $this->ignore_properties); 635 | $r .= $this->format_property_value_list($resource_uri, $properties); 636 | } 637 | } 638 | 639 | return $r; 640 | } 641 | 642 | 643 | function format_property_value_list($resource_uri, $properties) { 644 | $data = array(); 645 | foreach ($properties as $property) { 646 | if (! $this->template->is_excluded($resource_uri, $property) ) { 647 | $property_values = $this->desc->get_subject_property_values($resource_uri, $property); 648 | if ( count($property_values) > 0) { 649 | if ( count($property_values) == 1) { 650 | $label = ucfirst($this->desc->get_first_literal($property, RDFS_LABEL)); 651 | } 652 | else { 653 | $label = ucfirst($this->desc->get_first_literal($property, 'http://purl.org/net/vocab/2004/03/label#plural')); 654 | } 655 | 656 | $formatted_label = $this->format_property_label($property, $label); 657 | $formatted_value = $this->format_property_values($property, $property_values); 658 | 659 | $data[$resource_uri][$formatted_label] = $formatted_value; 660 | $this->template->exclude($resource_uri, $property); 661 | } 662 | } 663 | } 664 | return $this->format_table($data); 665 | } 666 | 667 | 668 | function format_table(&$data) 669 | { 670 | $r = ''; 671 | if (count($data) > 0) { 672 | foreach ($data as $s => $po) { 673 | $r .= "\n".''; 674 | $r .= "\n".''; 675 | $r .= "\n".''; 676 | $r .= "\n".''; 677 | foreach ($po as $p => $o) { 678 | $r .= "\n".''; 679 | } 680 | $r .= "\n".''; 681 | $r .= "\n".'
About '.''.$this->desc->get_label($s).'
PropertyValue
' . $p . '' . $o . '
'; 682 | } 683 | } 684 | return $r; 685 | } 686 | } 687 | 688 | 689 | /** 690 | * Overrides Moriarty's default store URI 691 | * 692 | */ 693 | class LDP_Store extends Store 694 | { 695 | var $sC; 696 | 697 | function __construct($su, $sC) 698 | { 699 | $this->sC = $sC; 700 | parent::__construct($su); 701 | } 702 | 703 | 704 | /** 705 | * Obtain a reference to this store's sparql service 706 | * 707 | * @return SparqlService 708 | */ 709 | function get_sparql_service() 710 | { 711 | return new LDP_SparqlServiceBase($this->uri, $this->credentials, $this->request_factory, $this->sC); 712 | } 713 | } 714 | 715 | 716 | 717 | /** 718 | * Controls which SPARQL query to use 719 | * TODO: More query types 720 | */ 721 | class LDP_SparqlServiceBase extends SparqlServiceBase 722 | { 723 | var $sC; 724 | 725 | function __construct($tu, $tc, $trq, $sC) 726 | { 727 | $this->sC = $sC; 728 | parent::__construct($tu, $tc, $trq); 729 | } 730 | 731 | 732 | function describe($uri, $type = 'cbd', $output = OUTPUT_TYPE_RDF) 733 | { 734 | $c = $this->sC->getConfig(); 735 | $prefixes = $this->sC->getPrefix(); 736 | $SPARQL_prefixes = ''; 737 | 738 | // if (!empty($c['sparql_query'][$type])) { 739 | foreach($prefixes as $prefixName => $namespace) { 740 | $SPARQL_prefixes .= "PREFIX $prefixName: <$namespace>\n"; 741 | } 742 | 743 | $query = preg_replace("##", "<$uri>", $SPARQL_prefixes.$c['sparql_query'][$type]); 744 | 745 | return $this->graph($query, $output); 746 | // } 747 | // else { 748 | // TODO 749 | // } 750 | } 751 | 752 | } 753 | 754 | 755 | 756 | /** 757 | * Main utility class for LDP 758 | */ 759 | class LDP extends LDP_UriSpace 760 | { 761 | var $sC; 762 | var $config = array(); 763 | var $requestURI = ''; 764 | var $currentRequest = array(); 765 | 766 | function __construct($sC) 767 | { 768 | $this->sC = $sC; 769 | $this->config = $sC->config; 770 | 771 | $this->config['site']['base'] = 'http://'.$this->config['site']['server'].$this->config['site']['path']; 772 | 773 | $this->config['server'][$this->config['site']['server']] = $this->config['site']['server']; 774 | 775 | /** 776 | * TODO: if ($_SERVER["QUERY_STRING"]) { '?' . $_SERVER["QUERY_STRING"]) : '' 777 | */ 778 | $this->requestURI = "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']; 779 | 780 | $this->getCurrentRequest(); /* Sets configuration for current request */ 781 | 782 | parent::__construct($this); 783 | } 784 | 785 | 786 | /** 787 | * Figure out what to give to the client 788 | */ 789 | function getCurrentRequest() 790 | { 791 | $ePs = implode("|", array_reverse($this->getEntityPaths())); 792 | 793 | $search = '#^(http://)('.$_SERVER['SERVER_NAME'].')('.$this->config['site']['path'].')('.$ePs.')?(.+)?\.(html|rdf|json|ttl)$#i'; 794 | 795 | if (preg_match($search, $this->requestURI, $matches)) { 796 | $this->currentRequest = $matches; 797 | } 798 | else { 799 | /* XXX: This might not be necessary */ 800 | } 801 | 802 | return $this->currentRequest; 803 | } 804 | 805 | 806 | /** 807 | * Returns the entity id from the current request. 808 | */ 809 | function getEntitySetId() 810 | { 811 | /** 812 | * We check whether it is recognized or unrecognized. 813 | * If recognized, we can most likely serve it. 814 | * If unrecognized, we might be able to serve it depending on what the 815 | * store responds with. 816 | */ 817 | 818 | if ($this->currentRequest[4] != '/' || empty($this->currentRequest[5])) { 819 | return $this->getKeyFromValue($this->currentRequest[4], $this->config['entity']); 820 | } 821 | 822 | return 'default'; 823 | } 824 | 825 | 826 | /** 827 | * Returns the query type based on the current request. 828 | */ 829 | function getEntityQuery() 830 | { 831 | $entitySetId = $this->getEntitySetId(); 832 | 833 | return $this->config['entity'][$entitySetId]['query']; 834 | } 835 | 836 | 837 | /** 838 | * Returns all of the entity paths that was set in site and LDP configuration 839 | */ 840 | function getEntityPaths() 841 | { 842 | $c = $this->getConfig(); 843 | $entityPaths = array(); 844 | 845 | foreach ($c['entity'] as $key => $value) { 846 | $entityPaths[] = $c['entity'][$key]['path']; 847 | } 848 | 849 | asort($entityPaths); 850 | 851 | return $entityPaths; 852 | } 853 | 854 | 855 | /** 856 | * Transforms the current request URI to the URI found in the RDF store. 857 | */ 858 | function getRemoteURIFromCurrentRequest() 859 | { 860 | $cR = $this->currentRequest; 861 | 862 | return $cR[1].array_search($cR[2], $this->config['server']).$cR[3].$cR[4].$cR[5]; 863 | } 864 | 865 | 866 | /** 867 | * Returns all of the configuration values that was set in site and LDP 868 | */ 869 | function getConfig() 870 | { 871 | return $this->config; 872 | } 873 | 874 | 875 | /** 876 | * Returns a namespace of prefix or the whole LDP and SITE prefix set 877 | */ 878 | function getPrefix($prefix = null) 879 | { 880 | if (is_null($prefix)) { 881 | return $this->config['prefixes']; 882 | } 883 | else { 884 | return $this->config['prefixes'][$prefix]; 885 | } 886 | } 887 | 888 | 889 | /** 890 | * Given QName, returns an URI from configured prefix list 891 | * 892 | * @return string 893 | */ 894 | function getURI($qname) 895 | { 896 | $c = $this->getConfig(); 897 | 898 | if(preg_match("#(.*):(.*)#", $qname, $m)) { 899 | $prefixName = $c['prefixes'][$m[1]]; 900 | if(isset($prefixName)) { 901 | return $prefixName.$m[2]; 902 | } 903 | } 904 | 905 | return; 906 | } 907 | 908 | 909 | /** 910 | * Returns the object value for a property object pair 911 | * based on property QName input 912 | * 913 | * @return string 914 | */ 915 | function object($qname, $po) 916 | { 917 | $c = $this->sC->getConfig(); 918 | 919 | if(preg_match("#(.*):(.*)#", $qname, $m)) { 920 | /** 921 | * $m[1] is prefixName, $m[2] is name 922 | */ 923 | return $po[$c['prefixes'][$m[1]].$m[2]][0]['value']; 924 | } 925 | 926 | return; 927 | } 928 | 929 | 930 | /** 931 | * Checks if a property object pair contains a property based on QName input 932 | * 933 | * @return boolean 934 | */ 935 | function hasProperty($qname, $po) 936 | { 937 | $c = $this->sC->getConfig(); 938 | 939 | if(preg_match("#(.*):(.*)#", $qname, $m)) { 940 | if(isset($po[$c['prefixes'][$m[1]].$m[2]])) { 941 | return true; 942 | } 943 | } 944 | 945 | return false; 946 | } 947 | 948 | 949 | /** 950 | * Given URI, returns QName as an HTML anchor 951 | * 952 | * @return string 953 | */ 954 | function getQName($uri) 955 | { 956 | //TODO: Need to access Paget's objects from here 957 | // return $this->term_widget->link_uri($uri); 958 | } 959 | 960 | 961 | /** 962 | * This would return the first match 963 | * 964 | * @return string 965 | */ 966 | function getKeyFromValue($needle, $a) 967 | { 968 | foreach ($a as $key => $subArray) { 969 | foreach ($subArray as $subKey => $value) { 970 | if ($value == $needle) { 971 | return $key; 972 | } 973 | } 974 | } 975 | 976 | return 'default'; 977 | } 978 | } 979 | -------------------------------------------------------------------------------- /classes/LDP_Config.php: -------------------------------------------------------------------------------- 1 | . 17 | 18 | * @category Config 19 | * @package LDP 20 | * @author Sarven Capadisli 21 | * @copyright 2010 Digital Enterprise Research Institute 22 | * @license http://www.fsf.org/licensing/licenses/gpl-3.0.html GNU General Public License version 3.0 23 | * @link http://deri.org/ 24 | */ 25 | 26 | 27 | class LDP_Config 28 | { 29 | var $config = array(); 30 | 31 | function __construct() 32 | { 33 | require_once SITE_DIR . 'config.php'; 34 | 35 | $this->config = $config; 36 | } 37 | } 38 | 39 | ?> 40 | -------------------------------------------------------------------------------- /classes/SITE_Template.php: -------------------------------------------------------------------------------- 1 | sC = $sC; 14 | parent::__construct($template_filename, $desc, $urispace, $request, $sC); 15 | } 16 | //XXX: End of DO NOT MODIFY 17 | } 18 | ?> 19 | -------------------------------------------------------------------------------- /config.php: -------------------------------------------------------------------------------- 1 | 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 14 | 'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#', 15 | 'xsd' => 'http://www.w3.org/2001/XMLSchema#', 16 | 'skos' => 'http://www.w3.org/2004/02/skos/core#', 17 | 'foaf' => 'http://xmlns.com/foaf/0.1/', 18 | 'dcterms' => 'http://purl.org/dc/terms/' 19 | ); 20 | 21 | /** 22 | * SPARQL Queries 23 | */ 24 | /* Empty query (temporary) */ 25 | $config['sparql_query']['empty'] = ''; 26 | 27 | /** 28 | * Default query is DESCRIBE 29 | * '' value is auto-assigned from current request URI 30 | */ 31 | $config['sparql_query']['default'] = " 32 | DESCRIBE 33 | "; 34 | /** 35 | * Entity Set 36 | */ 37 | /* URI path for this entity */ 38 | $config['entity']['default']['path'] = ''; 39 | /* SPARQL query to use for this entity e.g., $config['sparql_query']['default'] */ 40 | $config['entity']['default']['query'] = 'default'; 41 | /* HTML template to use for this entity */ 42 | $config['entity']['default']['template'] = 'page.default.html'; 43 | 44 | 45 | $config['sparql_query']['site_home'] = ""; 46 | $config['entity']['site_home']['path'] = "/"; 47 | $config['entity']['site_home']['query'] = 'site_home'; 48 | $config['entity']['site_home']['template'] = 'page.home.html'; 49 | 50 | $config['entity']['site_about']['path'] = "/about"; 51 | $config['entity']['site_about']['query'] = 'empty'; 52 | $config['entity']['site_about']['template'] = 'page.about.html'; 53 | 54 | ?> 55 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csarven/linked-data-pages/24c33792a0101ce8469de01db6f861f7b0b07802/favicon.ico -------------------------------------------------------------------------------- /index.php.sample: -------------------------------------------------------------------------------- 1 | 10 | * @copyright 2010 Digital Enterprise Research Institute 11 | * @license http://www.fsf.org/licensing/licenses/gpl-3.0.html GNU General Public License version 3.0 12 | * @link http://deri.org/ 13 | */ 14 | 15 | define('SITE_DIR', '/var/www/site/'); /* Site directory */ 16 | define('LDP_DIR', '/var/www/site/'); /* This package's directory */ 17 | define('PAGET_DIR', '/var/www/lib/paget/'); 18 | define('MORIARTY_DIR', '/var/www/lib/moriarty/'); 19 | define('MORIARTY_ARC_DIR', '/var/www/lib/arc2/'); 20 | 21 | define('STORE_URI', 'http://localhost:3030/dataset/query'); 22 | 23 | require_once LDP_DIR . 'classes/LDP_Config.php'; 24 | require_once LDP_DIR . 'classes/LDP.php'; 25 | require_once SITE_DIR .'classes/SITE_Template.php'; 26 | 27 | $config = new LDP_Config(); /* Grabs configuration values from this site */ 28 | $space = new LDP($config); /* Starts to bulid the request */ 29 | $space->dispatch(); /* Dispatches the requested URI */ 30 | ?> 31 | -------------------------------------------------------------------------------- /install.php: -------------------------------------------------------------------------------- 1 | fileContents['index.php'] = << 27 | * @copyright 2010 Digital Enterprise Research Institute 28 | * @license http://www.fsf.org/licensing/licenses/gpl-3.0.html GNU General Public License version 3.0 29 | * @link http://deri.org/ 30 | */ 31 | 32 | define('SITE_DIR', '{$this->post['dir_site']}'); /* Site directory */ 33 | define('LDP_DIR', '{$this->post['dir_ldp']}'); /* This package's directory */ 34 | define('PAGET_DIR', '{$this->post['dir_paget']}'); 35 | define('MORIARTY_DIR', '{$this->post['dir_moriarty']}'); 36 | define('MORIARTY_ARC_DIR', '{$this->post['dir_arc2']}'); 37 | 38 | define('STORE_URI', '{$this->post['sparql_endpoint']}'); 39 | 40 | require_once LDP_DIR . 'classes/LDP_Config.php'; 41 | require_once LDP_DIR . 'classes/LDP.php'; 42 | require_once SITE_DIR .'classes/SITE_Template.php'; 43 | 44 | \$config = new LDP_Config(); /* Grabs configuration values from this site */ 45 | \$space = new LDP(\$config); /* Starts to bulid the request */ 46 | \$space->dispatch(); /* Dispatches the requested URI */ 47 | ?> 48 | 49 | EOD; 50 | 51 | } 52 | 53 | 54 | function showPage() 55 | { 56 | echo << 58 | 61 | 62 | 63 | Install 64 | 65 | 66 |
67 |
68 |
69 |
70 |

Linked Data Pages installation

71 | {$this->handleInstall()} 72 |
73 |
74 |
75 |
76 | 77 | 78 | EOD; 79 | } 80 | 81 | 82 | function handleInstall() 83 | { 84 | //TODO: check to see if it was already installed 85 | 86 | if ($_SERVER['REQUEST_METHOD'] == 'POST') { 87 | return $this->processPost(); 88 | } else { 89 | return $this->getForm(); 90 | } 91 | } 92 | 93 | 94 | function getForm() 95 | { 96 | $formDataItems = array( 97 | 'dir_site' => ' 98 | 99 | 100 |

e.g., /var/www/site/

101 | ', 102 | 'dir_ldp' => ' 103 | 104 | 105 |

e.g., /var/www/lib/linked-data-pages/

106 | ', 107 | 'dir_paget' => ' 108 | 109 | 110 |

e.g., /var/www/lib/paget/

111 | ', 112 | 'dir_moriarty' => ' 113 | 114 | 115 |

e.g., /var/www/lib/moriarty/

116 | ', 117 | 'dir_arc2' => ' 118 | 119 | 120 |

e.g., /var/www/lib/arc2/

121 | ', 122 | 'sparql_endpoint' => ' 123 | 124 | 125 |

e.g., http://localhost:3030/dataset/query

126 | ' 127 | ); 128 | 129 | $formInstall = << 131 |
132 | Configuration 133 | 134 |
135 |

This installation process temporarily requires write access to the installation (site) directory. Please make sure to give write access to the user that's running this installation script.

136 |
137 | 138 |
139 | Directories 140 | 141 |
    142 | EOD; 143 | foreach($formDataItems as $k => $v) { 144 | $class = (isset($this->errorMessages[$k])) ? ' class="form_error"' : ''; 145 | 146 | $formInstall .= "\n\t\t\t"; 147 | $formInstall .= $formDataItems[$k]; 148 | if (isset($this->errorMessages[$k])) { 149 | $formInstall .= '

    '.$this->errorMessages[$k].'

    '; 150 | } 151 | $formInstall .= "\t\t"; 152 | } 153 | $formInstall .= << 156 |
157 | 158 | 159 |
160 | 161 | EOD; 162 | return $formInstall; 163 | } 164 | 165 | 166 | function successInstallation() 167 | { 168 | unset($_POST); 169 | 170 | $o = << 172 |
Results
173 |
174 |
    175 |
  • Installation successful!
  • 176 |
  • ... we will add more todo/tips here.
  • 177 |
178 |
179 | 180 | EOD; 181 | 182 | return $o; 183 | 184 | } 185 | 186 | function processPost() 187 | { 188 | $this->post = $_POST; 189 | 190 | unset($this->post['submit']); 191 | 192 | foreach($this->post as $key => $value) { 193 | /** 194 | * TODO: This is basic sanitization, we can do more. 195 | */ 196 | $this->post[$key] = trim($value); 197 | 198 | if (!empty($this->post[$key])) { 199 | $this->post[$key] = (substr($this->post[$key], -1) != '/') ? $this->post[$key].'/' : $this->post[$key]; 200 | 201 | if (!$this->checkRequirements($key)) { 202 | $this->errorMessages[$key] = $this->getErrorMessage('nowrite', $key); 203 | } 204 | } 205 | else { 206 | $this->errorMessages[$key] = $this->getErrorMessage('empty', $key); 207 | } 208 | } 209 | 210 | if (count($this->errorMessages) > 0) { 211 | return $this->getForm(); 212 | } 213 | else { 214 | $this->copyFiles(); 215 | unlink(__FILE__); 216 | return $this->successInstallation(); 217 | } 218 | } 219 | 220 | 221 | /** 222 | * Write permissions to a directory. 223 | */ 224 | function checkRequirements($key) 225 | { 226 | clearstatcache(); 227 | 228 | $directory = $this->post[$key]; 229 | 230 | $this->configureFileContents(); 231 | 232 | switch($key) { 233 | case 'dir_site': 234 | if (is_writable($directory)) { 235 | $this->writeToFile($directory.'index.php', $this->fileContents['index.php']); 236 | /** 237 | * TODO: $this->writeToFile($directory.'config.php', $this->fileContents['config.php']); 238 | */ 239 | return true; 240 | } 241 | else { 242 | return false; 243 | } 244 | break; 245 | 246 | default: 247 | return true; 248 | break; 249 | } 250 | } 251 | 252 | 253 | function copyFiles() 254 | { 255 | $source = $this->post['dir_ldp']; 256 | $dest = $this->post['dir_site']; 257 | 258 | $this->recurse_copy($source, $dest); 259 | } 260 | 261 | /** 262 | * Adapted on http://ca2.php.net/manual/en/function.copy.php#91010 263 | */ 264 | function recurse_copy($src,$dst) { 265 | $dir = opendir($src); 266 | @mkdir($dst); 267 | 268 | $filesSkip = array( 269 | '.', 270 | '..', 271 | 'COPYING', 272 | '.git', 273 | 'index.php.sample', 274 | 'install.php', 275 | 'LDP_Config.php', 276 | 'LDP.php', 277 | 'patches', 278 | 'scripts', 279 | 'TODO' 280 | ); 281 | 282 | while(false !== ( $file = readdir($dir)) ) { 283 | if (!in_array($file, $filesSkip)) { 284 | if ( is_dir($src . '/' . $file) ) { 285 | $this->recurse_copy($src . '/' . $file,$dst . '/' . $file); 286 | } 287 | else { 288 | copy($src . '/' . $file,$dst . '/' . $file); 289 | } 290 | } 291 | } 292 | closedir($dir); 293 | } 294 | 295 | 296 | function getErrorMessage($code, $key) 297 | { 298 | switch($code) { 299 | case 'nowrite': 300 | return ''.$this->post[$key].' is not writable.'; 301 | break; 302 | 303 | case 'empty': 304 | return 'Required directory name.'; 305 | break; 306 | 307 | default: 308 | return 'Who said what now? Check errorMessage()'; 309 | break; 310 | } 311 | 312 | } 313 | 314 | 315 | function writeToFile($file, $fileContents) 316 | { 317 | $fp = fopen($file, 'w'); 318 | fwrite($fp, $fileContents); 319 | 320 | fclose($fp); 321 | } 322 | 323 | } 324 | 325 | 326 | $i = new Install(); 327 | $i->showPage(); 328 | 329 | ?> 330 | -------------------------------------------------------------------------------- /patches/README: -------------------------------------------------------------------------------- 1 | Until some of the issues for Paget and Moriarty are resolved, 2 | copy (*) the files in these directories to your paget and moriarty library. 3 | 4 | * For now. Ideally, they will be actual patches with only the diffs 5 | 6 | -------------------------------------------------------------------------------- /patches/moriarty/simplegraph.class.php: -------------------------------------------------------------------------------- 1 | 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 18 | 'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#', 19 | 'owl' => 'http://www.w3.org/2002/07/owl#', 20 | 'cs' => 'http://purl.org/vocab/changeset/schema#', 21 | 'bf' => 'http://schemas.talis.com/2006/bigfoot/configuration#', 22 | 'frm' => 'http://schemas.talis.com/2006/frame/schema#', 23 | 24 | 'dc' => 'http://purl.org/dc/elements/1.1/', 25 | 'dct' => 'http://purl.org/dc/terms/', 26 | 'dctype' => 'http://purl.org/dc/dcmitype/', 27 | 'geo' => 'http://www.w3.org/2003/01/geo/wgs84_pos#', 28 | 'rel' => 'http://purl.org/vocab/relationship/', 29 | 'wn' => 'http://xmlns.com/wordnet/1.6/', 30 | 'air' => 'http://www.daml.org/2001/10/html/airport-ont#', 31 | 'contact' => 'http://www.w3.org/2000/10/swap/pim/contact#', 32 | 'frbr' => 'http://purl.org/vocab/frbr/core#', 33 | 34 | 'ad' => 'http://schemas.talis.com/2005/address/schema#', 35 | 'lib' => 'http://schemas.talis.com/2005/library/schema#', 36 | 'dir' => 'http://schemas.talis.com/2005/dir/schema#', 37 | 'user' => 'http://schemas.talis.com/2005/user/schema#', 38 | 'sv' => 'http://schemas.talis.com/2005/service/schema#', 39 | 'mo' => 'http://purl.org/ontology/mo/', 40 | 'status' => 'http://www.w3.org/2003/06/sw-vocab-status/ns#', 41 | 'label' => 'http://purl.org/net/vocab/2004/03/label#', 42 | 'skos' => 'http://www.w3.org/2004/02/skos/core#', 43 | 'bibo' => 'http://purl.org/ontology/bibo/', 44 | 'ov' => 'http://open.vocab.org/terms/', 45 | 'foaf' => 'http://xmlns.com/foaf/0.1/', 46 | 'void' => 'http://rdfs.org/ns/void#', 47 | 'xsd' => 'http://www.w3.org/2001/XMLSchema#', 48 | ); 49 | 50 | var $_labeller; 51 | 52 | function __construct($graph=false){ 53 | $this->_labeller = new Labeller(); 54 | if($graph){ 55 | if(is_string($graph)){ 56 | $this->add_rdf($graph); 57 | } else { 58 | $this->_index = $graph; 59 | } 60 | } 61 | 62 | } 63 | 64 | function __destruct(){ 65 | unset($this->_index); 66 | unset($this); 67 | } 68 | 69 | function set_request_factory($request_factory) { 70 | $this->request_factory = $request_factory; 71 | } 72 | 73 | 74 | /** 75 | * Map a portion of a URI to a short prefix for use when serialising the graph 76 | * @param string prefix the namespace prefix to associate with the URI 77 | * @param string uri the URI to associate with the prefix 78 | */ 79 | function set_namespace_mapping($prefix, $uri) { 80 | $this->_labeller->set_namespace_mapping($prefix, $uri); 81 | } 82 | 83 | /** 84 | * Convert a QName to a URI using registered namespace prefixes 85 | * @param string qname the QName to convert 86 | * @return string the URI corresponding to the QName if a suitable prefix exists, null otherwise 87 | */ 88 | function qname_to_uri($qname) { 89 | return $this->_labeller->qname_to_uri($qname); 90 | } 91 | 92 | /** 93 | * Convert a URI to a QName using registered namespace prefixes 94 | * @param string uri the URI to convert 95 | * @return string the QName corresponding to the URI if a suitable prefix exists, null otherwise 96 | */ 97 | function uri_to_qname($uri) { 98 | return $this->_labeller->uri_to_qname($uri); 99 | } 100 | 101 | function get_prefix($ns) { 102 | return $this->_labeller->get_prefix($ns); 103 | } 104 | 105 | function add_labelling_property($p) { 106 | $this->_labeller->add_labelling_property($p); 107 | } 108 | 109 | 110 | function update_prefix_mappings() { 111 | foreach ($this->_index as $s => $p_list) { 112 | foreach ($p_list as $p => $v_list) { 113 | $prefix = $this->_labeller->uri_to_qname($p); 114 | } 115 | } 116 | } 117 | 118 | 119 | 120 | 121 | /** 122 | * Constructs an array containing the type of the resource and its value 123 | * @param string resource a URI or blank node identifier (prefixed with _: e.g. _:name) 124 | * @return array an associative array with two keys: 'type' and 'value'. Type is either bnode or uri 125 | */ 126 | function make_resource_array($resource) { 127 | $resource_type = strpos($resource, '_:' ) === 0 ? 'bnode' : 'uri'; 128 | return array('type' => $resource_type, 'value' => $resource); 129 | } 130 | 131 | /** 132 | * Adds a triple with a resource object to the graph 133 | * @param string s the subject of the triple, either a URI or a blank node in the format _:name 134 | * @param string p the predicate URI of the triple 135 | * @param string o the object of the triple, either a URI or a blank node in the format _:name 136 | * @return boolean true if the triple was new, false if it already existed in the graph 137 | */ 138 | function add_resource_triple($s, $p, $o) { 139 | return $this->_add_triple($s, $p, array('type' => strpos($o, '_:' ) === 0 ? 'bnode' : 'uri', 'value' => $o)); 140 | } 141 | 142 | /** 143 | * Adds a triple with a literal object to the graph 144 | * @param string s the subject of the triple, either a URI or a blank node in the format _:name 145 | * @param string p the predicate of the triple as a URI 146 | * @param string o the object of the triple as a string 147 | * @param string lang the language code of the triple's object (optional) 148 | * @param string dt the datatype URI of the triple's object (optional) 149 | * @return boolean true if the triple was new, false if it already existed in the graph 150 | */ 151 | function add_literal_triple($s, $p, $o, $lang = null, $dt = null) { 152 | $o_info = array('type' => 'literal', 'value' => $o); 153 | if ( $lang != null ) { 154 | $o_info['lang'] = $lang; 155 | } 156 | if ( $dt != null ) { 157 | $o_info['datatype'] = $dt; 158 | } 159 | return $this->_add_triple($s, $p, $o_info); 160 | } 161 | 162 | private function _add_triple($s, $p, $o_info) { 163 | if (!isset($this->_index[$s])) { 164 | $this->_index[$s] = array(); 165 | $this->_index[$s][$p] = array( $o_info ); 166 | return true; 167 | } 168 | elseif (!isset($this->_index[$s][$p])) { 169 | $this->_index[$s][$p] = array( $o_info); 170 | return true; 171 | } 172 | else { 173 | if ( ! in_array( $o_info, $this->_index[$s][$p] ) ) { 174 | $this->_index[$s][$p][] = $o_info; 175 | return true; 176 | } 177 | } 178 | return false; 179 | } 180 | 181 | /** 182 | * @deprecated this is deprecated 183 | */ 184 | function get_triples() { 185 | return ARC2::getTriplesFromIndex($this->_to_arc_index($this->_index)); 186 | } 187 | 188 | /** 189 | * Get a copy of the graph's triple index 190 | * @see http://n2.talis.com/wiki/RDF_PHP_Specification 191 | */ 192 | function get_index() { 193 | return $this->_index; 194 | } 195 | 196 | 197 | /** 198 | * Serialise the graph to RDF/XML 199 | * @return string the RDF/XML version of the graph 200 | */ 201 | function to_rdfxml() { 202 | $this->update_prefix_mappings(); 203 | $serializer = ARC2::getRDFXMLSerializer( 204 | array( 205 | 'ns' => $this->_labeller->get_ns(), 206 | ) 207 | ); 208 | return $serializer->getSerializedIndex($this->_to_arc_index($this->_index)); 209 | } 210 | 211 | /** 212 | * Serialise the graph to Turtle 213 | * @see http://www.dajobe.org/2004/01/turtle/ 214 | * @return string the Turtle version of the graph 215 | */ 216 | function to_turtle() { 217 | $this->update_prefix_mappings(); 218 | $serializer = ARC2::getTurtleSerializer( 219 | array( 220 | 'ns' => $this->_labeller->get_ns(), 221 | ) 222 | ); 223 | return $serializer->getSerializedIndex($this->_to_arc_index($this->_index)); 224 | } 225 | 226 | /** 227 | * Serialise the graph to N-Triples 228 | * @see http://www.w3.org/TR/rdf-testcases/#ntriples 229 | * @return string the N-Triples version of the graph 230 | */ 231 | function to_ntriples() { 232 | $serializer = ARC2::getComponent('NTriplesSerializer', array()); 233 | return $serializer->getSerializedIndex($this->_to_arc_index($this->_index)); 234 | } 235 | 236 | 237 | /** 238 | * Serialise the graph to JSON 239 | * @see http://n2.talis.com/wiki/RDF_JSON_Specification 240 | * @return string the JSON version of the graph 241 | */ 242 | function to_json() { 243 | return json_encode($this->_index); 244 | } 245 | 246 | 247 | /** 248 | * Serialise the graph to HTML 249 | * @return string a HTML version of the graph 250 | */ 251 | function to_html($s = null, $guess_labels = true) { 252 | 253 | $this->update_prefix_mappings(); 254 | $h = ''; 255 | 256 | if ($s) { 257 | if (is_array($s)) { 258 | $subjects = array_intersect($s, $this->get_subjects()); 259 | if (count($subjects) == 0) return ''; 260 | } 261 | else { 262 | if (array_key_exists($s, $this->_index)) { 263 | $subjects = array($s); 264 | } 265 | else { 266 | return ''; 267 | } 268 | } 269 | } 270 | else { 271 | $subjects = $this->get_subjects(); 272 | } 273 | 274 | 275 | if (count($subjects) > 0) { 276 | foreach ($subjects as $subject) { 277 | if (count($subjects) > 1) { 278 | $h .= '

' . htmlspecialchars($this->get_label($subject)) . '

' . "\n"; 279 | } 280 | $h .= '' . "\n"; 281 | 282 | $properties = $this->get_subject_properties($subject, TRUE); 283 | $priority_properties = array_intersect($properties, $this->_property_order); 284 | $properties = array_merge($priority_properties, array_diff($properties, $priority_properties)); 285 | 286 | foreach ($properties as $p) { 287 | $h .= ''; 288 | $h .= ''; 307 | $h .= '' . "\n"; 308 | } 309 | 310 | $backlinks = array(); 311 | foreach ($this->_index as $rev_subj => $rev_subj_info) { 312 | foreach ($rev_subj_info as $rev_subj_p => $rev_subj_p_list) { 313 | foreach ($rev_subj_p_list as $rev_value) { 314 | if ( ( $rev_value['type'] == 'uri' || $rev_value['type'] == 'bnode') && $rev_value['value'] === $subject) { 315 | if (!isset($backlinks[$rev_subj_p])) { 316 | $backlinks[$rev_subj_p] = array(); 317 | } 318 | $backlinks[$rev_subj_p][] = $rev_subj; 319 | } 320 | } 321 | } 322 | } 323 | 324 | foreach ($backlinks as $backlink_p => $backlink_values) { 325 | $h .= ''; 326 | $h .= ''; 341 | $h .= '' . "\n"; 342 | } 343 | 344 | $h .= '
' . htmlspecialchars($this->get_label($p, true)). ''; 289 | for ($i = 0; $i < count($this->_index[$subject][$p]); $i++) { 290 | if ($i > 0) $h .= '
'; 291 | if ($this->_index[$subject][$p][$i]['type'] === 'literal') { 292 | $h .= htmlspecialchars($this->_index[$subject][$p][$i]['value'] ); 293 | } 294 | else { 295 | $h .= ''; 296 | if ($guess_labels) { 297 | $h .= htmlspecialchars($this->get_label($this->_index[$subject][$p][$i]['value']) ); 298 | } 299 | else { 300 | $h .= htmlspecialchars($this->_index[$subject][$p][$i]['value'] ); 301 | } 302 | 303 | $h .= ''; 304 | } 305 | } 306 | $h .= '
' . htmlspecialchars($this->get_inverse_label($backlink_p, true)). ''; 327 | for ($i = 0; $i < count($backlink_values); $i++) { 328 | if ($i > 0) $h .= '
'; 329 | 330 | $h .= ''; 331 | if ($guess_labels) { 332 | $h .= htmlspecialchars($this->get_label($backlink_values[$i]) ); 333 | } 334 | else { 335 | $h .= htmlspecialchars($backlink_values[$i] ); 336 | } 337 | 338 | $h .= ''; 339 | } 340 | $h .= '
' . "\n"; 345 | } 346 | } 347 | return $h; 348 | } 349 | 350 | 351 | /** 352 | * Fetch the first literal value for a given subject and predicate. If there are multiple possible values then one is selected at random. 353 | * @param string s the subject to search for 354 | * @param string p the predicate to search for, or an array of predicates 355 | * @param string default a default value to use if no literal values are found 356 | * @return string the first literal value found or the supplied default if no values were found 357 | */ 358 | function get_first_literal($s, $p, $default = null, $preferred_language = null) { 359 | 360 | $best_literal = $default; 361 | if ( array_key_exists($s, $this->_index)) { 362 | if (is_array($p)) { 363 | foreach($p as $p_uri) { 364 | if(array_key_exists($p_uri, $this->_index[$s]) ) { 365 | foreach ($this->_index[$s][$p_uri] as $value) { 366 | if ($value['type'] == 'literal') { 367 | if ($preferred_language == null) { 368 | return $value['value']; 369 | } 370 | else { 371 | if (array_key_exists('lang', $value) && $value['lang'] == $preferred_language) { 372 | return $value['value']; 373 | } 374 | else { 375 | $best_literal = $value['value']; 376 | } 377 | } 378 | } 379 | } 380 | } 381 | } 382 | } 383 | else if(array_key_exists($p, $this->_index[$s]) ) { 384 | foreach ($this->_index[$s][$p] as $value) { 385 | if ($value['type'] == 'literal') { 386 | if ($preferred_language == null) { 387 | return $value['value']; 388 | } 389 | else { 390 | if (array_key_exists('lang', $value) && $value['lang'] == $preferred_language) { 391 | return $value['value']; 392 | } 393 | else { 394 | $best_literal = $value['value']; 395 | } 396 | } 397 | } 398 | } 399 | } 400 | } 401 | 402 | return $best_literal; 403 | } 404 | 405 | /** 406 | * Fetch the first resource value for a given subject and predicate. If there are multiple possible values then one is selected at random. 407 | * @param string s the subject to search for 408 | * @param string p the predicate to search for 409 | * @param string default a default value to use if no literal values are found 410 | * @return string the first resource value found or the supplied default if no values were found 411 | */ 412 | function get_first_resource($s, $p, $default = null) { 413 | if ( array_key_exists($s, $this->_index) && array_key_exists($p, $this->_index[$s]) ) { 414 | foreach ($this->_index[$s][$p] as $value) { 415 | if ($value['type'] == 'uri' || $value['type'] == 'bnode' ) { 416 | return $value['value']; 417 | } 418 | } 419 | } 420 | else { 421 | return $default; 422 | } 423 | } 424 | 425 | /** 426 | * Remove a triple with a resource object from the graph 427 | * @param string s the subject of the triple, either a URI or a blank node in the format _:name 428 | * @param string p the predicate URI of the triple 429 | * @param string o the object of the triple, either a URI or a blank node in the format _:name 430 | */ 431 | function remove_resource_triple( $s, $p, $o) { 432 | for ($i = count($this->_index[$s][$p]) - 1; $i >= 0; $i--) { 433 | if (($this->_index[$s][$p][$i]['type'] == 'uri' || $this->_index[$s][$p][$i]['type'] == 'bnode') && $this->_index[$s][$p][$i]['value'] == $o) { 434 | array_splice($this->_index[$s][$p], $i, 1); 435 | } 436 | } 437 | 438 | if (count($this->_index[$s][$p]) == 0) { 439 | unset($this->_index[$s][$p]); 440 | } 441 | if (count($this->_index[$s]) == 0) { 442 | unset($this->_index[$s]); 443 | } 444 | 445 | } 446 | 447 | function remove_literal_triple( $s, $p, $o) { 448 | for ($i = count($this->_index[$s][$p]) - 1; $i >= 0; $i--) { 449 | if ($this->_index[$s][$p][$i]['type'] == 'literal' && $this->_index[$s][$p][$i]['value'] == $o) { 450 | array_splice($this->_index[$s][$p], $i, 1); 451 | } 452 | } 453 | 454 | if (count($this->_index[$s][$p]) == 0) { 455 | unset($this->_index[$s][$p]); 456 | } 457 | if (count($this->_index[$s]) == 0) { 458 | unset($this->_index[$s]); 459 | } 460 | 461 | } 462 | 463 | /** 464 | * Remove all triples having the supplied subject 465 | * @param string s the subject of the triple, either a URI or a blank node in the format _:name 466 | */ 467 | function remove_triples_about($s) { 468 | unset($this->_index[$s]); 469 | } 470 | 471 | 472 | /** 473 | * Replace the triples in the graph with those parsed from the supplied RDF/XML 474 | * @param string rdfxml the RDF/XML to parse 475 | * @param string base the base URI against which relative URIs in the RDF/XML document will be resolved 476 | */ 477 | function from_rdfxml($rdfxml, $base='') { 478 | if ($rdfxml) { 479 | $this->remove_all_triples(); 480 | $this->add_rdfxml($rdfxml, $base); 481 | } 482 | } 483 | 484 | /** 485 | * Replace the triples in the graph with those parsed from the supplied JSON 486 | * @see http://n2.talis.com/wiki/RDF_JSON_Specification 487 | * @param string json the JSON to parse 488 | */ 489 | function from_json($json) { 490 | if ($json) { 491 | $this->remove_all_triples(); 492 | $this->_index = json_decode($json, true); 493 | } 494 | } 495 | 496 | 497 | /** 498 | * Add the triples parsed from the supplied JSON to the graph 499 | * @see http://n2.talis.com/wiki/RDF_JSON_Specification 500 | * @param string json the JSON to parse 501 | */ 502 | function add_json($json) { 503 | if ($json) { 504 | $json_index = json_decode($json, true); 505 | $this->_index = $this->merge($this->_index, $json_index); 506 | } 507 | } 508 | 509 | function get_parser_errors(){ 510 | return $this->parser_errors; 511 | } 512 | /** 513 | * Add the triples parsed from the supplied RDF to the graph - let ARC guess the input 514 | * @param string rdf the RDF to parse 515 | * @param string base the base URI against which relative URIs in the RDF document will be resolved 516 | * @author Keith Alexander 517 | */ 518 | function add_rdf($rdf=false, $base='') { 519 | if ($rdf) { 520 | $trimRdf = trim($rdf); 521 | if($trimRdf[0]=='{'){ //lazy is-this-json assessment - might be better to try json_decode - but more costly 522 | $this->add_json($trimRdf); 523 | unset($trimRdf); 524 | } else { 525 | $parser = ARC2::getRDFParser(); 526 | $parser->parse($base, $rdf); 527 | $errors = $parser->getErrors(); 528 | if(!empty($errors)){ 529 | $this->parser_errors[]=$errors; 530 | } 531 | $this->_add_arc2_triple_list($parser->getTriples()); 532 | unset($parser); 533 | } 534 | } 535 | } 536 | 537 | /** 538 | * Add the triples parsed from the supplied RDF/XML to the graph 539 | * @param string rdfxml the RDF/XML to parse 540 | * @param string base the base URI against which relative URIs in the RDF/XML document will be resolved 541 | */ 542 | function add_rdfxml($rdfxml, $base='') { 543 | if ($rdfxml) { 544 | $parser = ARC2::getRDFXMLParser(); 545 | $parser->parse($base, $rdfxml ); 546 | $this->_add_arc2_triple_list($parser->getTriples()); 547 | unset($parser); 548 | } 549 | } 550 | 551 | /** 552 | * Replace the triples in the graph with those parsed from the supplied Turtle 553 | * @see http://www.dajobe.org/2004/01/turtle/ 554 | * @param string turtle the Turtle to parse 555 | * @param string base the base URI against which relative URIs in the Turtle document will be resolved 556 | */ 557 | function from_turtle($turtle, $base='') { 558 | if ($turtle) { 559 | $this->remove_all_triples(); 560 | $this->add_turtle($turtle, $base); 561 | } 562 | } 563 | 564 | /** 565 | * Add the triples parsed from the supplied Turtle to the graph 566 | * @see http://www.dajobe.org/2004/01/turtle/ 567 | * @param string turtle the Turtle to parse 568 | * @param string base the base URI against which relative URIs in the Turtle document will be resolved 569 | */ 570 | function add_turtle($turtle, $base='') { 571 | if ($turtle) { 572 | $parser = ARC2::getTurtleParser(); 573 | $parser->parse($base, $turtle ); 574 | $this->_add_arc2_triple_list($parser->getTriples()); 575 | unset($parser); 576 | } 577 | } 578 | 579 | 580 | /** 581 | * Replace the triples in the graph with those parsed from the supplied RDFa 582 | * @param string html the HTML containing RDFa to parse 583 | * @param string base the base URI against which relative URIs in the Turtle document will be resolved 584 | */ 585 | function from_rdfa($html, $base='') { 586 | if ($html) { 587 | $this->remove_all_triples(); 588 | $this->add_rdfa($html, $base); 589 | } 590 | } 591 | /** 592 | * Add the triples parsed from the supplied RDFa to the graph 593 | * @param string html the HTML containing RDFa to parse 594 | * @param string base the base URI against which relative URIs in the Turtle document will be resolved 595 | */ 596 | function add_rdfa($html, $base='') { 597 | if ($html) { 598 | $parser = ARC2::getSemHTMLParser(); 599 | $parser->parse($base, $html ); 600 | $parser->extractRDF('rdfa'); 601 | $this->_add_arc2_triple_list($parser->getTriples()); 602 | unset($parser); 603 | } 604 | } 605 | 606 | /** 607 | * Add the triples in the supplied graph to the current graph 608 | * @param SimpleGraph g the graph to read 609 | */ 610 | function add_graph($g) { 611 | $triples_were_added = false; 612 | $index = $g->get_index(); 613 | foreach ($index as $s => $p_list) { 614 | foreach ($p_list as $p => $o_list) { 615 | foreach ($o_list as $o_info) { 616 | if ($this->_add_triple($s, $p, $o_info) ) { 617 | $triples_were_added = true; 618 | } 619 | } 620 | } 621 | } 622 | return $triples_were_added; 623 | } 624 | 625 | 626 | private function _add_arc2_triple_list(&$triples) { 627 | $bnode_index = array(); 628 | 629 | // We can safely preserve bnode labels if the graph is empty, otherwise we need to rewrite them 630 | $rewrite_bnode_labels = $this->is_empty() ? FALSE : TRUE; 631 | 632 | foreach ($triples as $t) { 633 | $obj = array(); 634 | 635 | if ($rewrite_bnode_labels && $t['o_type'] == 'bnode') { 636 | if (!array_key_exists($t['o'], $bnode_index)) { 637 | $bnode_index[$t['o']] = uniqid('_:mor'); 638 | } 639 | $obj['value'] = $bnode_index[$t['o']]; 640 | } 641 | else { 642 | $obj['value'] = $t['o']; 643 | } 644 | 645 | if ($rewrite_bnode_labels && strpos($t['s'], '_:' ) === 0) { 646 | if (!array_key_exists($t['s'], $bnode_index)) { 647 | $bnode_index[$t['s']] = uniqid('_:mor'); 648 | } 649 | $t['s'] = $bnode_index[$t['s']]; 650 | } 651 | 652 | $t['s'] = $this->map_uri($t['s']); 653 | $t['p'] = $this->map_uri($t['p']); 654 | 655 | if ($t['o_type'] === 'iri' ) { 656 | $obj['type'] = 'uri'; 657 | } 658 | elseif ($t['o_type'] === 'literal1' || 659 | $t['o_type'] === 'literal2' || 660 | $t['o_type'] === 'long_literal1' || 661 | $t['o_type'] === 'long_literal2' 662 | ) { 663 | $obj['type'] = 'literal'; 664 | } 665 | else { 666 | $obj['type'] = $t['o_type']; 667 | } 668 | 669 | 670 | 671 | if ($obj['type'] == 'literal') { 672 | if ( isset( $t['o_dt'] ) && $t['o_dt'] ) { 673 | $obj['datatype'] = $t['o_dt']; 674 | } 675 | else if ( isset( $t['o_datatype'] ) && $t['o_datatype'] ) { 676 | $obj['datatype'] = $t['o_datatype']; 677 | } 678 | if ( isset( $t['o_lang']) && $t['o_lang']) { 679 | $obj['lang'] = $t['o_lang']; 680 | } 681 | } 682 | elseif ($obj['type'] == 'uri') { 683 | $obj['value'] = $this->map_uri($obj['value']); 684 | } 685 | 686 | if (!isset($this->_index[$t['s']])) { 687 | $this->_index[$t['s']] = array(); 688 | $this->_index[$t['s']][$t['p']] = array($obj); 689 | } 690 | elseif (!isset($this->_index[$t['s']][$t['p']])) { 691 | $this->_index[$t['s']][$t['p']] = array($obj); 692 | } 693 | else { 694 | if ( ! in_array( $obj, $this->_index[$t['s']][$t['p']] ) ) { 695 | $this->_index[$t['s']][$t['p']][] = $obj; 696 | } 697 | } 698 | } 699 | } 700 | 701 | 702 | // until ARC2 upgrades to support RDF/PHP we need to rename all types of "uri" to "iri" 703 | private function _to_arc_index(&$index) { 704 | $ret = array(); 705 | 706 | foreach ($index as $s => $s_info) { 707 | $ret[$s] = array(); 708 | foreach ($s_info as $p => $p_info) { 709 | $ret[$s][$p] = array(); 710 | foreach ($p_info as $o) { 711 | if (isset($o) && is_array($o)) { 712 | $o_new = array(); 713 | foreach ($o as $key => $value) { 714 | if ( $key == 'type' && $value == 'uri' ) { 715 | $o_new['type'] = 'iri'; 716 | } 717 | else { 718 | $o_new[$key] = $value; 719 | } 720 | } 721 | $ret[$s][$p][] = $o_new; 722 | } 723 | } 724 | } 725 | } 726 | return $ret; 727 | } 728 | 729 | /** 730 | * Tests whether the graph contains the given triple 731 | * @param string s the subject of the triple, either a URI or a blank node in the format _:name 732 | * @param string p the predicate URI of the triple 733 | * @param string o the object of the triple, either a URI or a blank node in the format _:name 734 | * @return boolean true if the triple exists in the graph, false otherwise 735 | */ 736 | function has_resource_triple($s, $p, $o) { 737 | if (array_key_exists($s, $this->_index) ) { 738 | if (array_key_exists($p, $this->_index[$s]) ) { 739 | foreach ($this->_index[$s][$p] as $value) { 740 | if ( ( $value['type'] == 'uri' || $value['type'] == 'bnode') && $value['value'] === $o) { 741 | return true; 742 | } 743 | } 744 | } 745 | } 746 | 747 | return false; 748 | } 749 | 750 | /** 751 | * Tests whether the graph contains the given triple 752 | * @param string s the subject of the triple, either a URI or a blank node in the format _:name 753 | * @param string p the predicate URI of the triple 754 | * @param string o the object of the triple as a literal value 755 | * @return boolean true if the triple exists in the graph, false otherwise 756 | */ 757 | function has_literal_triple($s, $p, $o, $lang = null, $dt = null) { 758 | if (array_key_exists($s, $this->_index) ) { 759 | if (array_key_exists($p, $this->_index[$s]) ) { 760 | foreach ($this->_index[$s][$p] as $value) { 761 | if ( ( $value['type'] == 'literal') && $value['value'] === $o) { 762 | 763 | if ($lang !== null) { 764 | return (array_key_exists('lang', $value) && $value['lang'] === $lang); 765 | } 766 | 767 | if ($dt !== null) { 768 | return (array_key_exists('datatype', $value) && $value['datatype'] === $dt); 769 | } 770 | return true; 771 | } 772 | } 773 | } 774 | } 775 | 776 | return false; 777 | } 778 | 779 | /** 780 | * Fetch the resource values for a given subject and predicate. 781 | * @param string s the subject to search for 782 | * @param string p the predicate to search for 783 | * @return array list of URIs and blank nodes that are the objects of triples with the supplied subject and predicate 784 | */ 785 | function get_resource_triple_values($s, $p) { 786 | $values = array(); 787 | if (array_key_exists($s, $this->_index) ) { 788 | if (array_key_exists($p, $this->_index[$s]) ) { 789 | foreach ($this->_index[$s][$p] as $value) { 790 | if ( ( $value['type'] == 'uri' || $value['type'] == 'bnode')) { 791 | $values[] = $value['value']; 792 | } 793 | } 794 | } 795 | } 796 | return $values; 797 | } 798 | 799 | /** 800 | * Fetch the literal values for a given subject and predicate. 801 | * @param string s the subject to search for 802 | * @param string p the predicate to search for 803 | * @return array list of literals that are the objects of triples with the supplied subject and predicate 804 | */ 805 | function get_literal_triple_values($s, $p) { 806 | $values = array(); 807 | if ( array_key_exists($s, $this->_index)) { 808 | if (is_array($p)) { 809 | foreach($p as $p_uri) { 810 | if(array_key_exists($p_uri, $this->_index[$s]) ) { 811 | foreach ($this->_index[$s][$p_uri] as $value) { 812 | if ($value['type'] == 'literal') { 813 | $values[] = $value['value']; 814 | } 815 | } 816 | } 817 | } 818 | } 819 | else if(array_key_exists($p, $this->_index[$s]) ) { 820 | foreach ($this->_index[$s][$p] as $value) { 821 | if ($value['type'] == 'literal') { 822 | $values[] = $value['value']; 823 | } 824 | } 825 | } 826 | } 827 | 828 | return $values; 829 | } 830 | 831 | 832 | /** 833 | * Fetch the values for a given subject and predicate. 834 | * @param string s the subject to search for 835 | * @param string p the predicate to search for 836 | * @return array list of values of triples with the supplied subject and predicate 837 | */ 838 | function get_subject_property_values($s, $p) { 839 | $values = array(); 840 | if (! is_array($p)) $p = array($p); 841 | if (array_key_exists($s, $this->_index) ) { 842 | foreach ($p as $pinst) { 843 | if (array_key_exists($pinst, $this->_index[$s]) ) { 844 | foreach ($this->_index[$s][$pinst] as $value) { 845 | $values[] = $value; 846 | } 847 | } 848 | } 849 | } 850 | return $values; 851 | } 852 | 853 | /** 854 | * Fetch a subgraph where all triples have given subject 855 | * @param string s the subject to search for 856 | * @return SimpleGraph triples with the supplied subject 857 | */ 858 | function get_subject_subgraph($s) { 859 | $sub = new SimpleGraph(); 860 | if (array_key_exists($s, $this->_index) ) { 861 | $sub->_index[$s] = $this->_index[$s]; 862 | } 863 | return $sub; 864 | } 865 | 866 | /** 867 | * Fetch an array of all the subjects 868 | * @return array 869 | */ 870 | function get_subjects() { 871 | return array_keys($this->_index); 872 | } 873 | 874 | 875 | /** 876 | * Fetch an array of all the subject that have and rdf type that matches that given 877 | * @param $t the type to match 878 | * @return array 879 | */ 880 | function get_subjects_of_type($t) { 881 | return $this->get_subjects_where_resource('http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $t); 882 | } 883 | 884 | /** 885 | * Fetch an array of all the subjects where the predicate and object match a ?s $p $o triple in the graph and the object is a resource 886 | * @param $p the predicate to match 887 | * @param $o the resource object to match 888 | * @return array 889 | */ 890 | function get_subjects_where_resource($p, $o) { 891 | return array_merge($this->get_subjects_where($p, $o, 'uri'), $this->get_subjects_where($p, $o, 'bnode')); 892 | } 893 | 894 | /** 895 | * Fetch an array of all the subjects where the predicate and object match a ?s $p $o triple in the graph and the object is a literal value 896 | * @param $p the predicate to match 897 | * @param $o the resource object to match 898 | * @return array 899 | */ 900 | function get_subjects_where_literal($p, $o) { 901 | return $this->get_subjects_where($p, $o, 'literal'); 902 | } 903 | 904 | private function get_subjects_where($p, $o, $type) 905 | { 906 | $subjects = array(); 907 | foreach ($this->_index as $subject => $properties) 908 | { 909 | if (array_key_exists($p, $properties)) 910 | { 911 | foreach ($properties[$p] as $object) 912 | { 913 | if ($object['type'] == $type && $object['value'] == $o) 914 | { 915 | $subjects[] = $subject; 916 | break; 917 | } 918 | } 919 | } 920 | } 921 | return $subjects; 922 | } 923 | 924 | /** 925 | * Fetch the properties of a given subject and predicate. 926 | * @param string s the subject to search for 927 | * @param boolean distinct if true then duplicate properties are included only once (optional, default is true) 928 | * @return array list of property URIs 929 | */ 930 | function get_subject_properties($s, $distinct = TRUE) { 931 | $values = array(); 932 | if (array_key_exists($s, $this->_index) ) { 933 | foreach ($this->_index[$s] as $prop => $prop_values ) { 934 | if ($distinct) { 935 | $values[] = $prop; 936 | } 937 | else { 938 | for ($i = 0; $i < count($prop_values); $i++) { 939 | $values[] = $prop; 940 | } 941 | } 942 | } 943 | } 944 | return $values; 945 | } 946 | 947 | 948 | /** 949 | * Tests whether the graph contains a triple with the given subject and predicate 950 | * @param string s the subject of the triple, either a URI or a blank node in the format _:name 951 | * @param string p the predicate URI of the triple 952 | * @return boolean true if a matching triple exists in the graph, false otherwise 953 | */ 954 | function subject_has_property($s, $p) { 955 | if (array_key_exists($s, $this->_index) ) { 956 | return (array_key_exists($p, $this->_index[$s]) ); 957 | } 958 | return false; 959 | } 960 | 961 | /** 962 | * Tests whether the graph contains a triple with the given subject 963 | * @param string s the subject of the triple, either a URI or a blank node in the format _:name 964 | * @return boolean true if the graph contains any triples with the specified subject, false otherwise 965 | */ 966 | function has_triples_about($s) { 967 | return array_key_exists($s, $this->_index); 968 | } 969 | 970 | 971 | /** 972 | * Removes all triples with the given subject and predicate 973 | * @param string s the subject of the triple, either a URI or a blank node in the format _:name 974 | * @param string p the predicate URI of the triple 975 | */ 976 | function remove_property_values($s, $p) { 977 | unset($this->_index[$s][$p]); 978 | } 979 | 980 | /** 981 | * Clears all triples out of the graph 982 | */ 983 | function remove_all_triples() { 984 | $this->_index = array(); 985 | } 986 | 987 | /** 988 | * Tests whether the graph contains any triples 989 | * @return boolean true if the graph contains no triples, false otherwise 990 | */ 991 | function is_empty() { 992 | return ( count($this->_index) == 0); 993 | } 994 | 995 | 996 | function get_label($resource_uri, $capitalize = false, $use_qnames = FALSE) { 997 | return $this->_labeller->get_label($resource_uri, $this, $capitalize, $use_qnames); 998 | } 999 | 1000 | function get_inverse_label($resource_uri, $capitalize = false, $use_qnames = FALSE) { 1001 | return $this->_labeller->get_inverse_label($resource_uri, $this, $capitalize, $use_qnames); 1002 | } 1003 | 1004 | function get_description($resource_uri = null) { 1005 | if ($resource_uri == null) { 1006 | $resource_uri = $this->_primary_resource; 1007 | } 1008 | $text = $this->get_first_literal($resource_uri,'http://purl.org/dc/terms/description', '', 'en'); 1009 | if ( strlen($text) == 0) { 1010 | $text = $this->get_first_literal($resource_uri,DC_DESCRIPTION, '', 'en'); 1011 | } 1012 | if ( strlen($text) == 0) { 1013 | $text = $this->get_first_literal($resource_uri,RDFS_COMMENT, '', 'en'); 1014 | } 1015 | if ( strlen($text) == 0) { 1016 | $text = $this->get_first_literal($resource_uri,'http://purl.org/rss/1.0/description', '', 'en'); 1017 | } 1018 | if ( strlen($text) == 0) { 1019 | $text = $this->get_first_literal($resource_uri,'http://purl.org/dc/terms/abstract', '', 'en'); 1020 | } 1021 | if ( strlen($text) == 0) { 1022 | $text = $this->get_first_literal($resource_uri,'http://purl.org/vocab/bio/0.1/olb', '', 'en'); 1023 | } 1024 | return $text; 1025 | } 1026 | 1027 | 1028 | 1029 | function reify($resources, $nodeID_prefix='Statement') 1030 | { 1031 | $RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'; 1032 | $reified = array(); 1033 | $statement_no = 1; 1034 | foreach($resources as $uri => $properties){ 1035 | foreach($properties as $property => $objects){ 1036 | foreach($objects as $object){ 1037 | while(!isset($statement_nodeID) OR isset($resources[$statement_nodeID]) OR isset($reified[$statement_nodeID])) 1038 | { 1039 | $statement_nodeID = '_:'.$nodeID_prefix.($statement_no++); 1040 | } 1041 | $reified[$statement_nodeID]= array( 1042 | $RDF.'type'=>array( 1043 | array('type'=>'uri','value'=>$RDF.'Statement') 1044 | ), 1045 | $RDF.'subject' => array(array('type'=> (substr($uri,0,2)=='_:')? 'bnode' : 'uri', 'value'=>$uri)), 1046 | $RDF.'predicate' => array(array('type'=>'uri','value'=>$property)), 1047 | $RDF.'object' => array($object), 1048 | ); 1049 | 1050 | } 1051 | } 1052 | } 1053 | 1054 | return ($reified); 1055 | } 1056 | 1057 | /** 1058 | * diff 1059 | * returns a simpleIndex consisting of all the statements in array1 that weren't found in any of the subsequent arrays 1060 | * @param array1, array2, [array3, ...] 1061 | * @return array 1062 | * @author Keith 1063 | **/ 1064 | function diff(){ 1065 | $indices = func_get_args(); 1066 | if(count($indices)==1){ 1067 | array_unshift($indices, $this->_index); 1068 | } 1069 | $base = array_shift($indices); 1070 | if (count($base) === 0) return array(); 1071 | $diff = array(); 1072 | 1073 | foreach($base as $base_uri => $base_ps) { 1074 | foreach($indices as $index){ 1075 | if(!isset($index[$base_uri])) { 1076 | $diff[$base_uri] = $base_ps; 1077 | } 1078 | else { 1079 | foreach($base_ps as $base_p => $base_obs) { 1080 | if(!isset($index[$base_uri][$base_p])) { 1081 | $diff[$base_uri][$base_p] = $base_obs; 1082 | } 1083 | else { 1084 | foreach($base_obs as $base_o){ 1085 | // because we want to enforce strict type check 1086 | // on in_array, we need to ensure that array keys 1087 | // are ordered the same 1088 | ksort($base_o); 1089 | $base_p_values = $index[$base_uri][$base_p]; 1090 | foreach($base_p_values as &$v) 1091 | { 1092 | ksort($v); 1093 | } 1094 | if(!in_array($base_o, $base_p_values, true)) { 1095 | $diff[$base_uri][$base_p][]=$base_o; 1096 | } 1097 | } 1098 | } 1099 | } 1100 | } 1101 | } 1102 | } 1103 | 1104 | return $diff; 1105 | } 1106 | 1107 | /** 1108 | * merge 1109 | * merges all rdf/json-style arrays passed as parameters 1110 | * @param array1, array2, [array3, ...] 1111 | * @return array 1112 | * @author Keith 1113 | **/ 1114 | 1115 | function merge(){ 1116 | 1117 | $old_bnodeids = array(); 1118 | $indices = func_get_args(); 1119 | if(count($indices)==1){ 1120 | array_unshift($indices, $this->_index); 1121 | } 1122 | 1123 | $current = array_shift($indices); 1124 | foreach($indices as $newGraph) 1125 | { 1126 | if (isset($newGraph) && is_array($newGraph)) { 1127 | foreach($newGraph as $uri => $properties) 1128 | { 1129 | /* Make sure that bnode ids don't overlap: 1130 | _:a in g1 isn't the same as _:a in g2 */ 1131 | 1132 | if(substr($uri,0,2)=='_:')//bnode 1133 | { 1134 | $old_id = $uri; 1135 | $count = 1; 1136 | 1137 | while(isset($current[$uri]) OR 1138 | ( $old_id!=$uri AND isset($newGraph[$uri]) ) 1139 | OR isset($old_bnodeids[$uri]) 1140 | ) 1141 | { 1142 | $uri.=$count++; 1143 | } 1144 | 1145 | if($old_id != $uri) $old_bnodeids[$old_id] = $uri; 1146 | } 1147 | 1148 | if (isset($properties) && is_array($properties)) { 1149 | foreach($properties as $property => $objects) 1150 | { 1151 | if (isset($objects) && is_array($objects)) { 1152 | foreach($objects as $object) 1153 | { 1154 | /* make sure that the new bnode is being used*/ 1155 | if(isset($object['type']) && $object['type']=='bnode') 1156 | { 1157 | $bnode = $object['value']; 1158 | 1159 | if(isset($old_bnodeids[$bnode])) $object['value'] = $old_bnodeids[$bnode]; 1160 | else //bnode hasn't been transposed 1161 | { 1162 | $old_bnode_id = $bnode; 1163 | $count=1; 1164 | while(isset($current[$bnode]) OR 1165 | ( $object['value']!=$bnode AND isset($newGraph[$bnode]) ) 1166 | OR isset($old_bnodeids[$uri]) 1167 | ) 1168 | { 1169 | $bnode.=$count++; 1170 | } 1171 | 1172 | if($old_bnode_id!=$bnode) $old_bnodeids[$old_bnode_id] = $bnode; 1173 | $object['value'] = $bnode; 1174 | } 1175 | } 1176 | 1177 | if(!isset($current[$uri][$property]) OR !in_array($object, $current[$uri][$property])) 1178 | { 1179 | $current[$uri][$property][]=$object; 1180 | } 1181 | } 1182 | } 1183 | } 1184 | } 1185 | } 1186 | } 1187 | } 1188 | return $current; 1189 | } 1190 | 1191 | function replace_resource($look_for, $replace_with) { 1192 | $remove_list_resources = array(); 1193 | $remove_list_literals = array(); 1194 | $add_list_resources = array(); 1195 | $add_list_literals = array(); 1196 | foreach ($this->_index as $s => $p_list) { 1197 | if ($s == $look_for) { 1198 | foreach ($p_list as $p => $o_list) { 1199 | if ($p == $look_for) { 1200 | foreach ($o_list as $o_info) { 1201 | if ($o_info['type'] == 'literal') { 1202 | $lang = array_key_exists('lang', $o_info) ? $o_info['lang'] : null; 1203 | $dt = array_key_exists('datatype', $o_info) ? $o_info['datatype'] : null; 1204 | 1205 | $remove_list_literals[] = array($look_for, $look_for, $o_info['value'], $lang, $dt); 1206 | $add_list_literals[] = array($replace_with, $replace_with, $o_info['value'], $lang, $dt); 1207 | } 1208 | else { 1209 | if ($o_info['value'] == $look_for) { 1210 | $remove_list_resources[] = array($look_for, $look_for, $look_for); 1211 | $add_list_resources[] = array($replace_with, $replace_with, $replace_with); 1212 | } 1213 | else { 1214 | $remove_list_resources[] = array($look_for, $look_for, $o_info['value']); 1215 | $add_list_resources[] = array($replace_with, $replace_with, $o_info['value']); 1216 | } 1217 | } 1218 | } 1219 | } 1220 | else { 1221 | foreach ($o_list as $o_info) { 1222 | if ($o_info['type'] == 'literal') { 1223 | $lang = array_key_exists('lang', $o_info) ? $o_info['lang'] : null; 1224 | $dt = array_key_exists('datatype', $o_info) ? $o_info['datatype'] : null; 1225 | 1226 | $remove_list_literals[] = array($look_for, $p, $o_info['value'], $lang, $dt); 1227 | $add_list_literals[] = array($replace_with, $p, $o_info['value'], $lang, $dt); 1228 | } 1229 | else { 1230 | if ($o_info['value'] == $look_for) { 1231 | $remove_list_resources[] = array($look_for, $p, $look_for); 1232 | $add_list_resources[] = array($replace_with, $p, $replace_with); 1233 | } 1234 | else { 1235 | $remove_list_resources[] = array($look_for, $p, $o_info['value']); 1236 | $add_list_resources[] = array($replace_with, $p, $o_info['value']); 1237 | } 1238 | } 1239 | } 1240 | } 1241 | } 1242 | } 1243 | else { 1244 | 1245 | foreach ($p_list as $p => $o_list) { 1246 | if ($p == $look_for) { 1247 | foreach ($o_list as $o_info) { 1248 | if ($o_info['type'] == 'literal') { 1249 | $lang = array_key_exists('lang', $o_info) ? $o_info['lang'] : null; 1250 | $dt = array_key_exists('datatype', $o_info) ? $o_info['datatype'] : null; 1251 | 1252 | $remove_list_literals[] = array($s, $look_for, $o_info['value'], $lang, $dt); 1253 | $add_list_literals[] = array($s, $replace_with, $o_info['value'], $lang, $dt); 1254 | } 1255 | else { 1256 | if ($o_info['value'] == $look_for) { 1257 | $remove_list_resources[] = array($s, $look_for, $look_for); 1258 | $add_list_resources[] = array($s, $replace_with, $replace_with); 1259 | } 1260 | else { 1261 | $remove_list_resources[] = array($s, $look_for, $o_info['value']); 1262 | $add_list_resources[] = array($s, $replace_with, $o_info['value']); 1263 | } 1264 | } 1265 | } 1266 | } 1267 | else { 1268 | foreach ($o_list as $o_info) { 1269 | if ($o_info['type'] != 'literal' && $o_info['value'] == $look_for) { 1270 | $remove_list_resources[] = array($s, $p, $look_for); 1271 | $add_list_resources[] = array($s, $p, $replace_with); 1272 | } 1273 | } 1274 | } 1275 | } 1276 | } 1277 | } 1278 | 1279 | foreach ($remove_list_resources as $t) { 1280 | $this->remove_resource_triple($t[0], $t[1], $t[2]); 1281 | } 1282 | foreach ($add_list_resources as $t) { 1283 | $this->add_resource_triple($t[0], $t[1], $t[2]); 1284 | } 1285 | 1286 | foreach ($remove_list_literals as $t) { 1287 | $this->remove_literal_triple($t[0], $t[1], $t[2], $t[3], $t[4]); 1288 | } 1289 | foreach ($add_list_literals as $t) { 1290 | $this->add_literal_triple($t[0], $t[1], $t[2], $t[3], $t[4]); 1291 | } 1292 | 1293 | } 1294 | 1295 | /** 1296 | * Read RDF from the supplied URIs and add to the current graph 1297 | * @param Any uri_list a URI, or array of URIs to fetch 1298 | * @param boolean include_response when TRUE include RDF about each retrieval operation 1299 | */ 1300 | function read_data($uri_list, $include_response = FALSE) { 1301 | if (empty( $this->request_factory) ) { 1302 | $this->request_factory = new HttpRequestFactory(); 1303 | } 1304 | 1305 | if (! is_array($uri_list)) { 1306 | $uri_list= array($uri_list); 1307 | } 1308 | 1309 | $requests = array(); 1310 | foreach ($uri_list as $uri) { 1311 | $request = $this->request_factory->make( 'GET', $uri ); 1312 | $request->set_accept('application/json, text/turtle, text/n3, text/rdf+n3, application/x-turtle, application/rdf+xml;q=0.8,application/xml;q=0.6, */*'); 1313 | $request->execute_async(); 1314 | $requests[] = $request; 1315 | } 1316 | 1317 | foreach ($requests as $request) { 1318 | $response = $request->get_async_response(); 1319 | 1320 | if ($include_response) { 1321 | $this->add_turtle($response->to_turtle()); 1322 | } 1323 | if ($response->is_success()) { 1324 | if ( strpos($response->headers['content-type'], 'application/rdf+xml') === 0 1325 | || strpos($response->headers['content-type'], 'application/xml') === 0) { 1326 | $this->add_rdfxml($response->body); 1327 | } 1328 | else if ( strpos($response->headers['content-type'], 'text/turtle') === 0 1329 | || strpos($response->headers['content-type'], 'text/n3') === 0 1330 | || strpos($response->headers['content-type'], 'text/rdf+n3') === 0 1331 | || strpos($response->headers['content-type'], 'application/x-turtle') === 0) { 1332 | $this->add_turtle($response->body); 1333 | } 1334 | else if ( strpos($response->headers['content-type'], 'application/json') === 0) { 1335 | $this->add_json($response->body); 1336 | } 1337 | } 1338 | } 1339 | } 1340 | 1341 | function get_list_values($listUri) { 1342 | $array = array(); 1343 | while(!empty($listUri) AND $listUri != RDF_NIL){ 1344 | $array[]=$this->get_first_resource($listUri, RDF_FIRST); 1345 | $listUri = $this->get_first_resource($listUri, RDF_REST); 1346 | } 1347 | return $array; 1348 | } 1349 | 1350 | function get_sequence_values($sequenceUri) { 1351 | $triples = $this->get_index(); 1352 | $properties = array(); 1353 | 1354 | if (isset($triples[$sequenceUri])) 1355 | { 1356 | foreach ($triples[$sequenceUri] as $property => $objects) 1357 | { 1358 | if (strpos($property, RDF_) !== false) 1359 | { 1360 | $key = substr($property, strpos($property, '_') + 1 ); 1361 | $value = $this->get_first_resource($sequenceUri, $property); 1362 | 1363 | 1364 | if (empty($value)) 1365 | { 1366 | $value = $this->get_first_literal($sequenceUri, $property); 1367 | } 1368 | 1369 | $properties[$key] = $value; 1370 | } 1371 | } 1372 | 1373 | ksort($properties, SORT_NUMERIC); 1374 | } 1375 | 1376 | $values = array(); 1377 | 1378 | foreach($properties as $key=>$value) 1379 | { 1380 | $values[] = $value; 1381 | } 1382 | 1383 | return $values; 1384 | } 1385 | 1386 | } 1387 | 1388 | -------------------------------------------------------------------------------- /patches/paget/paget_abstractresource.class.php: -------------------------------------------------------------------------------- 1 | _uri = $uri; 7 | } 8 | 9 | function get_uri() { 10 | return $this->_uri; 11 | } 12 | 13 | function get(&$urispace,&$request) { 14 | $extension = 'rdf'; 15 | $accepts = $request->accept; 16 | foreach ($accepts as $accept) { 17 | if ($accept == 'application/rdf+xml') { 18 | break; 19 | } 20 | else if ($accept == 'application/json') { 21 | $extension = 'json'; 22 | break; 23 | } 24 | else if ($accept == 'text/turtle') { 25 | $extension = 'ttl'; 26 | break; 27 | } 28 | else if ($accept == 'text/html') { 29 | $extension = 'html'; 30 | break; 31 | } 32 | } 33 | 34 | $parts = parse_url($this->_uri); 35 | 36 | $port = ''; 37 | if($parts['port'] != '80' || $parts['port'] != '') { 38 | $port = ":" . $parts['port']; 39 | } 40 | 41 | $base_uri = $parts['scheme'] . '://' . $parts['host'] . $port . $parts['path']; 42 | $suffix = ''; 43 | if (!empty($parts['query'])) $suffix = '?' . $parts['query']; 44 | 45 | $desc_uri = $base_uri . '.' . $extension . $suffix ; 46 | 47 | return new PAGET_Response(303, 'See ' . $desc_uri, array('location' => $desc_uri)); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /patches/paget/paget_resourcedescription.class.php: -------------------------------------------------------------------------------- 1 | array('type' => 'application/rdf+xml', 'label' => 'RDF/XML'), 16 | 'html' => array('type' => 'text/html', 'label' => 'HTML'), 17 | 'json' => array('type' => 'application/json', 'label' => 'JSON'), 18 | 'ttl' => array('type' => 'text/turtle', 'label' => 'Turtle'), 19 | ); 20 | function __construct($desc_uri, $resource_uri, $type) { 21 | $this->_uri = $desc_uri; 22 | $this->_primary_resource = $resource_uri; 23 | $this->_type = $type; 24 | $this->read_triples(); 25 | parent::__construct(); 26 | 27 | } 28 | 29 | function get_prefix_mappings() { 30 | return array_flip($this->_ns); 31 | } 32 | 33 | function is_valid() { 34 | return $this->_is_valid; 35 | } 36 | 37 | function read_triples() { 38 | $resources = $this->get_resources(); 39 | if (count($resources) > 0) { 40 | $this->_primary_resource = $resources[0]; 41 | } 42 | $this->add_representation_triples(); 43 | 44 | 45 | 46 | 47 | $this->_is_valid = false; 48 | foreach ($resources as $resource_uri) { 49 | $this->add_resource_triple( $this->_uri, FOAF_TOPIC, $resource_uri ); 50 | $generators = $this->get_generators(); 51 | foreach ($generators as $generator) { 52 | $generator->add_triples($resource_uri, $this); 53 | } 54 | 55 | if ( array_key_exists($resource_uri, $this->get_index())) { 56 | $this->_is_valid = true; 57 | } 58 | } 59 | 60 | $augmentors = $this->get_augmentors(); 61 | foreach ($augmentors as $augmentor) { 62 | $augmentor->process($this); 63 | } 64 | } 65 | 66 | function add_representation_triples() { 67 | $this->add_resource_triple( $this->_uri, RDF_TYPE, FOAF_DOCUMENT ); 68 | $this->add_resource_triple( $this->_uri, RDF_TYPE, 'http://purl.org/dc/dcmitype/Text' ); 69 | $this->add_resource_triple( $this->_uri, FOAF_PRIMARYTOPIC, $this->_primary_resource ); 70 | 71 | $parts = parse_url($this->_uri); 72 | 73 | if ( preg_match('~^(.+)\.(html|rdf|json|ttl)$~', $parts['path'], $m)) { 74 | $base_uri = $parts['scheme'] . '://' . $parts['host'] . $m[1]; 75 | $suffix = ''; 76 | if (array_key_exists('query', $parts) && strlen($parts['query']) > 0) $suffix = '?' . $parts['query']; 77 | 78 | foreach ($this->_media_types as $extension => $type_info) { 79 | if ( $extension != $this->_type) { 80 | $this->add_resource_triple( $this->_uri, 'http://purl.org/dc/terms/hasFormat', $base_uri. '.' . $extension . $suffix ); 81 | $this->add_resource_triple( $base_uri. '.' . $extension . $suffix , RDF_TYPE, 'http://purl.org/dc/dcmitype/Text' ); 82 | $this->add_resource_triple( $base_uri. '.' . $extension . $suffix , RDF_TYPE, FOAF_DOCUMENT ); 83 | $this->add_literal_triple( $base_uri. '.' . $extension . $suffix , 'http://purl.org/dc/elements/1.1/format', $type_info['type'] ); 84 | $this->add_literal_triple( $base_uri. '.' . $extension . $suffix , RDFS_LABEL, $type_info['label'] ); 85 | } 86 | } 87 | } 88 | } 89 | 90 | 91 | function get_resources() { 92 | $resources = array($this->_primary_resource); 93 | return $resources; 94 | } 95 | 96 | 97 | function get_generators() { 98 | return array( ); 99 | } 100 | 101 | function get_augmentors() { 102 | return array( new PAGET_SimplePropertyLabeller() ); 103 | } 104 | 105 | function get_primary_resource_uri() { 106 | return $this->_primary_resource; 107 | } 108 | 109 | function get_uri() { 110 | return $this->_uri; 111 | } 112 | 113 | function get_label($resource_uri = null) { 114 | if ($resource_uri == null) { 115 | $resource_uri = $this->_primary_resource; 116 | } 117 | $label = $this->get_first_literal($resource_uri,'http://www.w3.org/2004/02/skos/core#prefLabel', '', 'en'); 118 | if ( strlen($label) == 0) { 119 | $label = $this->get_first_literal($resource_uri,RDFS_LABEL, '', 'en'); 120 | } 121 | if ( strlen($label) == 0) { 122 | $label = $this->get_first_literal($resource_uri,'http://purl.org/dc/terms/title', '', 'en'); 123 | } 124 | if ( strlen($label) == 0) { 125 | $label = $this->get_first_literal($resource_uri,DC_TITLE, '', 'en'); 126 | } 127 | if ( strlen($label) == 0) { 128 | $label = $this->get_first_literal($resource_uri,'http://purl.org/rss/1.0/title', '', 'en'); 129 | } 130 | if ( strlen($label) == 0) { 131 | $label = $this->get_first_literal($resource_uri,FOAF_NAME, '', 'en'); 132 | } 133 | if ( strlen($label) == 0) { 134 | $label = $this->get_first_literal($resource_uri,RDF_VALUE, '', 'en'); 135 | } 136 | if ( strlen($label) == 0) { 137 | $label = $resource_uri; 138 | } 139 | 140 | 141 | return $label; 142 | } 143 | 144 | 145 | function get_description($resource_uri = null) { 146 | if ($resource_uri == null) { 147 | $resource_uri = $this->_primary_resource; 148 | } 149 | $text = $this->get_first_literal($resource_uri,'http://purl.org/dc/terms/description', '', 'en'); 150 | if ( strlen($text) == 0) { 151 | $text = $this->get_first_literal($resource_uri,DC_DESCRIPTION, '', 'en'); 152 | } 153 | if ( strlen($text) == 0) { 154 | $text = $this->get_first_literal($resource_uri,RDFS_COMMENT, '', 'en'); 155 | } 156 | if ( strlen($text) == 0) { 157 | $text = $this->get_first_literal($resource_uri,'http://purl.org/rss/1.0/description', '', 'en'); 158 | } 159 | if ( strlen($text) == 0) { 160 | $text = $this->get_first_literal($resource_uri,'http://vocab.org/bio/0.1/olb', '', 'en'); 161 | } 162 | return $text; 163 | } 164 | function get(&$urispace,&$request) { 165 | 166 | 167 | $accepts = $request->accept; 168 | 169 | if ($this->_type == 'rdf') { 170 | $response = new PAGET_Response(200, $this->to_rdfxml(), array('content-type'=>'application/rdf+xml') ); 171 | } 172 | else if ($this->_type == 'json') { 173 | $response = new PAGET_Response(200, $this->to_json(), array('content-type'=>'application/json') ); 174 | } 175 | else if ($this->_type == 'ttl') { 176 | $response = new PAGET_Response(200, $this->to_turtle(), array('content-type'=>'text/turtle') ); 177 | } 178 | else if ($this->_type == 'html') { 179 | $response = new PAGET_Response(200, $this->get_html($urispace, $request), array('content-type'=>'text/html') ); 180 | } 181 | else { 182 | $response = new PAGET_Response(200, $this->get_html($urispace, $request), array('content-type'=>'text/html') ); 183 | // $response = new PAGET_Response(200, $this->to_rdfxml(), array('content-type'=>'application/rdf+xml') ); 184 | } 185 | return $response; 186 | } 187 | 188 | function set_template($tmpl) { 189 | $this->_template = $tmpl; 190 | } 191 | 192 | function get_html(&$urispace, &$request) { 193 | $tmpl = $this->_template; 194 | if ( null == $tmpl ) { 195 | $tmpl = $urispace->get_template($request); 196 | } 197 | if ( null == $tmpl ) { 198 | $tmpl = PAGET_DIR . 'templates' . DIRECTORY_SEPARATOR . 'plain.tmpl.html'; 199 | } 200 | 201 | $template = new PAGET_Template($tmpl, $this, $urispace, $request); 202 | return $template->execute(); 203 | 204 | } 205 | 206 | 207 | function get_inverse_index() { 208 | if ($this->_inverse_index == null) { 209 | $g = new SimpleGraph(); 210 | 211 | foreach ($this->_index as $s => $p_list) { 212 | foreach ($p_list as $p => $v_list) { 213 | foreach ($v_list as $v_info) { 214 | if ( isset($v_info['type']) && $v_info['type'] == 'uri' ) { 215 | $g->add_resource_triple($v_info['value'], $p, $s); 216 | } 217 | } 218 | } 219 | } 220 | 221 | $this->_inverse_index = $g->get_index(); 222 | } 223 | return $this->_inverse_index; 224 | } 225 | 226 | function consume_first_literal($s, $p, $def = '') { 227 | return $this->get_first_literal($s, $p, $def); 228 | } 229 | 230 | 231 | // This function maps a URI to a local equivalent 232 | // Override this when you want the link in your HTML output to point to somewhere other than the URI itself, e.g. a proxy 233 | // The default implementation rewrites URIs to the domain name suffixed with .local for assisting with testing 234 | // For example http://example.com/foo might map to http://example.com.local/foo if the application is being accessed from example.com.local 235 | function map_uri($uri) { 236 | if (isset($_SERVER["HTTP_HOST"])) { 237 | if (preg_match('~http://([^/]+)/~i', $uri, $m)) { 238 | if ( $_SERVER["HTTP_HOST"] == $m[1] . '.local' ) { 239 | return str_replace($m[1], $_SERVER["HTTP_HOST"], $uri); 240 | } 241 | else { 242 | return $uri; 243 | } 244 | } 245 | } 246 | } 247 | 248 | } 249 | -------------------------------------------------------------------------------- /patches/paget/paget_storebackedurispace.class.php: -------------------------------------------------------------------------------- 1 | _store_uri = $store_uri; 18 | } 19 | 20 | function get_resource($request) { 21 | $request_uri = $request->uri; 22 | 23 | if ( preg_match('~^(.+)\.(html|rdf|json|ttl)$~', $request->full_path, $m)) { 24 | $base_path = $m[1]; 25 | $type = $m[2]; 26 | if ($base_path == $this->_base_path. '~search') { 27 | $query = isset($request->data["query"]) ? $request->data["query"] : ''; 28 | $offset = isset($request->data["offset"]) ? $request->data["offset"] : '0'; 29 | 30 | $desc = new PAGET_StoreSearch($request_uri, $type, $this->_store_uri, $query, 30, $offset); 31 | $desc->set_template($this->_description_template); 32 | return $desc; 33 | } 34 | else if ($base_path == $this->_base_path. '~browse') { 35 | if (! defined('AUTH_USER') && ! defined('AUTH_PWD')) return null; 36 | $token = isset($request->data["token"]) ? $request->data["token"] : null; 37 | 38 | $desc = new PAGET_StoreOAI($request_uri, $type, $this->_store_uri, $token); 39 | $desc->set_template($this->_description_template); 40 | return $desc; 41 | 42 | } 43 | else { 44 | $resource_uri = preg_replace("~\.local/~", "/", substr($request->uri, 0, strlen($request->uri)-strlen($type) - 1)); 45 | if (isset($this->_static_data[$resource_uri])) { 46 | $desc = new PAGET_FileBackedResourceDescription($request_uri, $resource_uri, $type, $this->_static_data[$resource_uri], 'rdfxml'); 47 | } 48 | else { 49 | $desc = new PAGET_StoreBackedResourceDescription($request_uri, $resource_uri, $type, $this->_store_uri); 50 | } 51 | $desc->set_template($this->_description_template); 52 | foreach ($this->_ns as $short_name => $uri) { 53 | $desc->set_namespace_mapping($short_name , $uri); 54 | } 55 | if ($desc->is_valid()) { 56 | return $desc; 57 | } 58 | } 59 | } 60 | else { 61 | return new PAGET_AbstractResource($request_uri); 62 | } 63 | 64 | return null; 65 | } 66 | 67 | function set_namespace_mapping($short_name, $uri) { 68 | $this->_ns[$short_name] = $uri; 69 | } 70 | 71 | function set_static_data($resource_uri, $filename) { 72 | $this->_static_data[$resource_uri] = $filename; 73 | } 74 | function set_description_template($filename) { 75 | $this->_description_template = $filename; 76 | } 77 | 78 | function set_search_template($filename) { 79 | $this->_search_template = $filename; 80 | } 81 | 82 | function get_template($request) { 83 | return $this->_description_template; 84 | } 85 | 86 | function set_base_path($path) { 87 | $this->_base_path = $path; 88 | } 89 | } 90 | 91 | -------------------------------------------------------------------------------- /patches/paget/paget_template.class.php: -------------------------------------------------------------------------------- 1 | desc = $desc; 21 | $this->template_filename = $template_filename; 22 | $this->urispace = $urispace; 23 | $this->request = $request; 24 | 25 | $this->table_widget = new PAGET_TableDataWidget($this->desc, $this, $urispace); 26 | $this->seq_widget = new PAGET_SeqWidget($this->desc, $this, $urispace); 27 | $this->bag_widget = new PAGET_BagWidget($this->desc, $this, $urispace); 28 | $this->rss_widget = new PAGET_RSSWidget($this->desc, $this, $urispace); 29 | $this->ontology_widget = new PAGET_OntologyWidget($this->desc, $this, $urispace); 30 | $this->term_widget = new PAGET_TermWidget($this->desc, $this, $urispace); 31 | $this->literal_widget = new PAGET_LiteralWidget($this->desc, $this, $urispace); 32 | 33 | } 34 | 35 | function execute() { 36 | ob_start(); 37 | try { 38 | include($this->template_filename); 39 | $buffer = ob_get_clean(); 40 | return $buffer; 41 | } 42 | catch (Exception $ex) { 43 | ob_end_clean(); 44 | throw $ex; 45 | } 46 | } 47 | 48 | function get_title($resource_uri = null) { 49 | return $this->desc->get_label($resource_uri, $this); 50 | } 51 | 52 | function get_description($resource_uri = null) { 53 | return $this->desc->get_description($resource_uri, $this); 54 | } 55 | 56 | 57 | 58 | function render($resource_info, $inline = FALSE, $brief = FALSE) { 59 | if ($resource_info['type'] == 'bnode' || $resource_info['type'] == 'uri') { 60 | $resource_uri = $resource_info['value']; 61 | if ( $this->desc->has_resource_triple($resource_uri, RDF_TYPE, RDF_PROPERTY) || $this->desc->has_resource_triple($resource_uri, RDF_TYPE, RDFS_CLASS) ) { 62 | $widget = $this->term_widget; 63 | } 64 | else if ( $this->desc->has_resource_triple($resource_uri, RDF_TYPE, 'http://www.w3.org/2002/07/owl#Ontology') ) { 65 | $widget = $this->ontology_widget; 66 | } 67 | else if ( $this->desc->has_resource_triple($resource_uri, RDF_TYPE, 'http://purl.org/rss/1.0/channel') ) { 68 | $widget = $this->rss_widget; 69 | } 70 | else if ( $this->desc->has_resource_triple($resource_uri, RDF_TYPE, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq') ) { 71 | $widget = $this->seq_widget; 72 | } 73 | else if ( $this->desc->has_resource_triple($resource_uri, RDF_TYPE, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag') ) { 74 | $widget = $this->bag_widget; 75 | } 76 | else { 77 | $widget = $this->table_widget; 78 | } 79 | } 80 | else { 81 | $widget = $this->literal_widget; 82 | } 83 | return $widget->render($resource_info, $inline, $brief); 84 | } 85 | 86 | 87 | 88 | function exclude($resource_uri, $property_uri) { 89 | $this->excludes[$resource_uri . ' ' . $property_uri] = 1; 90 | } 91 | 92 | function is_excluded($resource_uri, $property_uri) { 93 | return array_key_exists($resource_uri . ' ' . $property_uri, $this->excludes); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /patches/paget/paget_termwidget.class.php: -------------------------------------------------------------------------------- 1 | render_brief($resource_info, $inline); 8 | $resource_uri = $resource_info['value']; 9 | $ret = $other = ''; 10 | if (!$inline) { 11 | $ret .= '' .htmlspecialchars( $this->get_title($resource_uri)) . ''; 12 | } 13 | 14 | 15 | $index = $this->desc->get_index(); 16 | $inverse_index = $this->desc->get_inverse_index(); 17 | $is_property = $this->desc->has_resource_triple( $resource_uri, RDF_TYPE, RDF_PROPERTY ); 18 | 19 | $ret .= '

URI: ' . $this->link_uri($resource_uri, $resource_uri) . '

'; 20 | $ret .= '

' . htmlspecialchars($this->get_description($resource_uri)) . '

'; 21 | 22 | $data = array(); 23 | 24 | if ( $this->desc->subject_has_property($resource_uri, 'http://purl.org/vocab/vann/usageNote') ) { 25 | $ret .= 'Usage'; 26 | $literal_widget = new PAGET_LiteralWidget($this->desc, $this->template, $this->urispace); 27 | foreach ($this->desc->get_subject_property_values($resource_uri, 'http://purl.org/vocab/vann/usageNote') as $value) { 28 | $ret .= sprintf('
%s
', $literal_widget->render($value, FALSE, FALSE)); 29 | } 30 | } 31 | 32 | 33 | $semantics = ''; 34 | if ($is_property) { 35 | $characteristics = array(); 36 | 37 | if ( $this->desc->has_resource_triple( $resource_uri, RDF_TYPE, OWL_SYMMETRICPROPERTY ) ) { 38 | $characteristics[] = 'symmetrical'; 39 | } 40 | if ( $this->desc->has_resource_triple( $resource_uri, RDF_TYPE, OWL_TRANSITIVEPROPERTY ) ) { 41 | $characteristics[] = 'transitive'; 42 | } 43 | if ( $this->desc->has_resource_triple( $resource_uri, RDF_TYPE, OWL_FUNCTIONALPROPERTY ) ) { 44 | $characteristics[] = 'functional'; 45 | } 46 | if ( $this->desc->has_resource_triple( $resource_uri, RDF_TYPE, OWL_INVERSEFUNCTIONALPROPERTY ) ) { 47 | $characteristics[] = 'inverse functional'; 48 | } 49 | 50 | 51 | if ( count($characteristics) > 0 ) { 52 | $semantics .= 'This property is '; 53 | for ($i = 0; $i < count($characteristics); $i++) { 54 | if ( $i > 0 ) { 55 | if ($i == count($characteristics) - 1) { $semantics .= ' and '; } 56 | else { $semantics .= ', '; } 57 | } 58 | $semantics .= $characteristics[$i]; 59 | } 60 | $semantics .= '. '; 61 | } 62 | 63 | $semantics .= $this->list_relations_prose($index, $resource_uri, RDFS_DOMAIN, 'Having this property implies being ','. '); 64 | $semantics .= $this->list_relations_prose($index, $resource_uri, RDFS_RANGE, 'Every value of this property is ','. '); 65 | 66 | if ( $this->desc->subject_has_property($resource_uri, OWL_INVERSEOF ) ) { 67 | if ( $this->desc->subject_has_property($resource_uri, RDFS_SUBPROPERTYOF ) ) { 68 | $semantics .= $this->list_relations_prose($index, $resource_uri, RDFS_SUBPROPERTYOF, 'It is a sub-property of ', ' and ', FALSE); 69 | } 70 | else { 71 | $semantics .= 'It is '; 72 | } 73 | $semantics .= $this->list_relations_prose($index, $resource_uri, OWL_INVERSEOF, 'the inverse of ', '', FALSE); 74 | } 75 | else { 76 | $semantics .= $this->list_relations_prose($index, $resource_uri, RDFS_SUBPROPERTYOF, 'It is a sub-property of ', '. ', FALSE); 77 | } 78 | $semantics .= $this->list_relations_prose($index, $resource_uri, OWL_EQUIVALENTPROPERTY, 'It is equivalent to ', '', FALSE); 79 | 80 | 81 | } 82 | else { 83 | $restrictions = array(); 84 | if ( $this->desc->subject_has_property($resource_uri, RDFS_SUBCLASSOF ) ) { 85 | foreach ($this->desc->get_resource_triple_values($resource_uri, RDFS_SUBCLASSOF) as $super_uri) { 86 | if ($this->desc->has_resource_triple($super_uri, RDF_TYPE, 'http://www.w3.org/2002/07/owl#Restriction') ) { 87 | $restricted_property = $this->desc->get_first_resource($super_uri, 'http://www.w3.org/2002/07/owl#onProperty'); 88 | if ($this->desc->subject_has_property($super_uri, 'http://www.w3.org/2002/07/owl#cardinality')) { 89 | $restriction_value = $this->desc->get_first_literal($super_uri, 'http://www.w3.org/2002/07/owl#cardinality'); 90 | $restrictions[] = sprintf('exactly %s %s property', $restriction_value, $this->link_uri($restricted_property) ); 91 | } 92 | else if ($this->desc->subject_has_property($super_uri, 'http://www.w3.org/2002/07/owl#minCardinality')) { 93 | $restriction_value = $this->desc->get_first_literal($super_uri, 'http://www.w3.org/2002/07/owl#minCardinality'); 94 | $restrictions[] = sprintf('at least %s %s properties', $restriction_value, $this->link_uri($restricted_property) ); 95 | } 96 | else if ($this->desc->subject_has_property($super_uri, 'http://www.w3.org/2002/07/owl#maxCardinality')) { 97 | $restriction_value = $this->desc->get_first_literal($super_uri, 'http://www.w3.org/2002/07/owl#maxCardinality'); 98 | $restrictions[] = sprintf('at most %s %s properties', $restriction_value, $this->link_uri($restricted_property) ); 99 | } 100 | } 101 | } 102 | } 103 | 104 | if ($restrictions) { 105 | $semantics .= 'Every member of this class has '; 106 | for ($i = 0; $i < count($restrictions); $i++) { 107 | if ($i > 0) { 108 | if ($i == count($restrictions) - 1) { 109 | $semantics .= ' and '; 110 | } 111 | else { 112 | $semantics .= ', '; 113 | } 114 | } 115 | $semantics .= $restrictions[$i]; 116 | } 117 | $semantics .= '. '; 118 | } 119 | 120 | $semantics .= $this->list_relations_prose($index, $resource_uri, RDFS_SUBCLASSOF, 'Being a member of this class implies also being a member of ', '. ', false); 121 | $semantics .= $this->list_relations_prose($index, $resource_uri, OWL_DISJOINTWITH, 'No member of this class can also be a member of ', '. ', false, 'or'); 122 | $semantics .= $this->list_relations_prose($inverse_index, $resource_uri, RDFS_DOMAIN, 'Having', ' implies being a member of this class. ', true, 'or'); 123 | $semantics .= $this->list_relations_prose($inverse_index, $resource_uri, RDFS_RANGE, 'Things are a member of this class if they are the value of ', '. ', true, 'or'); 124 | $semantics .= $this->list_relations_prose($index, $resource_uri, OWL_EQUIVALENTCLASS, 'It is equivalent to ', '. ', FALSE); 125 | } 126 | 127 | if ($semantics) { 128 | $ret .= 'Semantics'; 129 | $ret .= sprintf('

%s

', $semantics); 130 | } 131 | 132 | if ( $this->desc->subject_has_property($resource_uri, 'http://purl.org/vocab/vann/example') ) { 133 | $ret .= 'Examples'; 134 | foreach ($this->desc->get_subject_property_values($resource_uri, 'http://purl.org/vocab/vann/example') as $v_info) { 135 | $title = $this->desc->get_first_literal($v_info['value'], array(RDFS_LABEL, DC_TITLE), 'Example', 'en'); 136 | $comment = $this->desc->get_first_literal($v_info['value'], array(RDFS_COMMENT), '', 'en'); 137 | if ($comment) { 138 | $ret .= '' . htmlspecialchars($title) . ''; 139 | $ret .= $comment; 140 | } 141 | } 142 | 143 | } 144 | 145 | if ( $this->desc->subject_has_property($resource_uri, 'http://www.w3.org/2004/02/skos/core#changeNote') || $this->desc->subject_has_property($resource_uri, 'http://www.w3.org/2004/02/skos/core#historyNote' ) || $this->desc->subject_has_property($resource_uri, 'http://purl.org/dc/terms/issued' ) ) { 146 | $ret .= 'Status'; 147 | 148 | if ($this->desc->subject_has_property($resource_uri, 'http://www.w3.org/2003/06/sw-vocab-status/ns#term_status')) { 149 | $status_code = $this->desc->get_first_literal($resource_uri, 'http://www.w3.org/2003/06/sw-vocab-status/ns#term_status', ''); 150 | if ( $status_code == 'unstable') { 151 | $status = 'is deemed to be semantically unstable and is subject to its meaning being changed.'; 152 | } 153 | else if ( $status_code == 'stable') { 154 | $status = 'is deemed to be semantically stable and its meaning should not change in the foreseable future.'; 155 | } 156 | else if ( $status_code == 'testing') { 157 | $status = 'is undergoing testing to determine if it is semantically stable and its meaning may change in the foreseable future.'; 158 | } 159 | } 160 | 161 | if ($status) { 162 | $ret .= sprintf('

This term %s

', $status); 163 | } 164 | 165 | $history_widget = new PAGET_HistoryWidget($this->desc, $this->template, $this->urispace); 166 | $ret .= $history_widget->render($resource_info, FALSE, FALSE); 167 | } 168 | 169 | $data_widget = new PAGET_TableDataWidget($this->desc, $this->template, $this->urispace); 170 | $data_widget->ignore_properties($this->ignore_properties); 171 | $data_widget->ignore_properties(array(RDF_TYPE, DC_TITLE, RDFS_LABEL, DC_DESCRIPTION, RDFS_COMMENT, 'http://purl.org/vocab/vann/example', 'http://www.w3.org/2003/06/sw-vocab-status/ns#term_status', 'http://www.w3.org/2004/02/skos/core#definition')); 172 | $data_widget->ignore_properties(array(OWL_EQUIVALENTCLASS, RDFS_RANGE, RDFS_DOMAIN, OWL_DISJOINTWITH, RDFS_SUBCLASSOF, RDFS_SUBPROPERTYOF, OWL_EQUIVALENTPROPERTY, OWL_INVERSEOF, OWL_SYMMETRICPROPERTY, OWL_FUNCTIONALPROPERTY, OWL_INVERSEFUNCTIONALPROPERTY, OWL_TRANSITIVEPROPERTY )); 173 | $data_widget->ignore_properties(array('http://www.w3.org/2004/02/skos/core#changeNote', 'http://www.w3.org/2004/02/skos/core#historyNote', 'http://purl.org/dc/terms/issued')); 174 | $data_widget->ignore_properties(array('http://purl.org/vocab/vann/usageNote', 'http://purl.org/net/vocab/2004/03/label#plural')); 175 | $other .= $data_widget->render($resource_info, FALSE, FALSE); 176 | if (strlen(trim($other)) > 0) { 177 | $ret .= 'Other Information' . $other; 178 | } 179 | 180 | return $ret; 181 | } 182 | 183 | 184 | 185 | function get_description($resource_uri, $brief = FALSE) { 186 | $definition = ''; 187 | $status = ''; 188 | $intro = ''; 189 | $info = ''; 190 | 191 | if ($this->desc->has_resource_triple( $resource_uri, RDF_TYPE, RDF_PROPERTY )) { 192 | $intro = 'A property representing '; 193 | } 194 | else if ($this->desc->has_resource_triple( $resource_uri, RDF_TYPE, RDFS_CLASS )) { 195 | $intro = 'A class whose members are '; 196 | } 197 | 198 | 199 | if ($this->desc->subject_has_property($resource_uri, 'http://www.w3.org/2004/02/skos/core#definition')) { 200 | if (strlen($info) == 0 && strlen(intro) > 0) { 201 | $info = $intro . lcfirst($this->desc->get_first_literal($resource_uri, 'http://www.w3.org/2004/02/skos/core#definition', '')); 202 | } 203 | else { 204 | $info .= $this->desc->get_first_literal($resource_uri, 'http://www.w3.org/2004/02/skos/core#definition', ''); 205 | } 206 | } 207 | $info .= $this->add_period_if_needed($info); 208 | 209 | if ($brief == FALSE || strlen($info) == 0) { 210 | $comments = $this->desc->get_literal_triple_values($resource_uri, RDFS_COMMENT); 211 | foreach ($comments as $comment) { 212 | $info .= ' ' . $comment; 213 | $info .= $this->add_period_if_needed($info); 214 | } 215 | 216 | if (strlen($status) > 0) { 217 | $info .= $this->add_period_if_needed($info); 218 | $info .= ' This term ' . $status; 219 | } 220 | } 221 | return $info; 222 | 223 | } 224 | 225 | function add_period_if_needed($text) { 226 | if (strlen($text) ==0 || preg_match('~\.\s*$~', $text) ) return ''; 227 | return '. '; 228 | } 229 | 230 | 231 | function list_relations_prose(&$index, $uri, $property, $prefix, $suffix='', $use_definite_article = true, $conjunction = 'and') { 232 | $ret = ''; 233 | if ( array_key_exists($uri, $index)) { 234 | if ( array_key_exists($property, $index[$uri])) { 235 | $ret .= htmlspecialchars($prefix) . ' '; 236 | $values = array(); 237 | for ($i = 0 ; $i < count($index[$uri][$property]); $i++) { 238 | if ($index[$uri][$property][$i]['value'] != $uri) { 239 | $is_restriction = FALSE; 240 | $value = $index[$uri][$property][$i]['value']; 241 | if ( isset($index[$value][RDF_TYPE]) ) { 242 | for ($tmp = 0; $tmp < count($index[$value][RDF_TYPE]); $tmp++) { 243 | if ($index[$value][RDF_TYPE][$tmp]['value'] == 'http://www.w3.org/2002/07/owl#Restriction') { 244 | $is_restriction = TRUE; 245 | } 246 | } 247 | } 248 | if (! $is_restriction) { 249 | $values[] = $index[$uri][$property][$i]; 250 | } 251 | } 252 | } 253 | 254 | for ($i = 0 ; $i < count($values); $i++) { 255 | if ($i > 0) { 256 | if ($i < count($values) - 1) { $ret .= ', '; } 257 | else if ($i == count($values) - 1) { $ret .= ' ' . $conjunction . ' '; } 258 | } 259 | $text = $values[$i]['value']; 260 | $ret .= $this->link_uri($text, '', $use_definite_article); 261 | } 262 | $ret .= htmlspecialchars($suffix); 263 | } 264 | } 265 | 266 | return $ret; 267 | } 268 | 269 | 270 | function list_relations(&$index, $uri, $property, $label) { 271 | $ret = ''; 272 | if ( array_key_exists($uri, $index)) { 273 | if ( array_key_exists($property, $index[$uri])) { 274 | $ret .= htmlspecialchars($label) . ': '; 275 | for ($i = 0 ; $i < count($index[$uri][$property]); $i++) { 276 | if ($i > 0) { $ret .= ', '; } 277 | $ret .= $this->link_uri($index[$uri][$property][$i]['value']); 278 | } 279 | } 280 | } 281 | $ret .= '.'; 282 | return $ret; 283 | } 284 | } 285 | -------------------------------------------------------------------------------- /scripts/fuseki.importrdf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PRWODI=$PWD 4 | BN=$BASENAME 5 | 6 | for file in *.ttl; 7 | do 8 | filename=$(basename $file); 9 | extension=${filename##*.}; 10 | graph=${filename%.*}; 11 | sudo /etc/fuseki/./s-put --verbose http://localhost:3030/site/data http://site/graph/$graph $file; 12 | done; 13 | -------------------------------------------------------------------------------- /templates/foot.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /templates/footer.html: -------------------------------------------------------------------------------- 1 | 44 | 45 | -------------------------------------------------------------------------------- /templates/head.html: -------------------------------------------------------------------------------- 1 | 2 | <?php e($title); echo " — ".$c['site']['name'];?> 3 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | desc->get_resource_triple_values($this->desc->get_uri(), 'http://purl.org/dc/terms/hasFormat'); 23 | foreach ($formats as $format_uri) { 24 | $media_type = $this->desc->get_first_literal($format_uri, 'http://purl.org/dc/elements/1.1/format'); 25 | $label = $this->desc->get_first_literal($format_uri, RDFS_LABEL, $media_type); 26 | echo ' ' . "\n"; 27 | } 28 | ?> 29 | 30 | -------------------------------------------------------------------------------- /templates/header.html: -------------------------------------------------------------------------------- 1 | 23 | 24 | -------------------------------------------------------------------------------- /templates/html.html: -------------------------------------------------------------------------------- 1 | desc->get_primary_resource_uri(); 3 | $title = $this->get_title($resource_uri); 4 | $description = $this->get_description($resource_uri); 5 | $description = ($description == '') ? $this->get_title($resource_uri) : $description; 6 | 7 | $sC = $this->sC; 8 | $c = $sC->getConfig(); 9 | 10 | $entitySetId = $sC->getEntitySetId(); 11 | 12 | $charset = "utf-8"; 13 | $lang = "en"; 14 | 15 | $xmlProlog = ''; 16 | 17 | if ( stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml") || stristr($_SERVER["HTTP_ACCEPT"],"application/xml") || stristr($_SERVER["HTTP_ACCEPT"],"text/xml") || !isset($_SERVER["HTTP_ACCEPT"])) { 18 | 19 | if (stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml")) { 20 | $contentType="application/xhtml+xml"; 21 | } 22 | else if (stristr($_SERVER["HTTP_ACCEPT"],"application/xml")) { 23 | $contentType="application/xml"; 24 | } 25 | else if (stristr($_SERVER["HTTP_ACCEPT"],"text/xml")) { 26 | $contentType="text/xml"; 27 | } 28 | else { 29 | $contentType="application/xhtml+xml"; 30 | } 31 | 32 | $xmlProlog = ''."\n"; 33 | } 34 | else { 35 | $contentType = "text/html"; 36 | } 37 | 38 | header ("Content-Type: $contentType; charset=$charset"); 39 | header ("Content-Language: $lang"); 40 | 41 | echo $xmlProlog; 42 | ?> 43 | 44 | 57 | -------------------------------------------------------------------------------- /templates/nav.html: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /templates/page.about.html: -------------------------------------------------------------------------------- 1 | desc->get_primary_resource_uri(); 3 | $title = $this->get_title($resource_uri); 4 | 5 | $sC = $this->sC; 6 | $c = $sC->getConfig(); 7 | 8 | $entitySetId = $sC->getEntitySetId(); 9 | 10 | echo ''."\n"; 11 | ?> 12 | 13 | 23 | 24 | About <?php echo $c['site']['name'];?> 25 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | desc->get_resource_triple_values($this->desc->get_uri(), 'http://purl.org/dc/terms/hasFormat'); 45 | foreach ($formats as $format_uri) { 46 | $media_type = $this->desc->get_first_literal($format_uri, 'http://purl.org/dc/elements/1.1/format'); 47 | $label = $this->desc->get_first_literal($format_uri, RDFS_LABEL, $media_type); 48 | echo ' ' . "\n"; 49 | } 50 | ?> 51 | 52 | 53 | 54 | 55 |
56 | 57 |
58 | 59 |
60 |

About this package

61 | 62 |
63 |
64 |

Who is behind this?

65 | 66 |

This package is created by Linked Data Research Centre, DERI, NUI Galway with support of the EC FP7 Integrated Project Creating Knowledge out of Interlinked Data (LOD2) and the EC FP7 Support Action LOD Around The Clock (LATC).

67 |
68 |
Partners
69 |
70 |
    71 |
  • 72 |
  • LOD2 logo
  • 73 |
  • LATC logo
  • 74 |
  • FP7 Logo
  • 75 |
76 |
77 |
78 |
79 |
80 |
81 | 82 |
83 |
Page notice
84 |
85 | 89 |
90 |
91 |
92 | 93 | 95 | 96 |
97 | 98 | -------------------------------------------------------------------------------- /templates/page.class.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 |
9 | 10 |
11 | 12 |
13 |

This page is about

14 | 15 |
16 |
17 | renderClass(); 19 | ?> 20 | 21 |
22 | 23 |
24 |
25 |
26 | 27 |
28 | 29 | -------------------------------------------------------------------------------- /templates/page.default.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 |
9 | 10 |
11 | 12 |
13 |

This page is about

14 | 15 |
16 |
17 | render(array('value' => $resource_uri, 'type'=>'uri'), FALSE); 19 | ?> 20 | 21 |
22 | 23 |
24 |
25 |
26 | 27 |
28 | 29 | -------------------------------------------------------------------------------- /templates/page.home.html: -------------------------------------------------------------------------------- 1 | desc->get_primary_resource_uri(); 3 | $title = $this->get_title($resource_uri); 4 | 5 | $sC = $this->sC; 6 | $c = $sC->getConfig(); 7 | 8 | $entitySetId = $sC->getEntitySetId(); 9 | 10 | echo ''."\n"; 11 | ?> 12 | 13 | 23 | 24 | <?php echo $c['site']['name'];?> 25 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | desc->get_resource_triple_values($this->desc->get_uri(), 'http://purl.org/dc/terms/hasFormat'); 45 | foreach ($formats as $format_uri) { 46 | $media_type = $this->desc->get_first_literal($format_uri, 'http://purl.org/dc/elements/1.1/format'); 47 | $label = $this->desc->get_first_literal($format_uri, RDFS_LABEL, $media_type); 48 | echo ' ' . "\n"; 49 | } 50 | ?> 51 | 52 | 53 | 54 | 55 |
56 | 57 |
58 | 59 |
60 |

Welcome!

61 | 62 |
63 |
64 |

Looks like things are in order!

65 |

But, don't just stop here, make your Linked Data site better:

66 |
    67 |
  • Create templates
  • 68 |
  • Create new queries for those templates
  • 69 |
70 |
71 |
72 |
73 | 74 |
75 |
Page notice
76 |
77 | 81 |
82 |
83 |
84 | 85 | 87 | 88 |
89 | 90 | -------------------------------------------------------------------------------- /theme/base/css/display.css: -------------------------------------------------------------------------------- 1 | /** theme: base 2 | * 3 | * @author Sarven Capadisli 4 | * @license http://creativecommons.org/licenses/by/3.0/ Creative Commons Attribution 3.0 Unported 5 | */ 6 | 7 | @font-face { 8 | font-family: "CMU Sans Serif Medium"; 9 | src: local("CMU Sans Serif Medium"), url("http://linked-research.270a.info/media/fonts/cmunss.otf"); 10 | } 11 | @font-face { 12 | font-family: "CMU Sans Serif Bold"; 13 | src: local("CMU Sans Serif Bold"), url("http://linked-research.270a.info/media/fonts/cmunsx.otf"); 14 | font-weight: bold !important; 15 | } 16 | @font-face { 17 | font-family: "CMU Sans Serif Italic"; 18 | src: local("CMU Sans Serif Italic"), url("http://linked-research.270a.info/media/fonts/cmunsi.otf"); 19 | font-style: italic, oblique !important; 20 | } 21 | @font-face { 22 | font-family: "CMU Sans Serif Bold Italic"; 23 | src: local("CMU Sans Serif Bold Italic"), url("http://linked-research.270a.info/media/fonts/cmunbxo.otf"); 24 | font-weight: bold; 25 | font-style: italic, oblique; 26 | } 27 | @font-face { 28 | font-family: "CMU Sans Serif Monospace"; 29 | src: local("CMU Sans Serif Monospace"), url("http://linked-research.270a.info/media/fonts/cmuntt.otf"); 30 | } 31 | 32 | 33 | @media screen, projection, tv { 34 | * { margin:0; padding:0; } 35 | img { display:block; border:0; } 36 | a abbr { cursor: pointer; border-bottom:0; } 37 | table { border-collapse:collapse; } 38 | tr { vertical-align:top; } 39 | ol { list-style-position:inside; } 40 | /*html { font-size: 87.5%; }*/ 41 | body { 42 | background-color:#FFFFFF; 43 | color:#000000; 44 | font-family: "CMU Sans Serif Medium", sans-serif !important; 45 | font-size:1.3em !important; 46 | line-height:1.65; 47 | position:relative; 48 | } 49 | h1,h2,h3,h4,h5,h6 { 50 | margin-bottom:0.5em; 51 | overflow:hidden; 52 | } 53 | h1 { 54 | font-size:1.8em; 55 | margin-bottom:1em; 56 | } 57 | h2 { font-size:1.6em; } 58 | h3 { font-size:1.3em; } 59 | h4 { font-size:1.1em; } 60 | h5 { font-size:1em; } 61 | h6 { font-size:0.9em; } 62 | 63 | code { font-size:1.2em; } 64 | 65 | h1,h2,h3,h4,h5,h6,b,strong, input[type="submit"], dt { 66 | font-family: "CMU Sans Serif Bold", sans-serif !important; 67 | } 68 | i, em, address { 69 | font-family: "CMU Sans Serif Italic", sans-serif !important; 70 | font-style:normal !important; 71 | } 72 | 73 | code, pre, kbd { 74 | font-family: "CMU Sans Serif Monospace", monospace !important; 75 | } 76 | 77 | legend { 78 | font-weight:bold; 79 | font-size:1.3em; 80 | } 81 | input, textarea, select, option, button { 82 | padding:4px; 83 | } 84 | input.submit { 85 | font-weight:bold; 86 | cursor:pointer; 87 | } 88 | textarea { 89 | overflow:auto; 90 | } 91 | option { 92 | padding-bottom:0; 93 | } 94 | fieldset { 95 | padding:0; 96 | border:0; 97 | } 98 | form ul li { 99 | list-style-type:none; 100 | margin:0 0 18px 0; 101 | } 102 | form label { 103 | font-weight:bold; 104 | } 105 | input.checkbox, 106 | input.radio { 107 | position:relative; 108 | top:2px; 109 | left:auto; 110 | border:0; 111 | } 112 | button { 113 | font-weight:bold; 114 | font-family: monospace; 115 | padding:0 4px; 116 | } 117 | 118 | kbd { 119 | font-weight:bold; 120 | padding:2px 6px; 121 | border-width:1px; 122 | border-style: solid 123 | border-radius:4px; 124 | -moz-border-radius:4px; 125 | -webkit-border-radius:4px; 126 | } 127 | 128 | 129 | .error, 130 | .success, 131 | .warning { 132 | padding:4px 1.55%; 133 | border-radius:4px; 134 | -moz-border-radius:4px; 135 | -webkit-border-radius:4px; 136 | margin-bottom:18px; 137 | border-width:2px; 138 | border-style:solid; 139 | } 140 | 141 | .dn { display:none; } 142 | 143 | caption { 144 | font-weight:bold; 145 | font-size:1.3em; 146 | text-align:left; 147 | } 148 | thead tr { 149 | border-bottom:0; 150 | } 151 | thead td { 152 | font-size:1.1em; 153 | font-weight:bold; 154 | } 155 | 156 | th, td { 157 | padding-top:0.5em; 158 | padding-bottom:0.5em; 159 | padding-right:1em; 160 | } 161 | th { 162 | text-align:left; 163 | } 164 | tr { 165 | border-bottom-width:1px; 166 | border-bottom-style:solid; 167 | } 168 | tr:last-child { 169 | border-bottom:0; 170 | } 171 | 172 | 173 | address { 174 | float:left; 175 | margin-left:18px; 176 | font-style:normal; 177 | width:50% 178 | } 179 | address.vcard img.logo { 180 | margin-right:0; 181 | } 182 | address .fn { 183 | font-weight:bold; 184 | } 185 | address img + .fn, 186 | address object + .fn { 187 | /*display:none;*/ 188 | margin-top:11px; 189 | } 190 | address a { 191 | text-decoration:none; 192 | } 193 | 194 | address img, 195 | address object, 196 | address span { 197 | float:left; 198 | } 199 | 200 | address img, 201 | address object { 202 | margin-right:18px; 203 | } 204 | address span { 205 | float:left; 206 | } 207 | 208 | 209 | #header { 210 | width:100%; 211 | position:relative; 212 | float:left; 213 | padding-top:18px; 214 | margin-bottom:18px; 215 | } 216 | 217 | #site_nav_global_primary { 218 | float:right; 219 | margin-right:18px; 220 | margin-bottom:11px; 221 | margin-left:18px; 222 | } 223 | #site_nav_global_primary dd { 224 | margin-bottom:0; 225 | } 226 | #site_nav_global_primary ul { 227 | padding-top:11px; 228 | } 229 | #site_nav_global_primary li { 230 | display:inline; 231 | margin-right:18px; 232 | } 233 | 234 | 235 | #footer { 236 | float:left; 237 | width:64%; 238 | padding:18px; 239 | width:96.42%; 240 | margin-bottom:1em; 241 | } 242 | 243 | #site_nav_local_sections { 244 | width:100%; 245 | float:left; 246 | } 247 | #site_nav_local_sections dt { 248 | display:none; 249 | } 250 | #site_nav_local_sections li { 251 | float:left; 252 | margin-right:18px; 253 | list-style-type:none; 254 | } 255 | #site_nav_local_sections a { 256 | float:left; 257 | text-decoration:none; 258 | padding:4px 11px; 259 | border-radius-topleft:4px; 260 | border-radius-topright:4px; 261 | -moz-border-radius-topleft:4px; 262 | -moz-border-radius-topright:4px; 263 | -webkit-border-top-left-radius:4px; 264 | -webkit-border-top-right-radius:4px; 265 | border-radius-topleft:0; 266 | border-radius-topright:0; 267 | border-width:1px; 268 | border-style:solid; 269 | border-bottom:0; 270 | font-weight:bold; 271 | } 272 | #site_nav_local_sections .nav { 273 | float:left; 274 | width:100%; 275 | } 276 | 277 | #site_nav_global_primary dt, 278 | #site_nav_global_secondary dt { 279 | display:none; 280 | } 281 | 282 | #site_nav_global_secondary { 283 | width:64%; 284 | margin-bottom:11px; 285 | float:left; 286 | } 287 | 288 | #site_nav_global_secondary ul li { 289 | display:inline; 290 | margin-right:18px; 291 | } 292 | 293 | 294 | #wrap { 295 | margin:0 auto; 296 | width:100%; 297 | min-width:760px; 298 | max-width:1003px; 299 | overflow:hidden; 300 | } 301 | 302 | #core { 303 | position:relative; 304 | width:100%; 305 | float:left; 306 | margin-bottom:1em; 307 | } 308 | 309 | #content { 310 | width:95%; 311 | min-height:259px; 312 | padding:1.795%; 313 | float:left; 314 | border-radius:7px; 315 | -moz-border-radius:7px; 316 | -webkit-border-radius:7px; 317 | border-width:1px; 318 | border-style:solid; 319 | } 320 | 321 | #content_inner { 322 | position:relative; 323 | width:100%; 324 | float:left; 325 | } 326 | 327 | #aside_primary { 328 | width:27.917%; 329 | min-height:259px; 330 | float:left; 331 | margin-left:0.699%; 332 | padding:1.795%; 333 | border-radius:7px; 334 | -moz-border-radius:7px; 335 | -webkit-border-radius:7px; 336 | border-width:1px; 337 | border-style:solid; 338 | } 339 | 340 | 341 | #content p, 342 | #content ul, 343 | #content ol, 344 | #content table { 345 | margin-bottom:1em; 346 | } 347 | 348 | #content ul { 349 | list-style-position:inside; 350 | } 351 | 352 | 353 | #resource #content { 354 | width:95%; 355 | } 356 | 357 | .resource_about { 358 | clear:both; 359 | margin-bottom:3em; 360 | } 361 | .resource_about thead { 362 | display:none; 363 | } 364 | 365 | 366 | #resource_data { 367 | 368 | } 369 | 370 | #resource_data .related { 371 | margin-bottom:3em; 372 | float:left; 373 | width:46%; 374 | } 375 | 376 | #resource_data .related:nth-child(odd) { 377 | margin-right:8%; 378 | } 379 | 380 | 381 | #resource_data table { 382 | width:100%; 383 | } 384 | 385 | #resource_data dl { 386 | margin-bottom:2em; 387 | } 388 | 389 | #resource_data dt { 390 | font-size:1.3em; 391 | } 392 | 393 | #resource_data dt:nth-child(n) { 394 | margin-top:1em; 395 | } 396 | 397 | #resource_data dt:first-child { 398 | margin-top:0; 399 | } 400 | 401 | #resource_data dl li { 402 | margin-bottom:0.5em; 403 | } 404 | 405 | 406 | .entry-content { 407 | margin-bottom:3em; 408 | float:left; 409 | width:100%; 410 | } 411 | 412 | 413 | dt { 414 | font-weight:bold; 415 | margin-bottom:0.5em; 416 | } 417 | 418 | dd { 419 | margin-bottom:1.25em; 420 | } 421 | 422 | #this_uri { 423 | margin-bottom:3em; 424 | } 425 | 426 | 427 | h1 img { 428 | float:left; 429 | margin-right:2em; 430 | width:12%; 431 | } 432 | 433 | 434 | #partners dt { 435 | display:none; 436 | } 437 | #partners ul { 438 | list-style-type:none; 439 | } 440 | 441 | 442 | 443 | #partners { 444 | width:65%; 445 | margin:0 auto; 446 | } 447 | 448 | #partners li { 449 | display:inline; 450 | margin-left:4em; 451 | } 452 | #partners li:first-child { 453 | margin-left:0; 454 | } 455 | #partners li img { 456 | vertical-align:middle; 457 | display:inline-block; 458 | } 459 | 460 | 461 | #page_notice { 462 | clear:both; 463 | padding:18px; 464 | 465 | } 466 | #page_notice dt { 467 | display:none; 468 | } 469 | #page_notice li { 470 | float:left; 471 | margin-right:3em; 472 | list-style-type:none; 473 | } 474 | 475 | 476 | .badge_lod { 477 | display:block; 478 | width:88px; 479 | height:32px; 480 | text-indent:-9999px; 481 | border-bottom:0; 482 | } 483 | 484 | 485 | 486 | /* 487 | dl.propertiesobjects { 488 | float:left; 489 | width:100%; 490 | clear:both; 491 | } 492 | 493 | dl.propertiesobjects dt, 494 | dl.propertiesobjects dd { 495 | float:left; 496 | margin-bottom:1em; 497 | word-break:break-word; 498 | } 499 | 500 | dl.propertiesobjects dt { 501 | width:35%; 502 | margin-right:3%; 503 | clear:both; 504 | font-weight:bold; 505 | text-align:right; 506 | } 507 | dl.propertiesobjects dd { 508 | width:62%; 509 | overflow:hidden; 510 | } 511 | dl.propertiesobjects dd:hover { 512 | overflow:visible; 513 | } 514 | */ 515 | 516 | 517 | #resource_data_alternate { 518 | float:right; 519 | } 520 | 521 | #resource_data_alternate li { 522 | list-style-type:none; 523 | display:inline; 524 | margin-right:18px; 525 | } 526 | 527 | 528 | #chart_about-dataset tbody th { 529 | width:40%; 530 | } 531 | 532 | #chart_about-dataset tbody td { 533 | width:25%; 534 | } 535 | 536 | 537 | .lit { 538 | margin-bottom:1em; 539 | } 540 | .lit .lang { 541 | font-weight:bold; 542 | } 543 | 544 | 545 | #form_analysis { 546 | float:left; 547 | width:33%; 548 | margin-right:5%; 549 | } 550 | 551 | #form_analysis select { 552 | /*width:325px;*/ 553 | width:100%; 554 | margin-bottom:18px; 555 | } 556 | 557 | #form_analysis optgroup, 558 | #form_analysis option { 559 | /*width:100%;*/ 560 | } 561 | 562 | #form_analysis optgroup { 563 | font-size:120%; 564 | margin-top:11px; 565 | } 566 | #form_analysis option { 567 | font-size:85%; 568 | } 569 | 570 | #plot { 571 | float:left; 572 | /*width:45%;*/ 573 | margin-bottom:2.5em; 574 | } 575 | 576 | #statsSummary { 577 | clear:both; 578 | float:left; 579 | margin-left:33.5%; 580 | width:65.5%; 581 | } 582 | 583 | #submit { 584 | font-weight:bold; 585 | padding:4px; 586 | float:right; 587 | margin-top:18px; 588 | } 589 | 590 | #lsd-analysis-results { 591 | margin-bottom:18px; 592 | width:100%; 593 | } 594 | #lsd-analysis-results caption { 595 | display:none; 596 | } 597 | 598 | #content #download-csv { 599 | float:right; 600 | margin-right:1.25em; 601 | margin-bottom:0; 602 | padding-left:21px; 603 | background:url(../../default/images/icons/icon_diskette.gif) no-repeat 0 50%; 604 | } 605 | 606 | #oh-yeah { 607 | text-align:right; 608 | } 609 | 610 | body.disconnected { 611 | background-color:#E5E5E5 !important; 612 | opacity:1 !important; 613 | } 614 | 615 | 616 | 617 | /*Bootstrap stuff*/ 618 | .tab-content > .tab-pane { 619 | display:none; 620 | } 621 | .tab-content > .active { 622 | display:block; 623 | } 624 | 625 | #content .nav-tabs { 626 | float:left; 627 | width:100%; 628 | margin-bottom:2em; 629 | } 630 | 631 | .nav-tabs li { 632 | float:left; 633 | list-style-type:none; 634 | } 635 | .nav-tabs li a { 636 | border-bottom:1px solid #E5E5E5; 637 | padding:0.5em 1em; 638 | display:block; 639 | text-decoration:none; 640 | } 641 | .nav-tabs > .active > a { 642 | border:1px solid #E5E5E5; 643 | border-bottom:0; 644 | border-top-left-radius:10px; 645 | border-top-right-radius:10px; 646 | background-color:#F0F0F0; 647 | } 648 | 649 | 650 | #observation #form_search { 651 | clear:both; 652 | float:left; 653 | width:100%; 654 | } 655 | 656 | #observation #form_search li { 657 | list-style-type:none; 658 | } 659 | 660 | #observation #form_indicator, 661 | #observation #form_country, 662 | #observation #form_year { 663 | float:left; 664 | margin-right:1em; 665 | } 666 | 667 | #observation #form_search legend, 668 | #observation #form_search label { 669 | display:none; 670 | } 671 | #observation #form_indicator select { 672 | width:23em; 673 | } 674 | #observation #form_country select { 675 | width:17em; 676 | } 677 | #observation #form_country { 678 | 679 | } 680 | 681 | /*#figure_270a-dataspaces,*/ 682 | /*#dataspaces {*/ 683 | /*float:left;*/ 684 | /*}*/ 685 | 686 | #figure_270a-dataspaces object { 687 | /*width:auto;*/ 688 | /*margin-right:2%;*/ 689 | width:100%; 690 | margin:0 auto; 691 | } 692 | #dataspaces { 693 | /*width:29.25%;*/ 694 | /*margin-top:3.5em;*/ 695 | column-count: 2; 696 | column-gap: 1em; 697 | -moz-column-count: 2; 698 | -moz-column-gap: 1em; 699 | -webkit-column-count: 2; 700 | -webkit-column-gap: 1em; 701 | } 702 | 703 | #stats-analysis { 704 | clear:both; 705 | } 706 | 707 | 708 | 709 | } /*end of screen, projection, tv*/ 710 | 711 | 712 | 713 | @media print { 714 | a:after { background-color:#FFFFFF; } 715 | a:not([href^="#"]):after { content:" <"attr(href)"> "; } 716 | img { border:none; } 717 | p { orphans: 2; widows: 1; } 718 | 719 | #site_nav_global_primary, 720 | #site_nav_local_sections, 721 | #site_nav_global_secondary, 722 | #aside_primary { 723 | display:none; 724 | } 725 | .timestamp dt, .timestamp dd { 726 | display:inline; 727 | } 728 | 729 | }/*end of @media print*/ 730 | -------------------------------------------------------------------------------- /theme/default/css/display.css: -------------------------------------------------------------------------------- 1 | /** theme: default 2 | * 3 | * @author Sarven Capadisli 4 | * @license http://creativecommons.org/licenses/by/4.0/ Creative Commons Attribution 3.0 Unported 5 | */ 6 | 7 | @import url(../../base/css/display.css); 8 | 9 | @media screen, projection, tv { 10 | body, 11 | a:active { 12 | background-color:#E5E5E5; 13 | color:#333333; 14 | } 15 | 16 | a { 17 | color:#0000E4; 18 | } 19 | 20 | h1,h2,h3,h4,h5,h6, 21 | caption, dt 22 | button { 23 | text-shadow:1px 1px 1px #CCCCCC; 24 | } 25 | 26 | tr { 27 | border-color:#EEEEEE; 28 | } 29 | 30 | kbd { 31 | border-color:#CCCCCC; 32 | } 33 | 34 | address { 35 | margin-right:2%; 36 | } 37 | 38 | 39 | #content { 40 | box-shadow:5px 7px 7px rgba(194, 194, 194, 0.3); 41 | -moz-box-shadow:5px 7px 7px rgba(194, 194, 194, 0.3); 42 | -webkit-box-shadow:5px 7px 7px rgba(194, 194, 194, 0.3); 43 | background-image:url(../images/illustrations/illu_node-connections-2.gif); 44 | background-repeat:no-repeat; 45 | background-position:100% 0; 46 | } 47 | #content, 48 | #site_nav_local_sections a, 49 | #aside_primary { 50 | border-color:transparent; 51 | } 52 | #content, 53 | #site_nav_local_sections .current a { 54 | background-color:#FFFFFF; 55 | } 56 | 57 | 58 | #site_nav_local_sections li.current { 59 | box-shadow:3px 7px 5px rgba(194, 194, 194, 0.5); 60 | -moz-box-shadow:3px 7px 5px rgba(194, 194, 194, 0.5); 61 | -webkit-box-shadow:3px 7px 5px rgba(194, 194, 194, 0.5); 62 | } 63 | #site_nav_local_sections a { 64 | background-color:rgba(194, 194, 194, 0.5); 65 | } 66 | #site_nav_local_sections a:hover { 67 | background-color:rgba(255, 255, 255, 0.7); 68 | } 69 | #site_nav_local_sections .current a { 70 | text-shadow: rgba(194,194,194,0.5) 1px 1px 1px; 71 | } 72 | 73 | 74 | 75 | 76 | 77 | .processing { 78 | width:16px; 79 | height:16px; 80 | background:url(../images/icons/icon_processing.gif) no-repeat 0 0; 81 | } 82 | 83 | #content #download-csv { 84 | background:url(../images/icons/icon_diskette.gif) no-repeat 0 50%; 85 | } 86 | 87 | 88 | 89 | #aside_primary { 90 | background-color:#EEEEEE; 91 | } 92 | 93 | 94 | .warning { 95 | background-color:#FFFFCC; 96 | border-color:#AAAAAA; 97 | } 98 | 99 | 100 | #datasets-from-source tbody td:first-child { 101 | width:45%; 102 | } 103 | 104 | } /*end of @media screen, projection, tv*/ 105 | -------------------------------------------------------------------------------- /theme/default/images/icons/icon_diskette.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csarven/linked-data-pages/24c33792a0101ce8469de01db6f861f7b0b07802/theme/default/images/icons/icon_diskette.gif -------------------------------------------------------------------------------- /theme/default/images/icons/icon_loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csarven/linked-data-pages/24c33792a0101ce8469de01db6f861f7b0b07802/theme/default/images/icons/icon_loading.gif -------------------------------------------------------------------------------- /theme/default/images/icons/icon_processing.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csarven/linked-data-pages/24c33792a0101ce8469de01db6f861f7b0b07802/theme/default/images/icons/icon_processing.gif -------------------------------------------------------------------------------- /theme/default/images/illustrations/illu_node-connections-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csarven/linked-data-pages/24c33792a0101ce8469de01db6f861f7b0b07802/theme/default/images/illustrations/illu_node-connections-1.gif -------------------------------------------------------------------------------- /theme/default/images/illustrations/illu_node-connections-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csarven/linked-data-pages/24c33792a0101ce8469de01db6f861f7b0b07802/theme/default/images/illustrations/illu_node-connections-2.gif -------------------------------------------------------------------------------- /theme/default/images/logos/logo_270a-linked-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csarven/linked-data-pages/24c33792a0101ce8469de01db6f861f7b0b07802/theme/default/images/logos/logo_270a-linked-data.png --------------------------------------------------------------------------------