first commit

This commit is contained in:
Sven Wappler
2021-04-17 00:26:33 +02:00
commit 866c63cc63
813 changed files with 100696 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
<?php
namespace WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\OptionBased\QueryGroup;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\OptionBased\AbstractOptionFacetItem;
/**
* Value object that represent an option of a queryGroup facet.
*
* @author Frans Saris <frans@beech.it>
* @author Timo Hund <timo.hund@dkd.de>
*/
class Option extends AbstractOptionFacetItem
{
/**
* @param QueryGroupFacet $facet
* @param string $label
* @param string $value
* @param int $documentCount
* @param bool $selected
*/
public function __construct(QueryGroupFacet $facet, $label = '', $value = '', $documentCount = 0, $selected = false)
{
parent::__construct($facet, $label, $value, $documentCount, $selected);
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\OptionBased\QueryGroup;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\OptionBased\AbstractOptionsFacet;
use WapplerSystems\Meilisearch\Domain\Search\ResultSet\SearchResultSet;
/**
* Class QueryGroupFacet
*
* @author Frans Saris <frans@beech.it>
* @author Timo Hund <timo.hund@dkd.de>
*/
class QueryGroupFacet extends AbstractOptionsFacet
{
const TYPE_QUERY_GROUP = 'queryGroup';
/**
* String
* @var string
*/
protected static $type = self::TYPE_QUERY_GROUP;
/**
* OptionsFacet constructor
*
* @param SearchResultSet $resultSet
* @param string $name
* @param string $field
* @param string $label
* @param array $configuration Facet configuration passed from typoscript
*/
public function __construct(SearchResultSet $resultSet, $name, $field, $label = '', array $configuration = [])
{
parent::__construct($resultSet, $name, $field, $label, $configuration);
}
}

View File

@@ -0,0 +1,143 @@
<?php
namespace WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\OptionBased\QueryGroup;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\AbstractFacetParser;
use WapplerSystems\Meilisearch\Domain\Search\ResultSet\SearchResultSet;
use WapplerSystems\Meilisearch\System\Solr\ResponseAdapter;
/**
* Class QueryGroupFacetParser
*
* @author Frans Saris <frans@beech.it>
* @author Timo Hund <timo.hund@dkd.de>
*/
class QueryGroupFacetParser extends AbstractFacetParser
{
/**
* @param SearchResultSet $resultSet
* @param string $facetName
* @param array $facetConfiguration
* @return QueryGroupFacet|null
*/
public function parse(SearchResultSet $resultSet, $facetName, array $facetConfiguration)
{
$response = $resultSet->getResponse();
$fieldName = $facetConfiguration['field'];
$label = $this->getPlainLabelOrApplyCObject($facetConfiguration);
$rawOptions = $this->getRawOptions($response, $fieldName);
$noOptionsInResponse = $rawOptions === [];
$hideEmpty = !$resultSet->getUsedSearchRequest()->getContextTypoScriptConfiguration()->getSearchFacetingShowEmptyFacetsByName($facetName);
if ($noOptionsInResponse && $hideEmpty) {
return null;
}
/** @var QueryGroupFacet $facet */
$facet = $this->objectManager->get(
QueryGroupFacet::class,
$resultSet,
$facetName,
$fieldName,
$label,
$facetConfiguration
);
$activeFacets = $resultSet->getUsedSearchRequest()->getActiveFacetNames();
$facet->setIsUsed(in_array($facetName, $activeFacets, true));
if (!$noOptionsInResponse) {
$facet->setIsAvailable(true);
foreach ($rawOptions as $query => $count) {
$value = $this->getValueByQuery($query, $facetConfiguration);
// Skip unknown queries
if ($value === null) {
continue;
}
if ($this->getIsExcludedFacetValue($query, $facetConfiguration)) {
continue;
}
$isOptionsActive = $resultSet->getUsedSearchRequest()->getHasFacetValue($facetName, $value);
$label = $this->getLabelFromRenderingInstructions(
$value,
$count,
$facetName,
$facetConfiguration
);
$facet->addOption($this->objectManager->get(Option::class, $facet, $label, $value, $count, $isOptionsActive));
}
}
// after all options have been created we apply a manualSortOrder if configured
// the sortBy (lex,..) is done by the solr server and triggered by the query, therefore it does not
// need to be handled in the frontend.
$this->applyManualSortOrder($facet, $facetConfiguration);
$this->applyReverseOrder($facet, $facetConfiguration);
return $facet;
}
/**
* Get raw query options
*
* @param ResponseAdapter $response
* @param string $fieldName
* @return array
*/
protected function getRawOptions(ResponseAdapter $response, $fieldName)
{
$options = [];
foreach ($response->facet_counts->facet_queries as $rawValue => $count) {
if ((int)$count === 0) {
continue;
}
// todo: add test cases to check if this is needed https://forge.typo3.org/issues/45440
// remove tags from the facet.query response, for facet.field
// and facet.range Solr does that on its own automatically
$rawValue = preg_replace('/^\{!ex=[^\}]*\}(.*)/', '\\1', $rawValue);
list($field, $query) = explode(':', $rawValue, 2);
if ($field === $fieldName) {
$options[$query] = $count;
}
}
return $options;
}
/**
* @param string $query
* @param array $facetConfiguration
* @return string|null
*/
protected function getValueByQuery($query, array $facetConfiguration)
{
$value = null;
foreach ($facetConfiguration['queryGroup.'] as $valueKey => $config) {
if (isset($config['query']) && $config['query'] === $query) {
$value = rtrim($valueKey, '.');
break;
}
}
return $value;
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\OptionBased\QueryGroup;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\DefaultFacetQueryBuilder;
use WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\FacetQueryBuilderInterface;
use WapplerSystems\Meilisearch\System\Configuration\TypoScriptConfiguration;
class QueryGroupFacetQueryBuilder extends DefaultFacetQueryBuilder implements FacetQueryBuilderInterface {
/**
* @param string $facetName
* @param TypoScriptConfiguration $configuration
* @return array
*/
public function build($facetName, TypoScriptConfiguration $configuration)
{
$facetParameters = [];
$facetConfiguration = $configuration->getSearchFacetingFacetByName($facetName);
foreach ($facetConfiguration['queryGroup.'] as $queryName => $queryConfiguration) {
$tags = $this->buildExcludeTags($facetConfiguration, $configuration);
$facetParameters['facet.query'][] = $tags . $facetConfiguration['field'] . ':' . $queryConfiguration['query'];
}
return $facetParameters;
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\OptionBased\QueryGroup;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\AbstractFacetPackage;
/**
* Class QueryGroupPackage
*/
class QueryGroupPackage extends AbstractFacetPackage {
/**
* @return string
*/
public function getParserClassName() {
return (string)QueryGroupFacetParser::class;
}
/**
* @return string
*/
public function getQueryBuilderClassName()
{
return (string)QueryGroupFacetQueryBuilder::class;
}
/**
* @return string
*/
public function getUrlDecoderClassName()
{
return (string)QueryGroupUrlDecoder::class;
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\OptionBased\QueryGroup;
/***************************************************************
* Copyright notice
*
* (c) 2012-2015 Ingo Renner <ingo@typo3.org>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets\FacetUrlDecoderInterface;
/**
* Filter encoder to build facet query parameters
*
* @author Timo Hund <timo.hund@dkd.de>
* @author Ingo Renner <ingo@typo3.org>
*/
class QueryGroupUrlDecoder implements FacetUrlDecoderInterface
{
/**
* Parses the query filter from GET parameters in the URL and translates it
* to a Lucene filter value.
*
* @param string $filterValue the filter query from plugin
* @param array $configuration options set in a facet's configuration
* @return string Value to be used in a Lucene filter
*/
public function decode($filterValue, array $configuration = [])
{
return $configuration[$filterValue . '.']['query'];
}
}