|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* Define the Wordlift_Sparql_Service class. |
|
5
|
|
|
*/ |
|
6
|
|
|
|
|
7
|
|
|
/** |
|
8
|
|
|
* The Wordlift_Sparql_Service class provides functions related to SPARQL queries. |
|
9
|
|
|
* |
|
10
|
|
|
* @since 3.6.0 |
|
11
|
|
|
*/ |
|
12
|
|
|
class Wordlift_Sparql_Service { |
|
13
|
|
|
|
|
14
|
|
|
/** |
|
15
|
|
|
* A {@link Wordlift_Log_Service} instance. |
|
16
|
|
|
* |
|
17
|
|
|
* @since 3.6.0 |
|
18
|
|
|
* @access private |
|
19
|
|
|
* @var \Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance. |
|
20
|
|
|
*/ |
|
21
|
|
|
private $log; |
|
22
|
|
|
|
|
23
|
|
|
/** |
|
24
|
|
|
* The {@link Wordlift_Sparql_Service} singleton instance. |
|
25
|
|
|
* |
|
26
|
|
|
* @since 3.6.0 |
|
27
|
|
|
* @access private |
|
28
|
|
|
* @var \Wordlift_Sparql_Service $instance The {@link Wordlift_Sparql_Service} singleton instance. |
|
29
|
|
|
*/ |
|
30
|
|
|
private static $instance; |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* Create a {@link Wordlift_Sparql_Service} instance. |
|
34
|
|
|
* |
|
35
|
|
|
* @since 3.6.0 |
|
36
|
|
|
*/ |
|
37
|
|
|
public function __construct() { |
|
38
|
|
|
|
|
39
|
|
|
$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Sparql_Service' ); |
|
40
|
|
|
|
|
41
|
|
|
self::$instance = $this; |
|
42
|
|
|
|
|
43
|
|
|
} |
|
44
|
|
|
|
|
45
|
|
|
/** |
|
46
|
|
|
* Get the singleton instance of the {@link Wordlift_Sparql_Service}. |
|
47
|
|
|
* |
|
48
|
|
|
* @since 3.6.0 |
|
49
|
|
|
* @return \Wordlift_Sparql_Service |
|
50
|
|
|
*/ |
|
51
|
|
|
public static function get_instance() { |
|
52
|
|
|
|
|
53
|
|
|
return self::$instance; |
|
54
|
|
|
} |
|
55
|
|
|
|
|
56
|
|
|
/** |
|
57
|
|
|
* Queue a SPARQL statement for execution. |
|
58
|
|
|
* |
|
59
|
|
|
* @since 3.6.0 |
|
60
|
|
|
* |
|
61
|
|
|
* @param string $stmt The SPARQL statement. |
|
62
|
|
|
*/ |
|
63
|
|
|
public function queue( $stmt ) { |
|
64
|
|
|
|
|
65
|
|
|
rl_execute_sparql_update_query( $stmt ); |
|
66
|
|
|
|
|
67
|
|
|
} |
|
68
|
|
|
|
|
69
|
|
|
/** |
|
70
|
|
|
* Execute the SELECT query. |
|
71
|
|
|
* |
|
72
|
|
|
* @since 3.12.2 |
|
73
|
|
|
* |
|
74
|
|
|
* @param string $query The SELECT query to execute. |
|
75
|
|
|
* |
|
76
|
|
|
* @return WP_Error|array The response or WP_Error on failure. |
|
77
|
|
|
*/ |
|
78
|
|
View Code Duplication |
public function select( $query ) { |
|
|
|
|
|
|
79
|
|
|
|
|
80
|
|
|
// Prepare the SPARQL statement by prepending the default namespaces. |
|
81
|
|
|
$sparql = rl_sparql_prefixes() . "\n" . $query; |
|
82
|
|
|
|
|
83
|
|
|
// Get the SPARQL SELECT URL. |
|
84
|
|
|
$url = wl_configuration_get_query_select_url( 'csv' ) . urlencode( $sparql ); |
|
85
|
|
|
|
|
86
|
|
|
// Prepare the request. |
|
87
|
|
|
$args = unserialize( WL_REDLINK_API_HTTP_OPTIONS ); |
|
88
|
|
|
|
|
89
|
|
|
return wp_remote_get( $url, $args ); |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
/** |
|
93
|
|
|
* Formats the provided value according to the specified type in order to |
|
94
|
|
|
* insert the value using SPARQL. The value is also escaped. |
|
95
|
|
|
* |
|
96
|
|
|
* @since 3.6.0 |
|
97
|
|
|
* |
|
98
|
|
|
* @param string $value The value. |
|
99
|
|
|
* @param string $type The value type. |
|
100
|
|
|
* |
|
101
|
|
|
* @return string The formatted value for SPARQL statements. |
|
102
|
|
|
*/ |
|
103
|
|
|
public function format( $value, $type ) { |
|
104
|
|
|
|
|
105
|
|
|
// see https://www.w3.org/TR/sparql11-query/. |
|
106
|
|
|
|
|
107
|
|
|
switch ( $type ) { |
|
108
|
|
|
|
|
109
|
|
|
case Wordlift_Schema_Service::DATA_TYPE_BOOLEAN: |
|
|
|
|
|
|
110
|
|
|
|
|
111
|
|
|
// SPARQL supports 'true' and 'false', so we evaluate the $value |
|
112
|
|
|
// and return true/false accordingly. |
|
|
|
|
|
|
113
|
|
|
return $value ? 'true' : 'false'; |
|
114
|
|
|
|
|
115
|
|
|
case Wordlift_Schema_Service::DATA_TYPE_DATE: |
|
|
|
|
|
|
116
|
|
|
|
|
117
|
|
|
return sprintf( '"%s"^^xsd:date', self::escape( $value ) ); |
|
118
|
|
|
|
|
119
|
|
|
|
|
120
|
|
|
case Wordlift_Schema_Service::DATA_TYPE_DOUBLE: |
|
|
|
|
|
|
121
|
|
|
|
|
122
|
|
|
return sprintf( '"%s"^^xsd:double', self::escape( $value ) ); |
|
123
|
|
|
|
|
124
|
|
|
case Wordlift_Schema_Service::DATA_TYPE_INTEGER: |
|
|
|
|
|
|
125
|
|
|
|
|
126
|
|
|
return sprintf( '"%s"^^xsd:integer', self::escape( $value ) ); |
|
127
|
|
|
|
|
128
|
|
|
case Wordlift_Schema_Service::DATA_TYPE_STRING: |
|
|
|
|
|
|
129
|
|
|
|
|
130
|
|
|
return sprintf( '"%s"^^xsd:string', self::escape( $value ) ); |
|
131
|
|
|
|
|
132
|
|
|
case Wordlift_Schema_Service::DATA_TYPE_URI: |
|
|
|
|
|
|
133
|
|
|
|
|
134
|
|
|
return sprintf( '<%s>', self::escape_uri( $value ) ); |
|
135
|
|
|
|
|
136
|
|
|
default: |
|
|
|
|
|
|
137
|
|
|
|
|
138
|
|
|
$this->log->warn( "Unknown data type [ type :: $type ]" ); |
|
139
|
|
|
|
|
140
|
|
|
// Try to insert the value anyway. |
|
141
|
|
|
return sprintf( '"%s"', self::escape( $value ) ); |
|
142
|
|
|
} |
|
143
|
|
|
|
|
144
|
|
|
} |
|
145
|
|
|
|
|
146
|
|
|
/** |
|
147
|
|
|
* Escapes an URI for a SPARQL statement. |
|
148
|
|
|
* |
|
149
|
|
|
* @since 3.6.0 |
|
150
|
|
|
* |
|
151
|
|
|
* @param string $uri The URI to escape. |
|
152
|
|
|
* |
|
153
|
|
|
* @return string The escaped URI. |
|
154
|
|
|
*/ |
|
155
|
|
|
public static function escape_uri( $uri ) { |
|
156
|
|
|
|
|
157
|
|
|
// Should we validate the IRI? |
|
158
|
|
|
// http://www.w3.org/TR/sparql11-query/#QSynIRI |
|
159
|
|
|
|
|
160
|
|
|
$uri = str_replace( '<', '\<', $uri ); |
|
161
|
|
|
$uri = str_replace( '>', '\>', $uri ); |
|
162
|
|
|
|
|
163
|
|
|
return $uri; |
|
164
|
|
|
} |
|
165
|
|
|
|
|
166
|
|
|
/** |
|
167
|
|
|
* Escapes a string for a SPARQL statement. |
|
168
|
|
|
* |
|
169
|
|
|
* @since 3.6.0 |
|
170
|
|
|
* |
|
171
|
|
|
* @param string $string The string to escape. |
|
172
|
|
|
* |
|
173
|
|
|
* @return string The escaped string. |
|
174
|
|
|
*/ |
|
175
|
|
|
public static function escape( $string ) { |
|
176
|
|
|
|
|
177
|
|
|
// see http://www.w3.org/TR/rdf-sparql-query/ |
|
178
|
|
|
// '\t' U+0009 (tab) |
|
|
|
|
|
|
179
|
|
|
// '\n' U+000A (line feed) |
|
180
|
|
|
// '\r' U+000D (carriage return) |
|
|
|
|
|
|
181
|
|
|
// '\b' U+0008 (backspace) |
|
|
|
|
|
|
182
|
|
|
// '\f' U+000C (form feed) |
|
183
|
|
|
// '\"' U+0022 (quotation mark, double quote mark) |
|
184
|
|
|
// "\'" U+0027 (apostrophe-quote, single quote mark) |
|
185
|
|
|
// '\\' U+005C (backslash) |
|
|
|
|
|
|
186
|
|
|
|
|
187
|
|
|
$string = str_replace( '\\', '\\\\', $string ); |
|
188
|
|
|
$string = str_replace( '\'', '\\\'', $string ); |
|
189
|
|
|
$string = str_replace( '"', '\\"', $string ); |
|
190
|
|
|
$string = str_replace( "\f", '\\f', $string ); |
|
191
|
|
|
$string = str_replace( "\b", '\\b', $string ); |
|
192
|
|
|
$string = str_replace( "\r", '\\r', $string ); |
|
193
|
|
|
$string = str_replace( "\n", '\\n', $string ); |
|
194
|
|
|
$string = str_replace( "\t", '\\t', $string ); |
|
195
|
|
|
|
|
196
|
|
|
return $string; |
|
197
|
|
|
} |
|
198
|
|
|
|
|
199
|
|
|
} |
|
200
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.