- var_dump: documentation ( source)
- preg_match: documentation ( source)
- trim: documentation ( source)
- strtolower: documentation ( source)
<?php
class Version
{
const STAGE_ALPHA = 1;
const STAGE_BETA = 2;
const STAGE_RC = 3;
const STAGE_RELEASE = 4;
public $major;
public $minor;
public $release;
public $stageName;
public $stageNo;
private $stageMap = [
'alpha' => self::STAGE_ALPHA,
'beta' => self::STAGE_BETA,
'rc' => self::STAGE_RC,
];
/**
* @param string $version
* @throws \Exception
*/
public function __construct($version)
{
static $tagNameExpr = '#
^
v?
(?P<major>[0-9]+)
\.
(?P<minor>[0-9]+)
(?:\.(?P<release>[0-9]+))?
(?:-
(?P<stage>alpha|beta|rc)
(?:(?P<stageno>\d+))?
)?
$
#ix';
if (!preg_match($tagNameExpr, trim(strtolower($version)), $match)) {
throw new \Exception('Invalid version spec string');
}
$this->major = $match['major'];
$this->minor = $match['minor'];
$this->release = isset($match['release']) ? (int)$match['release'] : null;
$this->stageName = isset($match['stage']) ? $match['stage'] : '';
$this->stageNo = isset($match['stageno']) ? $match['stageno'] : null;
}
/**
* @return string
*/
public function __toString()
{
return "$this->major.$this->minor."
. ($this->release ?: 0)
. ($this->stageNo ? '-' . $this->stageName . $this->stageNo : '');
}
/**
* @param string[] $stages
* @return bool
*/
public function isValidNextStage(array $stages)
{
$latestStageType = $latestStagePoint = 0;
foreach ($stages as $stage) {
if ($stage === '') {
// a release already exists
return false;
}
if (preg_match('#^(alpha|beta|rc)(\d+)$#', strtolower($stage), $match)) {
if ($this->stageMap[$match[1]] > $latestStageType) {
$latestStageType = $this->stageMap[$match[1]];
$latestStagePoint = 0;
} else if ($this->stageMap[$match[1]] === $latestStageType && $match[2] > $latestStagePoint) {
$latestStagePoint = (int)$match[2];
}
}
}
if (!$this->stageName) {
// this is a release and one does not yet exist
return true;
}
if (!isset($this->stageMap[$this->stageName])) {
// invalid new stage
return false;
}
if ($this->stageMap[$this->stageName] < $latestStageType) {
// new stage lower than latest
return false;
}
if ($this->stageMap[$this->stageName] > $latestStageType) {
// new stage greater than latest, number must be 1
if (!isset($this->stageNo)) {
$this->stageNo = 1;
return true;
}
return $this->stageNo === 1;
}
if (!isset($this->stageNo)) {
$this->stageNo = $latestStagePoint + 1;
return true;
}
return $this->stageNo === $latestStagePoint + 1;
}
}
var_dump(new Version('1.12-beta'));