Files
jobifygarden/app/Repositories/JobRepository.php
T
2026-04-03 20:33:24 +03:00

211 lines
5.9 KiB
PHP

<?php
namespace App\Repositories;
use App\Models\Job;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Collection;
class JobRepository
{
/**
* Get all active jobs with pagination
*/
public function getActiveJobs(int $perPage = 15): LengthAwarePaginator
{
return Job::with(['source', 'category', 'jobLocation'])
->active()
->latest('posted_at')
->paginate($perPage);
}
/**
* Find a job by ID
*/
public function find(int $id): ?Job
{
return Job::with(['source', 'category', 'jobLocation'])->find($id);
}
/**
* Get jobs by category
*/
public function getByCategory(int $categoryId, int $perPage = 15): LengthAwarePaginator
{
return Job::with(['source', 'category', 'jobLocation'])
->active()
->where('job_category_id', $categoryId)
->latest('posted_at')
->paginate($perPage);
}
/**
* Get jobs by location
*/
public function getByLocation(int $locationId, int $perPage = 15): LengthAwarePaginator
{
return Job::with(['source', 'category', 'jobLocation'])
->active()
->where('job_location_id', $locationId)
->latest('posted_at')
->paginate($perPage);
}
/**
* Get remote jobs
*/
public function getRemoteJobs(int $perPage = 15): LengthAwarePaginator
{
return Job::with(['source', 'category', 'jobLocation'])
->active()
->remote()
->latest('posted_at')
->paginate($perPage);
}
/**
* Get recent jobs (last N days)
*/
public function getRecentJobs(int $days = 7, int $perPage = 15): LengthAwarePaginator
{
return Job::with(['source', 'category', 'jobLocation'])
->active()
->where(function ($query) use ($days) {
$query->where('posted_at', '>=', now()->subDays($days))
->orWhere(function ($q) use ($days) {
$q->whereNull('posted_at')
->where('created_at', '>=', now()->subDays($days));
});
})
->latest('posted_at')
->paginate($perPage);
}
/**
* Get jobs by experience level
*/
public function getByExperienceLevel(string $level, int $perPage = 15): LengthAwarePaginator
{
return Job::with(['source', 'category', 'jobLocation'])
->active()
->experienceLevel($level)
->latest('posted_at')
->paginate($perPage);
}
/**
* Get jobs by type
*/
public function getByJobType(string $type, int $perPage = 15): LengthAwarePaginator
{
return Job::with(['source', 'category', 'jobLocation'])
->active()
->ofType($type)
->latest('posted_at')
->paginate($perPage);
}
/**
* Get similar jobs (same category, exclude current)
*/
public function getSimilarJobs(Job $job, int $limit = 5): Collection
{
return Job::with(['source', 'category', 'jobLocation'])
->active()
->where('id', '!=', $job->id)
->where('job_category_id', $job->job_category_id)
->latest('posted_at')
->limit($limit)
->get();
}
/**
* Get featured jobs (most recent from diverse sources)
*/
public function getFeaturedJobs(int $limit = 10): Collection
{
// First, build a subquery with window function
$subQuery = \DB::table('jobs')
->selectRaw('jobs.*, ROW_NUMBER() OVER (PARTITION BY job_source_id ORDER BY posted_at DESC) as rn')
->whereNull('deleted_at')
->where(function ($query) {
$query->whereNull('expires_at')
->orWhere('expires_at', '>', now());
});
// Then query from that subquery filtering by rn
// Use withoutGlobalScopes to prevent SoftDeletes from adding WHERE clause
return Job::withoutGlobalScopes()
->with(['source', 'category', 'jobLocation'])
->fromSub($subQuery, 'ranked_jobs')
->whereRaw('ranked_jobs.rn <= 2')
->orderBy('posted_at', 'desc')
->limit($limit)
->get();
}
/**
* Get job statistics
*/
public function getStatistics(): array
{
$total = Job::count();
$active = Job::active()->count();
$remote = Job::active()->remote()->count();
$recentlyAdded = Job::where('created_at', '>=', now()->subDays(7))->count();
$topCategories = Job::active()
->select('job_category_id', \DB::raw('COUNT(*) as count'))
->whereNotNull('job_category_id')
->groupBy('job_category_id')
->orderBy('count', 'desc')
->limit(5)
->with('category')
->get();
return [
'total_jobs' => $total,
'active_jobs' => $active,
'remote_jobs' => $remote,
'recently_added' => $recentlyAdded,
'top_categories' => $topCategories,
];
}
/**
* Create a new job
*/
public function create(array $data): Job
{
return Job::create($data);
}
/**
* Update a job
*/
public function update(Job $job, array $data): bool
{
return $job->update($data);
}
/**
* Delete a job
*/
public function delete(Job $job): bool
{
return $job->delete();
}
/**
* Get jobs count by source
*/
public function getCountBySource(): Collection
{
return Job::with('source')
->select('job_source_id', \DB::raw('COUNT(*) as count'))
->groupBy('job_source_id')
->orderBy('count', 'desc')
->get();
}
}