danielebarchiesi@4
|
1 <?php
|
danielebarchiesi@4
|
2
|
danielebarchiesi@4
|
3 /**
|
danielebarchiesi@4
|
4 * @file
|
danielebarchiesi@4
|
5 * Functions for managing RDF Terms.
|
danielebarchiesi@4
|
6 */
|
danielebarchiesi@4
|
7
|
danielebarchiesi@4
|
8 function rdfx_get_properties() {
|
danielebarchiesi@4
|
9 $property_tids = _rdfx_get_terms('property');
|
danielebarchiesi@4
|
10 return $property_tids;
|
danielebarchiesi@4
|
11 }
|
danielebarchiesi@4
|
12
|
danielebarchiesi@4
|
13 function rdfx_get_classes() {
|
danielebarchiesi@4
|
14 $class_tids = _rdfx_get_terms('class');
|
danielebarchiesi@4
|
15 return $class_tids;
|
danielebarchiesi@4
|
16 }
|
danielebarchiesi@4
|
17
|
danielebarchiesi@4
|
18 function _rdfx_get_terms($term_type) {
|
danielebarchiesi@4
|
19 $term_types = rdfx_term_types();
|
danielebarchiesi@4
|
20 switch ($term_type) {
|
danielebarchiesi@4
|
21 case 'property':
|
danielebarchiesi@4
|
22 $types = array_keys($term_types['properties']['term_types']);
|
danielebarchiesi@4
|
23 break;
|
danielebarchiesi@4
|
24 case 'class':
|
danielebarchiesi@4
|
25 $types = array_keys($term_types['classes']['term_types']);
|
danielebarchiesi@4
|
26 break;
|
danielebarchiesi@4
|
27 default:
|
danielebarchiesi@4
|
28 $types = array_merge(array_keys($term_types['properties']['term_types']), array_keys($term_types['classes']['term_types']));
|
danielebarchiesi@4
|
29 }
|
danielebarchiesi@4
|
30 $query = db_select('rdfx_term_types', 'rdftt')
|
danielebarchiesi@4
|
31 ->fields('rdft', array('tid'))
|
danielebarchiesi@4
|
32 ->condition('rdftt.type', $types, 'IN');
|
danielebarchiesi@4
|
33 $query->join('rdfx_terms', 'rdft', 'rdftt.tid = rdft.tid');
|
danielebarchiesi@4
|
34 $query->join('rdfx_namespaces', 'rdfns', 'rdfns.nsid = rdft.nsid');
|
danielebarchiesi@4
|
35 $query->join('rdfx_vocabulary_graphs', 'rdfvg', 'rdfvg.main_ns = rdfns.nsid');
|
danielebarchiesi@4
|
36 $terms = $query->execute()->fetchCol();
|
danielebarchiesi@4
|
37 return $terms;
|
danielebarchiesi@4
|
38 }
|
danielebarchiesi@4
|
39
|
danielebarchiesi@4
|
40 /**
|
danielebarchiesi@4
|
41 * Gets a list of all defined namespaces.
|
danielebarchiesi@4
|
42 */
|
danielebarchiesi@4
|
43 function rdfx_get_namespaces() {
|
danielebarchiesi@4
|
44 $rdf_namespaces = &drupal_static(__FUNCTION__);
|
danielebarchiesi@4
|
45 if (empty($rdf_namespaces)) {
|
danielebarchiesi@4
|
46 $rdf_namespaces = rdf_get_namespaces();
|
danielebarchiesi@4
|
47 }
|
danielebarchiesi@4
|
48 return $rdf_namespaces;
|
danielebarchiesi@4
|
49 }
|
danielebarchiesi@4
|
50
|
danielebarchiesi@4
|
51 /**
|
danielebarchiesi@4
|
52 * Implements hook_rdf_namespaces.
|
danielebarchiesi@4
|
53 */
|
danielebarchiesi@4
|
54 function rdfx_rdf_namespaces() {
|
danielebarchiesi@4
|
55 // Starts with some additionnal common namespaces which core does not include.
|
danielebarchiesi@4
|
56 $ns_mappings = array(
|
danielebarchiesi@4
|
57 'owl' => 'http://www.w3.org/2002/07/owl#',
|
danielebarchiesi@4
|
58 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
|
danielebarchiesi@4
|
59 'rss' => 'http://purl.org/rss/1.0/',
|
danielebarchiesi@4
|
60 // url() does not support empty fragment.
|
danielebarchiesi@4
|
61 'site' => url('ns', array('absolute' => TRUE)) . '#',
|
danielebarchiesi@4
|
62 );
|
danielebarchiesi@4
|
63
|
danielebarchiesi@4
|
64 // Gets the custom namespaces stored in the database.
|
danielebarchiesi@4
|
65 $query = db_select('rdfx_vocabulary_graphs', 'g');
|
danielebarchiesi@4
|
66 $query->fields('n', array('prefix', 'uri'));
|
danielebarchiesi@4
|
67 $query->join('rdfx_namespaces', 'n', 'g.main_ns = n.nsid');
|
danielebarchiesi@4
|
68 $query->orderBy('n.prefix');
|
danielebarchiesi@4
|
69 $namespaces = $query->execute()->fetchAllKeyed();
|
danielebarchiesi@4
|
70 foreach ($namespaces as $prefix => $uri) {
|
danielebarchiesi@4
|
71 $ns_mappings[$prefix] = $uri;
|
danielebarchiesi@4
|
72 }
|
danielebarchiesi@4
|
73
|
danielebarchiesi@4
|
74 return $ns_mappings;
|
danielebarchiesi@4
|
75 }
|
danielebarchiesi@4
|
76
|
danielebarchiesi@4
|
77 /**
|
danielebarchiesi@4
|
78 * Saves the main namespace mapping for a vocabulary graph and the additional
|
danielebarchiesi@4
|
79 * namespace mappings as defined in the document.
|
danielebarchiesi@4
|
80 */
|
danielebarchiesi@4
|
81 function _rdfx_save_vocabulary($main_ns, $main_ns_prefix, $vocabulary) {
|
danielebarchiesi@4
|
82 $current_time = REQUEST_TIME;
|
danielebarchiesi@4
|
83 // If the vocabulary URI matches the main_ns of a vocabulary source, then
|
danielebarchiesi@4
|
84 // this is an update to that record. Otherwise, this is a newly imported
|
danielebarchiesi@4
|
85 // source.
|
danielebarchiesi@4
|
86 $gid = rdfx_get_gid($main_ns);
|
danielebarchiesi@4
|
87
|
danielebarchiesi@4
|
88 // If there is an existing vocabulary, make sure that the main_ns is in the
|
danielebarchiesi@4
|
89 // namespaces array and that the user defined mapping is the last in the
|
danielebarchiesi@4
|
90 // array so the prefix reflects the user definition. Also change the
|
danielebarchiesi@4
|
91 // vocabulary graph updated date.
|
danielebarchiesi@4
|
92 if ($gid) {
|
danielebarchiesi@4
|
93 $vocabulary['namespaces'][$main_ns_prefix] = $main_ns;
|
danielebarchiesi@4
|
94 db_update('rdfx_vocabulary_graphs')
|
danielebarchiesi@4
|
95 ->fields(array('date_updated' => $current_time,))
|
danielebarchiesi@4
|
96 ->execute();
|
danielebarchiesi@4
|
97 }
|
danielebarchiesi@4
|
98
|
danielebarchiesi@4
|
99 // If this is a new vocabulary, create a graph with a main namespace and
|
danielebarchiesi@4
|
100 // add the additional namespaces.
|
danielebarchiesi@4
|
101 else {
|
danielebarchiesi@4
|
102 // @todo If the vocab URI isn't used in any terms, don't add it to ns table.
|
danielebarchiesi@4
|
103 // This may happen where multiple files are defining a vocabulary.
|
danielebarchiesi@4
|
104
|
danielebarchiesi@4
|
105 // @todo This should be handled as a transaction in case there is an error
|
danielebarchiesi@4
|
106 // in the middle. If there is an error, then there will be an SQL error
|
danielebarchiesi@4
|
107 // when the user retries the import.
|
danielebarchiesi@4
|
108
|
danielebarchiesi@4
|
109 // Insert this namespace to get the nsid. The vocabulary_source entry will
|
danielebarchiesi@4
|
110 // point to this nsid for the main_ns. We temporarily insert 0 for the gid,
|
danielebarchiesi@4
|
111 // then update when we have the real gid.
|
danielebarchiesi@4
|
112 $nsid = db_insert('rdfx_namespaces')
|
danielebarchiesi@4
|
113 ->fields(array('uri' => $main_ns, 'prefix' => $main_ns_prefix, 'gid' => '0'))
|
danielebarchiesi@4
|
114 ->execute();
|
danielebarchiesi@4
|
115 $gid = db_insert('rdfx_vocabulary_graphs')
|
danielebarchiesi@4
|
116 ->fields(array(
|
danielebarchiesi@4
|
117 'main_ns' => $nsid,
|
danielebarchiesi@4
|
118 'date_created' => $current_time,
|
danielebarchiesi@4
|
119 'date_updated' => $current_time,))
|
danielebarchiesi@4
|
120 ->execute();
|
danielebarchiesi@4
|
121 db_update('rdfx_namespaces')
|
danielebarchiesi@4
|
122 ->condition('nsid', $nsid)
|
danielebarchiesi@4
|
123 ->fields(array('gid' => $gid))
|
danielebarchiesi@4
|
124 ->execute();
|
danielebarchiesi@4
|
125 }
|
danielebarchiesi@4
|
126 // Insert/update the vocabulary title.
|
danielebarchiesi@4
|
127 if (count($vocabulary['title']) > 0) {
|
danielebarchiesi@4
|
128 foreach ($vocabulary['title'] as $langcode => $title) {
|
danielebarchiesi@4
|
129 $query = db_merge('rdfx_vocabulary_details')
|
danielebarchiesi@4
|
130 ->key(array('gid' => $gid, 'language' => $langcode))
|
danielebarchiesi@4
|
131 ->fields(array('language' => $langcode, 'label' => $title));
|
danielebarchiesi@4
|
132 $status = $query->execute();
|
danielebarchiesi@4
|
133 }
|
danielebarchiesi@4
|
134 }
|
danielebarchiesi@4
|
135
|
danielebarchiesi@4
|
136 // Insert/update the vocabulary description.
|
danielebarchiesi@4
|
137 if (count($vocabulary['description']) > 0) {
|
danielebarchiesi@4
|
138 foreach ($vocabulary['description'] as $langcode => $description) {
|
danielebarchiesi@4
|
139 $query = db_merge('rdfx_vocabulary_details')
|
danielebarchiesi@4
|
140 ->key(array('gid' => $gid, 'language' => $langcode))
|
danielebarchiesi@4
|
141 ->fields(array('language' => $langcode, 'description' => $description));
|
danielebarchiesi@4
|
142 $status = $query->execute();
|
danielebarchiesi@4
|
143 }
|
danielebarchiesi@4
|
144 }
|
danielebarchiesi@4
|
145
|
danielebarchiesi@4
|
146 // Insert/update the other namespace mappings used in this vocabulary graph.
|
danielebarchiesi@4
|
147 if (count($vocabulary['namespaces']) > 0) {
|
danielebarchiesi@4
|
148 foreach ($vocabulary['namespaces'] as $prefix => $namespace) {
|
danielebarchiesi@4
|
149 if ($namespace != $main_ns) {
|
danielebarchiesi@4
|
150 $query = db_merge('rdfx_namespaces')
|
danielebarchiesi@4
|
151 ->key(array('gid' => $gid, 'uri' => $namespace))
|
danielebarchiesi@4
|
152 ->fields(array('uri' => $namespace, 'prefix' => $prefix, 'gid' => $gid))
|
danielebarchiesi@4
|
153 ->updateFields(array('prefix' => $prefix));
|
danielebarchiesi@4
|
154 $status = $query->execute();
|
danielebarchiesi@4
|
155 }
|
danielebarchiesi@4
|
156 }
|
danielebarchiesi@4
|
157 }
|
danielebarchiesi@4
|
158
|
danielebarchiesi@4
|
159 $nsids = rdfx_get_nsids($main_ns);
|
danielebarchiesi@4
|
160 return $nsids;
|
danielebarchiesi@4
|
161 }
|
danielebarchiesi@4
|
162
|
danielebarchiesi@4
|
163 /**
|
danielebarchiesi@4
|
164 * Saves vocabulary terms.
|
danielebarchiesi@4
|
165 */
|
danielebarchiesi@4
|
166 function rdfx_save_terms($vocabulary_uri, $prefix, $vocabulary) {
|
danielebarchiesi@4
|
167 $nsids = _rdfx_save_vocabulary($vocabulary_uri, $prefix, $vocabulary);
|
danielebarchiesi@4
|
168 foreach ($vocabulary['terms'] as $term_type => $terms) {
|
danielebarchiesi@4
|
169 foreach ($terms as $term_uri => $term_description) {
|
danielebarchiesi@4
|
170 list($term_ns, $term_local_name) = rdfx_split_uri($term_uri);
|
danielebarchiesi@4
|
171 if (isset($nsids[$term_ns])) {
|
danielebarchiesi@4
|
172 $nsid = $nsids[$term_ns];
|
danielebarchiesi@4
|
173 }
|
danielebarchiesi@4
|
174 else {
|
danielebarchiesi@4
|
175 // If the namespace wasn't mapped to a prefix in the source graph, we
|
danielebarchiesi@4
|
176 // didn't save it to the namespaces table, so we need to add an entry.
|
danielebarchiesi@4
|
177
|
danielebarchiesi@4
|
178 // @todo For the prefix value, we save the URI... should this be changed?
|
danielebarchiesi@4
|
179 $gid = rdfx_get_gid($vocabulary_uri);
|
danielebarchiesi@4
|
180 $nsid = db_insert('rdfx_namespaces')
|
danielebarchiesi@4
|
181 ->fields(array('uri' => $term_ns, 'prefix' => $term_ns, 'gid' => $gid))
|
danielebarchiesi@4
|
182 ->execute();
|
danielebarchiesi@4
|
183 $nsids[$term_ns] = $nsid;
|
danielebarchiesi@4
|
184 }
|
danielebarchiesi@4
|
185
|
danielebarchiesi@4
|
186 // Get the tid of this term, saving to {rdfx_terms} if not already there.
|
danielebarchiesi@4
|
187 $tid = db_query("SELECT tid FROM {rdfx_terms} WHERE nsid = :nsid AND local_name = :localname", array(':nsid' => $nsid, ':localname' => $term_local_name))->fetchField();
|
danielebarchiesi@4
|
188 if ($tid == NULL) {
|
danielebarchiesi@4
|
189 $tid = db_insert('rdfx_terms')
|
danielebarchiesi@4
|
190 ->fields(array('nsid', 'local_name'))
|
danielebarchiesi@4
|
191 ->values(array(
|
danielebarchiesi@4
|
192 'nsid' => $nsid,
|
danielebarchiesi@4
|
193 'local_name' => $term_local_name,
|
danielebarchiesi@4
|
194 ))
|
danielebarchiesi@4
|
195 ->execute();
|
danielebarchiesi@4
|
196 }
|
danielebarchiesi@4
|
197
|
danielebarchiesi@4
|
198 // Add the current type to this term in {rdfx_term_types}.
|
danielebarchiesi@4
|
199 db_merge('rdfx_term_types')
|
danielebarchiesi@4
|
200 ->key(array('tid' => $tid, 'type' => $term_type))
|
danielebarchiesi@4
|
201 ->fields(array(
|
danielebarchiesi@4
|
202 'tid' => $tid,
|
danielebarchiesi@4
|
203 'type' => $term_type,
|
danielebarchiesi@4
|
204 ))
|
danielebarchiesi@4
|
205 ->execute();
|
danielebarchiesi@4
|
206
|
danielebarchiesi@4
|
207 // Add label and comment to {rdfx_term_details}.
|
danielebarchiesi@4
|
208 $term_details = array();
|
danielebarchiesi@4
|
209 if (isset($term_description['label'])) {
|
danielebarchiesi@4
|
210 foreach ($term_description['label'] as $lang => $text) {
|
danielebarchiesi@4
|
211 $term_details[$lang]['label'] = $text;
|
danielebarchiesi@4
|
212 }
|
danielebarchiesi@4
|
213 }
|
danielebarchiesi@4
|
214 if (isset($term_description['comment'])) {
|
danielebarchiesi@4
|
215 foreach ($term_description['comment'] as $lang => $text) {
|
danielebarchiesi@4
|
216 $term_details[$lang]['comment'] = $text;
|
danielebarchiesi@4
|
217 }
|
danielebarchiesi@4
|
218 }
|
danielebarchiesi@4
|
219 if (!empty($term_details)) {
|
danielebarchiesi@4
|
220 foreach ($term_details as $lang => $details) {
|
danielebarchiesi@4
|
221 db_merge('rdfx_term_details')
|
danielebarchiesi@4
|
222 ->key(array('tid' => $tid, 'language' => $lang))
|
danielebarchiesi@4
|
223 ->fields(array(
|
danielebarchiesi@4
|
224 'tid' => $tid,
|
danielebarchiesi@4
|
225 'language' => $lang,
|
danielebarchiesi@4
|
226 'label' => isset($details['label']) ? $details['label'] : NULL,
|
danielebarchiesi@4
|
227 'comment' => isset($details['comment']) ? $details['comment'] : NULL,
|
danielebarchiesi@4
|
228 ))
|
danielebarchiesi@4
|
229 ->execute();
|
danielebarchiesi@4
|
230 }
|
danielebarchiesi@4
|
231 }
|
danielebarchiesi@4
|
232
|
danielebarchiesi@4
|
233 // Add relationships to their respective tables. This is handled as a
|
danielebarchiesi@4
|
234 // complicated set of loops to reduce code duplication. To add a new
|
danielebarchiesi@4
|
235 // relationship, just add the array key that is used in
|
danielebarchiesi@4
|
236 // $types['properties']['description'] to define the relationship, and
|
danielebarchiesi@4
|
237 // then add the name of the table that stores the relationship.
|
danielebarchiesi@4
|
238 $relationships = array(
|
danielebarchiesi@4
|
239 'domain' => 'rdfx_term_domains',
|
danielebarchiesi@4
|
240 'range' => 'rdfx_term_ranges',
|
danielebarchiesi@4
|
241 );
|
danielebarchiesi@4
|
242 foreach ($relationships as $relationship => $table_name) {
|
danielebarchiesi@4
|
243 if (isset($term_description[$relationship])) {
|
danielebarchiesi@4
|
244 foreach ($term_description[$relationship] as $related_term) {
|
danielebarchiesi@4
|
245 $related_term_tid = rdfx_get_tid($related_term, $vocabulary_uri);
|
danielebarchiesi@4
|
246 if ($related_term_tid) {
|
danielebarchiesi@4
|
247 db_merge($table_name)
|
danielebarchiesi@4
|
248 ->key(array('tid' => $tid, $relationship . '_tid' => $related_term_tid))
|
danielebarchiesi@4
|
249 ->fields(array(
|
danielebarchiesi@4
|
250 'tid' => $tid,
|
danielebarchiesi@4
|
251 $relationship . '_tid' => $related_term_tid,
|
danielebarchiesi@4
|
252 ))
|
danielebarchiesi@4
|
253 ->execute();
|
danielebarchiesi@4
|
254 }
|
danielebarchiesi@4
|
255 }
|
danielebarchiesi@4
|
256 }
|
danielebarchiesi@4
|
257 }
|
danielebarchiesi@4
|
258 }
|
danielebarchiesi@4
|
259 }
|
danielebarchiesi@4
|
260 // @todo Add a hook that passes the $vocabulary and the $model.
|
danielebarchiesi@4
|
261 }
|
danielebarchiesi@4
|
262
|
danielebarchiesi@4
|
263 /**
|
danielebarchiesi@4
|
264 * Returns metadata about term types defined by rdf modules.
|
danielebarchiesi@4
|
265 *
|
danielebarchiesi@4
|
266 * If your module needs to determine what term types are being supplied by
|
danielebarchiesi@4
|
267 * other modules, call this function. Querying rdfx database tables directly
|
danielebarchiesi@4
|
268 * for this information is discouraged. Any additional term types should be
|
danielebarchiesi@4
|
269 * added through the corresponding alter hook.
|
danielebarchiesi@4
|
270 *
|
danielebarchiesi@4
|
271 * Three major bins of data are stored: tags, value_types, and functions. Each
|
danielebarchiesi@4
|
272 * entry in these bins is keyed by the value stored in the actual VotingAPI
|
danielebarchiesi@4
|
273 * tables, and contains an array with (minimally) 'name' and 'description' keys.
|
danielebarchiesi@4
|
274 * Modules can add extra keys to their entries if desired.
|
danielebarchiesi@4
|
275 *
|
danielebarchiesi@4
|
276 * This metadata can be modified or expanded using hook_rdfx_term_types_alter().
|
danielebarchiesi@4
|
277 *
|
danielebarchiesi@4
|
278 * @return
|
danielebarchiesi@4
|
279 * An array of metadata defined by RDFx Terms and altered by rdf modules.
|
danielebarchiesi@4
|
280 *
|
danielebarchiesi@4
|
281 * @see hook_rdfx_term_types_alter()
|
danielebarchiesi@4
|
282 *
|
danielebarchiesi@4
|
283 * Modeled on VotingAPI votingapi_metadata.
|
danielebarchiesi@4
|
284 */
|
danielebarchiesi@4
|
285 function rdfx_term_types($reset = FALSE) {
|
danielebarchiesi@4
|
286 static $types;
|
danielebarchiesi@4
|
287 if ($reset || !isset($types)) {
|
danielebarchiesi@4
|
288 $types['classes']['term_types'] = array();
|
danielebarchiesi@4
|
289 $types['properties']['term_types'] = array();
|
danielebarchiesi@4
|
290
|
danielebarchiesi@4
|
291 $term_details = '';
|
danielebarchiesi@4
|
292
|
danielebarchiesi@4
|
293 // @todo Should the inference consider subProp and subClass relationships
|
danielebarchiesi@4
|
294 // as well. ie. should all OWL classes also have the type RDFS Class
|
danielebarchiesi@4
|
295
|
danielebarchiesi@4
|
296 // @todo Switch to drupal cache
|
danielebarchiesi@4
|
297 $types['classes']['term_types'] = array(
|
danielebarchiesi@4
|
298 'rdfs_class' => array(
|
danielebarchiesi@4
|
299 'uri' => 'http://www.w3.org/2000/01/rdf-schema#Class',
|
danielebarchiesi@4
|
300 'inference' => array(
|
danielebarchiesi@4
|
301 'http://www.w3.org/2000/01/rdf-schema#subClassOf' => array(
|
danielebarchiesi@4
|
302 'subject',
|
danielebarchiesi@4
|
303 'object',
|
danielebarchiesi@4
|
304 ),
|
danielebarchiesi@4
|
305 'http://www.w3.org/2000/01/rdf-schema#domain' => array(
|
danielebarchiesi@4
|
306 'object',
|
danielebarchiesi@4
|
307 ),
|
danielebarchiesi@4
|
308 'http://www.w3.org/2000/01/rdf-schema#range' => array(
|
danielebarchiesi@4
|
309 'object',
|
danielebarchiesi@4
|
310 ),
|
danielebarchiesi@4
|
311 ),
|
danielebarchiesi@4
|
312 ),
|
danielebarchiesi@4
|
313 'owl_class' => array(
|
danielebarchiesi@4
|
314 'uri' => 'http://www.w3.org/2002/07/owl#Class',
|
danielebarchiesi@4
|
315 'inference' => array(
|
danielebarchiesi@4
|
316 'http://www.w3.org/2002/07/owl#equivalentClass' => array(
|
danielebarchiesi@4
|
317 'subject',
|
danielebarchiesi@4
|
318 'object',
|
danielebarchiesi@4
|
319 ),
|
danielebarchiesi@4
|
320 'http://www.w3.org/2002/07/owl#disjointWith' => array(
|
danielebarchiesi@4
|
321 'subject',
|
danielebarchiesi@4
|
322 'object',
|
danielebarchiesi@4
|
323 ),
|
danielebarchiesi@4
|
324 ),
|
danielebarchiesi@4
|
325 ),
|
danielebarchiesi@4
|
326 );
|
danielebarchiesi@4
|
327
|
danielebarchiesi@4
|
328 $types['properties']['term_types'] = array (
|
danielebarchiesi@4
|
329 'rdf_property' => array(
|
danielebarchiesi@4
|
330 'uri' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#Property',
|
danielebarchiesi@4
|
331 'inference' => array(
|
danielebarchiesi@4
|
332 'http://www.w3.org/2000/01/rdf-schema#domain' => array(
|
danielebarchiesi@4
|
333 'subject',
|
danielebarchiesi@4
|
334 ),
|
danielebarchiesi@4
|
335 'http://www.w3.org/2000/01/rdf-schema#range' => array(
|
danielebarchiesi@4
|
336 'subject',
|
danielebarchiesi@4
|
337 ),
|
danielebarchiesi@4
|
338 'http://www.w3.org/2000/01/rdf-schema#subPropertyOf' => array(
|
danielebarchiesi@4
|
339 'subject',
|
danielebarchiesi@4
|
340 'object',
|
danielebarchiesi@4
|
341 ),
|
danielebarchiesi@4
|
342 'http://www.w3.org/2002/07/owl#equivalentProperty' => array(
|
danielebarchiesi@4
|
343 'subject',
|
danielebarchiesi@4
|
344 'object',
|
danielebarchiesi@4
|
345 ),
|
danielebarchiesi@4
|
346 'http://www.w3.org/2002/07/owl#inverseOf' => array(
|
danielebarchiesi@4
|
347 'subject',
|
danielebarchiesi@4
|
348 'object',
|
danielebarchiesi@4
|
349 ),
|
danielebarchiesi@4
|
350 ),
|
danielebarchiesi@4
|
351 ),
|
danielebarchiesi@4
|
352 'owl_property_datatype' => array(
|
danielebarchiesi@4
|
353 'uri' => 'http://www.w3.org/2002/07/owl#DatatypeProperty',
|
danielebarchiesi@4
|
354 'inference' => array(
|
danielebarchiesi@4
|
355 ),
|
danielebarchiesi@4
|
356 ),
|
danielebarchiesi@4
|
357 'owl_property_object' => array(
|
danielebarchiesi@4
|
358 'uri' => 'http://www.w3.org/2002/07/owl#ObjectProperty',
|
danielebarchiesi@4
|
359 'inference' => array(
|
danielebarchiesi@4
|
360 ),
|
danielebarchiesi@4
|
361 ),
|
danielebarchiesi@4
|
362 'owl_property_functional' => array(
|
danielebarchiesi@4
|
363 'uri' => 'http://www.w3.org/2002/07/owl#FunctionalProperty',
|
danielebarchiesi@4
|
364 'inference' => array(
|
danielebarchiesi@4
|
365 ),
|
danielebarchiesi@4
|
366 ),
|
danielebarchiesi@4
|
367 'owl_property_inverse_functional' => array(
|
danielebarchiesi@4
|
368 'uri' => 'http://www.w3.org/2002/07/owl#InverseFunctionalProperty',
|
danielebarchiesi@4
|
369 'inference' => array(
|
danielebarchiesi@4
|
370 ),
|
danielebarchiesi@4
|
371 ),
|
danielebarchiesi@4
|
372 'owl_property_symmetric' => array(
|
danielebarchiesi@4
|
373 'uri' => 'http://www.w3.org/2002/07/owl#SymmetricProperty',
|
danielebarchiesi@4
|
374 'inference' => array(
|
danielebarchiesi@4
|
375 ),
|
danielebarchiesi@4
|
376 ),
|
danielebarchiesi@4
|
377 'owl_property_asymmetric' => array(
|
danielebarchiesi@4
|
378 'uri' => 'http://www.w3.org/2002/07/owl#AsymmetricProperty',
|
danielebarchiesi@4
|
379 'inference' => array(
|
danielebarchiesi@4
|
380 ),
|
danielebarchiesi@4
|
381 ),
|
danielebarchiesi@4
|
382 'owl_property_annotation' => array(
|
danielebarchiesi@4
|
383 'uri' => 'http://www.w3.org/2002/07/owl#AnnotationProperty',
|
danielebarchiesi@4
|
384 'inference' => array(
|
danielebarchiesi@4
|
385 ),
|
danielebarchiesi@4
|
386 ),
|
danielebarchiesi@4
|
387 'owl_property_reflexive' => array(
|
danielebarchiesi@4
|
388 'uri' => 'http://www.w3.org/2002/07/owl#ReflexiveProperty',
|
danielebarchiesi@4
|
389 'inference' => array(
|
danielebarchiesi@4
|
390 ),
|
danielebarchiesi@4
|
391 ),
|
danielebarchiesi@4
|
392 'owl_property_irreflexive' => array(
|
danielebarchiesi@4
|
393 'uri' => 'http://www.w3.org/2002/07/owl#IrreflexiveProperty',
|
danielebarchiesi@4
|
394 'inference' => array(
|
danielebarchiesi@4
|
395 ),
|
danielebarchiesi@4
|
396 ),
|
danielebarchiesi@4
|
397 'owl_property_transitive' => array(
|
danielebarchiesi@4
|
398 'uri' => 'http://www.w3.org/2002/07/owl#TransitiveProperty',
|
danielebarchiesi@4
|
399 'inference' => array(
|
danielebarchiesi@4
|
400 ),
|
danielebarchiesi@4
|
401 ),
|
danielebarchiesi@4
|
402 );
|
danielebarchiesi@4
|
403
|
danielebarchiesi@4
|
404 $types['classes']['description'] = array(
|
danielebarchiesi@4
|
405 'superclass' => array(
|
danielebarchiesi@4
|
406 'http://www.w3.org/2000/01/rdf-schema#subClassOf' => array(
|
danielebarchiesi@4
|
407 'object',
|
danielebarchiesi@4
|
408 ),
|
danielebarchiesi@4
|
409 ),
|
danielebarchiesi@4
|
410 'disjoint' => array(
|
danielebarchiesi@4
|
411 'http://www.w3.org/2002/07/owl#disjointWith' => array(
|
danielebarchiesi@4
|
412 'object',
|
danielebarchiesi@4
|
413 ),
|
danielebarchiesi@4
|
414 ),
|
danielebarchiesi@4
|
415 );
|
danielebarchiesi@4
|
416
|
danielebarchiesi@4
|
417 $types['properties']['description'] = array(
|
danielebarchiesi@4
|
418 'domain' => array(
|
danielebarchiesi@4
|
419 'http://www.w3.org/2000/01/rdf-schema#domain' => array(
|
danielebarchiesi@4
|
420 'object',
|
danielebarchiesi@4
|
421 ),
|
danielebarchiesi@4
|
422 ),
|
danielebarchiesi@4
|
423 'range' => array(
|
danielebarchiesi@4
|
424 'http://www.w3.org/2000/01/rdf-schema#range' => array(
|
danielebarchiesi@4
|
425 'object',
|
danielebarchiesi@4
|
426 ),
|
danielebarchiesi@4
|
427 ),
|
danielebarchiesi@4
|
428 'superproperty' => array(
|
danielebarchiesi@4
|
429 'http://www.w3.org/2000/01/rdf-schema#subPropertyOf' => array(
|
danielebarchiesi@4
|
430 'object',
|
danielebarchiesi@4
|
431 ),
|
danielebarchiesi@4
|
432 ),
|
danielebarchiesi@4
|
433 'inverse' => array(
|
danielebarchiesi@4
|
434 'http://www.w3.org/2002/07/owl#inverseOf' => array(
|
danielebarchiesi@4
|
435 'object',
|
danielebarchiesi@4
|
436 ),
|
danielebarchiesi@4
|
437 ),
|
danielebarchiesi@4
|
438 );
|
danielebarchiesi@4
|
439 drupal_alter('rdfx_term_types', $types);
|
danielebarchiesi@4
|
440 }
|
danielebarchiesi@4
|
441
|
danielebarchiesi@4
|
442 return $types;
|
danielebarchiesi@4
|
443 }
|
danielebarchiesi@4
|
444
|
danielebarchiesi@4
|
445 /**
|
danielebarchiesi@4
|
446 * Splits a URI into namespace and localpart.
|
danielebarchiesi@4
|
447 */
|
danielebarchiesi@4
|
448 function rdfx_split_uri ($uri) {
|
danielebarchiesi@4
|
449 $parts = ARC2::splitURI($uri);
|
danielebarchiesi@4
|
450 return $parts;
|
danielebarchiesi@4
|
451 }
|
danielebarchiesi@4
|
452
|
danielebarchiesi@4
|
453 function rdfx_get_tid($term_uri, $graph_main_ns) {
|
danielebarchiesi@4
|
454 $nsids = rdfx_get_nsids($graph_main_ns);
|
danielebarchiesi@4
|
455 list($term_ns, $term_local_name) = rdfx_split_uri($term_uri);
|
danielebarchiesi@4
|
456 if (isset($nsids[$term_ns])) {
|
danielebarchiesi@4
|
457 $tid = db_query("SELECT tid FROM {rdfx_terms} WHERE nsid = :nsid AND local_name = :localname", array(':nsid' => $nsids[$term_ns], ':localname' => $term_local_name))->fetchField();
|
danielebarchiesi@4
|
458 return $tid;
|
danielebarchiesi@4
|
459 }
|
danielebarchiesi@4
|
460 else {
|
danielebarchiesi@4
|
461 return NULL;
|
danielebarchiesi@4
|
462 }
|
danielebarchiesi@4
|
463 }
|
danielebarchiesi@4
|
464
|
danielebarchiesi@4
|
465 function rdfx_get_gid($main_ns) {
|
danielebarchiesi@4
|
466 $gids = db_select('rdfx_namespaces', 'rdfns', array());
|
danielebarchiesi@4
|
467 $gids->join('rdfx_vocabulary_graphs', 'rdfvg', 'rdfvg.main_ns = rdfns.nsid');
|
danielebarchiesi@4
|
468 $gids
|
danielebarchiesi@4
|
469 ->fields('rdfns', array('gid'))
|
danielebarchiesi@4
|
470 ->condition('rdfns.uri', $main_ns);
|
danielebarchiesi@4
|
471 // @todo There should only be one result if there is a matching vocab source.
|
danielebarchiesi@4
|
472 // However, perhaps we should test to make sure and throw an error?
|
danielebarchiesi@4
|
473 $gid = $gids->execute()->fetchField();
|
danielebarchiesi@4
|
474 return $gid;
|
danielebarchiesi@4
|
475 }
|
danielebarchiesi@4
|
476
|
danielebarchiesi@4
|
477 function rdfx_get_nsids($main_ns) {
|
danielebarchiesi@4
|
478 $gid = rdfx_get_gid($main_ns);
|
danielebarchiesi@4
|
479 $nsids = db_query("SELECT uri, nsid FROM {rdfx_namespaces} WHERE gid = :gid", array(':gid' => $gid))->fetchAllKeyed();
|
danielebarchiesi@4
|
480 return $nsids;
|
danielebarchiesi@4
|
481 }
|
danielebarchiesi@4
|
482
|
danielebarchiesi@4
|
483 function rdfx_curie($tid) {
|
danielebarchiesi@4
|
484 $query = db_select('rdfx_terms', 'rdft')
|
danielebarchiesi@4
|
485 ->fields('rdft', array('local_name'))
|
danielebarchiesi@4
|
486 ->fields('rdfns', array('prefix'))
|
danielebarchiesi@4
|
487 ->condition('rdft.tid', $tid, '=');
|
danielebarchiesi@4
|
488 $query->join('rdfx_namespaces', 'rdfns', 'rdfns.nsid = rdft.nsid');
|
danielebarchiesi@4
|
489 $result = $query->execute()->fetch();
|
danielebarchiesi@4
|
490 $curie = $result->prefix . ':' . $result->local_name;
|
danielebarchiesi@4
|
491 return $curie;
|
danielebarchiesi@4
|
492 }
|
danielebarchiesi@4
|
493
|
danielebarchiesi@4
|
494 function _rdfx_get_term_details($tid, $langcode = 'und') {
|
danielebarchiesi@4
|
495 $query_language = db_query("SELECT language FROM {rdfx_term_details} WHERE tid = :tid", array(':tid' => $tid));
|
danielebarchiesi@4
|
496 $languages = $query_language->fetchCol();
|
danielebarchiesi@4
|
497 if (!in_array($langcode, $languages)) {
|
danielebarchiesi@4
|
498 if (in_array('und', $languages)) {
|
danielebarchiesi@4
|
499 $langcode = 'und';
|
danielebarchiesi@4
|
500 }
|
danielebarchiesi@4
|
501 elseif (in_array('en', $languages)) {
|
danielebarchiesi@4
|
502 $langcode = 'en';
|
danielebarchiesi@4
|
503 }
|
danielebarchiesi@4
|
504 else {
|
danielebarchiesi@4
|
505 return;
|
danielebarchiesi@4
|
506 }
|
danielebarchiesi@4
|
507 }
|
danielebarchiesi@4
|
508 $query = db_select('rdfx_term_details', 'rdfd')
|
danielebarchiesi@4
|
509 ->fields('rdfd', array('label', 'comment'))
|
danielebarchiesi@4
|
510 ->condition('rdfd.tid', $tid, '=')
|
danielebarchiesi@4
|
511 ->condition('language', $langcode, '=');
|
danielebarchiesi@4
|
512 $details = $query->execute()->fetch();
|
danielebarchiesi@4
|
513 return $details;
|
danielebarchiesi@4
|
514 }
|
danielebarchiesi@4
|
515
|
danielebarchiesi@4
|
516 /**
|
danielebarchiesi@4
|
517 * Queries a set of triples for classes and properties, and builds
|
danielebarchiesi@4
|
518 * an associative array describing the vocabulary and any
|
danielebarchiesi@4
|
519 * classes and properties found.
|
danielebarchiesi@4
|
520 *
|
danielebarchiesi@4
|
521 * @param array $model An ARC2-style array of triples an RDFS vocabulary or OWL ontology
|
danielebarchiesi@4
|
522 * @param array $namespaces Associative array of namespaces parsed from the RDF file
|
danielebarchiesi@4
|
523 * @param string $ns_prefix Namespace prefix for the vocabulary
|
danielebarchiesi@4
|
524 * @param string $ns_uri Only terms in this namespace will be considered
|
danielebarchiesi@4
|
525 * @return array Array describing the vocabulary, its classes and properties.
|
danielebarchiesi@4
|
526 */
|
danielebarchiesi@4
|
527 function _rdfx_extract_schema(&$model, $namespaces, $ns_prefix, $ns_uri) {
|
danielebarchiesi@4
|
528 $vocabulary_details = _rdfx_get_vocabulary_details($model, $ns_uri);
|
danielebarchiesi@4
|
529 $terms = _rdfx_fetch_terms($model);
|
danielebarchiesi@4
|
530 $vocabulary = array(
|
danielebarchiesi@4
|
531 'uri' => $ns_uri,
|
danielebarchiesi@4
|
532 'title' => $vocabulary_details['title'],
|
danielebarchiesi@4
|
533 'description' => $vocabulary_details['description'],
|
danielebarchiesi@4
|
534 'terms' => $terms,
|
danielebarchiesi@4
|
535 'namespaces' => $namespaces,
|
danielebarchiesi@4
|
536 );
|
danielebarchiesi@4
|
537 return $vocabulary;
|
danielebarchiesi@4
|
538 }
|
danielebarchiesi@4
|
539
|
danielebarchiesi@4
|
540 function _rdfx_fetch_terms(&$model) {
|
danielebarchiesi@4
|
541 $terms = array();
|
danielebarchiesi@4
|
542 $term_uris = array();
|
danielebarchiesi@4
|
543
|
danielebarchiesi@4
|
544 // Retrieve the queries for term retrieval. This may have been modified by
|
danielebarchiesi@4
|
545 // other modules.
|
danielebarchiesi@4
|
546 $term_type_groups = rdfx_term_types();
|
danielebarchiesi@4
|
547
|
danielebarchiesi@4
|
548 foreach($term_type_groups as $term_type_group => $group) {
|
danielebarchiesi@4
|
549 foreach ($group['term_types'] as $term_type => $term) {
|
danielebarchiesi@4
|
550 $query = array(
|
danielebarchiesi@4
|
551 array('?', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $term['uri']),
|
danielebarchiesi@4
|
552 );
|
danielebarchiesi@4
|
553 foreach ($term['inference'] as $inference_uri => $query_types) {
|
danielebarchiesi@4
|
554 foreach ($query_types as $query_type) {
|
danielebarchiesi@4
|
555 switch ($query_type) {
|
danielebarchiesi@4
|
556 case 'subject':
|
danielebarchiesi@4
|
557 $query[] = array('?', $inference_uri, null);
|
danielebarchiesi@4
|
558 break;
|
danielebarchiesi@4
|
559 case 'object':
|
danielebarchiesi@4
|
560 $query[] = array(null, $inference_uri, '?');
|
danielebarchiesi@4
|
561 break;
|
danielebarchiesi@4
|
562 }
|
danielebarchiesi@4
|
563 }
|
danielebarchiesi@4
|
564 }
|
danielebarchiesi@4
|
565 $term_uris[$term_type] = _rdfx_query_find_uris($model, $query);
|
danielebarchiesi@4
|
566
|
danielebarchiesi@4
|
567 // Add term details and various relationships for each term, as defined
|
danielebarchiesi@4
|
568 // in rdfx_term_types() and altered by hook_rdfx_term_types_alter().
|
danielebarchiesi@4
|
569 $query_x = array();
|
danielebarchiesi@4
|
570 foreach ($term_uris[$term_type] as $term_uri) {
|
danielebarchiesi@4
|
571
|
danielebarchiesi@4
|
572 $terms[$term_type][$term_uri] = _evoc_query_for_term_description($model, $term_uri);
|
danielebarchiesi@4
|
573 foreach ($group['description'] as $property => $queries) {
|
danielebarchiesi@4
|
574 foreach ($queries as $predicate_uri => $query_types) {
|
danielebarchiesi@4
|
575 foreach ($query_types as $query_type) {
|
danielebarchiesi@4
|
576 switch ($query_type) {
|
danielebarchiesi@4
|
577 case 'subject':
|
danielebarchiesi@4
|
578 $query_x[$term_uri][$property][] = array('?', $predicate_uri, $term_uri);
|
danielebarchiesi@4
|
579 break;
|
danielebarchiesi@4
|
580 case 'object':
|
danielebarchiesi@4
|
581 $query_x[$term_uri][$property][] = array($term_uri, $predicate_uri, '?');
|
danielebarchiesi@4
|
582 break;
|
danielebarchiesi@4
|
583 }
|
danielebarchiesi@4
|
584 }
|
danielebarchiesi@4
|
585 }
|
danielebarchiesi@4
|
586 $terms[$term_type][$term_uri][$property] = _rdfx_query_find_uris($model, $query_x[$term_uri][$property]);
|
danielebarchiesi@4
|
587 }
|
danielebarchiesi@4
|
588 }
|
danielebarchiesi@4
|
589 }
|
danielebarchiesi@4
|
590 }
|
danielebarchiesi@4
|
591 return $terms;
|
danielebarchiesi@4
|
592 }
|
danielebarchiesi@4
|
593
|
danielebarchiesi@4
|
594 function _rdfx_get_vocabulary_details(&$model, $ns_uri) {
|
danielebarchiesi@4
|
595 $query_predicates = array(
|
danielebarchiesi@4
|
596 'title' => array(
|
danielebarchiesi@4
|
597 'http://www.w3.org/2000/01/rdf-schema#label',
|
danielebarchiesi@4
|
598 'http://purl.org/dc/elements/1.1/title',
|
danielebarchiesi@4
|
599 'http://purl.org/dc/terms/title',
|
danielebarchiesi@4
|
600 ),
|
danielebarchiesi@4
|
601 'description' => array(
|
danielebarchiesi@4
|
602 'http://www.w3.org/2000/01/rdf-schema#comment',
|
danielebarchiesi@4
|
603 'http://purl.org/dc/elements/1.1/description',
|
danielebarchiesi@4
|
604 'http://purl.org/dc/terms/description',
|
danielebarchiesi@4
|
605 ),
|
danielebarchiesi@4
|
606 );
|
danielebarchiesi@4
|
607
|
danielebarchiesi@4
|
608 if (substr($ns_uri, -1) == '#') {
|
danielebarchiesi@4
|
609 $uri = substr($ns_uri, 0, -1);
|
danielebarchiesi@4
|
610 }
|
danielebarchiesi@4
|
611
|
danielebarchiesi@4
|
612 foreach ($query_predicates as $query_element => $predicates) {
|
danielebarchiesi@4
|
613 foreach ($predicates as $predicate) {
|
danielebarchiesi@4
|
614 $queries[$query_element][] = array($ns_uri, $predicate, '?');
|
danielebarchiesi@4
|
615 // if ($uri !== NULL) {
|
danielebarchiesi@4
|
616 // $queries[$query_element][] = array($uri, $predicate, '?');
|
danielebarchiesi@4
|
617 // }
|
danielebarchiesi@4
|
618 }
|
danielebarchiesi@4
|
619 $details[$query_element] = _rdfx_query_find_literal($model, $queries[$query_element]);
|
danielebarchiesi@4
|
620 }
|
danielebarchiesi@4
|
621 return $details;
|
danielebarchiesi@4
|
622 }
|