<?php
/*
* This file is part of the PrestaSitemapBundle package.
*
* (c) PrestaConcept <https://prestaconcept.net>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Presta\SitemapBundle\Sitemap\Url;
use DateTimeInterface;
use Presta\SitemapBundle\Sitemap\Utils;
/**
* First class citizen of sitemaps.
*
* https://developers.google.com/search/docs/guides/create-URLs
*/
class UrlConcrete implements Url
{
public const CHANGEFREQ_ALWAYS = 'always';
public const CHANGEFREQ_HOURLY = 'hourly';
public const CHANGEFREQ_DAILY = 'daily';
public const CHANGEFREQ_WEEKLY = 'weekly';
public const CHANGEFREQ_MONTHLY = 'monthly';
public const CHANGEFREQ_YEARLY = 'yearly';
public const CHANGEFREQ_NEVER = 'never';
/**
* @var string
*/
protected $loc;
/**
* @var DateTimeInterface|null
*/
protected $lastmod;
/**
* @var string|null
*/
protected $changefreq;
/**
* @var float|null
*/
protected $priority;
/**
* Construct a new basic url
*
* @param string $loc Absolute url
* @param DateTimeInterface|null $lastmod Last modification date
* @param string|null $changefreq Change frequency
* @param float|string|int|null $priority Priority
*/
public function __construct(
string $loc,
DateTimeInterface $lastmod = null,
string $changefreq = null,
$priority = null
) {
$this->setLoc($loc);
$this->setLastmod($lastmod);
$this->setChangefreq($changefreq);
$this->setPriority($priority);
}
/**
* @param string $loc
*
* @return UrlConcrete
*/
public function setLoc(string $loc): self
{
$this->loc = $loc;
return $this;
}
/**
* @return string
*/
public function getLoc(): string
{
return $this->loc;
}
/**
* @param DateTimeInterface|null $lastmod
*
* @return UrlConcrete
*/
public function setLastmod(?DateTimeInterface $lastmod): self
{
$this->lastmod = $lastmod;
return $this;
}
/**
* @return DateTimeInterface|null
*/
public function getLastmod(): ?DateTimeInterface
{
return $this->lastmod;
}
/**
* Define the change frequency of this entry
*
* @param string|null $changefreq Define the change frequency
*
* @return UrlConcrete
*/
public function setChangefreq(string $changefreq = null): self
{
$frequencies = [
self::CHANGEFREQ_ALWAYS,
self::CHANGEFREQ_HOURLY,
self::CHANGEFREQ_DAILY,
self::CHANGEFREQ_WEEKLY,
self::CHANGEFREQ_MONTHLY,
self::CHANGEFREQ_YEARLY,
self::CHANGEFREQ_NEVER,
null,
];
if (!in_array($changefreq, $frequencies)) {
throw new \RuntimeException(
sprintf(
'The value "%s" is not supported by the option changefreq.' .
' See http://www.sitemaps.org/protocol.html#xmlTagDefinitions',
$changefreq
)
);
}
$this->changefreq = $changefreq;
return $this;
}
/**
* return the change frequency
*
* @return string|null
*/
public function getChangefreq(): ?string
{
return $this->changefreq;
}
/**
* Define the priority of this entry
*
* @param float|string|int|null $priority Define the priority
*
* @return UrlConcrete
*/
public function setPriority($priority = null): self
{
if ($priority === null) {
return $this;
}
if (is_string($priority) || is_int($priority)) {
$priority = (float)$priority;
}
if (is_float($priority) && $priority >= 0 && $priority <= 1) {
$this->priority = round($priority, 1);
} else {
throw new \RuntimeException(
sprintf(
'The value "%s" is not supported by the option priority,' .
' it must be a numeric between 0.0 and 1.0.' .
' See http://www.sitemaps.org/protocol.html#xmlTagDefinitions',
$priority
)
);
}
return $this;
}
/**
* @return float|null
*/
public function getPriority(): ?float
{
return $this->priority;
}
/**
* @inheritdoc
*/
public function toXml(): string
{
$xml = '<url><loc>' . Utils::encode($this->getLoc()) . '</loc>';
$lastmod = $this->getLastmod();
if ($lastmod) {
$xml .= '<lastmod>' . $lastmod->format('c') . '</lastmod>';
}
$changefreq = $this->getChangefreq();
if ($changefreq) {
$xml .= '<changefreq>' . $changefreq . '</changefreq>';
}
$priority = $this->getPriority();
if ($priority) {
$xml .= '<priority>' . number_format($priority, 1) . '</priority>';
}
$xml .= '</url>';
return $xml;
}
/**
* @inheritdoc
*/
public function getCustomNamespaces(): array
{
return []; // basic url has no namespace. see decorated urls
}
}