MediaWiki  master
SparqlClient.php
Go to the documentation of this file.
1 <?php
21 namespace MediaWiki\Sparql;
22 
24 use Wikimedia\AtEase\AtEase;
25 
31 class SparqlClient {
32 
36  public const MAX_GET_SIZE = 2048;
37 
42  private $userAgent;
43 
48  private $timeout = 30;
49 
54  private $endpoint;
55 
60  private $options = [];
61 
65  private $requestFactory;
66 
71  public function __construct( $url, HttpRequestFactory $requestFactory ) {
72  $this->endpoint = $url;
73  $this->requestFactory = $requestFactory;
74  $this->userAgent = $requestFactory->getUserAgent() . " SparqlClient";
75  }
76 
82  public function setTimeout( $timeout ) {
83  if ( $timeout >= 0 ) {
84  $this->timeout = $timeout;
85  }
86  return $this;
87  }
88 
93  public function setClientOptions( $options ) {
94  $this->options = $options;
95  return $this;
96  }
97 
102  public function getUserAgent() {
103  return $this->userAgent;
104  }
105 
113  public function setUserAgent( $agent ) {
114  $this->userAgent = $agent;
115  }
116 
126  public function appendUserAgent( $agent ) {
127  $this->userAgent .= ' ' . $agent;
128  }
129 
140  public function query( $sparql, $rawData = false ) {
141  if ( empty( $this->endpoint ) ) {
142  throw new SparqlException( 'Endpoint URL can not be empty' );
143  }
144  $queryData = [ "query" => $sparql, "format" => "json" ];
145  $options = array_merge( [ 'method' => 'GET' ], $this->options );
146 
147  if ( empty( $options['userAgent'] ) ) {
148  $options['userAgent'] = $this->userAgent;
149  }
150 
151  if ( $this->timeout >= 0 ) {
152  // Blazegraph setting, see https://wiki.blazegraph.com/wiki/index.php/REST_API
153  $queryData['maxQueryTimeMillis'] = $this->timeout * 1000;
154  $options['timeout'] = $this->timeout;
155  }
156 
157  if ( strlen( $sparql ) > self::MAX_GET_SIZE ) {
158  // big requests go to POST
159  $options['method'] = 'POST';
160  $options['postData'] = 'query=' . urlencode( $sparql );
161  unset( $queryData['query'] );
162  }
163 
164  $url = wfAppendQuery( $this->endpoint, $queryData );
165  $request = $this->requestFactory->create( $url, $options, __METHOD__ );
166 
167  $status = $request->execute();
168 
169  if ( !$status->isOK() ) {
170  throw new SparqlException( 'HTTP error: ' . $status->getWikiText( false, false, 'en' ) );
171  }
172  $result = $request->getContent();
173  AtEase::suppressWarnings();
174  $data = json_decode( $result, true );
175  AtEase::restoreWarnings();
176  if ( $data === null || $data === false ) {
177  throw new SparqlException( "HTTP request failed, response:\n" .
178  substr( $result, 1024 ) );
179  }
180 
181  return $this->extractData( $data, $rawData );
182  }
183 
194  private function extractData( $data, $rawData = false ) {
195  $result = [];
196  if ( $data && !empty( $data['results'] ) ) {
197  $vars = $data['head']['vars'];
198  $resrow = [];
199  foreach ( $data['results']['bindings'] as $row ) {
200  foreach ( $vars as $var ) {
201  if ( !isset( $row[$var] ) ) {
202  $resrow[$var] = null;
203  continue;
204  }
205  if ( $rawData ) {
206  $resrow[$var] = $row[$var];
207  } else {
208  $resrow[$var] = $row[$var]['value'];
209  }
210  }
211  $result[] = $resrow;
212  }
213  }
214  return $result;
215  }
216 
217 }
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
Factory creating MWHttpRequest objects.
Simple SPARQL client.
getUserAgent()
Get current user agent.
query( $sparql, $rawData=false)
Query SPARQL endpoint.
setTimeout( $timeout)
Set query timeout (in seconds)
appendUserAgent( $agent)
Append specific string to user agent.
const MAX_GET_SIZE
Limit on how long can be the query to be sent by GET.
__construct( $url, HttpRequestFactory $requestFactory)
setUserAgent( $agent)
Mote it is not recommended to completely override user agent for most applications.
Exception for SPARQLClient.