Commit fb5ad638 authored by Dainis Abols's avatar Dainis Abols
Browse files

Filter addition with two languages

v1.1.1
parent abcb267a
......@@ -6,6 +6,7 @@ use Lu\LuNames\Domain\Model\Person;
use Lu\LuNames\Domain\Repository\PersonRepository;
use Lu\LuNames\Domain\Repository\SourceRepository;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Resource\FileRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
......@@ -51,6 +52,7 @@ class FrontController extends ActionController
{
$uid = $this->request->getArgument('uid');
$person = $this->personRepository->findByUid($uid);
$pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
$assign = [
'photo' => $this->getPhoto($uid),
......@@ -59,6 +61,8 @@ class FrontController extends ActionController
'person' => $person,
];
$pageRenderer->addCssFile("EXT:lu_names/Resources/Public/Css/names_style.css");
$this->view->assignMultiple($assign);
}
......
......@@ -7,6 +7,7 @@ use Lu\LuApi\Helpers\DataHelper;
use Lu\LuNames\Domain\Model\Person;
use Lu\LuNames\Domain\Repository\PersonRepository;
use Lu\LuNames\Helpers\CacheHelper;
use Lu\LuNas\Filter;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Resource\FileRepository;
......@@ -75,6 +76,26 @@ class SearchController extends ActionController
*/
private $limit = 10;
/**
* Main sort array
*
* @var array
*/
private $sort = [
'default' => [],
'given_name' => [],
'maiden_name' => [],
'family_name' => [],
'mother' => [],
];
/**
* Set default sort
*
* @var string
*/
private $default_sort = 'default';
/**
* Parent IDs
*
......@@ -94,14 +115,13 @@ class SearchController extends ActionController
*/
public function __construct()
{
parent::__construct();
// Set language data
$languageAspect = GeneralUtility::makeInstance(Context::class)->getAspect('language');
$iso = $GLOBALS['TYPO3_REQUEST']->getAttribute('language')->getTwoLetterIsoCode();
$this->language = [
'id' => $languageAspect->getId(),
'iso' => $GLOBALS['TSFE']->sys_language_isocode,
'code' => $GLOBALS['TSFE']->sys_language_isocode == 'lv' ? 'lat' : 'eng',
'iso' => $iso,
'code' => $iso == 'lv' ? 'lat' : 'eng',
];
// Set uri builder
......@@ -134,7 +154,7 @@ class SearchController extends ActionController
// Generate letter list
$letters = $cacheHelper->get('letters');
if(!$letters) {
if (!$letters) {
$letters = $this->personRepository->getAllALetters();
$cacheHelper->set('letters', $letters);
}
......@@ -142,17 +162,23 @@ class SearchController extends ActionController
$this->addLetterLinks($letters);
// Get current page @FIXME There has to be a better way!
$this->currentPage = !empty($request['@widget_0']['currentPage']) ? (int)$request['@widget_0']['currentPage'] : 1;
$currentPage = $this->request->getArguments()['@widget_0']['currentPage'];
$this->currentPage = !empty($currentPage) ? (int)$currentPage : 1;
$cleanQuery = strip_tags($request['query'] ?? ($_REQUEST['tx_lusearch_pi1']['query'] ?? ''));
// Create sort
$this->createSortItem();
// Fetch data from SOLR
if (!empty($cleanQuery)) {
$data = $this->searchGeneral($cleanQuery);
[$data, $facets] = $this->searchGeneral($cleanQuery, $request);
}
// Check if letter search
if (!empty($request['letter'])) {
$data = $this->searchLetter($request['letter']);
[$data, $facets] = $this->searchLetter($request['letter'], $request);
$letters[strtolower($request['letter'])]['selected'] = true;
}
......@@ -189,7 +215,12 @@ class SearchController extends ActionController
// Assign final data element to view
$this->view->assign('data', $data);
$request = $this->getUrlRequest();
$this->view->assign('visual', $this->getVisualsFilter($request['filter']));
$this->view->assign('filters', $request['filter']);
$this->view->assign('facets', $facets);
$this->view->assign('letters', $letters);
$this->view->assign('sort', $this->sort);
}
/**
......@@ -199,16 +230,32 @@ class SearchController extends ActionController
*
* @return string
*/
private function searchGeneral($query)
private function searchGeneral($query, $request)
{
// Pre-set models and values
$dataHelper = new DataHelper();
// Search in SOLR
$solr = new SolrNames();
$person = new Person();
$filterModel = new Filter($request, $this->frontendSession);
$facets = [];
// Get current page
$currentPage = !empty($request['@widget_0']['currentPage']) ? (int)$request['@widget_0']['currentPage'] : 1;
// Set Limit
$solr->setLimit($this->limit);
// Get filters
$facet_filters = $filters = $filterModel->getFilters($request);
$solr->setOffset(($this->currentPage - 1) * $this->limit);
// Check facet call
if (!empty($request['filter'])) {
foreach($request['filter'] as $name=>$value)
$solr->setFacetFilter($name, $value);
}
// Set filters
$filters = [
'fate:'.$query,
......@@ -229,11 +276,44 @@ class SearchController extends ActionController
];
$solr->setFilters($filters);
// Set sort
foreach($this->sort as $sort=>$options) {
if ($options['selected'] == 1) {
switch ($sort) {
case 'default':
$solr->sort('', '');
break;
case 'given_name':
$solr->sort('given_name', 'asc');
$solr->sort('family_name', 'asc');
break;
case 'maiden_name':
$solr->sort('maiden_name', 'asc');
$solr->sort('family_name', 'asc');
$solr->sort('given_name', 'asc');
break;
case 'family_name':
$solr->sort('family_name', 'asc');
$solr->sort('given_name', 'asc');
break;
case 'mother':
$solr->sort('mother', 'asc');
$solr->sort('family_name', 'asc');
$solr->sort('given_name', 'asc');
break;
}
}
}
// Fetch data
$jsonData = $solr->fetch(true);
$result = $dataHelper->APIDecode($jsonData);
if (!empty($result)) {
$facets = $person->getFacets($result, $solr);
}
return $result;
// Return
return [$result, $facets];
}
/**
......@@ -243,30 +323,67 @@ class SearchController extends ActionController
*
* @return string
*/
private function searchLetter($query)
private function searchLetter($query, $request)
{
// Pre-set models and values
$dataHelper = new DataHelper();
$person = new Person();
// Search in SOLR
$solr = new SolrNames();
$solr->setLimit($this->limit);
$solr->setOffset(($this->currentPage - 1) * $this->limit);
$request = $this->getUrlRequest();
if (!empty($request['filter'])) {
foreach($request['filter'] as $name=>$value)
$solr->setFacetFilter($name, $value);
}
// Set filters
$filters = [
// 'maiden_name:'.$query.'*',
// 'given_name:'.$query.'*',
// 'other_name:'.$query.'*',
'family_name:'.$query.'*',
];
$solr->setFilters($filters);
// Set sort
foreach($this->sort as $sort=>$options) {
if ($options['selected'] == 1) {
switch ($sort) {
case 'default':
$solr->sort('', '');
break;
case 'given_name':
$solr->sort('given_name', 'asc');
$solr->sort('family_name', 'asc');
break;
case 'maiden_name':
$solr->sort('maiden_name', 'asc');
$solr->sort('family_name', 'asc');
$solr->sort('given_name', 'asc');
break;
case 'family_name':
$solr->sort('family_name', 'asc');
$solr->sort('given_name', 'asc');
break;
case 'mother':
$solr->sort('mother', 'asc');
$solr->sort('family_name', 'asc');
$solr->sort('given_name', 'asc');
break;
}
}
}
// Fetch data
$jsonData = $solr->fetch(true);
$result = $dataHelper->APIDecode($jsonData);
if (!empty($result)) {
$facets = $person->getFacets($result, $solr);
}
return $result;
// Return
return [$result, $facets];
}
/**
......@@ -282,7 +399,7 @@ class SearchController extends ActionController
$pageRenderer->addJsFooterFile("//code.jquery.com/ui/1.12.1/jquery-ui.js");
// Add own JS
// $pageRenderer->addJsFooterFile("/typo3conf/ext/lu_names/Resources/Public/JavaScript/scripts.js");
$pageRenderer->addJsFooterFile("/typo3conf/ext/lu_names/Resources/Public/JavaScript/scripts.js");
}
/**
......@@ -392,4 +509,89 @@ class SearchController extends ActionController
$letters[$key]['url'] = $this->uri_builder->reset()->uriFor('list', ['letter' => $key]);
}
}
/**
* Fetch additional request params for clean filters
*
* @param false $path
*
* @return array
*/
private function getUrlRequest($path = false)
{
$uri = parse_url($_SERVER['REQUEST_URI']);
parse_str($uri['query'], $request);
if (!$path) {
parse_str($uri['query'], $request);
} else {
$request = explode('&', $uri['query']);
$newRequest = [];
foreach($request as $key=> $req) {
$req = explode('=', $req);
$newRequest[$req[0]] = $req[1];
}
$request = $newRequest;
}
// Check if path requested
if ($path) {
$request = [
'path' => $uri['path'],
'request' => $request,
];
}
return $request;
}
/**
* Create sort items with links
*/
private function createSortItem()
{
$request = $this->getUrlRequest(true);
$thisSort = !empty($request['request']['sort']) ? $request['request']['sort'] : $this->default_sort;
foreach($this->sort as $sortKey => &$sortItem) {
$request['request']['sort'] = $sortKey;
// Rebuild sort
$url = [];
foreach($request['request'] as $key=>$value) {
if (!(strpos($key, 'currentPage') > 0 || strpos($key, 'cHash') === 0)) {
$url[] = $key.'='.$value;
}
}
$sortItem = [
'url' => $request['path'].'?'.implode('&', $url),
];
if ($thisSort == $sortKey) {
$sortItem['selected'] = 1;
}
}
}
/**
* Build visual filter display
*
* @param $filters
*
* @return array
*/
private function getVisualsFilter($filters)
{
// Preset
$visual = [];
$myPerson = new Person();
// Fetch title and move value to key
foreach($filters as $field => $items){
foreach($items as $item) {
$visual[$field][$item] = $myPerson->getTitleByFacet($field, $item);
}
}
return $visual;
}
}
<?php
namespace Lu\LuNames\Domain\Model;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
/**
* Class FamilyStatus
*
* @package Lu\LuNames\Domain\Model
*/
class FamilyStatus extends AbstractEntity
{
/**
* The name of the person
*
* @var string
**/
protected string $title = '';
/**
* @return string
*/
public function getTitle(): string
{
return $this->title;
}
/**
* Fetch title by id
*
* @param $uid
*
* @return mixed|string
*/
public function getTitleById($uid)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_lunames_domain_model_familystatus');
$queryBuilder->getRestrictions()->removeAll();
$queryBuilder->select('title')
->from('tx_lunames_domain_model_familystatus')
->where('uid = '.$uid);
// Read and load data
$result = $queryBuilder->execute()->fetch();
return $result['title'] ?? '';
}
}
......@@ -2,6 +2,8 @@
namespace Lu\LuNames\Domain\Model;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
/**
......@@ -32,5 +34,23 @@ class Location extends AbstractEntity
$this->title = $title;
}
/**
* Fetch title by id
*
* @param $uid
*
* @return mixed|string
*/
public function getTitleById($uid)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_lunames_domain_model_location');
$queryBuilder->getRestrictions()->removeAll();
$queryBuilder->select('title')
->from('tx_lunames_domain_model_location')
->where('uid = '.$uid);
// Read and load data
$result = $queryBuilder->execute()->fetch();
return $result['title'] ?? '';
}
}
......@@ -2,6 +2,8 @@
namespace Lu\LuNames\Domain\Model;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
/**
......@@ -25,4 +27,24 @@ class Occupation extends AbstractEntity
{
return $this->title;
}
/**
* Fetch title by id
*
* @param $uid
*
* @return mixed|string
*/
public function getTitleById($uid)
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_lunames_domain_model_occupation');
$queryBuilder->getRestrictions()->removeAll();
$queryBuilder->select('title')
->from('tx_lunames_domain_model_location')
->where('uid = '.$uid);
// Read and load data
$result = $queryBuilder->execute()->fetch();
return $result['title'] ?? '';
}
}
......@@ -2,6 +2,8 @@
namespace Lu\LuNames\Domain\Model;
use Lu\LuApi\DataSources\SolrNames;
use Lu\LuNames\Helpers\DataHelper;
use TYPO3\CMS\Core\DataHandling\SlugHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
......@@ -123,9 +125,9 @@ class Person extends AbstractEntity
protected string $gender = '';
/**
* @var string
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Lu\LuNames\Domain\Model\FamilyStatus>
*/
protected string $familyStatus = '';
protected ?ObjectStorage $familyStatus = null;
/**
* @var string
......@@ -155,6 +157,7 @@ class Person extends AbstractEntity
$this->warResidence = new ObjectStorage();
$this->prewarResidence = new ObjectStorage();
$this->occupation = new ObjectStorage();
$this->familyStatus = new ObjectStorage();
$this->sourceCodes = new ObjectStorage();
}
......@@ -329,9 +332,9 @@ class Person extends AbstractEntity
}
/**
* @return string
* @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage
*/
public function getFamilyStatus(): string
public function getFamilyStatus(): ObjectStorage
{
return $this->familyStatus;
}
......@@ -393,4 +396,157 @@ class Person extends AbstractEntity
return $slugHelper->generate($data, $uid);
}
/**
* Fetch facets
*
* @param $data
* @param $filters
*
* @return array
*/
public function getFacets($data, $solr)
{
// Pre-set used variables and models
$dataHelper = new DataHelper();
// Fetch data
$solr->useFacets(true);
$jsonData = $solr->fetch(true);
$response = $dataHelper->APIDecode($jsonData);
// Return facets
return !empty($response['facet_fields']) ? $this->convertFacets($response['facet_fields']) : ['error' => $response];
}
/**
* Convert facets to readable array
*
* @param $facets
*
* @return array
*/
private function convertFacets(array $facets): array
{
$result = [];
if (!empty($facets)) {
foreach ($facets as $field => $items) {
// Reformat items
$item = [];
for ($k = 0; $k < count($items); $k = $k + 2) {
if ($items[$k + 1] > 0) {
// Check if ID set
$name = $items[$k];
if (is_numeric($name)) {
$name = $this->getTitleByFacet($field, $name);
}
$item[] = [
'uid' => $items[$k],
'name' => $name,
'count' => $items[$k + 1],
'url' => $this->generateUrl($field, $items[$k]),
];
}
}
if (!empty($item)) {
$result[] = [
'name' => $field,
'items' => $item,
];
}
}
}
// Return result
return $result;
}
static public function as()
{
}
/**