meilisearch/Classes/Domain/Search/ResultSet/Facets/RequirementsService.php

125 lines
4.1 KiB
PHP
Raw Normal View History

2021-04-17 00:26:33 +02:00
<?php
namespace WapplerSystems\Meilisearch\Domain\Search\ResultSet\Facets;
/*
* 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 TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Service class to check for a facet if allRequirements are met for that facet.
*
* @author Timo Hund <timo.hund@dkd.de>
*/
class RequirementsService
{
/**
* Checks if facet meets all requirements.
*
* Evaluates configuration in "plugin.tx_meilisearch.search.faceting.facets.[facetName].requirements",
*
* @param AbstractFacet $facet
* @return bool true if facet might be rendered
*/
public function getAllRequirementsMet(AbstractFacet $facet)
{
$requirements = $facet->getRequirements();
if (!is_array($requirements) || count($requirements) === 0) {
return true;
}
foreach ($requirements as $requirement) {
$requirementMet = $this->getRequirementMet($facet, $requirement);
$requirementMet = $this->getNegationWhenConfigured($requirementMet, $requirement);
if (!$requirementMet) {
// early return as soon as one requirement is not met
return false;
}
}
return true;
}
/**
* Checks if a single requirement is met.
*
* @param AbstractFacet $facet
* @param array $requirement
* @return bool
*/
protected function getRequirementMet(AbstractFacet $facet, $requirement = []) {
$selectedItemValues = $this->getSelectedItemValues($facet, $requirement['facet']);
$csvActiveFacetItemValues = implode(', ', $selectedItemValues);
$requirementValues = GeneralUtility::trimExplode(',', $requirement['values']);
foreach ($requirementValues as $value) {
$noFacetOptionSelectedRequirementMet = ($value === '__none' && empty($selectedItemValues));
$anyFacetOptionSelectedRequirementMet = ($value === '__any' && !empty($selectedItemValues));
if ($noFacetOptionSelectedRequirementMet || $anyFacetOptionSelectedRequirementMet || in_array($value, $selectedItemValues) || fnmatch($value, $csvActiveFacetItemValues)) {
// when we find a single matching requirement we can exit and return true
return true;
}
}
return false;
}
/**
* Returns the active item values of a facet
*
* @param string $facetNameToCheckRequirementsOn
* @return AbstractFacetItem[]
*/
protected function getSelectedItemValues(AbstractFacet $facet, $facetNameToCheckRequirementsOn)
{
$facetToCheckRequirements = $facet->getResultSet()->getFacets()->getByName($facetNameToCheckRequirementsOn)->getByPosition(0);
if (!$facetToCheckRequirements instanceof AbstractFacet) {
throw new \InvalidArgumentException('Requirement for unexisting facet configured');
}
if (!$facetToCheckRequirements->getIsUsed()) {
// unused facets do not have active values.
return [];
}
$itemValues = [];
$activeFacetItems = $facetToCheckRequirements->getAllFacetItems();
foreach ($activeFacetItems as $item) {
/** @var AbstractFacetItem $item */
if ($item->getSelected()) {
$itemValues[] = $item->getUriValue();
}
}
return $itemValues;
}
/**
* Negates the result when configured.
*
* @param boolean $value
* @param array $configuration
* @return boolean
*/
protected function getNegationWhenConfigured($value, $configuration)
{
if (!is_array($configuration) || empty($configuration['negate']) || (bool)$configuration['negate'] === false) {
return $value;
}
return !((bool)$value);
}
}