<?php
namespace App\Controller;
use App\Constant\SearchTypeConstant;
use App\Repository\BandRepository;
use App\Repository\FileRepository;
use App\Repository\UserRepository;
use App\Services\SeoManager;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Constant\FileTypeConstant;
use App\Entity\BandMember;
use App\Entity\NewMemberSearch;
use App\Entity\User;
use App\Form\NewBandSearchFiltersType;
use App\Form\SearchFiltersType;
const MUSIC_STYLE = 'musicStyles';
class SearchController extends WhiplayController
{
/**
* Show search page
*
* @param Request $request
* @param SeoManager $seoManager
* @param string $searchContent
* @return Response
*/
public function show(Request $request, SeoManager $seoManager, string $searchContent = ''): Response
{
$seoManager
->setTitleAndDescription('search.show.seo.title', 'search.show.seo.description')
->useLogo();
$filterForm = $this->createForm(SearchFiltersType::class);
$filterForm->handleRequest($request);
$filterFormData = $filterForm->getData();
$selectedMusicStylesIds = [];
if (is_array($filterFormData) && isset($filterFormData[MUSIC_STYLE])) {
foreach ($filterFormData[MUSIC_STYLE] as $musicStyle) {
$selectedMusicStylesIds[] = $musicStyle->getId();
}
}
$data = [];
$searchTerm = htmlspecialchars(trim($searchContent));
foreach(SearchTypeConstant::getValues() as $searchType => $searchTypeInfos){
if ($searchTerm === '' && $searchType === 'user') {
continue;
}
$data[$searchType] = $this->getSearchDataByType($searchType, $selectedMusicStylesIds, 0, $searchTerm);
}
return $this->render('Search/show.html.twig', array(
'searchTypes' => $data,
'selectedMusicStylesIds' => $selectedMusicStylesIds,
'searchTerm' => $searchTerm,
'filterForm' => $filterForm->createView()
));
}
/**
* Show bands offers list page
*
* @param Request $request
* @param SeoManager $seoManager
* @return Response
*/
public function bandsOffers(Request $request, SeoManager $seoManager): Response
{
$seoManager
->setTitleAndDescription('search.bands_offers.seo.title', 'search.bands_offers.seo.description')
->useLogo();
/** @var User $user */
$user = $this->getUser();
/** @var BandMember $bandMember */
$bandMember = $user ? $user->getBands()->get(0) : null;
$defaultBand = $bandMember ? $bandMember->getBand() : null;
$filterForm = $this->createForm(NewBandSearchFiltersType::class);
$filterForm->handleRequest($request);
$filters = $request->request->get('new_band_search_filters');
$instrumentsIds = $filters && isset($filters["instruments"]) ? $filters["instruments"] : [];
$musicStylesIds = $filters && isset($filters[MUSIC_STYLE]) ? $filters[MUSIC_STYLE] : [];
$newMemberSearches = $this->getDoctrine()
->getRepository(NewMemberSearch::class)
->findLastOrdered($instrumentsIds, $musicStylesIds);
return $this->render('Search/bandOffers.html.twig', array(
'newMemberSearches' => $newMemberSearches,
'defaultBand' => $defaultBand,
'filterForm' => $filterForm->createView()
));
}
/**
* Show musicians search page
*
* @param Request $request
* @param SeoManager $seoManager
* @return Response
*/
public function musicians(Request $request, SeoManager $seoManager): Response
{
$seoManager
->setTitleAndDescription('search.musicians.seo.title', 'search.musicians.seo.description')
->useLogo();
$filterForm = $this->createForm(NewBandSearchFiltersType::class);
$filterForm->handleRequest($request);
$filters = $request->request->get('new_band_search_filters');
$instrumentsIds = $filters && isset($filters["instruments"]) ? $filters["instruments"] : [];
$musicStylesIds = $filters && isset($filters[MUSIC_STYLE]) ? $filters[MUSIC_STYLE] : [];
$musicians = $this->getDoctrine()
->getRepository(User::class)
->findAvailableMusicians($instrumentsIds, $musicStylesIds);
if ($this->getUser()) {
$musicians = array_filter($musicians, function($musician) {
return $musician !== $this->getUser();
});
}
return $this->render('Search/musicians.html.twig', array(
'musicians' => $musicians,
'filterForm' => $filterForm->createView()
));
}
/**
* Api method to fetch searched content
* lastId get parameter define from which id actions will be fetched
* searchType get parameter define which type to search
*
* @param Request $request
* @return Response
*/
public function api(Request $request): Response
{
if (!$request->isXmlHttpRequest()) {
return new Response('Forbidden', Response::HTTP_BAD_REQUEST);
}
$selectedMusicStylesIds = [];
if ($request->request->get(MUSIC_STYLE)) {
$selectedMusicStylesIds = json_decode($request->request->get(MUSIC_STYLE));
if (!is_array($selectedMusicStylesIds)) {
$selectedMusicStylesIds = [];
}
}
$lastId = $request->get('lastId') ? $request->get('lastId') : 0;
$searchType = $request->get('searchType') ? $request->get('searchType') : null;
$response = array('message' => 'no valid data');
if (isset(SearchTypeConstant::getValues()[$searchType])) {
$response = [];
$data[$searchType] = $this->getSearchDataByType($searchType, $selectedMusicStylesIds, $lastId);
foreach ($data[$searchType] as $entity) {
$infos = array();
$infos['id'] = $entity->getId();
$infos['view'] = '<div class="content-boxes-container">'.$this->render('Item/' . $searchType . '.html.twig', array(
$searchType => $entity,
))->getContent().'</div>';
$response[$searchType][] = $infos;
}
$response['message'] = 'OK';
if (count($data[$searchType]) < SearchTypeConstant::getValues()[$searchType]['limit']) {
$response['noMore'] = 'true';
}
}
return new JsonResponse($response, Response::HTTP_OK);
}
/**
* Private: Get content from $searchType
*
* @param string $searchType
* @param array $selectedMusicStylesIds
* @param int $lastId
* @param string $searchTerm
* @return array
*/
private function getSearchDataByType(
string $searchType,
array $selectedMusicStylesIds = [],
int $lastId = 0,
string $searchTerm = ''
): array {
$limitNumber = SearchTypeConstant::getValues()[$searchType]['limit'];
$data = [];
if (in_array($searchType, [FileTypeConstant::MUSIC, FileTypeConstant::VIDEO])) {
/** @var FileRepository $repository */
$repository = $this->getDoctrine()->getRepository(SearchTypeConstant::getValues()[$searchType]['class']);
$data = $repository
->findLastPublicFromType($searchType, $limitNumber, $lastId, $selectedMusicStylesIds, $searchTerm);
}
if (in_array($searchType, ['user', 'band'])) {
/** @var BandRepository|UserRepository $repository */
$repository = $this->getDoctrine()->getRepository(SearchTypeConstant::getValues()[$searchType]['class']);
$data = $repository
->findLastCreated($selectedMusicStylesIds, $lastId, $limitNumber, $searchTerm);
}
return $data;
}
}