parameters = $parameters;
$this->httpRequest = $httpRequest;
$this->features = $GLOBALS['smwgRemoteReqFeatures'];
if ( isset( $this->parameters['smwgRemoteReqFeatures'] ) ) {
$this->features = $this->parameters['smwgRemoteReqFeatures'];
}
}
/**
* @since 3.0
*/
public function clear() {
self::$isConnected = null;
}
/**
* @since 3.0
*
* @param integer $flag
*
* @return boolean
*/
public function hasFeature( $flag ) {
return ( ( (int)$this->features & $flag ) == $flag );
}
/**
* @since 3.0
*
* @param Query $query
*
* @return StringResult|string
*/
public function getQueryResult( Query $query ) {
if ( $query->isEmbedded() && $query->getLimit() == 0 ) {
return $this->further_link( $query );
}
if ( !isset( $this->parameters['url'] ) ) {
throw new RuntimeException( "Missing a remote URL for $source" );
}
$source = $query->getQuerySource();
$this->init();
if ( !$this->canConnect( $this->parameters['url'] ) ) {
return $this->error( 'smw-remote-source-unavailable', $this->parameters['url'] );
}
$result = $this->fetch( $query );
$isFromCache = false;
$isDisabled = false;
if ( $this->httpRequest instanceof CachedCurlRequest ) {
$isFromCache = $this->httpRequest->isFromCache();
}
if ( $result === self::SOURCE_DISABLED ) {
$result = $this->error( 'smw-remote-source-disabled', $source );
$isDisabled = true;
}
// Find out whether the source has send an ID and hereby produces an output
// that can be used by the `RemoteRequest`
if ( strpos( $result, self::REQUEST_ID ) === false ) {
$result = $this->error( 'smw-remote-source-unmatched-id', $source );
$isDisabled = true;
} else {
$result = str_replace( self::REQUEST_ID, '', $result );
}
// Add an information note depending on the context before the actual output
$callback = function( $result, array $options ) use( $isFromCache, $isDisabled, $source ) {
$options['source'] = $source;
$options['is.cached'] = $isFromCache;
$options['is.disabled'] = $isDisabled;
return $this->format_result( $result, $options );
};
$stringResult = new StringResult( $result, $query );
$stringResult->setPreOutputCallback( $callback );
$stringResult->setFromCache( $isFromCache );
if ( $query->getQueryMode() === Query::MODE_COUNT ) {
$stringResult->setCountValue( $result );
}
return $stringResult;
}
/**
* @since 3.0
*
* @param string $result
* @param array $options
*
* @return string
*/
public function format_result( $result, array $options ) {
// No changes to any export related output
if ( ( isset( $options['is.disabled'] ) && $options['is.disabled'] ) || !$this->hasFeature( SMW_REMOTE_REQ_SHOW_NOTE ) ) {
return $result;
}
if ( ( isset( $options['is.exportformat'] ) && $options['is.exportformat'] ) ) {
return $result;
}
$msg = $options['is.cached'] ? 'smw-remote-request-note-cached' : 'smw-remote-request-note';
return Html::rawElement(
'div',
[
'class' => 'smw-note smw-remote-query',
'style' => 'margin-top:12px;'
],
Html::rawElement(
'span',
[
'class' => 'smw-icon-info',
'style' => 'margin-left: -5px; padding: 10px 12px 12px 12px;'
]
) . Message::get( [ $msg, $options['source'] ], Message::PARSE, Message::USER_LANGUAGE )
) . $result;
}
private function further_link( $query ) {
$link = QueryLinker::get( $query );
// Find remaining parameters, format, template etc.
$extraParameters = $query->getOption( 'query.params' );
foreach ( $extraParameters as $key => $value ) {
if ( $key === 'limit' || $value === '' ) {
continue;
}
if ( is_array( $value ) ) {
$value = implode( ',', $value );
}
$link->setParameter( $value, $key );
}
return $link->getText( SMW_OUTPUT_WIKI );
}
private function init() {
if ( $this->httpRequest === null && isset( $this->parameters['cache'] ) ) {
$this->httpRequest = new CachedCurlRequest(
curl_init(),
ApplicationFactory::getInstance()->getCache()
);
$this->httpRequest->setOption(
ONOI_HTTP_REQUEST_RESPONSECACHE_TTL,
$this->parameters['cache']
);
$this->httpRequest->setOption(
ONOI_HTTP_REQUEST_RESPONSECACHE_PREFIX,
Site::id( 'smw:query:remote:' )
);
}
if ( $this->httpRequest === null ) {
$this->httpRequest = new CurlRequest( curl_init() );
}
}
private function error() {
$params = func_get_args();
return Html::rawElement(
'div',
[
'id' => $params[0],
'class' => 'smw-callout smw-callout-error'
],
Message::get( $params, Message::PARSE, Message::USER_LANGUAGE )
);
}
private function canConnect( $url ) {
$this->httpRequest->setOption( CURLOPT_URL, $url );
if ( self::$isConnected === null ) {
self::$isConnected = $this->httpRequest->ping();
}
return self::$isConnected;
}
private function fetch( $query ) {
$parameters = $query->toArray();
$default = '';
$params = [ 'title' => 'Special:Ask', 'q' => '', 'po' => '', 'p' => [] ];
if ( isset( $parameters['conditions'] ) ) {
$params['q'] = $parameters['conditions'];
}
if ( isset( $parameters['printouts'] ) ) {
$params['po'] = implode( '|', $parameters['printouts'] );
}
if ( !isset( $parameters['parameters'] ) ) {
$parameters['parameters'] = [];
}
// Find remaining parameters, format, template etc.
$extraParameters = $query->getOption( 'query.params' );
if ( is_array( $extraParameters ) ) {
$parameters['parameters'] = array_merge( $parameters['parameters'], $extraParameters );
}
foreach ( $parameters['parameters'] as $key => $value ) {
if ( $key === 'default' ) {
$default = $value;
}
if ( $value === '' ) {
continue;
}
if ( is_array( $value ) ) {
$value = implode( ',', $value );
}
$params['p'][] = "$key=$value";
}
$params['request_type'] = $query->isEmbedded() ? 'embed' : 'special_page';
$output = '';
$options = [
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query( $params ),
CURLOPT_RETURNTRANSFER => 1
];
foreach ( $options as $key => $value ) {
$this->httpRequest->setOption( $key, $value );
}
$output = $this->httpRequest->execute();
if ( $this->httpRequest->getLastError() !== '' ) {
$output = $this->httpRequest->getLastError();
}
// The remote Special:Ask doesn't return a default output hence it is done
// at this point
if ( $output === '' ) {
$output = $default;
}
return $output;
}
}