Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
100.00% |
1 / 1 |
|
100.00% |
13 / 13 |
CRAP | |
100.00% |
59 / 59 |
Range | |
100.00% |
1 / 1 |
|
100.00% |
13 / 13 |
28 | |
100.00% |
59 / 59 |
setValidator | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
getValidator | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getParser | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
setParser | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
getPatternDescription | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
setPatternDescription | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
addRangeSpec | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
getRange | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
addStringItemToRange | |
100.00% |
1 / 1 |
5 | |
100.00% |
13 / 13 |
|||
addItem | |
100.00% |
1 / 1 |
3 | |
100.00% |
5 / 5 |
|||
addRange | |
100.00% |
1 / 1 |
3 | |
100.00% |
6 / 6 |
|||
containsValue | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
getRangeSpec | |
100.00% |
1 / 1 |
7 | |
100.00% |
20 / 20 |
<?php declare(strict_types = 1); | |
/** | |
* @package: pvc | |
* @author: Doug Wilbourne (dougwilbourne@gmail.com) | |
* @version: 1.0 | |
*/ | |
namespace pvc\range; | |
use pvc\parser\ParserInterface; | |
use pvc\validator\base\ValidatorInterface; | |
abstract class Range | |
{ | |
/** | |
* @var ParserInterface | |
*/ | |
protected ParserInterface $rangeElementParser; | |
/** | |
* @var ValidatorInterface | |
*/ | |
protected ValidatorInterface $rangeElementValidator; | |
/** | |
* @var array[int]mixed | |
*/ | |
protected array $range = []; | |
/** | |
* @var string | |
*/ | |
protected string $patternDescription; | |
/** | |
* @function setValidator | |
* @param ValidatorInterface $validator | |
*/ | |
public function setValidator(ValidatorInterface $validator) : void | |
{ | |
$this->rangeElementValidator = $validator; | |
} | |
/** | |
* @function getValidator | |
* @return ValidatorInterface | |
*/ | |
public function getValidator(): ValidatorInterface | |
{ | |
return $this->rangeElementValidator; | |
} | |
/** | |
* @function getParser | |
* @return ParserInterface | |
*/ | |
public function getParser(): ParserInterface | |
{ | |
return $this->rangeElementParser; | |
} | |
/** | |
* @function setParser | |
* @param ParserInterface $parser | |
*/ | |
public function setParser(ParserInterface $parser): void | |
{ | |
$this->rangeElementParser = $parser; | |
} | |
/** | |
* @function getPatternDescription | |
* @return string | |
*/ | |
public function getPatternDescription(): string | |
{ | |
return $this->patternDescription; | |
} | |
/** | |
* @function setPatternDescription | |
* @param string $description | |
*/ | |
public function setPatternDescription(string $description): void | |
{ | |
$this->patternDescription = $description; | |
} | |
/** | |
* @function addRangeSpec | |
* @param string $rangeSpec | |
* @throws SetRangeException | |
*/ | |
public function addRangeSpec(string $rangeSpec) : void | |
{ | |
$rangeShell = explode(',', $rangeSpec); | |
foreach ($rangeShell as $item) { | |
$this->addStringItemToRange($item); | |
} | |
} | |
/** | |
* @function getRange | |
* @return array|array[] | |
*/ | |
public function getRange() | |
{ | |
return $this->range; | |
} | |
/** | |
* @function addStringItemToRange | |
* @param string $item | |
* @throws SetRangeException | |
*/ | |
public function addStringItemToRange(string $item) : void | |
{ | |
if ($this->rangeElementParser->parse($item)) { | |
$this->addItem($this->rangeElementParser->getParsedValue()); | |
return; | |
} | |
if (preg_match('/^(.+)-(.+)$/', $item, $matches)) { | |
if (false === $this->rangeElementParser->parse($matches[1])) { | |
throw new SetRangeException($this->patternDescription, $item); | |
} | |
$start = $this->rangeElementParser->getParsedValue(); | |
if (false === $this->rangeElementParser->parse($matches[2])) { | |
throw new SetRangeException($this->patternDescription, $item); | |
} | |
$end = $this->rangeElementParser->getParsedValue(); | |
$this->addRange($start, $end); | |
return; | |
} | |
throw new SetRangeException($this->patternDescription, $item); | |
} | |
/** | |
* @function addItem | |
* @param int $i | |
* @throws SetRangeException | |
*/ | |
public function addItem(int $i) : void | |
{ | |
if (!$this->rangeElementValidator->validate($i)) { | |
throw new SetRangeException($this->patternDescription, $i); | |
} | |
if (!in_array($i, $this->range)) { | |
$this->range[] = $i; | |
} | |
} | |
/** | |
* @function addRange | |
* @param int $start | |
* @param int $end | |
* @throws SetRangeException | |
*/ | |
public function addRange(int $start, int $end) : void | |
{ | |
if (!$this->rangeElementValidator->validate($start)) { | |
throw new SetRangeException($this->patternDescription, $start); | |
} | |
if (!$this->rangeElementValidator->validate($end)) { | |
throw new SetRangeException($this->patternDescription, $end); | |
} | |
$this->range = array_unique(array_merge($this->range, range($start, $end))); | |
} | |
/** | |
* @function containsValue | |
* @param int $value | |
* @return bool | |
*/ | |
public function containsValue(int $value) | |
{ | |
return in_array($value, $this->range); | |
} | |
/** | |
* @function getRangeSpec | |
* @return string | |
*/ | |
public function getRangeSpec(): string | |
{ | |
$resultArray = []; | |
// end cases | |
if (empty($this->range)) { | |
return ''; | |
} | |
if (count($this->range) == 1) { | |
return (string) $this->range[0]; | |
} | |
// sort range array into ascending values | |
asort($this->range); | |
// set up pointers to drag through the array | |
$arrayLength = count($this->range); | |
$beginningOfRange = $this->range[0]; | |
$previousValue = $this->range[0]; | |
for ($i = 1; $i < $arrayLength; $i++) { | |
if ($this->range[$i] != $previousValue + 1) { | |
// previous value is the end of the prior range so add the prior range to the result array | |
if ($beginningOfRange == $previousValue) { | |
$resultArray[] = $previousValue; | |
} else { | |
$resultArray[] = $beginningOfRange . '-' . $previousValue; | |
} | |
// start a new range | |
$beginningOfRange = $this->range[$i]; | |
} | |
$previousValue = $this->range[$i]; | |
} | |
// add the last range | |
if ($beginningOfRange == $previousValue) { | |
$resultArray[] = $previousValue; | |
} else { | |
$resultArray[] = $beginningOfRange . '-' . $previousValue; | |
} | |
// convert the result array to a string | |
return implode(',', $resultArray); | |
} | |
} |