109 lines
3.5 KiB
PHP
109 lines
3.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Group;
|
|
use App\Models\GroupRecruitmentProfile;
|
|
use App\Models\User;
|
|
|
|
class GroupRecruitmentService
|
|
{
|
|
public function __construct(
|
|
private readonly GroupHistoryService $history,
|
|
private readonly NotificationService $notifications,
|
|
) {
|
|
}
|
|
|
|
public function upsert(Group $group, array $attributes, User $actor): GroupRecruitmentProfile
|
|
{
|
|
$profile = GroupRecruitmentProfile::query()->firstOrNew([
|
|
'group_id' => $group->id,
|
|
]);
|
|
|
|
$before = $profile->exists ? $profile->only([
|
|
'is_recruiting',
|
|
'headline',
|
|
'description',
|
|
'roles_json',
|
|
'skills_json',
|
|
'contact_mode',
|
|
'visibility',
|
|
]) : null;
|
|
|
|
$profile->fill([
|
|
'is_recruiting' => (bool) ($attributes['is_recruiting'] ?? false),
|
|
'headline' => $attributes['headline'] ?? null,
|
|
'description' => $attributes['description'] ?? null,
|
|
'roles_json' => $this->normalizeList($attributes['roles_json'] ?? []),
|
|
'skills_json' => $this->normalizeList($attributes['skills_json'] ?? []),
|
|
'contact_mode' => $attributes['contact_mode'] ?? null,
|
|
'visibility' => (string) ($attributes['visibility'] ?? 'public'),
|
|
])->save();
|
|
|
|
if ($profile->is_recruiting && $profile->visibility === 'public') {
|
|
foreach ($group->follows()->with('user.profile')->get() as $follow) {
|
|
if ($follow->user) {
|
|
$this->notifications->notifyGroupRecruitmentUpdated($follow->user, $actor, $group, $profile);
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->history->record(
|
|
$group,
|
|
$actor,
|
|
'recruitment_updated',
|
|
$profile->is_recruiting ? 'Enabled or updated recruitment profile.' : 'Disabled recruitment profile.',
|
|
'group_recruitment_profile',
|
|
(int) $profile->id,
|
|
$before,
|
|
$profile->only([
|
|
'is_recruiting',
|
|
'headline',
|
|
'description',
|
|
'roles_json',
|
|
'skills_json',
|
|
'contact_mode',
|
|
'visibility',
|
|
]),
|
|
);
|
|
|
|
return $profile->fresh();
|
|
}
|
|
|
|
public function payloadForGroup(Group $group): ?array
|
|
{
|
|
$profile = $group->relationLoaded('recruitmentProfile')
|
|
? $group->recruitmentProfile
|
|
: $group->recruitmentProfile()->first();
|
|
|
|
if (! $profile) {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
'id' => (int) $profile->id,
|
|
'is_recruiting' => (bool) $profile->is_recruiting,
|
|
'headline' => $profile->headline,
|
|
'description' => $profile->description,
|
|
'roles' => array_values(array_filter($profile->roles_json ?? [])),
|
|
'skills' => array_values(array_filter($profile->skills_json ?? [])),
|
|
'contact_mode' => $profile->contact_mode,
|
|
'visibility' => $profile->visibility,
|
|
'updated_at' => $profile->updated_at?->toISOString(),
|
|
'roles_options' => config('groups.recruitment.roles', []),
|
|
'skills_options' => config('groups.recruitment.skills', []),
|
|
];
|
|
}
|
|
|
|
private function normalizeList(array $items): array
|
|
{
|
|
return collect($items)
|
|
->map(fn ($item): string => trim((string) $item))
|
|
->filter()
|
|
->unique()
|
|
->values()
|
|
->all();
|
|
}
|
|
} |