wikimedia/mediawiki-extensions-CirrusSearch

View on GitHub
includes/Query/PageIdFeature.php

Summary

Maintainability
A
1 hr
Test Coverage
<?php

namespace CirrusSearch\Query;

use CirrusSearch\Parser\AST\KeywordFeatureNode;
use CirrusSearch\Query\Builder\QueryBuildingContext;
use CirrusSearch\Search\SearchContext;
use CirrusSearch\SearchConfig;
use CirrusSearch\WarningCollector;
use Elastica\Query\AbstractQuery;
use Elastica\Query\Ids;
use MediaWiki\Message\Message;

/**
 * Filter by a set of page IDs. This is useful for re-validating cached query results.
 * Format: pageid:1|2|3
 */
class PageIdFeature extends SimpleKeywordFeature implements FilterQueryFeature {

    /** Maximum number of IDs allowed. */
    public const MAX_VALUES = 1000;

    /** @inheritDoc */
    public function getFilterQuery( KeywordFeatureNode $node, QueryBuildingContext $context ) {
        return $this->doGetFilterQuery( $node->getParsedValue(), $context->getSearchConfig() );
    }

    /** @inheritDoc */
    public function parseValue(
        $key, $value, $quotedValue, $valueDelimiter, $suffix, WarningCollector $warningCollector
    ) {
        $values = explode( '|', $value );
        $validValues = array_map( 'intval', array_values( array_filter( $values, 'ctype_digit' ) ) );
        if ( count( $validValues ) < count( $values ) ) {
            $invalidValues = array_values( array_diff( $values, $validValues ) );
            $warningCollector->addWarning( 'cirrussearch-feature-pageid-invalid-id',
                Message::listParam( $invalidValues, 'comma' ), count( $invalidValues ) );
        }

        if ( count( $validValues ) > self::MAX_VALUES ) {
            $warningCollector->addWarning(
                'cirrussearch-feature-too-many-conditions',
                $key,
                self::MAX_VALUES
            );
            $validValues = array_slice( $validValues, 0, self::MAX_VALUES );
        }

        return [ 'pageids' => $validValues ];
    }

    /**
     * @param array $parsedValue
     * @param SearchConfig $searchConfig
     * @return AbstractQuery|null
     */
    protected function doGetFilterQuery( array $parsedValue, SearchConfig $searchConfig ) {
        if ( !$parsedValue['pageids'] ) {
            return null;
        }
        $documentIds = array_map( [ $searchConfig, 'makeId' ], $parsedValue['pageids'] );
        return new Ids( $documentIds );
    }

    /** @inheritDoc */
    protected function getKeywords() {
        return [ 'pageid' ];
    }

    /** @inheritDoc */
    protected function doApply( SearchContext $context, $key, $value, $quotedValue, $negated ) {
        $filter = $this->doGetFilterQuery(
            $this->parseValue( $key, $value, $quotedValue, '', '', $context ),
            $context->getConfig()
        );
        if ( !$filter ) {
            $context->setResultsPossible( false );
        }
        return [ $filter, false ];
    }

}