summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Api/Browse/ListLookup.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Api/Browse/ListLookup.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Api/Browse/ListLookup.php252
1 files changed, 252 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Api/Browse/ListLookup.php b/www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Api/Browse/ListLookup.php
new file mode 100644
index 00000000..690035c2
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Api/Browse/ListLookup.php
@@ -0,0 +1,252 @@
+<?php
+
+namespace SMW\MediaWiki\Api\Browse;
+
+use Exception;
+use SMW\DIProperty;
+use SMW\RequestOptions;
+use SMW\SQLStore\SQLStore;
+use SMW\Store;
+use SMW\StringCondition;
+
+/**
+ * @license GNU GPL v2+
+ * @since 3.0
+ *
+ * @author mwjames
+ */
+class ListLookup extends Lookup {
+
+ const VERSION = 1;
+
+ /**
+ * @var Store
+ */
+ private $store;
+
+ /**
+ * @var ListAugmentor
+ */
+ private $listAugmentor;
+
+ /**
+ * @since 3.0
+ *
+ * @param Store $store
+ */
+ public function __construct( Store $store, ListAugmentor $listAugmentor ) {
+ $this->store = $store;
+ $this->listAugmentor = $listAugmentor;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @return string|integer
+ */
+ public function getVersion() {
+ return 'ListLookup:' . self::VERSION;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param array $parameters
+ *
+ * @return array
+ */
+ public function lookup( array $parameters ) {
+
+ $requestOptions = $this->newRequestOptions(
+ $parameters
+ );
+
+ $limit = $requestOptions->getLimit();
+ $list = [];
+ $continueOffset = 0;
+
+ // Increase by one to look ahead
+ $requestOptions->setLimit( $limit + 1 );
+ $ns = isset( $parameters['ns'] ) ? $parameters['ns'] : '';
+
+ switch ( $ns ) {
+ case NS_CATEGORY:
+ $type = 'category';
+ break;
+ case SMW_NS_PROPERTY:
+ $type = 'property';
+ break;
+ case SMW_NS_CONCEPT:
+ $type = 'concept';
+ break;
+ default:
+ $type = 'unlisted';
+ break;
+ }
+
+ if ( isset( $parameters['search'] ) ) {
+ list( $res, $continueOffset ) = $this->fetchFromTable( $ns, $requestOptions, $parameters );
+ }
+
+ // Changing this output format requires to set a new version
+ $res = [
+ 'query' => $res,
+ 'query-continue-offset' => $continueOffset,
+ 'version' => self::VERSION,
+ 'meta' => [
+ 'type' => $type,
+ 'limit' => $limit,
+ 'count' => count( $res )
+ ]
+ ];
+
+ $this->listAugmentor->augment(
+ $res,
+ $parameters
+ );
+
+ return $res;
+ }
+
+ private function newRequestOptions( $parameters ) {
+
+ $limit = 50;
+ $offset = 0;
+ $search = '';
+
+ if ( isset( $parameters['limit'] ) ) {
+ $limit = (int)$parameters['limit'];
+ }
+
+ if ( isset( $parameters['offset'] ) ) {
+ $offset = (int)$parameters['offset'];
+ }
+
+ $requestOptions = new RequestOptions();
+ $requestOptions->sort = true;
+ $requestOptions->setLimit( $limit );
+ $requestOptions->setOffset( $offset );
+
+ if ( isset( $parameters['search'] ) && isset( $parameters['strict'] ) ) {
+ $search = $parameters['search'];
+
+ if ( $search !== '' && $search{0} !== '_' ) {
+ $search = str_replace( "_", " ", $search );
+ }
+
+ $requestOptions->addStringCondition(
+ $search,
+ StringCondition::COND_EQ
+ );
+
+ } elseif ( isset( $parameters['search'] ) ) {
+ $search = $parameters['search'];
+
+ if ( $search !== '' && $search{0} !== '_' ) {
+ $search = str_replace( "_", " ", $search );
+ }
+
+ $requestOptions->addStringCondition(
+ $search,
+ StringCondition::STRCOND_MID
+ );
+
+ // Disjunctive condition to allow for auto searches to match foaf OR Foaf
+ $requestOptions->addStringCondition(
+ ucfirst( $search ),
+ StringCondition::STRCOND_MID,
+ true
+ );
+
+ // Allow something like FOO to match the search string `foo`
+ $requestOptions->addStringCondition(
+ strtoupper( $search ),
+ StringCondition::STRCOND_MID,
+ true
+ );
+
+ $requestOptions->addStringCondition(
+ strtolower( $search ),
+ StringCondition::STRCOND_MID,
+ true
+ );
+ }
+
+ return $requestOptions;
+ }
+
+ private function fetchFromTable( $ns, $requestOptions, $parameters ) {
+
+ $limit = $requestOptions->getLimit() - 1;
+ $list = [];
+ $options = [];
+
+ $fields = [
+ 'smw_id',
+ 'smw_title'
+ ];
+
+ // the query needs to do the filtering of internal properties, else LIMIT is wrong
+ if ( isset( $parameters['sort'] ) ) {
+ $options = $this->store->getSQLOptions( $requestOptions, 'smw_sort' );
+ $fields[] = 'smw_sort';
+ }
+
+ $conditions = [
+ 'smw_namespace' => $ns,
+ 'smw_iw' => '',
+ 'smw_subobject' => ''
+ ];
+
+ if ( ( $cond = $this->store->getSQLConditions( $requestOptions, '', 'smw_sortkey', false ) ) !== '' ) {
+ $conditions[] = $cond;
+ $fields[] = 'smw_sortkey';
+ }
+
+ $connection = $this->store->getConnection( 'mw.db' );
+
+ $res = $connection->select(
+ $connection->tableName( SQLStore::ID_TABLE ),
+ $fields,
+ $conditions,
+ __METHOD__,
+ $options
+ );
+
+ $count = 0;
+ $continueOffset = 0;
+
+ foreach ( $res as $row ) {
+
+ $key = $row->smw_title;
+ $count++;
+
+ if ( $count > $limit ) {
+ $continueOffset = $requestOptions->getOffset() + $limit;
+ break;
+ }
+
+ if ( $ns === SMW_NS_PROPERTY ) {
+ try {
+ $label = DIProperty::newFromUserLabel( $row->smw_title )->getLabel();
+ } catch( Exception $e ) {
+ continue;
+ }
+
+ } else {
+ $label = str_replace( '_', ' ', $row->smw_title );
+ }
+
+ $list[$key] = [
+ // Only keep the ID as internal field which is
+ // removed by the Augmentor
+ 'id' => $row->smw_id,
+ 'label' => $label,
+ 'key' => $key
+ ];
+ }
+
+ return [ $list, $continueOffset ];
+ }
+
+}