By Sebastiaan de Jonge, published on Friday, March 29, 2013 at 08:00

By default, the Solr documentation says you are not able to use both. In some cases though, it would be useful if this was possible. Achieving the actual result isn't even that hard. This example shows you how to still make these two options work together in a facet.

Default behaviour

By default, the one will override the other. To be more precise, singleOptionMode overrule selectingSelectedFacetOptionRemovesFilter. And it's easy to see why if we look more closely at Solr's source.

if ($this->facetConfiguration['selectingSelectedFacetOptionRemovesFilter']
	&& $optionSelected
) {
	$optionLink    = $facetLinkBuilder->getRemoveFacetOptionLink($optionText);
	$optionLinkUrl = $facetLinkBuilder->getRemoveFacetOptionUrl();
}
if ($this->facetConfiguration['singleOptionMode']) {
	$optionLink    = $facetLinkBuilder->getReplaceFacetOptionLink($optionText);
	$optionLinkUrl = $facetLinkBuilder->getReplaceFacetOptionUrl();
}

The option singleOptionMode literally overwrites selectingSelectedFacetOptionRemovesFilter.

Making things work

In order to use both options at the same time on a facet, we will need to XCLASS Solr's link builder class. I've come up with the following.

/**
 * Solr facet link builder XCLASS
 *
 * @author Sebastiaan de Jonge <office@sebastiaandejonge.com>
 */
class ux_tx_solr_facet_LinkBuilder extends tx_solr_facet_LinkBuilder {
	/**
	 * Creates a replacement link for the current selected option for the current facet. If the option matches the
	 * current selected option it will be replaced with a removal link instead.
	 *
	 * @return string URL to replace a facet's active option with this option
	 */
	public function getReplaceFacetOptionUrl() {
		if ($this->removeInsteadOfReplace()) {
			return parent::getRemoveFacetOptionUrl();
		} else {
			return parent::getReplaceFacetOptionUrl();
		}
	}
	/**
	 * Creates a replacement link for the current selected option for the current facet. If the option matches the
	 * current selected option it will be replaced with a removal link instead.
	 *
	 * @param string $linkText link text
	 * @return string Html tag with link to replace a facet's active option with this option
	 */
	public function getReplaceFacetOptionLink($linkText) {
		if ($this->removeInsteadOfReplace()) {
			return parent::getRemoveFacetOptionLink($linkText);
		} else {
			return parent::getReplaceFacetOptionLink($linkText);
		}
	}
	/**
	 * Checks if the current replacement links needs to be replaced with a removal link instead.
	 *
	 * @return bool
	 */
	public function removeInsteadOfReplace() {
		if (!$this->facetConfiguration['selectingSelectedFacetOptionRemovesFilter']) return FALSE;
		// Get the filter parameters
		$filterParameters = $this->replaceFacetAndEncodeFilterParameters();
		// Get the current parameters
		$currentParameters = t3lib_div::_GPmerged('tx_solr');
		$currentParameters = $currentParameters['filter'];
		sort($currentParameters);
		sort($filterParameters);
		return $currentParameters == $filterParameters;
	}
}

How it works

The first two functions are basically extended versions of the original ones found in Solr's link builder class. Adding of course the check for the selectingSelectedFacetOptionRemovesFilter option.

The final function is where all the magic happens. The process is actually quite simple. First we check to see if the removal option is actually required. If so, we will continue and see if the current option is active. We do so by comparing Solr's filter parameters with those that the link builder would generate. If they match, we have a winner!

Comments