phase 9
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Job;
|
||||
use App\Models\JobCategory;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
class SitemapService
|
||||
{
|
||||
/**
|
||||
* Generate XML sitemap
|
||||
*/
|
||||
public function generateSitemap(): string
|
||||
{
|
||||
$xml = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');
|
||||
|
||||
// Add homepage
|
||||
$this->addUrl($xml, route('home'), now(), 'daily', '1.0');
|
||||
|
||||
// Add jobs index
|
||||
$this->addUrl($xml, route('jobs.index'), now(), 'daily', '0.9');
|
||||
|
||||
// Add remote jobs
|
||||
$this->addUrl($xml, route('jobs.remote'), now(), 'daily', '0.9');
|
||||
|
||||
// Add categories
|
||||
$categories = JobCategory::all();
|
||||
foreach ($categories as $category) {
|
||||
$this->addUrl(
|
||||
$xml,
|
||||
route('jobs.category', $category->slug),
|
||||
$category->updated_at,
|
||||
'daily',
|
||||
'0.8'
|
||||
);
|
||||
}
|
||||
|
||||
// Add active jobs
|
||||
$jobs = Job::where(function ($query) {
|
||||
$query->whereNull('expires_at')
|
||||
->orWhere('expires_at', '>', now());
|
||||
})
|
||||
->orderBy('posted_at', 'desc')
|
||||
->limit(10000) // Limit to 10k most recent jobs
|
||||
->get(['id', 'posted_at', 'updated_at']);
|
||||
|
||||
foreach ($jobs as $job) {
|
||||
$this->addUrl(
|
||||
$xml,
|
||||
route('jobs.show', $job->id),
|
||||
$job->updated_at ?? $job->posted_at,
|
||||
'weekly',
|
||||
'0.7'
|
||||
);
|
||||
}
|
||||
|
||||
return $xml->asXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add URL to sitemap
|
||||
*/
|
||||
private function addUrl(
|
||||
\SimpleXMLElement $xml,
|
||||
string $url,
|
||||
?\DateTimeInterface $lastmod = null,
|
||||
string $changefreq = 'weekly',
|
||||
string $priority = '0.5'
|
||||
): void {
|
||||
$urlElement = $xml->addChild('url');
|
||||
$urlElement->addChild('loc', htmlspecialchars($url));
|
||||
|
||||
if ($lastmod) {
|
||||
$urlElement->addChild('lastmod', $lastmod->format('Y-m-d'));
|
||||
}
|
||||
|
||||
$urlElement->addChild('changefreq', $changefreq);
|
||||
$urlElement->addChild('priority', $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate sitemap index for large sites
|
||||
*/
|
||||
public function generateSitemapIndex(): string
|
||||
{
|
||||
$xml = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></sitemapindex>');
|
||||
|
||||
// Add main sitemap
|
||||
$this->addSitemapToIndex($xml, route('sitemap.main'), now());
|
||||
|
||||
// Add jobs sitemap
|
||||
$this->addSitemapToIndex($xml, route('sitemap.jobs'), now());
|
||||
|
||||
return $xml->asXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add sitemap to index
|
||||
*/
|
||||
private function addSitemapToIndex(\SimpleXMLElement $xml, string $url, \DateTimeInterface $lastmod): void
|
||||
{
|
||||
$sitemapElement = $xml->addChild('sitemap');
|
||||
$sitemapElement->addChild('loc', htmlspecialchars($url));
|
||||
$sitemapElement->addChild('lastmod', $lastmod->format('Y-m-d'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate main sitemap (static pages and categories)
|
||||
*/
|
||||
public function generateMainSitemap(): string
|
||||
{
|
||||
$xml = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');
|
||||
|
||||
// Add homepage
|
||||
$this->addUrl($xml, route('home'), now(), 'daily', '1.0');
|
||||
|
||||
// Add jobs index
|
||||
$this->addUrl($xml, route('jobs.index'), now(), 'daily', '0.9');
|
||||
|
||||
// Add remote jobs
|
||||
$this->addUrl($xml, route('jobs.remote'), now(), 'daily', '0.9');
|
||||
|
||||
// Add categories
|
||||
$categories = JobCategory::all();
|
||||
foreach ($categories as $category) {
|
||||
$this->addUrl(
|
||||
$xml,
|
||||
route('jobs.category', $category->slug),
|
||||
$category->updated_at,
|
||||
'daily',
|
||||
'0.8'
|
||||
);
|
||||
}
|
||||
|
||||
return $xml->asXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate jobs sitemap
|
||||
*/
|
||||
public function generateJobsSitemap(): string
|
||||
{
|
||||
$xml = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');
|
||||
|
||||
// Add active jobs
|
||||
$jobs = Job::where(function ($query) {
|
||||
$query->whereNull('expires_at')
|
||||
->orWhere('expires_at', '>', now());
|
||||
})
|
||||
->orderBy('posted_at', 'desc')
|
||||
->limit(50000) // Sitemap limit
|
||||
->get(['id', 'posted_at', 'updated_at']);
|
||||
|
||||
foreach ($jobs as $job) {
|
||||
$this->addUrl(
|
||||
$xml,
|
||||
route('jobs.show', $job->id),
|
||||
$job->updated_at ?? $job->posted_at,
|
||||
'weekly',
|
||||
'0.7'
|
||||
);
|
||||
}
|
||||
|
||||
return $xml->asXML();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user