diff --git a/app/Console/Commands/CertificatesIssues.php b/app/Console/Commands/CertificatesIssues.php
index da5f2c03b..00d998f81 100644
--- a/app/Console/Commands/CertificatesIssues.php
+++ b/app/Console/Commands/CertificatesIssues.php
@@ -31,7 +31,7 @@ public function handle(): int
{
$issues = Participation::whereNull('participation_url')
- ->where('status', '=', 'PENDING')
+ ->where('status', 'PENDING')
->where('created_at', '<', Carbon::now()->subMinutes(5))->get();
Log::info('certificate with issues: '.count($issues));
diff --git a/app/Console/Commands/CertificatesOfParticipationGeneration.php b/app/Console/Commands/CertificatesOfParticipationGeneration.php
index f6ea73224..e61d1f4c5 100644
--- a/app/Console/Commands/CertificatesOfParticipationGeneration.php
+++ b/app/Console/Commands/CertificatesOfParticipationGeneration.php
@@ -28,7 +28,7 @@ class CertificatesOfParticipationGeneration extends Command
public function handle(): int
{
- $participations = Participation::whereNull('participation_url')->where('status', '=', 'PENDING')->orderByDesc('created_at')->get();
+ $participations = Participation::whereNull('participation_url')->where('status', 'PENDING')->orderByDesc('created_at')->get();
$this->info(count($participations).' certificates of participation to generate');
diff --git a/app/Console/Commands/EventsIndexOptimize.php b/app/Console/Commands/EventsIndexOptimize.php
new file mode 100644
index 000000000..64822ce11
--- /dev/null
+++ b/app/Console/Commands/EventsIndexOptimize.php
@@ -0,0 +1,73 @@
+option('rollback');
+
+ $this->info(($rollback ? 'Dropping' : 'Adding') . ' indexes on events table...');
+
+ $indexes = [
+ 'idx_status' => 'CREATE INDEX idx_status ON events(status)',
+ 'idx_country_iso' => 'CREATE INDEX idx_country_iso ON events(country_iso)',
+ 'idx_status_country' => 'CREATE INDEX idx_status_country ON events(status, country_iso)',
+ 'idx_start_date' => 'CREATE INDEX idx_start_date ON events(start_date)',
+ 'idx_end_date' => 'CREATE INDEX idx_end_date ON events(end_date)',
+ 'idx_activity_type' => 'CREATE INDEX idx_activity_type ON events(activity_type)',
+ 'idx_highlighted_status' => 'CREATE INDEX idx_highlighted_status ON events(highlighted_status)',
+ 'idx_lat_lon' => 'CREATE INDEX idx_lat_lon ON events(latitude, longitude)',
+ 'idx_creator_id' => 'CREATE INDEX idx_creator_id ON events(creator_id)',
+ 'idx_user_email' => 'CREATE INDEX idx_user_email ON events(user_email)',
+ 'idx_status_start' => 'CREATE INDEX idx_status_start ON events(status, start_date)',
+ ];
+
+ foreach ($indexes as $name => $sql) {
+ try {
+ if ($rollback) {
+ DB::statement("DROP INDEX {$name} ON events");
+ $this->info("Dropped index: {$name}");
+ } else {
+ $exists = DB::select(
+ "SELECT COUNT(1) as count FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = 'events' AND index_name = ?",
+ [$name]
+ );
+
+ if (!empty($exists) && $exists[0]->count == 0) {
+ DB::statement($sql);
+ $this->info("Created index: {$name}");
+ } else {
+ $this->line("Index already exists: {$name}");
+ }
+ }
+ } catch (\Throwable $e) {
+ $this->error("Failed to " . ($rollback ? 'drop' : 'create') . " index {$name}: " . $e->getMessage());
+ }
+ }
+
+ $this->info('Index operation completed.');
+ return 0;
+ }
+}
diff --git a/app/Console/Commands/Excellence.php b/app/Console/Commands/Excellence.php
index 647611feb..d564fc037 100644
--- a/app/Console/Commands/Excellence.php
+++ b/app/Console/Commands/Excellence.php
@@ -47,7 +47,7 @@ public function handle(): void
//Select the winners from the Database
$winners = [];
foreach ($codeweek4all_codes as $codeweek4all_code) {
- $creators = Event::whereYear('end_date', '=', $edition)->where('status', '=', 'APPROVED')->where('codeweek_for_all_participation_code', '=', $codeweek4all_code)->pluck('creator_id');
+ $creators = Event::whereYear('end_date', '=', $edition)->where('status', 'APPROVED')->where('codeweek_for_all_participation_code', '=', $codeweek4all_code)->pluck('creator_id');
foreach ($creators as $creator) {
if (! in_array($creator, $winners)) {
$winners[] = $creator;
diff --git a/app/Console/Commands/LocationExtraction.php b/app/Console/Commands/LocationExtraction.php
index 2b59801aa..b6ebc31f1 100644
--- a/app/Console/Commands/LocationExtraction.php
+++ b/app/Console/Commands/LocationExtraction.php
@@ -32,7 +32,7 @@ public function handle(): void
Event::whereNull('deleted_at')->
// where('id','=',163373)->
// where('creator_id',153701)->
- where('status', '=', 'APPROVED')->
+ where('status', 'APPROVED')->
whereNull('location_id')->chunkById($this->step, function ($events, $index) {
$this->reportProgress($index);
diff --git a/app/Console/Commands/SyncEventAgesFromAudience.php b/app/Console/Commands/SyncEventAgesFromAudience.php
new file mode 100644
index 000000000..362c22a03
--- /dev/null
+++ b/app/Console/Commands/SyncEventAgesFromAudience.php
@@ -0,0 +1,83 @@
+ [1], // Pre-school children
+ '6-9' => [2], // Elementary school students
+ '10-12' => [2], // Upper primary → still Elementary
+ '13-15' => [3], // Lower secondary → High school
+ '16-18' => [3], // Upper secondary → High school
+ '19-25' => [4, 5], // Graduate & Post graduate students
+ 'over-25' => [6, 7, 9], // Employed + Unemployed adults + Teachers
+ ];
+
+ /**
+ * Execute the console command.
+ */
+ public function handle()
+ {
+ $this->info('Syncing event.ages from audience_event...');
+
+ $map = self::AGE_AUDIENCE_MAP;
+
+ $audienceToAges = [];
+ foreach ($map as $ageKey => $audienceIds) {
+ foreach ($audienceIds as $audienceId) {
+ $audienceToAges[$audienceId][] = $ageKey;
+ }
+ }
+
+ $links = DB::table('audience_event')
+ ->select('event_id', 'audience_id')
+ ->get()
+ ->groupBy('event_id');
+
+ $updated = 0;
+
+ foreach ($links as $eventId => $group) {
+ $ageKeys = collect($group)
+ ->flatMap(function ($row) use ($audienceToAges) {
+ return $audienceToAges[$row->audience_id] ?? [];
+ })
+ ->unique()
+ ->values()
+ ->all();
+
+ if (!empty($ageKeys)) {
+ Event::where('id', $eventId)->update([
+ 'ages' => json_encode($ageKeys),
+ ]);
+ $updated++;
+ }
+ }
+
+ $this->info("Updated `ages` field for $updated events.");
+ return 0;
+ }
+}
diff --git a/app/Console/Commands/SyncThemesFromFinalList.php b/app/Console/Commands/SyncThemesFromFinalList.php
new file mode 100644
index 000000000..0e83d0c9f
--- /dev/null
+++ b/app/Console/Commands/SyncThemesFromFinalList.php
@@ -0,0 +1,267 @@
+ 'AI & Generative AI',
+ 'Artificial intelligence' => 'AI & Generative AI',
+
+ // Robotics, Drones, Devices
+ 'Robotics' => 'Robotics, Drones & Smart Devices',
+ 'Drones' => 'Robotics, Drones & Smart Devices',
+ 'Hardware' => 'Robotics, Drones & Smart Devices',
+ 'Digital Technologies' => 'Robotics, Drones & Smart Devices',
+
+ // Web/App/Software Dev
+ 'Mobile app development' => 'Web, App & Software Development',
+ 'Web development' => 'Web, App & Software Development',
+ 'Software development' => 'Web, App & Software Development',
+
+ // Game Design
+ 'Game design' => 'Game Design',
+
+ // Cybersecurity & Data
+ 'Data manipulation and visualisation' => 'Cybersecurity & Data', // best match despite not direct
+
+ // Visual/Block Programming
+ 'Basic programming concepts' => 'Visual/Block Programming',
+ 'Visual/Block programming' => 'Visual/Block Programming',
+
+ // Art & Creative Coding
+ 'Art and creativity' => 'Art & Creative Coding',
+
+ // Internet of Things & Wearables
+ 'Sensors' => 'Internet of Things & Wearables',
+ 'Internet of things and wearable computing' => 'Internet of Things & Wearables',
+
+ // AR/VR/3D
+ '3D printing' => 'AR, VR & 3D Technologies',
+ 'Augmented reality' => 'AR, VR & 3D Technologies',
+
+ // Digital Careers
+ 'Digital careers' => 'Digital Careers & Learning Pathways',
+ 'Digital learning pathways' => 'Digital Careers & Learning Pathways',
+
+ // Soft Skills
+ 'Soft Skills' => 'Digital Literacy & Soft Skills',
+
+ // Unplugged & Playful
+ 'Unplugged activities' => 'Unplugged & Playful Activities',
+ 'Playful coding activities' => 'Unplugged & Playful Activities',
+
+ // Diversity
+ 'Promoting diversity' => 'Promoting Diversity & Inclusion',
+
+ // Awareness
+ 'Motivation and awareness raising' => 'Awareness & Inspiration',
+
+ // Other
+ 'Other' => 'Other',
+ ];
+
+ protected $finalThemes = [
+ [17, 'AI & Generative AI', 15],
+ [6, 'Robotics, Drones & Smart Devices', 1],
+ [2, 'Web, App & Software Development', 4],
+ [13, 'Game Design', 10],
+ [5, 'Cybersecurity & Data', 2],
+ [1, 'Visual/Block Programming', 5],
+ [11, 'Art & Creative Coding', 8],
+ [14, 'Internet of Things & Wearables', 11],
+ [16, 'AR, VR & 3D Technologies', 12],
+ [3, 'Digital Careers & Learning Pathways', 13],
+ [4, 'Digital Literacy & Soft Skills', 14],
+ [9, 'Unplugged & Playful Activities', 6],
+ [19, 'Promoting Diversity & Inclusion', 17],
+ [18, 'Awareness & Inspiration', 16],
+ [8, 'Other', 18],
+ ];
+
+ /**
+ * Execute the console command.
+ */
+ public function handle()
+ {
+ $restoreOnly = $this->option('restore');
+
+ if ($restoreOnly) {
+ return $this->restoreBackup();
+ }
+
+ $this->info('Starting themes sync and migration...');
+
+ DB::beginTransaction();
+
+ try {
+ DB::statement('SET FOREIGN_KEY_CHECKS=0');
+ config(['database.connections.mysql.strict' => false]);
+ DB::reconnect();
+
+ $eventThemeOld = DB::table('event_theme')
+ ->join('themes', 'event_theme.theme_id', '=', 'themes.id')
+ ->select('event_theme.event_id', 'themes.name as old_theme_name', 'event_theme.theme_id')
+ ->get();
+
+ if ( !Storage::disk('excel')->exists(self::BACKUP_FILE)) {
+ Storage::disk('excel')->put(self::BACKUP_FILE, $eventThemeOld->toJson(JSON_PRETTY_PRINT));
+ $this->info('Backed up current event_theme to ' . self::BACKUP_FILE);
+ }
+ else {
+ $this->info('No update, Backed up current event_theme exist in ' . self::BACKUP_FILE);
+ }
+
+ DB::table('event_theme')->delete();
+ DB::table('themes')->delete();
+
+ $finalThemesMap = collect($this->finalThemes)->map(function ($theme) {
+ return [
+ 'id' => $theme[0],
+ 'name' => $theme[1],
+ 'order' => $theme[2],
+ ];
+ });
+
+ DB::table('themes')->insert($finalThemesMap->toArray());
+
+ // Set AUTO_INCREMENT to max(id) + 1
+ $maxId = collect($this->finalThemes)->max(fn($theme) => $theme[0]);
+ DB::statement('ALTER TABLE themes AUTO_INCREMENT = ' . ($maxId + 1));
+
+ $newThemes = DB::table('themes')->get()->keyBy('name');
+
+ $mappedRows = [];
+
+ foreach ($eventThemeOld as $item) {
+ $newName = self::OLD_TO_NEW_THEME_MAP[$item->old_theme_name] ?? null;
+ if ($newName && isset($newThemes[$newName])) {
+ $mappedRows[] = [
+ 'event_id' => $item->event_id,
+ 'theme_id' => $newThemes[$newName]->id,
+ ];
+ }
+ }
+
+ $validatedRows = [];
+
+ foreach (array_chunk($mappedRows, 500) as $chunk) {
+ $eventIds = array_column($chunk, 'event_id');
+
+ $existingIds = DB::table('events')
+ ->whereIn('id', $eventIds)
+ ->pluck('id')
+ ->toArray();
+
+ $validatedRows = array_merge($validatedRows, array_filter($chunk, fn($row) => in_array($row['event_id'], $existingIds)));
+ }
+
+ $uniqueRows = collect($validatedRows)
+ ->unique(fn($row) => $row['event_id'] . '-' . $row['theme_id'])
+ ->values()
+ ->all();
+
+ foreach (array_chunk($uniqueRows, 1000) as $chunk) {
+ DB::table('event_theme')->insert($chunk);
+ }
+
+ DB::statement('SET FOREIGN_KEY_CHECKS=1');
+ config(['database.connections.mysql.strict' => true]);
+ DB::reconnect();
+
+ DB::commit();
+
+ $this->info("Themes synced and event_theme migrated successfully. Total migrated: " . count($uniqueRows));
+ } catch (\Throwable $e) {
+ DB::rollBack();
+ $this->error("Error syncing themes: " . $e->getMessage());
+ }
+
+ return 0;
+ }
+
+ protected function restoreBackup(): int
+ {
+ $this->info('Restoring event_theme from backup...');
+
+ if (!Storage::disk('excel')->exists(self::BACKUP_FILE)) {
+ $this->error('Backup file not found: ' . self::BACKUP_FILE);
+ return 1;
+ }
+
+ $raw = Storage::disk('excel')->get(self::BACKUP_FILE);
+ $data = json_decode($raw, true);
+ $data = collect($data)->map(function ($row) {
+ return [
+ 'event_id' => $row['event_id'],
+ 'theme_id' => $row['theme_id'],
+ ];
+ })->values()->all();
+
+ if (empty($data)) {
+ $this->error('Backup is empty or invalid.');
+ return 1;
+ }
+
+ try {
+ config(['database.connections.mysql.strict' => false]);
+ DB::reconnect();
+
+ DB::beginTransaction();
+ DB::statement('SET FOREIGN_KEY_CHECKS=0');
+
+ DB::table('event_theme')->delete();
+ DB::table('themes')->delete();
+
+ DB::statement('SET FOREIGN_KEY_CHECKS=1');
+ DB::commit();
+
+ $this->info('Running legacy ThemeTableSeeder...');
+ $this->callSilent('db:seed', [
+ '--class' => 'ThemeTableSeeder',
+ ]);
+
+ DB::beginTransaction();
+ DB::statement('SET FOREIGN_KEY_CHECKS=0');
+
+ foreach (array_chunk($data, 1000) as $chunk) {
+ DB::table('event_theme')->insert($chunk);
+ }
+
+ DB::statement('SET FOREIGN_KEY_CHECKS=1');
+ DB::commit();
+
+ config(['database.connections.mysql.strict' => true]);
+ DB::reconnect();
+
+ $this->info('Restored event_theme successfully: ' . count($data) . ' rows.');
+ } catch (\Throwable $e) {
+ DB::rollBack();
+ $this->error('Restore failed: ' . $e->getMessage());
+ return 1;
+ }
+
+ return 0;
+ }
+}
diff --git a/app/Event.php b/app/Event.php
index 75fd24aad..04efe209a 100644
--- a/app/Event.php
+++ b/app/Event.php
@@ -16,6 +16,7 @@
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
+use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Spatie\Activitylog\LogOptions;
use Stevebauman\Purify\Casts\PurifyHtmlOnGet;
@@ -67,6 +68,58 @@ class Event extends Model
'location_id',
'leading_teacher_tag',
'mass_added_for',
+ 'activity_format',
+ 'duration',
+ 'recurring_event',
+ 'recurring_type',
+ 'males_count',
+ 'females_count',
+ 'other_count',
+ 'is_extracurricular_event',
+ 'is_standard_school_curriculum',
+ 'is_use_resource',
+ 'ages'
+ ];
+
+ public const ACTIVITY_FORMATS = [
+ 'coding-camp',
+ 'summer-camp',
+ 'weekend-course',
+ 'evening-course',
+ 'careerday',
+ 'university-visit',
+ 'coding-home',
+ 'code-week-challenge',
+ 'competition',
+ 'other',
+ ];
+
+ public const DURATIONS = [
+ '0-1',
+ '1-2',
+ '2-4',
+ 'over-4',
+ ];
+
+ public const RECURRING_TYPES = [
+ 'consecutive',
+ 'individual',
+ ];
+
+ public const RECURRING_EVENTS = [
+ 'daily',
+ 'weekly',
+ 'monthly',
+ ];
+
+ public const AGES = [
+ 'under-5',
+ '6-9',
+ '10-12',
+ '13-15',
+ '16-18',
+ '19-25',
+ 'over-25',
];
// protected $policies = [
@@ -74,7 +127,7 @@ class Event extends Model
// Event::class => EventPolicy::class
// ];
- //protected $appends = ['LatestModeration'];
+ protected $appends = ['picture_path'];
public function getUrlAttribute() {
if (!empty($this->slug)) {
@@ -109,6 +162,12 @@ protected function casts(): array
'title' => PurifyHtmlOnGet::class,
'location' => PurifyHtmlOnGet::class,
'language' => PurifyHtmlOnGet::class,
+
+ 'activity_format' => 'array',
+ 'is_extracurricular_event' => 'boolean',
+ 'is_standard_school_curriculum' => 'boolean',
+ 'ages' => 'array',
+ 'is_use_resource' => 'boolean',
];
}
@@ -140,6 +199,8 @@ public function picture_path()
return $this->picture;
}
+ // For local test
+ // return Storage::disk('public')->url($this->picture);
return config('codeweek.aws_url').$this->picture;
} else {
return 'https://s3-eu-west-1.amazonaws.com/codeweek-dev/events/pictures/event_default_picture.png';
@@ -212,7 +273,7 @@ public function scopeFilter($query, EventFilters $filters)
public static function getByYear($year)
{
- $events = Event::where('status', 'like', 'APPROVED')->where(
+ $events = Event::where('status', 'APPROVED')->where(
'start_date',
'>',
Carbon::createFromDate($year, 1, 1)
diff --git a/app/Filters/EventFilters.php b/app/Filters/EventFilters.php
index 5686edfbb..c01cbd3cb 100755
--- a/app/Filters/EventFilters.php
+++ b/app/Filters/EventFilters.php
@@ -3,7 +3,6 @@
namespace App\Filters;
use App\Tag;
-use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
@@ -15,7 +14,20 @@ class EventFilters extends Filters
*
* @var array
*/
- protected $filters = ['countries', 'query', 'themes', 'audiences', 'types', 'year', 'creator_id', 'tag'];
+ protected $filters = [
+ 'countries',
+ 'query',
+ 'themes',
+ 'audiences',
+ 'types',
+ 'year',
+ 'creator_id',
+ 'tag',
+ 'formats',
+ 'ages',
+ 'languages',
+ 'start_date'
+ ];
public function __construct(Request $request)
{
@@ -50,13 +62,11 @@ protected function countries($countries): Builder
protected function year($year)
{
return $this->builder->whereYear('end_date', '=', $year);
-
}
protected function creator_id($creator_id)
{
return $this->builder->where('creator_id', '=', $creator_id);
-
}
protected function query($query)
@@ -85,7 +95,6 @@ protected function themes($themes)
return $this->builder
->leftJoin('event_theme', 'events.id', '=', 'event_theme.event_id')
->whereIn('event_theme.theme_id', $themesIds);
-
}
protected function tag($tag)
@@ -104,7 +113,6 @@ protected function tag($tag)
return $this->builder
->leftJoin('event_tag', 'events.id', '=', 'event_tag.event_id')
->where('event_tag.tag_id', $selectedTag->id);
-
}
protected function audiences($audiences)
@@ -119,7 +127,6 @@ protected function audiences($audiences)
return $this->builder
->leftJoin('audience_event', 'events.id', '=', 'audience_event.event_id')
->whereIn('audience_event.audience_id', $audiencesIds);
-
}
protected function types($types)
@@ -129,11 +136,62 @@ protected function types($types)
return;
}
- $keys = collect($types)->pluck('key')->all();
+ $keys = collect($types)->pluck('id')->all();
$result = $this->builder->whereIn('activity_type', $keys);
return $result;
+ }
+
+ protected function start_date($start_date)
+ {
+ if (!empty($start_date)) {
+ return $this->builder->where('start_date', '>=', $start_date);
+ }
+ return;
+ }
+
+ protected function languages($languages)
+ {
+
+ if (empty($languages)) {
+ return;
+ }
+
+ $keys = collect($languages)->pluck('id')->all();
+
+ $result = $this->builder->whereIn('language', $keys);
+
+ return $result;
+ }
+ protected function formats($formats)
+ {
+ if (empty($formats)) {
+ return;
+ }
+
+ $keys = collect($formats)->pluck('id')->all();
+
+ $this->builder->where(function ($query) use ($keys) {
+ foreach ($keys as $key) {
+ $query->orWhereRaw("JSON_CONTAINS(activity_format, '\"$key\"')");
+ }
+ });
+ }
+
+ protected function ages($ages)
+ {
+ if (empty($ages)) {
+ return;
+ }
+
+ $keys = collect($ages)->pluck('id')->all();
+
+ $this->builder->where(function ($query) use ($keys) {
+ foreach ($keys as $key) {
+ $query->orWhereRaw("JSON_CONTAINS(ages, '\"$key\"')");
+ }
+ });
}
}
diff --git a/app/Helpers/Codeweek4AllHelper.php b/app/Helpers/Codeweek4AllHelper.php
index fe8745454..6500c58fa 100644
--- a/app/Helpers/Codeweek4AllHelper.php
+++ b/app/Helpers/Codeweek4AllHelper.php
@@ -17,7 +17,7 @@ public static function kpis($code, $edition = null)
$result = Event::select(DB::raw('count(DISTINCT creator_id) as total_creators, sum(participants_count) as participants_count, count(id) as event_count, codeweek_for_all_participation_code'))
->where([
- ['status', 'like', 'APPROVED'],
+ ['status', 'APPROVED'],
['codeweek_for_all_participation_code', '=', $code],
])
->whereYear('end_date', '=', $edition)
@@ -39,7 +39,7 @@ public static function countries($code, $edition = null)
select(DB::raw('count(DISTINCT creator_id) as total_creators, sum(participants_count) as total_participants, codeweek_for_all_participation_code'))
->where([
- ['status', 'like', 'APPROVED'],
+ ['status', 'APPROVED'],
])
->whereYear('end_date', '=', $edition)
->groupBy('codeweek_for_all_participation_code')
@@ -51,7 +51,7 @@ public static function countries($code, $edition = null)
$result = Event::select(DB::raw('sum(participants_count) as participants_count, count(id) as event_count, codeweek_for_all_participation_code'))
->where([
- ['status', 'like', 'APPROVED'],
+ ['status', 'APPROVED'],
['codeweek_for_all_participation_code', '=', $code],
])
->whereYear('end_date', '=', $edition)
@@ -71,7 +71,7 @@ public static function getDetailsByCodeweek4All(array $toArray, $edition = null)
return Event::select(DB::raw('codeweek_for_all_participation_code, sum(participants_count) as total_participants, count(DISTINCT creator_id) as total_creators, count(DISTINCT country_iso) as total_countries, count(id) as total_activities, ((100.0*count(reported_at))/count(*)) as reporting_percentage'))
->where([
- ['status', 'like', 'APPROVED'],
+ ['status', 'APPROVED'],
])
->whereYear('end_date', '=', $edition)
->whereIn('codeweek_for_all_participation_code', $toArray)
@@ -88,7 +88,7 @@ public static function getCountriesByCodeweek4All($code, $edition = null)
$result = Event::select(DB::raw('countries.name , count(events.id) as event_per_country'))
->join('countries', 'events.country_iso', '=', 'countries.iso')
->where([
- ['status', 'like', 'APPROVED'],
+ ['status', 'APPROVED'],
['codeweek_for_all_participation_code', 'like', $code],
])
->whereYear('end_date', '=', $edition)
@@ -103,7 +103,7 @@ public static function getInitiatorByCodeweek4All($code)
$result = Event::select(DB::raw('users.email'))
->join('users', 'events.creator_id', '=', 'users.id')
->where([
- ['status', 'like', 'APPROVED'],
+ ['status', 'APPROVED'],
['codeweek_for_all_participation_code', 'like', $code],
])
->orderBy('events.created_at', 'asc')
diff --git a/app/Helpers/EventHelper.php b/app/Helpers/EventHelper.php
index 378b3cc71..59639afa5 100644
--- a/app/Helpers/EventHelper.php
+++ b/app/Helpers/EventHelper.php
@@ -20,7 +20,7 @@ public static function getCloseEvents($longitude, $latitude, $id = 0, $num = 3)
}
$events = Event::selectRaw(
- 'id, title, slug, start_date, end_date, picture, description, picture, creator_id,
+ 'id, title, slug, start_date, end_date, picture, description, picture, creator_id, highlighted_status, recurring_event,
( 6371 *
acos( cos( radians(?) ) *
cos( radians( latitude ) ) *
@@ -31,7 +31,7 @@ public static function getCloseEvents($longitude, $latitude, $id = 0, $num = 3)
AS distance',
[$latitude, $longitude, $latitude]
)
- ->where('status', '=', 'APPROVED')
+ ->where('status', 'APPROVED')
->where('id', '<>', $id)
->where('end_date', '>', Carbon::now())
->orderBy('distance')
@@ -55,7 +55,7 @@ public static function getPendindEvents()
array_push($countries, $country->country_iso);
}
- $events = Event::where('status', '=', 'PENDING')
+ $events = Event::where('status', 'PENDING')
->distinct()
->select('country_iso')
->where('start_date', '>', Carbon::createFromDate(2018, 1, 1))
@@ -67,7 +67,7 @@ public static function getPendindEvents()
public static function getReportedEventsWithoutCertificates()
{
- $events = Event::where('status', '=', 'APPROVED')
+ $events = Event::where('status', 'APPROVED')
->whereNotNull('reported_at')
->whereNull('certificate_url')
->whereNotNull('approved_by')
@@ -81,7 +81,7 @@ public static function getReportedEventsWithoutCertificates()
private static function getPendingEventsForCountry($country)
{
- $events = Event::where('status', '=', 'PENDING')
+ $events = Event::where('status', 'PENDING')
->where('start_date', '>', Carbon::createFromDate(2018, 1, 1))
->where('country_iso', $country)
->get();
@@ -92,7 +92,7 @@ private static function getPendingEventsForCountry($country)
private static function getPendingEventsCountForCountry($country)
{
- $count = Event::where('status', '=', 'PENDING')
+ $count = Event::where('status', 'PENDING')
->select('country_iso')
->where('start_date', '>', Carbon::createFromDate(2018, 1, 1))
->where('country_iso', $country)
@@ -103,7 +103,7 @@ private static function getPendingEventsCountForCountry($country)
private static function getEventsQuery()
{
- return Event::where('status', '=', 'PENDING')
+ return Event::where('status', 'PENDING')
->where('start_date', '>', Carbon::createFromDate(2018, 1, 1));
}
@@ -140,7 +140,7 @@ public static function getNextPendingEvent(Event $event, ?string $country = null
return self::getEventsQuery()->where('id', '>', $event->id)->limit(1)->first();
} else {
//Get pending events count for specific country
- return Event::where('status', '=', 'PENDING')
+ return Event::where('status', 'PENDING')
->where('country_iso', $country)
->where('start_date', '>', Carbon::createFromDate(2018, 1, 1))
->where('id', '<>', $event->id)->limit(1)->first();
diff --git a/app/Helpers/ExcellenceWinnersHelper.php b/app/Helpers/ExcellenceWinnersHelper.php
index 0c902cd48..e6a9b550b 100644
--- a/app/Helpers/ExcellenceWinnersHelper.php
+++ b/app/Helpers/ExcellenceWinnersHelper.php
@@ -33,7 +33,7 @@ public static function criteria1($edition)
$codes = Event::select(DB::raw('sum(participants_count) as total_participants, codeweek_for_all_participation_code'))
->where([
- ['status', 'like', 'APPROVED'],
+ ['status', 'APPROVED'],
])
->whereYear('end_date', '=', $edition)
->groupBy('codeweek_for_all_participation_code')
@@ -52,7 +52,7 @@ public static function criteria2($edition)
$codes = Event::select(DB::raw('count(DISTINCT creator_id) as total_creators, sum(participants_count) as total_participants, codeweek_for_all_participation_code'))
->where([
- ['status', 'like', 'APPROVED'],
+ ['status', 'APPROVED'],
])
->whereYear('end_date', '=', $edition)
->groupBy('codeweek_for_all_participation_code')
@@ -72,7 +72,7 @@ public static function criteria3($edition)
$codes = Event::select(DB::raw('count(DISTINCT country_iso) as total_countries, sum(participants_count) as total_participants,codeweek_for_all_participation_code'))
->where([
- ['status', 'like', 'APPROVED'],
+ ['status', 'APPROVED'],
])
->whereYear('end_date', '=', $edition)
->groupBy('codeweek_for_all_participation_code')
diff --git a/app/Helpers/MailingHelper.php b/app/Helpers/MailingHelper.php
index 443b0e3e1..9aad7f671 100644
--- a/app/Helpers/MailingHelper.php
+++ b/app/Helpers/MailingHelper.php
@@ -11,7 +11,7 @@ public static function getActiveCreators($country)
$activeIds = DB::table('events')
->join('users', 'users.id', '=', 'events.creator_id')
- ->where('status', '=', 'APPROVED')
+ ->where('status', 'APPROVED')
->where('users.receive_emails', true)
->where('events.country_iso', '=', $country)
->whereNull('users.deleted_at')
@@ -25,7 +25,7 @@ public static function getActiveCreators($country)
return DB::table('events')
->join('users', 'users.id', '=', 'events.creator_id')
- ->where('status', '=', 'APPROVED')
+ ->where('status', 'APPROVED')
->whereNull('events.deleted_at')
->whereIntegerInRaw('events.creator_id', $activeIds)
->groupBy('users.email')
diff --git a/app/Helpers/ReminderHelper.php b/app/Helpers/ReminderHelper.php
index 442fb665c..ee43f99cd 100644
--- a/app/Helpers/ReminderHelper.php
+++ b/app/Helpers/ReminderHelper.php
@@ -15,7 +15,7 @@ public static function getInactiveCreators($edition)
$activeIds = DB::table('events')
->join('users', 'users.id', '=', 'events.creator_id')
//->where('creator_id','=',$this->id)
- ->where('status', '=', 'APPROVED')
+ ->where('status', 'APPROVED')
->where('users.receive_emails', true)
->whereNull('users.deleted_at')
->whereNull('events.deleted_at')
@@ -29,7 +29,7 @@ public static function getInactiveCreators($edition)
return DB::table('events')
->join('users', 'users.id', '=', 'events.creator_id')
//->where('creator_id','=',$this->id)
- ->where('status', '=', 'APPROVED')
+ ->where('status', 'APPROVED')
->whereNull('events.deleted_at')
->where(function ($query) use ($edition) {
return $query->whereYear('events.end_date', '=', $edition - 1);
@@ -49,7 +49,7 @@ public static function getActiveCreators()
$activeIds = DB::table('events')
->join('users', 'users.id', '=', 'events.creator_id')
- ->where('status', '=', 'APPROVED')
+ ->where('status', 'APPROVED')
->where('users.receive_emails', true)
->whereNull('users.deleted_at')
->whereNull('events.deleted_at')
@@ -62,7 +62,7 @@ public static function getActiveCreators()
return DB::table('events')
->join('users', 'users.id', '=', 'events.creator_id')
- ->where('status', '=', 'APPROVED')
+ ->where('status', 'APPROVED')
->whereNull('events.deleted_at')
->whereIntegerInRaw('events.creator_id', $activeIds)
->groupBy('users.email')
diff --git a/app/Http/Controllers/Api/EventsController.php b/app/Http/Controllers/Api/EventsController.php
index 994df55ec..d80d1516d 100644
--- a/app/Http/Controllers/Api/EventsController.php
+++ b/app/Http/Controllers/Api/EventsController.php
@@ -105,7 +105,7 @@ public function germany(Request $request)
]);
$collection = \App\Http\Resources\EventResource::collection(
- Event::where('status', 'like', 'APPROVED')
+ Event::where('status', 'APPROVED')
->where('country_iso', 'DE')
->whereYear('end_date', '=', $validated['year'])
->get()
@@ -158,7 +158,7 @@ public function geobox(Request $request)
}
$collection = \App\Http\Resources\EventResource::collection(
- Event::where('status', 'like', 'APPROVED')
+ Event::where('status', 'APPROVED')
->where($box)
->whereYear('end_date', '=', $year)
->get()
diff --git a/app/Http/Controllers/EventController.php b/app/Http/Controllers/EventController.php
index 6ae8701ca..76af99321 100755
--- a/app/Http/Controllers/EventController.php
+++ b/app/Http/Controllers/EventController.php
@@ -26,7 +26,7 @@ class EventController extends Controller
*/
public function __construct()
{
- $this->middleware('auth')->except(['index', 'show', 'my']);
+ $this->middleware('auth')->except(['show', 'my']);
}
public function my(): View
@@ -49,40 +49,6 @@ public function my(): View
//
// }
- /**
- * Display a listing of the resource.
- */
- public function index(Request $request): View
- {
- $years = range(Carbon::now()->year, 2014, -1);
-
- $selectedYear = $request->input('year')
- ? $request->input('year')
- : Carbon::now()->year;
-
- $iso_country_of_user = User::getGeoIPData()->iso_code;
-
- $ambassadors = User::role('ambassador')
- ->where('country_iso', '=', $iso_country_of_user)
- ->get();
-
- return view('events')->with([
- 'events' => $this->eventsNearMe(),
- 'years' => $years,
- 'selectedYear' => $selectedYear,
- 'countries' => Country::withActualYearEvents(),
- 'current_country_iso' => $iso_country_of_user,
- 'ambassadors' => $ambassadors,
- ]);
- }
-
- private function eventsNearMe()
- {
- $geoip = User::getGeoIPData();
-
- return EventHelper::getCloseEvents($geoip->lon, $geoip->lat);
- }
-
/**
* Show the form for creating a new resource.
*/
@@ -186,7 +152,7 @@ public function edit(Event $event): View
->pluck('id')
->toArray();
$selected_audiences = implode(',', $selected_audiences);
- $selected_country = $event->country()->first()->iso;
+ $selected_country = optional($event->country()->first())->iso;
$selected_language = is_null($event->language)
? 'en'
: $event->language;
diff --git a/app/Http/Controllers/ExcellenceWinnersController.php b/app/Http/Controllers/ExcellenceWinnersController.php
index 1222f2770..dd68a311d 100644
--- a/app/Http/Controllers/ExcellenceWinnersController.php
+++ b/app/Http/Controllers/ExcellenceWinnersController.php
@@ -35,14 +35,14 @@ public function list(Request $request, $edition = 2024): View
$details = ExcellenceWinnersHelper::query($edition, false);
$total_events = DB::table('events')
- ->where('status', '=', 'APPROVED')
+ ->where('status', 'APPROVED')
//->where('codeweek_for_all_participation_code', '<>', 'cw19-apple-eu')
->whereYear('end_date', '=', $edition)
->whereNull('deleted_at')
->count();
$total_reported = DB::table('events')
- ->where('status', '=', 'APPROVED')
+ ->where('status', 'APPROVED')
->whereNotNull('reported_at')
->whereNull('deleted_at')
->whereYear('end_date', '=', $edition)
diff --git a/app/Http/Controllers/ScoreboardController.php b/app/Http/Controllers/ScoreboardController.php
index ecc6e62a0..9d802a7d2 100644
--- a/app/Http/Controllers/ScoreboardController.php
+++ b/app/Http/Controllers/ScoreboardController.php
@@ -38,7 +38,7 @@ public function index(Request $request)
$total = Cache::remember('total_' . $edition, $cache_time, function () use ($edition) {
Log::info("Setting cache for scoreboard total in " . $edition);
return DB::table('events')
- ->where('status', "=", "APPROVED")
+ ->where('status', "APPROVED")
->whereNull('deleted_at')
->whereYear('end_date', '=', $edition)
->count();
@@ -52,7 +52,7 @@ public function index(Request $request)
$events = DB::table('events')
->join('countries', 'events.country_iso', '=', 'countries.iso')
->select('countries.iso as country_iso', 'countries.name as country_name', 'countries.population as country_population', DB::raw('count(*) as total'))
- ->where('status', "=", "APPROVED")
+ ->where('status', "APPROVED")
->whereYear('end_date', '=', $edition)
->whereNull('deleted_at')
->where('countries.parent', "=", "")
@@ -63,7 +63,7 @@ public function index(Request $request)
$eventsFromDependencies = DB::table('events')
->join('countries', 'events.country_iso', '=', 'countries.iso')
->select('countries.population as population', 'countries.parent as iso', DB::raw('count(*) as total'))
- ->where('status', "=", "APPROVED")
+ ->where('status', "APPROVED")
->whereNull('deleted_at')
->whereYear('end_date', '=', $edition)
->whereNotNull('countries.parent')
diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php
index 9b59747a4..265e93fa7 100755
--- a/app/Http/Controllers/SearchController.php
+++ b/app/Http/Controllers/SearchController.php
@@ -60,74 +60,46 @@ public function search(Request $request): View
public function searchPOST(EventFilters $filters, Request $request)
{
- $events = $this->getEvents($filters);
+ $paginatedEvents = $this->getPaginatedEvents($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 [$paginatedEvents];
}
- return $result;
+ $mapData = $this->transformEventsForMap($filters);
+
+ return [$paginatedEvents, $mapData];
}
- protected function getEvents(EventFilters $filters)
+ protected function getPaginatedEvents(EventFilters $filters)
{
-
- $events = Event::where('status', 'like', 'APPROVED')
+ return Event::where('status', 'APPROVED')
->filter($filters)
+ ->orderByRaw("start_date > ? desc", [Carbon::today()])
->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);
+ ->paginate(12);
}
- protected function getAllEventsToMap(EventFilters $filters)
+ protected function transformEventsForMap(EventFilters $filters)
{
-
$flattened = Arr::flatten($filters->getFilters());
$filtered = array_filter($flattened, fn($v) => $v !== null && $v !== '');
- $composed_key = implode(',', $filtered);
+ $composed_key = 'map_' . implode(',', $filtered);
- if (empty($composed_key)) {
- Log::info('Skipping cache due to empty composed_key');
- return Event::where('status', 'APPROVED')
- ->filter($filters)
- ->get()
- ->groupBy('country');
- }
+ return Cache::remember($composed_key, 300, function () use ($filters) {
+ $grouped = [];
- $value = Cache::get($composed_key, function () use ($composed_key, $filters) {
- Log::info("Building cache [{$composed_key}]");
- $events = Event::where('status', 'like', 'APPROVED')
+ Event::select('id', 'geoposition', 'country_iso') // Only required fields
+ ->where('status', 'APPROVED')
->filter($filters)
- ->get();
-
- $events = $this->eventTransformer->transformCollection($events);
-
- $events = $events->groupBy('country');
-
- Cache::put($composed_key, $events, 5 * 60);
-
- return $events;
+ ->cursor()
+ ->each(function ($event) use (&$grouped) {
+ $transformed = app(\App\Http\Transformers\EventTransformer::class)->transform($event);
+ $country = $transformed['country'] ?? 'unknown';
+ $grouped[$country][] = $transformed;
+ });
+
+ return collect($grouped);
});
-
- Log::info("Serving from cache [{$composed_key}]");
-
- return $value;
}
}
diff --git a/app/Http/Requests/EventRequest.php b/app/Http/Requests/EventRequest.php
index 3e37fd724..eb506c159 100644
--- a/app/Http/Requests/EventRequest.php
+++ b/app/Http/Requests/EventRequest.php
@@ -31,6 +31,7 @@ public function rules(): array
'title' => 'required|min:5',
'description' => 'required|min:5',
'organizer' => 'required',
+ 'duration' => 'required',
'location' => 'required_unless:activity_type,open-online,invite-online',
'event_url' => 'required_if:activity_type,open-online,invite-online',
'language' => ['required', $this->in($languages)],
@@ -38,6 +39,9 @@ public function rules(): array
'end_date' => 'required|after:start_date',
'audience' => ['required', new ValidAudience],
'theme' => ['required', new ValidTheme],
+ 'participants_count' => 'required',
+ 'ages' => 'required',
+ 'is_extracurricular_event' => 'required|boolean',
'country_iso' => 'required|exists:countries,iso',
'user_email' => 'required',
'organizer_type' => 'required',
@@ -50,14 +54,20 @@ public function rules(): array
public function messages(): array
{
return [
+ 'activity_type.required' => 'Please select an activity type.',
'title.required' => 'Please enter a title for your event.',
'description.required' => 'Please write a short description of what the event is about.',
'organizer.required' => 'Please enter an organizer.',
+ 'duration.required' => 'Please specify the event duration.',
'location.required' => 'Please enter a location.',
'start_date.required' => 'Please enter a valid date and time (example: 2014-10-22 18:00).',
'end_date.required' => 'Please enter a valid date and time (example: 2014-10-22 18:00).',
'audience.required' => 'If unsure, choose Other and provide more information in the description.',
'theme.required' => 'If unsure, choose Other and provide more information in the description.',
+ 'participants_count.required' => 'Please specify the expected number of participants.',
+ 'ages.required' => 'Please select at least one age group.',
+ 'is_extracurricular_event.required' => 'Please specify if this is an extracurricular event.',
+ 'is_extracurricular_event.boolean' => 'The extracurricular event field must be true or false.',
'country.required' => 'The event\'s location should be in Europe.',
'event_url.url' => 'The activity\'s web page address should be a valid URL.',
'event_url.required' => 'The activity\'s web page is required for online activities.',
diff --git a/app/Imports/AppleEventsImport.php b/app/Imports/AppleEventsImport.php
index 229afaa3c..91ea0b221 100644
--- a/app/Imports/AppleEventsImport.php
+++ b/app/Imports/AppleEventsImport.php
@@ -7,16 +7,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-class AppleEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class AppleEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
- public function parseDate($date)
- {
- return Date::excelToDateTimeObject($date);
- }
-
public function model(array $row): ?Model
{
@@ -45,6 +38,41 @@ public function model(array $row): ?Model
'latitude' => $row['latitude'],
'language' => strtolower(explode('_', $row['language'])[0]),
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/AvandeEventsImport.php b/app/Imports/AvandeEventsImport.php
index 7ab7b435b..7d1d678e2 100644
--- a/app/Imports/AvandeEventsImport.php
+++ b/app/Imports/AvandeEventsImport.php
@@ -9,10 +9,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class AvandeEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class AvandeEventsImport extends AppleEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -72,6 +71,41 @@ public function model(array $row): ?Model
'language' => !empty($row['language']) ? strtolower(explode('_', $row['language'])[0]) : 'en',
'approved_by' => 19588,
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/BaseEventsImport.php b/app/Imports/BaseEventsImport.php
new file mode 100644
index 000000000..fbe106889
--- /dev/null
+++ b/app/Imports/BaseEventsImport.php
@@ -0,0 +1,40 @@
+map(fn($v) => trim($v))
+ ->filter(fn($v) => in_array($v, $valid, true))
+ ->values()
+ ->all();
+ }
+
+ protected function validateSingleChoice(?string $input, array $valid): ?string
+ {
+ return in_array($input, $valid, true) ? $input : null;
+ }
+}
diff --git a/app/Imports/BulgariaEventsImport.php b/app/Imports/BulgariaEventsImport.php
index 3f50d5184..cf34ed8aa 100644
--- a/app/Imports/BulgariaEventsImport.php
+++ b/app/Imports/BulgariaEventsImport.php
@@ -8,10 +8,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class BulgariaEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class BulgariaEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -48,6 +47,41 @@ public function model(array $row): ?Model
'longitude' => $row['longitude'],
'latitude' => $row['latitude'],
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/CoderDojoEventsImport.php b/app/Imports/CoderDojoEventsImport.php
index 367457081..cc213a98b 100644
--- a/app/Imports/CoderDojoEventsImport.php
+++ b/app/Imports/CoderDojoEventsImport.php
@@ -3,15 +3,13 @@
namespace App\Imports;
use App\Event;
-use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
-class CoderDojoEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class CoderDojoEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -65,6 +63,41 @@ public function model(array $row): ?Model
'language' => !empty($row['language']) ? trim($row['language']) : 'nl',
'approved_by' => 19588,
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/CodingActivitiesEUCodeWeekSiteImport.php b/app/Imports/CodingActivitiesEUCodeWeekSiteImport.php
index 413e1226b..9eb268af0 100644
--- a/app/Imports/CodingActivitiesEUCodeWeekSiteImport.php
+++ b/app/Imports/CodingActivitiesEUCodeWeekSiteImport.php
@@ -3,16 +3,13 @@
namespace App\Imports;
use App\Event;
-use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
-use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class CodingActivitiesEUCodeWeekSiteImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class CodingActivitiesEUCodeWeekSiteImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -71,6 +68,41 @@ public function model(array $row): ?Model
'language' => $row['language'],
'approved_by' => 19588,
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/DutchDanceEventsImport.php b/app/Imports/DutchDanceEventsImport.php
index f0231de4a..7524aab59 100644
--- a/app/Imports/DutchDanceEventsImport.php
+++ b/app/Imports/DutchDanceEventsImport.php
@@ -10,10 +10,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class DutchDanceEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class DutchDanceEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -64,6 +63,41 @@ public function model(array $row): ?Model
'latitude' => $row['longitude'],
'language' => strtolower($row['language']),
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/DutchMoorlagEventsImport.php b/app/Imports/DutchMoorlagEventsImport.php
index 344ea3465..5179f39b9 100644
--- a/app/Imports/DutchMoorlagEventsImport.php
+++ b/app/Imports/DutchMoorlagEventsImport.php
@@ -8,10 +8,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class DutchMoorlagEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class DutchMoorlagEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -48,6 +47,41 @@ public function model(array $row): ?Model
'latitude' => $row['longitude'],
'language' => strtolower($row['language']),
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/DutchSimoneEventsImport.php b/app/Imports/DutchSimoneEventsImport.php
index eed2bca19..fda1bd800 100644
--- a/app/Imports/DutchSimoneEventsImport.php
+++ b/app/Imports/DutchSimoneEventsImport.php
@@ -8,10 +8,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class DutchSimoneEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class DutchSimoneEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -48,6 +47,41 @@ public function model(array $row): ?Model
'latitude' => $row['latitude'],
'language' => strtolower($row['language']),
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/EventiEventsImport.php b/app/Imports/EventiEventsImport.php
index 6b7c7b566..c4bd15672 100644
--- a/app/Imports/EventiEventsImport.php
+++ b/app/Imports/EventiEventsImport.php
@@ -3,96 +3,129 @@
namespace App\Imports;
use App\Event;
-use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
-class EventiEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class EventiEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
- public function parseDate($date)
- {
- $arr = explode(',', $date);
- array_shift($arr);
- return implode($arr);
- }
-
- public function model(array $row): ?Model
- {
- // Validate required fields
- if (
- empty($row['activity_title']) ||
- empty($row['name_of_organisation']) ||
- empty($row['description']) ||
- empty($row['type_of_organisation']) ||
- empty($row['activity_type']) ||
- empty($row['country']) ||
- empty($row['start_date']) ||
- empty($row['end_date'])
- ) {
- Log::error('Missing required fields in row');
- return null;
+ public function parseDate($date)
+ {
+ $arr = explode(',', $date);
+ array_shift($arr);
+ return implode($arr);
}
- try {
- $event = new Event([
- 'status' => 'APPROVED',
- 'title' => trim($row['activity_title']),
- 'slug' => str_slug(trim($row['activity_title'])),
- 'organizer' => trim($row['name_of_organisation']),
- 'description' => trim($row['description']),
- 'organizer_type' => trim($row['type_of_organisation']),
- 'activity_type' => trim($row['activity_type']),
- 'location' => !empty($row['address']) ? trim($row['address']) : 'online',
- 'event_url' => !empty($row['organiser_website']) ? trim($row['organiser_website']) : '',
- 'contact_person' => !empty($row['contact_email']) ? trim($row['contact_email']) : '',
- 'user_email' => '',
- 'creator_id' => 132942,
- 'country_iso' => trim($row['country']),
- 'picture' => !empty($row['image_path']) ? trim($row['image_path']) : '',
- 'pub_date' => now(),
- 'created' => now(),
- 'updated' => now(),
- 'codeweek_for_all_participation_code' => 'cw20-coderdojo-eu',
- 'start_date' => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['start_date']),
- 'end_date' => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['end_date']),
- 'geoposition' => (!empty($row['latitude']) && !empty($row['longitude'])) ? $row['latitude'] . ',' . $row['longitude'] : '',
- 'longitude' => !empty($row['longitude']) ? trim($row['longitude']) : '',
- 'latitude' => !empty($row['latitude']) ? trim($row['latitude']) : '',
- 'language' => !empty($row['language']) ? trim($row['language']) : 'nl',
- 'approved_by' => 19588,
- 'mass_added_for' => 'Excel',
- ]);
-
- $event->save();
-
- if (!empty($row['audience_comma_separated_ids'])) {
- $audiences = array_unique(array_map('trim', explode(',', $row['audience_comma_separated_ids'])));
- $audiences = array_filter($audiences, function ($id) {
- return is_numeric($id) && $id > 0 && $id <= 100;
- });
- if (!empty($audiences)) {
- $event->audiences()->attach($audiences);
+ public function model(array $row): ?Model
+ {
+ // Validate required fields
+ if (
+ empty($row['activity_title']) ||
+ empty($row['name_of_organisation']) ||
+ empty($row['description']) ||
+ empty($row['type_of_organisation']) ||
+ empty($row['activity_type']) ||
+ empty($row['country']) ||
+ empty($row['start_date']) ||
+ empty($row['end_date'])
+ ) {
+ Log::error('Missing required fields in row');
+ return null;
}
- }
-
- if (!empty($row['theme_comma_separated_ids'])) {
- $themes = array_unique(array_map('trim', explode(',', $row['theme_comma_separated_ids'])));
- $themes = array_filter($themes, function ($id) {
- return is_numeric($id) && $id > 0 && $id <= 100;
- });
- if (!empty($themes)) {
- $event->themes()->attach($themes);
- }
- }
- return $event;
- } catch (\Exception $e) {
- Log::error('Event import failed: ' . $e->getMessage());
- return null;
+ try {
+ $event = new Event([
+ 'status' => 'APPROVED',
+ 'title' => trim($row['activity_title']),
+ 'slug' => str_slug(trim($row['activity_title'])),
+ 'organizer' => trim($row['name_of_organisation']),
+ 'description' => trim($row['description']),
+ 'organizer_type' => trim($row['type_of_organisation']),
+ 'activity_type' => trim($row['activity_type']),
+ 'location' => !empty($row['address']) ? trim($row['address']) : 'online',
+ 'event_url' => !empty($row['organiser_website']) ? trim($row['organiser_website']) : '',
+ 'contact_person' => !empty($row['contact_email']) ? trim($row['contact_email']) : '',
+ 'user_email' => '',
+ 'creator_id' => 132942,
+ 'country_iso' => trim($row['country']),
+ 'picture' => !empty($row['image_path']) ? trim($row['image_path']) : '',
+ 'pub_date' => now(),
+ 'created' => now(),
+ 'updated' => now(),
+ 'codeweek_for_all_participation_code' => 'cw20-coderdojo-eu',
+ 'start_date' => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['start_date']),
+ 'end_date' => \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row['end_date']),
+ 'geoposition' => (!empty($row['latitude']) && !empty($row['longitude'])) ? $row['latitude'] . ',' . $row['longitude'] : '',
+ 'longitude' => !empty($row['longitude']) ? trim($row['longitude']) : '',
+ 'latitude' => !empty($row['latitude']) ? trim($row['latitude']) : '',
+ 'language' => !empty($row['language']) ? trim($row['language']) : 'nl',
+ 'approved_by' => 19588,
+ 'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
+ ]);
+
+ $event->save();
+
+ if (!empty($row['audience_comma_separated_ids'])) {
+ $audiences = array_unique(array_map('trim', explode(',', $row['audience_comma_separated_ids'])));
+ $audiences = array_filter($audiences, function ($id) {
+ return is_numeric($id) && $id > 0 && $id <= 100;
+ });
+ if (!empty($audiences)) {
+ $event->audiences()->attach($audiences);
+ }
+ }
+
+ if (!empty($row['theme_comma_separated_ids'])) {
+ $themes = array_unique(array_map('trim', explode(',', $row['theme_comma_separated_ids'])));
+ $themes = array_filter($themes, function ($id) {
+ return is_numeric($id) && $id > 0 && $id <= 100;
+ });
+ if (!empty($themes)) {
+ $event->themes()->attach($themes);
+ }
+ }
+
+ return $event;
+ } catch (\Exception $e) {
+ Log::error('Event import failed: ' . $e->getMessage());
+ return null;
+ }
}
- }
}
diff --git a/app/Imports/EventsImport.php b/app/Imports/EventsImport.php
index a1c315d08..de16306ef 100644
--- a/app/Imports/EventsImport.php
+++ b/app/Imports/EventsImport.php
@@ -9,9 +9,8 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
-class EventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class EventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -56,6 +55,41 @@ public function model(array $row): ?Model
'longitude' => $row['longitude'],
'latitude' => $row['latitude'],
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/GenericEventsImport.php b/app/Imports/GenericEventsImport.php
index f5e86c8a8..72d5403be 100644
--- a/app/Imports/GenericEventsImport.php
+++ b/app/Imports/GenericEventsImport.php
@@ -10,10 +10,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class GenericEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class GenericEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -64,6 +63,41 @@ public function model(array $row): ?Model
'latitude' => $row['latitude'],
'language' => strtolower($row['language']),
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/HamburgEventsImport.php b/app/Imports/HamburgEventsImport.php
index 2ef82da0c..022200d37 100644
--- a/app/Imports/HamburgEventsImport.php
+++ b/app/Imports/HamburgEventsImport.php
@@ -9,10 +9,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class HamburgEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class HamburgEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -49,6 +48,41 @@ public function model(array $row): ?Model
'longitude' => $row['longitude'],
'latitude' => $row['latitude'],
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/IrelandDreamSpaceImport.php b/app/Imports/IrelandDreamSpaceImport.php
index 1dd8ebe24..adda2e679 100644
--- a/app/Imports/IrelandDreamSpaceImport.php
+++ b/app/Imports/IrelandDreamSpaceImport.php
@@ -5,14 +5,12 @@
use App\Event;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
-use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class IrelandDreamSpaceImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class IrelandDreamSpaceImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -61,6 +59,41 @@ public function model(array $row): ?Model
'language' => '',
'approved_by' => 19588,
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/IrelandEventsImport.php b/app/Imports/IrelandEventsImport.php
index 5cb2b36ef..ab8a5b62b 100644
--- a/app/Imports/IrelandEventsImport.php
+++ b/app/Imports/IrelandEventsImport.php
@@ -4,17 +4,15 @@
use App\Event;
use App\User;
-use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class IrelandEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class IrelandEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
// public function parseDate($date, $time) {
// $time = Date::excelToDateTimeObject($time);
@@ -72,6 +70,41 @@ public function model(array $row): ?Model
'latitude' => str_replace(',', '.', $row['latitude']),
'language' => 'en',
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/LuxembourgEventsImport.php b/app/Imports/LuxembourgEventsImport.php
index faaf2d34e..41649dfca 100644
--- a/app/Imports/LuxembourgEventsImport.php
+++ b/app/Imports/LuxembourgEventsImport.php
@@ -8,10 +8,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class LuxembourgEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class LuxembourgEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -47,6 +46,41 @@ public function model(array $row): ?Model
'latitude' => $row['latitude'],
'language' => strtolower($row['language']),
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/MagentaEventsImport.php b/app/Imports/MagentaEventsImport.php
index 256d0ac59..088d7858f 100644
--- a/app/Imports/MagentaEventsImport.php
+++ b/app/Imports/MagentaEventsImport.php
@@ -7,10 +7,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class MagentaEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class MagentaEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -46,6 +45,41 @@ public function model(array $row): ?Model
'latitude' => $row['latitude'],
'language' => strtolower($row['language']),
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/ReportedEventsImport.php b/app/Imports/ReportedEventsImport.php
index ee0b29534..3d2b0b2fc 100644
--- a/app/Imports/ReportedEventsImport.php
+++ b/app/Imports/ReportedEventsImport.php
@@ -10,10 +10,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class ReportedEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class ReportedEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -67,6 +66,41 @@ public function model(array $row): ?Model
'average_participant_age' => 10,
'percentage_of_females' => 50,
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/TelerikEventsImport.php b/app/Imports/TelerikEventsImport.php
index 58b3bb9ba..5662cd663 100644
--- a/app/Imports/TelerikEventsImport.php
+++ b/app/Imports/TelerikEventsImport.php
@@ -8,10 +8,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class TelerikEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class TelerikEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -48,6 +47,41 @@ public function model(array $row): ?Model
'longitude' => $row['longitude'],
'latitude' => $row['latitude'],
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/UKDigitAllCharityEventsImport.php b/app/Imports/UKDigitAllCharityEventsImport.php
index cfae5b1c8..1ec5fb084 100644
--- a/app/Imports/UKDigitAllCharityEventsImport.php
+++ b/app/Imports/UKDigitAllCharityEventsImport.php
@@ -8,10 +8,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class UKDigitAllCharityEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class UKDigitAllCharityEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -48,6 +47,41 @@ public function model(array $row): ?Model
'latitude' => $row['latitude'],
'language' => strtolower($row['language']),
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/Imports/UKDigitAllEventsImport.php b/app/Imports/UKDigitAllEventsImport.php
index 4811180ca..5f2041caf 100644
--- a/app/Imports/UKDigitAllEventsImport.php
+++ b/app/Imports/UKDigitAllEventsImport.php
@@ -8,10 +8,9 @@
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
-use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\Shared\Date;
-class UKDigitAllEventsImport extends DefaultValueBinder implements ToModel, WithCustomValueBinder, WithHeadingRow
+class UKDigitAllEventsImport extends BaseEventsImport implements ToModel, WithCustomValueBinder, WithHeadingRow
{
public function parseDate($date)
{
@@ -46,6 +45,41 @@ public function model(array $row): ?Model
'latitude' => $row['latitude'],
'language' => strtolower($row['language']),
'mass_added_for' => 'Excel',
+ 'recurring_event' => isset($row['recurring_event'])
+ ? $this->validateSingleChoice($row['recurring_event'], Event::RECURRING_EVENTS)
+ : null,
+
+ 'males_count' => isset($row['males_count']) ? (int) $row['males_count'] : null,
+ 'females_count' => isset($row['females_count']) ? (int) $row['females_count'] : null,
+ 'other_count' => isset($row['other_count']) ? (int) $row['other_count'] : null,
+
+ 'is_extracurricular_event' => isset($row['is_extracurricular_event'])
+ ? $this->parseBool($row['is_extracurricular_event'])
+ : false,
+
+ 'is_standard_school_curriculum' => isset($row['is_standard_school_curriculum'])
+ ? $this->parseBool($row['is_standard_school_curriculum'])
+ : false,
+
+ 'is_use_resource' => isset($row['is_use_resource'])
+ ? $this->parseBool($row['is_use_resource'])
+ : false,
+
+ 'activity_format' => isset($row['activity_format'])
+ ? $this->validateMultiChoice($row['activity_format'], Event::ACTIVITY_FORMATS)
+ : [],
+
+ 'ages' => isset($row['ages'])
+ ? $this->validateMultiChoice($row['ages'], Event::AGES)
+ : [],
+
+ 'duration' => isset($row['duration'])
+ ? $this->validateSingleChoice($row['duration'], Event::DURATIONS)
+ : null,
+
+ 'recurring_type' => isset($row['recurring_type'])
+ ? $this->validateSingleChoice($row['recurring_type'], Event::RECURRING_TYPES)
+ : null,
]);
$event->save();
diff --git a/app/MeetAndCodeRSSItem.php b/app/MeetAndCodeRSSItem.php
index bdff5460f..c8ac2afb6 100644
--- a/app/MeetAndCodeRSSItem.php
+++ b/app/MeetAndCodeRSSItem.php
@@ -60,6 +60,31 @@
*/
class MeetAndCodeRSSItem extends Model
{
+ protected $fillable = [
+ 'activity_format',
+ 'duration',
+ 'recurring_event',
+ 'recurring_type',
+ 'males_count',
+ 'females_count',
+ 'other_count',
+ 'is_extracurricular_event',
+ 'is_standard_school_curriculum',
+ 'is_use_resource',
+ 'ages'
+ ];
+
+ protected function casts(): array
+ {
+ return [
+ 'activity_format' => 'array',
+ 'is_extracurricular_event' => 'boolean',
+ 'is_standard_school_curriculum' => 'boolean',
+ 'ages' => 'array',
+ 'is_use_resource' => 'boolean',
+ ];
+ }
+
public function getCountryIso()
{
@@ -73,7 +98,6 @@ public function getCountryIso()
default:
return Country::where('name', 'like', $this->country)->first()->iso;
}
-
}
private function mapOrganisationTypes($organisation_type)
@@ -84,7 +108,6 @@ private function mapOrganisationTypes($organisation_type)
default:
return 'other';
}
-
}
private function mapActivityTypes($activity_type)
@@ -97,7 +120,6 @@ private function mapActivityTypes($activity_type)
default:
return 'other';
}
-
}
public function createEvent($user)
@@ -125,9 +147,20 @@ public function createEvent($user)
'end_date' => $this->end_date,
'longitude' => $this->lon,
'latitude' => $this->lat,
- 'geoposition' => $this->lat.','.$this->lon,
+ 'geoposition' => $this->lat . ',' . $this->lon,
'language' => MeetAndCodeHelper::getLanguage($this->link),
'mass_added_for' => 'RSS meet_and_code',
+ 'activity_format' => is_array($this->activity_format) ? $this->activity_format : [],
+ 'duration' => $this->duration,
+ 'recurring_event' => $this->recurring_event,
+ 'recurring_type' => $this->recurring_type,
+ 'males_count' => $this->males_count,
+ 'females_count' => $this->females_count,
+ 'other_count' => $this->other_count,
+ 'is_extracurricular_event' => $this->is_extracurricular_event,
+ 'is_standard_school_curriculum' => $this->is_standard_school_curriculum,
+ 'ages' => is_array($this->ages) ? $this->ages : [],
+ 'is_use_resource' => $this->is_use_resource,
]);
$event->save();
@@ -137,6 +170,5 @@ public function createEvent($user)
$event->themes()->attach(8);
return $event;
-
}
}
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index 31366704c..0d22c7105 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -9,9 +9,11 @@
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\View;
+use Illuminate\Support\Arr;
use Illuminate\Support\ServiceProvider;
use Illuminate\Validation\Rules\Password;
use Illuminate\Support\Facades\Blade;
+use Illuminate\Support\Facades\Lang;
class AppServiceProvider extends ServiceProvider
{
@@ -40,6 +42,7 @@ function ($view) {
$view->with('audiences', \App\Audience::all());
$view->with('activity_types', \App\ActivityType::list());
$view->with('countries', \App\Country::translated());
+ $view->with('languages', Arr::sort(Lang::get('base.languages')));
$view->with('active_countries', \App\Country::withEvents());
$view->with(
'themes',
diff --git a/app/Queries/EventsQuery.php b/app/Queries/EventsQuery.php
index 1894ae1d1..fd153e194 100644
--- a/app/Queries/EventsQuery.php
+++ b/app/Queries/EventsQuery.php
@@ -37,6 +37,13 @@ public static function store(Request $request)
abort(503, 'Title error');
}
+ if (!isset($request['participants_count'])) {
+ $request['participants_count'] = (int) $request['males_count'] + (int) $request['females_count'] + (int) $request['other_count'];
+ if ($request['participants_count'] > 0) {
+ $request['percentage_of_females'] = number_format((int) $request['females_count'] / (int) $request['participants_count'] * 100, 2);
+ }
+ }
+
$request['pub_date'] = Carbon::now();
$request['created'] = Carbon::now();
$request['updated'] = Carbon::now();
@@ -62,6 +69,14 @@ public static function store(Request $request)
$request['codeweek_for_all_participation_code'] = $codeweek_4_all_generated_code;
}
+ if (!empty($request['activity_format']) && is_string($request['activity_format'])) {
+ $request['activity_format'] = explode(',', $request['activity_format']);
+ }
+
+ if (!empty($request['ages']) && is_string($request['ages'])) {
+ $request['ages'] = explode(',', $request['ages']);
+ }
+
$event = Event::create($request->toArray());
if (! empty($request['tags'])) {
@@ -101,11 +116,26 @@ public static function update(Request $request, Event $event)
$request['latitude'] = explode(',', $request['geoposition'])[0];
$request['longitude'] = explode(',', $request['geoposition'])[1];
+ if (!isset($request['participants_count'])) {
+ $request['participants_count'] = (int) $request['males_count'] + (int) $request['females_count'] + (int) $request['other_count'];
+ if ($request['participants_count'] > 0) {
+ $request['percentage_of_females'] = number_format((int) $request['females_count'] / (int) $request['participants_count'] * 100, 2);
+ }
+ }
+
//In order to appear again in the list for the moderators
if ($event->status == 'REJECTED') {
$request['status'] = 'PENDING';
}
+ if (!empty($request['activity_format']) && is_string($request['activity_format'])) {
+ $request['activity_format'] = explode(',', $request['activity_format']);
+ }
+
+ if (!empty($request['ages']) && is_string($request['ages'])) {
+ $request['ages'] = explode(',', $request['ages']);
+ }
+
$event->update($request->toArray());
$request['theme'] = explode(',', $request['theme']);
diff --git a/app/Queries/SuperOrganiserQuery.php b/app/Queries/SuperOrganiserQuery.php
index ac8510d74..f10b52a90 100644
--- a/app/Queries/SuperOrganiserQuery.php
+++ b/app/Queries/SuperOrganiserQuery.php
@@ -20,7 +20,7 @@ public static function mine()
public static function winners($edition)
{
$winners = DB::table('events')
- ->where('status', '=', 'APPROVED')
+ ->where('status', 'APPROVED')
->whereNull('deleted_at')
->whereYear('end_date', '=', $edition)
->groupBy('creator_id')
diff --git a/app/User.php b/app/User.php
index 1f45713e1..f33e37b58 100644
--- a/app/User.php
+++ b/app/User.php
@@ -385,8 +385,8 @@ public function activities($edition)
{
return DB::table('events')
- ->where('creator_id', '=', $this->id)
- ->where('status', "=", "APPROVED")
+ ->where('creator_id', $this->id)
+ ->where('status', "APPROVED")
->whereNull('deleted_at')
->whereYear('end_date', '=', $edition)
->count();
@@ -397,7 +397,7 @@ public function reported($edition = null)
$query = DB::table('events')
->where('creator_id', '=', $this->id)
- ->where('status', "=", "APPROVED")
+ ->where('status', "APPROVED")
->whereNotNull('reported_at')
->whereNull('deleted_at');
@@ -429,7 +429,7 @@ public function influence($edition = null)
// Log::info("$nameInTag - $edition not in cache");
$taggedActivities = $this->taggedActivities()
- ->where('status', '=', 'APPROVED');
+ ->where('status', 'APPROVED');
if (!is_null($edition)) {
$taggedActivities->whereYear('events.created_at', '=', $edition);
diff --git a/database/migrations/2025_05_06_162855_add_new_fields_for_new_form_to_events_table.php b/database/migrations/2025_05_06_162855_add_new_fields_for_new_form_to_events_table.php
new file mode 100644
index 000000000..b7638eae4
--- /dev/null
+++ b/database/migrations/2025_05_06_162855_add_new_fields_for_new_form_to_events_table.php
@@ -0,0 +1,50 @@
+json('activity_format')->nullable();
+ $table->string('duration')->nullable()->after('activity_format');
+ $table->string('recurring_event')->nullable()->after('duration');
+ $table->string('recurring_type')->nullable()->after('recurring_event');
+ $table->integer('males_count')->nullable()->after('recurring_type');
+ $table->integer('females_count')->nullable()->after('males_count');
+ $table->integer('other_count')->nullable()->after('females_count');
+ $table->boolean('is_extracurricular_event')->default(false)->after('other_count');
+ $table->boolean('is_standard_school_curriculum')->default(false)->after('is_extracurricular_event');
+ $table->json('ages')->nullable()->after('is_standard_school_curriculum');
+ $table->boolean('is_use_resource')->default(false)->after('ages');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('events', function (Blueprint $table) {
+ $table->dropColumn([
+ 'activity_format',
+ 'duration',
+ 'recurring_event',
+ 'recurring_type',
+ 'males_count',
+ 'females_count',
+ 'other_count',
+ 'is_extracurricular_event',
+ 'is_standard_school_curriculum',
+ 'ages',
+ 'is_use_resource',
+ ]);
+ });
+ }
+};
diff --git a/database/migrations/2025_05_15_102937_add_new_fields_for_new_form_to_meet_and_code_r_s_s_items_table.php b/database/migrations/2025_05_15_102937_add_new_fields_for_new_form_to_meet_and_code_r_s_s_items_table.php
new file mode 100644
index 000000000..995db3c3c
--- /dev/null
+++ b/database/migrations/2025_05_15_102937_add_new_fields_for_new_form_to_meet_and_code_r_s_s_items_table.php
@@ -0,0 +1,38 @@
+json('activity_format')->nullable();
+ $table->string('duration')->nullable()->after('activity_format');
+ $table->string('recurring_event')->nullable()->after('duration');
+ $table->string('recurring_type')->nullable()->after('recurring_event');
+ $table->integer('males_count')->nullable()->after('recurring_type');
+ $table->integer('females_count')->nullable()->after('males_count');
+ $table->integer('other_count')->nullable()->after('females_count');
+ $table->boolean('is_extracurricular_event')->default(false)->after('other_count');
+ $table->boolean('is_standard_school_curriculum')->default(false)->after('is_extracurricular_event');
+ $table->json('ages')->nullable()->after('is_standard_school_curriculum');
+ $table->boolean('is_use_resource')->default(false)->after('ages');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('meet_and_code_r_s_s_items', function (Blueprint $table) {
+ //
+ });
+ }
+};
diff --git a/public/images/activity/banner.png b/public/images/activity/banner.png
new file mode 100644
index 000000000..4606ddf0d
Binary files /dev/null and b/public/images/activity/banner.png differ
diff --git a/public/images/check-white.svg b/public/images/check-white.svg
new file mode 100644
index 000000000..2edf088d0
--- /dev/null
+++ b/public/images/check-white.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/images/icon_error.svg b/public/images/icon_error.svg
new file mode 100644
index 000000000..de1cef492
--- /dev/null
+++ b/public/images/icon_error.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/images/icon_image.svg b/public/images/icon_image.svg
new file mode 100644
index 000000000..cc27b798d
--- /dev/null
+++ b/public/images/icon_image.svg
@@ -0,0 +1,5 @@
+
diff --git a/public/images/marker-blue.svg b/public/images/marker-blue.svg
new file mode 100644
index 000000000..69337484a
--- /dev/null
+++ b/public/images/marker-blue.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/public/images/marker-orange.svg b/public/images/marker-orange.svg
new file mode 100644
index 000000000..a58a8c519
--- /dev/null
+++ b/public/images/marker-orange.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/public/images/star.svg b/public/images/star.svg
new file mode 100644
index 000000000..26db2ca91
--- /dev/null
+++ b/public/images/star.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/assets/sass/app.scss b/resources/assets/sass/app.scss
index 34fa24498..0e049f9ce 100644
--- a/resources/assets/sass/app.scss
+++ b/resources/assets/sass/app.scss
@@ -12,6 +12,7 @@
@import "components/pagination";
@import "components/calendar";
@import "components/table";
+@import "components/tinymce";
//Import pages
@import "pages";
diff --git a/resources/assets/sass/components/forms.scss b/resources/assets/sass/components/forms.scss
index e79471a5e..90d8e2ae9 100644
--- a/resources/assets/sass/components/forms.scss
+++ b/resources/assets/sass/components/forms.scss
@@ -1,4 +1,18 @@
+.custom-geo-input {
+ input {
+ width: 100%;
+ border: 2px solid #a4b8d9;
+ border-radius: 24px;
+ height: 48px;
+ font-size: 20px;
+ line-height: 28px;
+ padding: 0 16px;
+ color: #20262C;
+ }
+}
+
.multiselect.multi-select {
+
&.multiselect--active {
.multiselect--values {
display: none;
@@ -9,6 +23,7 @@
}
.multiselect__tags{
+ cursor: pointer;
border-radius: 24px;
min-height: 46px;
border: 2px solid #A4B8D9;
@@ -25,13 +40,13 @@
height: 100%;
}
.multiselect__placeholder,
- .multiselect__single{
+ .multiselect__tags .multiselect__single{
padding: 0;
margin: 0;
font-size: 16px;
font-style: normal;
font-weight: 400;
- color: #333E48;
+ color: #20262C;
}
.multiselect__placeholder {
max-width: 100%;
@@ -41,6 +56,7 @@
text-overflow: ellipsis;
line-height: 18px;
}
+
.multiselect__single {
padding-top: 6px;
color: #333E48;
@@ -54,7 +70,7 @@
height: 8px;
width: 8px;
border: none;
- border-left: 2px solid #5F718A;
+ border-left: 2px solid #1C4DA1;
transform: rotate(45deg) !important;
}
.multiselect__select:after {
@@ -66,7 +82,7 @@
height: 8px;
width: 8px;
border: none;
- border-left: 2px solid #5F718A;
+ border-left: 2px solid #1C4DA1;
transform: rotate(-45deg);
}
.multiselect__tags-wrap{
@@ -78,6 +94,83 @@
margin: 0;
}
}
+
+ &.large-text {
+ .multiselect__placeholder,
+ .multiselect__single{
+ font-size: 20px;
+ line-height: 24px;
+ }
+ .multiselect__placeholder {
+ line-height: 24px;
+ }
+ .multiselect__input {
+ line-height: 24px;
+ }
+ .multiselect__tags{
+ padding: 9px 40px 8px 16px;
+ min-height: 48px;
+ }
+ }
+
+ &.new-theme {
+ .multiselect__placeholder {
+ display: block;
+ }
+ .multiselect__tags {
+ border-radius: 24px !important;
+ }
+
+ .multiselect__content-wrapper {
+ border: 2px solid #ADB2B6;
+ border-radius: 12px;
+ }
+
+ &.multiple .multiselect__content-wrapper {
+ overflow: hidden;
+ padding: 16px 12px 16px 0;
+
+ .multiselect__content {
+ min-height: 1px;
+ max-height: calc(300px - 32px);
+ overflow: auto;
+
+ &::-webkit-scrollbar {
+ border-radius: 6px;
+ width: 12px;
+ display: block;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: #E8EDF6;
+ border-radius: 8px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #1C4DA1;
+ border-radius: 6px;
+ }
+ }
+ }
+
+ .multiselect__option {
+ padding-left: 24px;
+ font-size: 20px;
+ &.multiselect__option--highlight {
+ background-color: #eee;
+ color: #20262C;
+ }
+ &.multiselect__option--selected {
+ background-color: transparent;
+ &:hover {
+ background-color: #eee;
+ }
+ }
+ &:after {
+ display: none;
+ }
+ }
+ }
}
.multiselect .multiselect__tags{
diff --git a/resources/assets/sass/components/tinymce.scss b/resources/assets/sass/components/tinymce.scss
new file mode 100644
index 000000000..518111cb8
--- /dev/null
+++ b/resources/assets/sass/components/tinymce.scss
@@ -0,0 +1,27 @@
+.custom-tinymce {
+ .tox-tinymce {
+ border: 2px solid #a4b8d9;
+ border-radius: 24px;
+ }
+
+ .tox-editor-container {
+ .tox-menubar {
+ padding: 0 12px;
+ }
+ }
+ .tox-toolbar-overlord {
+ .tox-toolbar__primary {
+ .tox-toolbar__group:first-child {
+ padding-left: 12px;
+ }
+ .tox-toolbar__group:last-child {
+ padding-right: 12px;
+ }
+ }
+ }
+
+ .tox .tox-statusbar {
+ height: 24px;
+ padding: 4px 16px 4px 16px;
+ }
+}
diff --git a/resources/excel/sample.xlsx b/resources/excel/sample.xlsx
index b62539dbe..a351ec147 100644
Binary files a/resources/excel/sample.xlsx and b/resources/excel/sample.xlsx differ
diff --git a/resources/js/app.js b/resources/js/app.js
index 53c4e4f73..7ef78419b 100644
--- a/resources/js/app.js
+++ b/resources/js/app.js
@@ -1,5 +1,6 @@
import './bootstrap';
import { createApp } from 'vue';
+import ActivityForm from './components/activity-form/index.vue';
import ResourceForm from './components/ResourceForm.vue';
import ResourceCard from './components/ResourceCard.vue';
import ResourcePill from './components/ResourcePill.vue';
@@ -15,6 +16,8 @@ import PictureForm from "./components/PictureForm.vue";
import Flash from "./components/Flash.vue";
import InputTags from "./components/InputTags.vue";
import ReportEvent from "./components/ReportEvent.vue";
+import EventCard from "./components/EventCard.vue";
+import EventDetail from "./components/EventDetail.vue";
import SearchPageComponent from "./components/SearchPageComponent.vue";
// import { createI18n } from 'vue-i18n';
@@ -34,6 +37,7 @@ app.use(i18nVue, {
return await langs[`../lang/${lang}.json`]();
}
})
+app.component('ActivityForm', ActivityForm);
app.component('ResourceForm', ResourceForm);
app.component('ResourceCard', ResourceCard);
app.component('ResourcePill', ResourcePill);
@@ -52,4 +56,6 @@ app.component('InputTags', InputTags);
app.component('SearchPageComponent', SearchPageComponent);
app.component('AvatarForm', AvatarForm);
app.component('PartnerGallery', PartnerGallery);
+app.component('EventCard', EventCard);
+app.component('EventDetail', EventDetail);
app.mount("#app");
diff --git a/resources/js/components/AutocompleteGeo.vue b/resources/js/components/AutocompleteGeo.vue
index 38a9562e8..f3619d443 100644
--- a/resources/js/components/AutocompleteGeo.vue
+++ b/resources/js/components/AutocompleteGeo.vue
@@ -37,21 +37,26 @@ export default {
geoposition: String,
location: String
},
- setup(props) {
+ emits: ['onChange'],
+ setup(props, { emit }) {
const item = ref(props.value ? { name: props.value } : null);
const items = ref(null);
const template = ItemTemplate;
- const inputAttrs = {
+ const inputAttrs = ref({
placeholder: props.placeholder,
name: props.name,
autocomplete: "off"
- };
+ });
const localGeoposition = ref(props.geoposition);
const initialLocation = props.location;
-
+ watch(() => props.placeholder, () => {
+ inputAttrs.value.placeholder = props.placeholder;
+ });
const itemSelected = (selectedItem) => {
+ emit('onChange', { location: selectedItem?.name || '' });
+
if (selectedItem && selectedItem.name && selectedItem.magicKey) {
const baseURL = "/api/proxy/geocode"; // Update to your Laravel endpoint
axios.get(baseURL, {
@@ -66,7 +71,16 @@ export default {
window.map.setView([candidate.location.y, candidate.location.x], 16);
}
const countryIso2 = findCountry(candidate.attributes.Country).iso2;
- document.getElementById('id_country').value = countryIso2;
+
+ emit('onChange', {
+ location: selectedItem?.name || '',
+ geoposition: [candidate.location.y, candidate.location.x],
+ country_iso: countryIso2 || '',
+ });
+
+ if (document.getElementById('id_country')) {
+ document.getElementById('id_country').value = countryIso2;
+ }
}).catch(error => {
console.error('Error:', error);
});
diff --git a/resources/js/components/DateTime.vue b/resources/js/components/DateTime.vue
index f5a624413..6b13b9be6 100644
--- a/resources/js/components/DateTime.vue
+++ b/resources/js/components/DateTime.vue
@@ -1,7 +1,7 @@
+ {{ fromText }} - {{ toText }}
+
+ Format of the activity:
+
+ {{ activityFormatOptionsMap[format] }}
+
+ {{ $t('event.activitytype.label') }}:
+
+
+ {{ $t(`event.activitytype.${event.activity_type}`) }}
+
+
+ {{ $t('resources.Languages') }}:
+
+ {{ $t(`base.languages.${event.language}`) }}
+ Recurring event:
+ {{ recurringFrequentlyMap[event.recurring_event] }}
+
+ {{ durationOptionsMap[event.duration] }}
+
+ {{ recurringTypeOptionsMap[event.recurring_type] }}
+
+ {{ $t('event.audience_title') }}:
+
+ {{ $t(`event.audience.${audience.name}`) }}
+ Age range:
+ {{ ageOptionsMap[ageId] }}
+ Themes:
+ {{ $t(`event.theme.${theme.name}`) }}
+
+ {{ $t('event.address.label') }}:
+
+ {{ event.location }}
+
+ Activity description:
+ Email address:
+ {{ event.contact_person }}
+
+
+
+
+
+ {{ text }}
+
+
+
+
+
+
+ {{ event.title }}
+
+
{{ year }}
- {{ countries }}
- {{ audiences }}
- {{ themes }}
- {{ types }}
- + {{ stepItem.name }} +
+