Skip to content

Global Search #2360

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions app/Enums/GlobalSearchFiltersEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?php

namespace App\Enums;

use App\Event;
use App\StaticPage;
use App\Podcast;

enum GlobalSearchFiltersEnum: string
{
case ALL = 'All';
case PODCASTS = 'Podcasts';
case HACKATHONS = 'Hackathons';
case ONLINE_COURSES = 'Online Courses';
case TRAINING = 'Training';
case CHALLENGES = 'Challenges';
case LEARN = 'Learn';
case TEACH = 'Teach';
case PRESENTATIONS_AND_TOOLKITS = 'Presentations and Toolkits';
case ACTIVITIES = 'Activities';
case BLOGS = 'Blogs';
case OTHERS = 'Others';

/**
* Get additional information for each filter.
*/
public function meta(): array
{
return match ($this) {
self::ALL => [
'type_search' => 'all',
'model' => null,
'search_fields' => [],
],
self::PODCASTS => [
'type_search' => 'model',
'model' => Podcast::class,
'search_fields' => ['title'],
'map_fields' => [
'name' => '{title}',
'category' => 'Podcast',
'description' => '{description}',
'thumbnail' => '{image}',
'path' => '{url}',
'link_type' => 'internal',
'language' => 'en',
]
],
self::HACKATHONS,
self::ONLINE_COURSES,
self::TRAINING,
self::CHALLENGES,
self::PRESENTATIONS_AND_TOOLKITS,
self::OTHERS => [
'type_search' => 'model',
'model' => StaticPage::class,
'search_fields' => [
'description',
'keywords'
],
'map_fields' => [
'name' => '{name}',
'category' => '{category}',
'description' => '{description}',
'thumbnail' => '{thumbnail}',
'path' => '{path}',
'link_type' => '{link_type}',
'language' => '{language}',
]
],
self::LEARN => [
'type_search' => 'function',
'function' => 'searchResources',
'params' => ['section' => 'learn'],
'map_fields' => [
'name' => '{name}',
'category' => 'Learn',
'description' => '',
'thumbnail' => '/img/event_default_picture.png',
'path' => '#',
'link_type' => 'internal',
'language' => 'en',
]
],
self::TEACH => [
'type_search' => 'function',
'function' => 'searchResources',
'params' => ['section' => 'teach'],
'map_fields' => [
'name' => '{name}',
'category' => 'Teach',
'description' => '',
'thumbnail' => '/img/event_default_picture.png',
'path' => '#',
'link_type' => 'internal',
'language' => 'en',
]
],
self::BLOGS => [
'type_search' => 'blog'
],
self::ACTIVITIES => [
'type_search' => 'model',
'model' => Event::class,
'search_fields' => ['title'],
'map_fields' => [
'name' => '{title}',
'category' => 'Activities',
'description' => '{description}',
'thumbnail' => '{picture}',
'path' => '{url}',
'link_type' => 'internal',
'language' => 'en',
]
],
};
}

/**
* Get a list of all enum values.
*/
public static function values(): array
{
return array_column(self::cases(), 'value');
}

/**
* Get a list of all filter keys.
*/
public static function keys(): array
{
return array_map(fn ($case) => $case->name, self::cases());
}
}
7 changes: 7 additions & 0 deletions app/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ class Event extends Model

//protected $appends = ['LatestModeration'];

public function getUrlAttribute() {
return route('view_event', [
'event' => $this->id,
'slug' => $this->slug
]);
}

public function getJavascriptData()
{
return $this->only(['geoposition', 'title', 'description']);
Expand Down
1 change: 0 additions & 1 deletion app/Http/Controllers/PodcastsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public function index(Request $request): View

public function show(Podcast $podcast): View
{

return view('podcast', compact('podcast'));
}

Expand Down
122 changes: 4 additions & 118 deletions app/Http/Controllers/SearchController.php
Original file line number Diff line number Diff line change
@@ -1,127 +1,13 @@
<?php
<?php

namespace App\Http\Controllers;

use App\Country;
use App\Event;
use App\Filters\EventFilters;
use App\Http\Transformers\EventTransformer;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;

class SearchController extends Controller
{
protected $eventTransformer;

/**
* EventController constructor.
*/
public function __construct(EventTransformer $eventTransformer)
{
$this->eventTransformer = $eventTransformer;
}

public function search(Request $request): View
{

$query = $request->input('q', '');
$selected_year = $request->input('year', Carbon::now()->year);

$country_iso = $request->input('country_iso', null);
$tag = $request->input('tag', '');

$selected_country = [];

if (! is_null($country_iso)) {
$country = Country::where('iso', $country_iso)->first();
if ($country) {
$country->translation = __('countries.'.$country->name);
$selected_country[] = $country;
}

}

$current_year = Carbon::now()->year;
$years = [];
for ($year = $current_year; $year >= 2014; $year--) {
$years[] = $year;
}

return view('event.search', compact(['query', 'years', 'selected_country', 'selected_year', 'tag']));
}

public function searchPOST(EventFilters $filters, Request $request)
{
$events = $this->getEvents($filters);

//Log::info($request->input('page'));
if ($request->input('page')) {
$result = [$events];
} else {
Log::info('no page');
$eventsMap = $this->getAllEventsToMap($filters);
$result = [$events, $eventsMap];
}

return $result;
}

protected function getEvents(EventFilters $filters)
public function index()
{

$events = Event::where('status', 'like', 'APPROVED')
->filter($filters)
->orderBy('start_date')
->get()
->groupBy(function ($event) {
if ($event->start_date <= Carbon::today()) {
return 'past';
}

return 'future';
});

if (is_null($events->get('future')) || is_null($events->get('past'))) {
return $events->flatten()->paginate(12);
}

return $events->get('future')->merge($events->get('past'))->paginate(12);

}

protected function getAllEventsToMap(EventFilters $filters)
{

$flattened = Arr::flatten($filters->getFilters());

$composed_key = '';

foreach ($flattened as $value) {
$composed_key .= $value.',';
}

$value = Cache::get($composed_key, function () use ($composed_key, $filters) {
Log::info("Building cache [{$composed_key}]");
$events = Event::where('status', 'like', 'APPROVED')
->filter($filters)
->get();

$events = $this->eventTransformer->transformCollection($events);

$events = $events->groupBy('country');

Cache::put($composed_key, $events, 5 * 60);

return $events;
});

Log::info("Serving from cache [{$composed_key}]");

return $value;

return view('static.search');
}
}
}
40 changes: 40 additions & 0 deletions app/Livewire/GlobalSearchFilterComponent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace App\Livewire;

use Livewire\Component;
use App\Enums\GlobalSearchFiltersEnum;
use App\Services\GlobalSearchService;

class GlobalSearchFilterComponent extends Component
{
public $selectedFilter = GlobalSearchFiltersEnum::ALL->value;

protected $globalSearchService;

protected $queryString = [
'selectedFilter' => ['except' => GlobalSearchFiltersEnum::ALL->value],
];

public function __construct()
{
$this->globalSearchService = new GlobalSearchService();
}

public function selectFilter($filter)
{
if (!GlobalSearchFiltersEnum::tryFrom($filter)) {
return;
}

$this->selectedFilter = $filter;
$this->dispatch('filterChanged', filter: $filter);
}

public function render()
{
return view('livewire.filter-component', [
'filters' => GlobalSearchFiltersEnum::values(),
]);
}
}
2 changes: 1 addition & 1 deletion app/Livewire/PartnerFilterComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public function selectFilter($filter)

public function render()
{
return view('livewire.partner-filter-component', [
return view('livewire.filter-component', [
'filters' => ['Partners', 'Council Presidency', 'EU Code Week Supporters'] // Available filters
]);
}
Expand Down
Loading