2021-04-17 00:26:33 +02:00
< ? php
namespace WapplerSystems\Meilisearch\ViewHelpers ;
/*
* 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\System\Url\UrlHelper ;
use WapplerSystems\Meilisearch\System\Util\SiteUtility ;
use WapplerSystems\Meilisearch\Util ;
use TYPO3\CMS\Core\Utility\GeneralUtility ;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController ;
/**
* Class SearchFormViewHelper
*
* @ author Frans Saris < frans @ beech . it >
* @ author Timo Hund < timo . hund @ dkd . de >
*/
2021-04-17 21:20:54 +02:00
class SearchFormViewHelper extends AbstractMeilisearchFrontendTagBasedViewHelper
2021-04-17 00:26:33 +02:00
{
/**
* @ var string
*/
protected $tagName = 'form' ;
/**
* @ var TypoScriptFrontendController
*/
protected $frontendController ;
/**
* @ var bool
*/
protected $escapeChildren = true ;
/**
* @ var bool
*/
protected $escapeOutput = false ;
/**
* Constructor
*/
public function __construct ()
{
parent :: __construct ();
$this -> frontendController = $GLOBALS [ 'TSFE' ];
}
/**
* Initialize arguments .
*
* @ return void
*/
public function initializeArguments ()
{
parent :: initializeArguments ();
$this -> registerTagAttribute ( 'enctype' , 'string' , 'MIME type with which the form is submitted' );
$this -> registerTagAttribute ( 'method' , 'string' , 'Transfer type (GET or POST)' , false , 'get' );
$this -> registerTagAttribute ( 'name' , 'string' , 'Name of form' );
$this -> registerTagAttribute ( 'onreset' , 'string' , 'JavaScript: On reset of the form' );
$this -> registerTagAttribute ( 'onsubmit' , 'string' , 'JavaScript: On submit of the form' );
$this -> registerUniversalTagAttributes ();
$this -> registerArgument ( 'pageUid' , 'integer' , 'When not set current page is used' , false );
$this -> registerArgument ( 'additionalFilters' , 'array' , 'Additional filters' , false );
$this -> registerArgument ( 'additionalParams' , 'array' , 'Query parameters to be attached to the resulting URI' , false , []);
$this -> registerArgument ( 'pageType' , 'integer' , 'Type of the target page. See typolink.parameter' , false , 0 );
$this -> registerArgument ( 'noCache' , 'boolean' , 'Set this to disable caching for the target page. You should not need this.' , false , false );
$this -> registerArgument ( 'noCacheHash' , 'boolean' , 'Set this to supress the cHash query parameter created by TypoLink. You should not need this.' , false , false );
$this -> registerArgument ( 'section' , 'string' , 'The anchor to be added to the action URI (only active if $actionUri is not set)' , false , '' );
$this -> registerArgument ( 'absolute' , 'boolean' , 'If set, the URI of the rendered link is absolute' , false , false );
$this -> registerArgument ( 'addQueryString' , 'boolean' , 'If set, the current query parameters will be kept in the URI' , false , false );
$this -> registerArgument ( 'argumentsToBeExcludedFromQueryString' , 'array' , 'arguments to be removed from the URI. Only active if $addQueryString = TRUE' , false , []);
$this -> registerArgument ( 'addQueryStringMethod' , 'string' , 'Set which parameters will be kept. Only active if $addQueryString = TRUE' , false );
$this -> registerArgument ( 'addSuggestUrl' , 'boolean' , 'Indicates if suggestUrl should be rendered or not' , false , true );
$this -> registerArgument ( 'suggestHeader' , 'string' , 'The header for the top results' , false , 'Top Results' );
$this -> registerArgument ( 'suggestPageType' , 'integer' , 'The page type that should be used for the suggest' , false , 7384 );
}
/**
* Render search form tag
*
* @ return string
*/
public function render ()
{
$pageUid = $this -> arguments [ 'pageUid' ];
if ( $pageUid === null && ! empty ( $this -> getTypoScriptConfiguration () -> getSearchTargetPage ())) {
$pageUid = $this -> getTypoScriptConfiguration () -> getSearchTargetPage ();
}
$uri = $this -> buildUriFromPageUidAndArguments ( $pageUid );
$this -> tag -> addAttribute ( 'action' , trim ( $uri ));
if ( $this -> arguments [ 'addSuggestUrl' ]) {
$this -> tag -> addAttribute ( 'data-suggest' , $this -> getSuggestUrl ( $this -> arguments [ 'additionalFilters' ], $pageUid ));
}
$this -> tag -> addAttribute ( 'data-suggest-header' , htmlspecialchars ( $this -> arguments [ 'suggestHeader' ]));
$this -> tag -> addAttribute ( 'accept-charset' , $this -> frontendController -> metaCharset );
// Get search term
// @extensionScannerIgnoreLine
$this -> getTemplateVariableContainer () -> add ( 'q' , $this -> getQueryString ());
// @extensionScannerIgnoreLine
$this -> getTemplateVariableContainer () -> add ( 'pageUid' , $pageUid );
// @extensionScannerIgnoreLine
$this -> getTemplateVariableContainer () -> add ( 'languageUid' , Util :: getLanguageUid ());
// @extensionScannerIgnoreLine
$this -> getTemplateVariableContainer () -> add ( 'existingParameters' , $this -> getExistingSearchParameters ());
// @extensionScannerIgnoreLine
$this -> getTemplateVariableContainer () -> add ( 'addPageAndLanguageId' , ! $this -> getIsSiteManagedSite ( $pageUid ));
$formContent = $this -> renderChildren ();
// @extensionScannerIgnoreLine
$this -> getTemplateVariableContainer () -> remove ( 'addPageAndLanguageId' );
// @extensionScannerIgnoreLine
$this -> getTemplateVariableContainer () -> remove ( 'q' );
// @extensionScannerIgnoreLine
$this -> getTemplateVariableContainer () -> remove ( 'pageUid' );
// @extensionScannerIgnoreLine
$this -> getTemplateVariableContainer () -> remove ( 'languageUid' );
// @extensionScannerIgnoreLine
$this -> getTemplateVariableContainer () -> remove ( 'existingParameters' );
$this -> tag -> setContent ( $formContent );
return $this -> tag -> render ();
}
/**
* Get the existing search parameters in an array
* Returns an empty array if search . keepExistingParametersForNewSearches is not set
*
* @ return array
*/
protected function getExistingSearchParameters ()
{
$searchParameters = [];
if ( $this -> getTypoScriptConfiguration () -> getSearchKeepExistingParametersForNewSearches ()) {
$arguments = GeneralUtility :: _GPmerged ( $this -> getTypoScriptConfiguration () -> getSearchPluginNamespace ());
unset ( $arguments [ 'q' ], $arguments [ 'id' ], $arguments [ 'L' ]);
$searchParameters = $this -> translateSearchParametersToInputTagAttributes ( $arguments );
}
return $searchParameters ;
}
/**
* Translate the multi - dimensional array of existing arguments into a flat array of name - value pairs for the input tags
*
* @ param $arguments
* @ param string $nameAttributePrefix
* @ return array
*/
protected function translateSearchParametersToInputTagAttributes ( $arguments , $nameAttributePrefix = '' )
{
$attributes = [];
foreach ( $arguments as $key => $value ) {
$name = $nameAttributePrefix . '[' . $key . ']' ;
if ( is_array ( $value )) {
$attributes = array_merge (
$attributes ,
$this -> translateSearchParametersToInputTagAttributes ( $value , $name )
);
} else {
$attributes [ $name ] = $value ;
}
}
return $attributes ;
}
/**
* When a site is managed with site management the language and the id are encoded in the path segment of the url .
* When no speaking urls are active ( e . g . with TYPO3 8 and no realurl ) this information is passed as query parameter
* and would get lost when it is only part of the query arguments in the action parameter of the form .
*
* @ return boolean
*/
protected function getIsSiteManagedSite ( $pageId )
{
return SiteUtility :: getIsSiteManagedSite ( $pageId );
}
/**
* @ return \TYPO3Fluid\Fluid\Core\Variables\VariableProviderInterface
*/
protected function getTemplateVariableContainer ()
{
return $this -> templateVariableContainer ;
}
/**
* @ return string
*/
protected function getQueryString ()
{
$resultSet = $this -> getSearchResultSet ();
if ( $resultSet === null ) {
return '' ;
}
return trim ( $this -> getSearchResultSet () -> getUsedSearchRequest () -> getRawUserQuery ());
}
/**
* @ param NULL | array $additionalFilters
* @ param int $pageUid
* @ return string
*/
protected function getSuggestUrl ( $additionalFilters , $pageUid )
{
$uriBuilder = $this -> getControllerContext () -> getUriBuilder ();
$pluginNamespace = $this -> getTypoScriptConfiguration () -> getSearchPluginNamespace ();
$suggestUrl = $uriBuilder -> reset () -> setTargetPageUid ( $pageUid ) -> setTargetPageType ( $this -> arguments [ 'suggestPageType' ]) -> setUseCacheHash ( false ) -> setArguments ([ $pluginNamespace => [ 'additionalFilters' => $additionalFilters ]]) -> build ();
/* @var UrlHelper $urlService */
$urlService = GeneralUtility :: makeInstance ( UrlHelper :: class , $suggestUrl );
$suggestUrl = $urlService -> removeQueryParameter ( 'cHash' ) -> getUrl ();
return $suggestUrl ;
}
/**
* @ param int | null $pageUid
* @ return string
*/
protected function buildUriFromPageUidAndArguments ( $pageUid ) : string
{
$uriBuilder = $this -> getControllerContext () -> getUriBuilder ();
$uri = $uriBuilder
-> reset ()
-> setTargetPageUid ( $pageUid )
-> setTargetPageType ( $this -> arguments [ 'pageType' ] ? ? 0 )
-> setNoCache ( $this -> arguments [ 'noCache' ] ? ? false )
-> setUseCacheHash ( ! $this -> arguments [ 'noCacheHash' ])
-> setArguments ( $this -> arguments [ 'additionalParams' ] ? ? [])
-> setCreateAbsoluteUri ( $this -> arguments [ 'absolute' ] ? ? false )
-> setAddQueryString ( $this -> arguments [ 'addQueryString' ] ? ? false )
-> setArgumentsToBeExcludedFromQueryString ( $this -> arguments [ 'argumentsToBeExcludedFromQueryString' ] ? ? [])
-> setAddQueryStringMethod ( $this -> arguments [ 'addQueryStringMethod' ] ? ? '' )
-> setSection ( $this -> arguments [ 'section' ] ? ? '' )
-> build ();
return $uri ;
}
}