summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Specials/Ask/ParametersProcessor.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Specials/Ask/ParametersProcessor.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Specials/Ask/ParametersProcessor.php273
1 files changed, 273 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Specials/Ask/ParametersProcessor.php b/www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Specials/Ask/ParametersProcessor.php
new file mode 100644
index 00000000..19d86c2e
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/MediaWiki/Specials/Ask/ParametersProcessor.php
@@ -0,0 +1,273 @@
+<?php
+
+namespace SMW\MediaWiki\Specials\Ask;
+
+use SMWInfolink as Infolink;
+use SMWQueryProcessor as QueryProcessor;
+use WebRequest;
+
+/**
+ * @license GNU GPL v2+
+ * @since 3.0
+ *
+ * @author mwjames
+ */
+class ParametersProcessor {
+
+ /**
+ * @var integer
+ */
+ private static $defaultLimit = 50;
+
+ /**
+ * @var integer
+ */
+ private static $maxInlineLimit = 500;
+
+ /**
+ * @since 3.0
+ *
+ * @param integer $defaultLimit
+ */
+ public static function setDefaultLimit( $defaultLimit ) {
+ self::$defaultLimit = $defaultLimit;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param integer $maxInlineLimit
+ */
+ public static function setMaxInlineLimit( $maxInlineLimit ) {
+ self::$maxInlineLimit = $maxInlineLimit;
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param WebRequest $request
+ * @param array|null $params
+ *
+ * @return string
+ */
+ public static function process( WebRequest $request, $params ) {
+
+ // First make all inputs into a simple parameter list that can again be
+ // parsed into components later.
+ $parameterList = self::getParameterList( $request, $params );
+ $printouts = [];
+
+ // Check for q= query string, used whenever this special page calls
+ // itself (via submit or plain link):
+ if ( ( $q = $request->getText( 'q' ) ) !== '' ) {
+ $parameterList[] = $q;
+ }
+
+ // Parameters separated by newlines here (compatible with text-input for
+ // printouts)
+ if ( ( $po = $request->getText( 'po' ) ) !== '' ) {
+ $printouts = explode( "\n", $po );
+ }
+
+ // Check for param strings in po (printouts), appears in some links
+ // and in submits:
+ $parameterList = self::checkParameterList(
+ $request,
+ $parameterList,
+ $printouts
+ );
+
+ list( $queryString, $parameters, $printouts ) = QueryProcessor::getComponentsFromFunctionParams(
+ $parameterList,
+ false
+ );
+
+ unset( $parameters['cl'] );
+
+ // Try to complete undefined parameter values from dedicated URL params.
+ if ( !array_key_exists( 'format', $parameters ) ) {
+ $parameters['format'] = 'broadtable';
+ }
+
+ $sort_count = 0;
+ $empty_first_sort = false;
+
+ // First check whether the sorting options input send an
+ // request data as array
+ if ( ( $sort_values = $request->getArray( 'sort_num', [] ) ) !== [] ) {
+
+ // Find out whether something like `|?sort=,Has text` was used
+ if ( $sort_values[0] === '' ) {
+ $empty_first_sort = true;
+ }
+
+ if ( is_array( $sort_values ) ) {
+
+ // Filter all empty values
+ $sort = array_filter( $sort_values );
+ $sort_count = count( $sort );
+
+ // Add an empty element on the first position which got filter
+ // and was to prevent countless empty elements when no other sort
+ // was metioned
+ if ( $sort_count > 0 && $empty_first_sort ) {
+ array_unshift( $sort, '' );
+ $sort_count++;
+ }
+
+ $parameters['sort'] = implode( ',', $sort );
+ }
+ } elseif ( $request->getCheck( 'sort' ) ) {
+ $parameters['sort'] = $request->getVal( 'sort', '' );
+ }
+
+ // First check whether the order options input send an
+ // request data as array
+ if ( ( $order_values = $request->getArray( 'order_num', [] ) ) !== [] ) {
+
+ // Count doesn't match means we have a order from an
+ // empty (#subject) carrying around which we don't permit when
+ // sorting via columns
+ if ( is_array( $order_values ) && count( $order_values ) != $sort_count ) {
+ array_pop( $order_values );
+ }
+
+ if ( is_array( $order_values ) ) {
+ $order = array_filter( $order_values );
+ $parameters['order'] = implode( ',', $order );
+ }
+
+ } elseif ( $request->getCheck( 'order' ) ) {
+ $parameters['order'] = $request->getVal( 'order', '' );
+ } elseif ( !array_key_exists( 'order', $parameters ) ) {
+ $parameters['order'] = 'asc';
+ $parameters['sort'] = '';
+ }
+
+ if ( !array_key_exists( 'offset', $parameters ) ) {
+ $parameters['offset'] = $request->getVal( 'offset', 0 );
+ }
+
+ if ( !array_key_exists( 'limit', $parameters ) ) {
+ $parameters['limit'] = $request->getVal( 'limit', self::$defaultLimit );
+ }
+
+ $parameters['limit'] = min( $parameters['limit'], self::$maxInlineLimit );
+
+ return [ $queryString, $parameters, $printouts ];
+ }
+
+ private static function getParameterList( $request, $params ) {
+
+ // Called from wiki, get all parameters
+ if ( !$request->getCheck( 'q' ) ) {
+ return Infolink::decodeParameters( $params, true );
+ }
+
+ // Called by own Special, ignore full param string in that case
+ $query_val = $request->getVal( 'p' );
+
+ if ( !empty( $query_val ) ) {
+ // p is used for any additional parameters in certain links.
+ $parameterList = Infolink::decodeParameters( $query_val, false );
+ } else {
+ $query_values = $request->getArray( 'p' );
+
+ if ( is_array( $query_values ) ) {
+ foreach ( $query_values as $key => $val ) {
+ if ( empty( $val ) ) {
+ unset( $query_values[$key] );
+ }
+ }
+ }
+
+ // p is used for any additional parameters in certain links.
+ $parameterList = Infolink::decodeParameters( $query_values, false );
+ }
+
+ foreach ( $parameterList as $key => $value ) {
+ // Concatenate checkbox values into a simple comma separated list
+ if ( is_array( $value ) ) {
+ $parameterList[$key] = implode( ',', $value );
+ }
+ }
+
+ return $parameterList;
+ }
+
+ private static function checkParameterList( $request, $parameterList, $printouts ) {
+
+ // Add initial ? if omitted (all params considered as printouts)
+ foreach ( $printouts as $param ) {
+ $param = trim( $param );
+
+ if ( ( $param !== '' ) && ( $param { 0 } != '?' ) ) {
+ $param = '?' . $param;
+ }
+
+ $parameterList[] = $param;
+ }
+
+ $parameters = [];
+ unset( $parameterList['title'] );
+
+ // MW's internal token
+ unset( $parameterList['wpEditToken'] );
+
+ foreach ( $parameterList as $key => $value ) {
+ if ( self::hasPipe( $key, $value ) ) {
+
+ // #3523 `?TestAsk=[[Foo|Bar]]` replace `|`
+ if ( self::hasLink( $value ) ) {
+ $value = self::replace( '|', '0x7C', $value );
+ }
+
+ // #1407 Split: `?Has property=Foo|+index=1` into a [ '?Has property=Foo', '+index=1' ])
+ foreach ( explode( '|', $value ) as $k => $val ) {
+
+ // #3523 `?TestAsk=[[Foo|Bar]]|+index=1` decode
+ // the part that contains `0x7C`
+ if ( strpos( $val, '0x7C' ) !== false ) {
+ $val = self::replace( '0x7C', '|', $val );
+ }
+
+ $parameters[] = $k == 0 && $key{0} == '?' ? $key . '=' . $val : $val;
+ }
+ } elseif ( is_string( $key ) ) {
+ $parameters[$key] = $value;
+ } else {
+ $parameters[] = $value;
+ }
+ }
+
+ return $parameters;
+ }
+
+ private static function hasPipe( $key, $value ) {
+
+ if ( $key !== '' && $key{0} == '?' && strpos( $value, '|' ) !== false ) {
+ return true;
+ }
+
+ if ( is_string( $value ) && $value !== '' && $value{0} == '?' && strpos( $value, '|' ) !== false ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private static function hasLink( $value ) {
+ return strpos( $value, '[[' ) !== false && strpos( $value, ']]' ) !== false ;
+ }
+
+ private static function replace( $source, $target, $value ) {
+ return preg_replace_callback(
+ '/\[\[([^\[\]]*)\]\]/xu',
+ function( array $matches ) use ( $source, $target ) {
+ return str_replace( [ $source ], [ $target ], $matches[0] );
+ },
+ $value
+ );
+ }
+
+}