/** * write a string to the stream * * @param string $data * @return void */ public function writeString($data) { // robustness! RequireStringy::check($data, E4xx_UnsupportedType::class); // let the StreamHead do all the work :) $this->tokeniseAndWriteToStream($data); }
/** * throws exceptions if $item is empty * * this is a wrapper around our IsEmpty check * * @param string $itemName * human-readable name of $item * @param mixed $item * the data to check * @param string $exception * the class to use when throwing an exception * @return void */ public static function check($itemName, $item, $exception = E4xx_DataCannotBeEmpty::class) { // robustness! RequireStringy::check($itemName); // make sure that $item is not empty if (IsEmpty::check($item)) { throw new $exception($itemName); } }
/** * throws exceptions if $item is not a PHP class that exists * * this is a wrapper around our IsObjectOfType check * * @param mixed $item * the container to check * @param string $type * the class or interface that we want to check against * @param string $exception * the class to use when throwing an exception * @return void */ public static function check($item, $type, $exception = E4xx_UnsupportedType::class) { // robustness! RequireStringy::check($type, $exception); // make sure we have a PHP class that exists if (!IsObjectOfType::check($item, $type)) { throw new $exception(SimpleType::from($item)); } }
/** * is the filename actually a folder? * * @param mixed $path * the filename to check * @return boolean * TRUE if the filename is a folder * FALSE otherwise */ public static function check($path) { // defensive programming!! RequireStringy::check($path, E4xx_UnsupportedType::class); if (!is_dir($path)) { return false; } return true; }
/** * throws exceptions if $path is not a valid dot.notation.support path * * @param string $path * the path to check * @param string $eUnsupportedType * the class to use when throwing an unsupported-type exception * @param string $eNotDotNotationPath * the class to use when throwing a not-dot-notation-path exception * @return void */ public static function check($path, $eUnsupportedType = E4xx_UnsupportedType::class, $eNotDotNotationPath = E4xx_NotDotNotationPath::class) { // make sure we have a string RequireStringy::check($path, $eUnsupportedType); // make sure the string contains a dot.notation.support path if (!IsDotNotationPath::checkString($path)) { throw new $eNotDotNotationPath($path); } }
/** * extract all but the end of a dot.notation.support string * * @param string $dotNotation * the string to extract from * @param int $start * which part do we want to start from? * @param int $len * how many parts do we want? * @return string * the extracted parts */ public static function fromString($dotNotation, $start, $len) { // robustness! RequireStringy::check($dotNotation, E4xx_UnsupportedType::class); RequireInteger::check($start, E4xx_UnsupportedType::class); RequireInteger::check($len, E4xx_UnsupportedType::class); $parts = explode(".", (string) $dotNotation); $parts = array_slice($parts, (int) $start, (int) $len); return implode(".", $parts); }
/** * is the path a file on disk? * * @param mixed $path * path to the file to check * @return boolean * TRUE if the path is a file on disk * FALSE otherwise */ public static function check($path) { // defensive programming!! RequireStringy::check($path, E4xx_UnsupportedType::class); if (!is_file($path)) { return false; } // if we get here, then we are happy return true; }
/** * map a string such as '=' to the appropriate operator * * @param string $input * the input to map * @return string * the class name of the operator to use */ public static function to($input) { // robustness! RequireStringy::check($input, E4xx_UnsupportedType::class); if (!isset(self::$operatorMap[$input])) { throw new E4xx_UnknownOperator($input); } // send back our result return self::$operatorMap[$input]; }
/** * throws exceptions if $item is not a PHP class or interface that exists * * this is a wrapper around our IsDefinedObjectType check * * @param mixed $item * the container to check * @param string $eNoSuchClass * the exception to throw if $item isn't a valid PHP class * @param string $eUnsupportedType * the exception to throw if $item isn't something that we can check * @return void */ public static function check($item, $eNoSuchClass = E4xx_NoSuchClass::class, $eUnsupportedType = E4xx_UnsupportedType::class) { RequireStringy::check($item, $eUnsupportedType); if (trait_exists($item)) { throw new $eUnsupportedType(SimpleType::from($item)); } // make sure we have a PHP class that exists if (!IsDefinedObjectType::check($item)) { throw new $eNoSuchClass($item); } }
public function __construct($command, $returnCode, $output) { // robustness! RequireTraversable::checkMixed($command, E4xx_UnsupportedType::class); RequireNumeric::check($returnCode, E4xx_UnsupportedType::class); RequireStringy::checkMixed($output, E4xx_UnsupportedType::class); $this->setCommand($command); $this->setReturnCode($returnCode); $this->setOutput($output); // all done $this->makeReadOnly(); }
/** * is $path a file, and can we run it? * * @param string $path * the file to check * @return void * * @throws E4xx_InvalidPath * if $path is not a file, or otherwise does not exist * @throws E4xx_FileIsNotExecutable * if $path is a file, but we do not have permissions to run it */ public static function check($path) { // robustness RequireStringy::check($path); // do we have a file? if (!IsFile::check($path)) { throw new E4xx_InvalidPath($path); } // can we read it? if (!IsReadableFile::check($path)) { throw new E4xx_FileIsNotExecutable($path); } }
/** * is the filename actually the absolute path to a folder? * * @param mixed $filename * the filename to check * @return boolean * TRUE if the filename is a folder * FALSE otherwise */ public static function check($filename) { // defensive programming! RequireStringy::check($filename, E4xx_UnsupportedType::class); // if it is not a folder, no point in checking any further if (!is_dir((string) $filename)) { return false; } // check for absoluteness $absDir = BuildAbsolutePath::fromString((string) $filename); if ($filename !== $absDir && $filename[0] !== '/') { return false; } // if we get here, we are happy return true; }
/** * do a very basic comparison of two strings * * @param string $a * the lhs string to use * @param string $b * the rhs string to use * @return int * CompareTwoNumbers::A_IS_LESS, if $a < $b * CompareTwoNumbers::A_IS_GREATER, if $a > $b * CompareTwoNumbers::BOTH_ARE_EQUAL otherweise */ public static function calculate($a, $b) { // robustness RequireStringy::check($a, E4xx_UnsupportedType::class); RequireStringy::check($b, E4xx_UnsupportedType::class); // unfortunately, strcmp() doesn't return -1 / 0 / 1 $res = strcmp($a, $b); if ($res < 0) { return CompareTwoNumbers::A_IS_LESS; } else { if ($res > 0) { return CompareTwoNumbers::A_IS_GREATER; } } return CompareTwoNumbers::BOTH_ARE_EQUAL; }
/** * is the given filename pointing at valid JSON? * * @param mixed $path * the filename to inspect * @return boolean * TRUE if the file is valid JSON * FALSE otherwise */ public static function check($path) { // defensive programming!! RequireStringy::check($path, E4xx_UnsupportedType::class); if (!IsReadableFile::check($path)) { return false; } $contents = file_get_contents($path); if (empty($contents)) { return false; } $payload = json_decode($contents); if ($payload === null) { return false; } return true; }
/** * do we have a dot.notation string at all? * * @param string $item * the item to examine * @return boolean * TRUE if the string is in dot.notation * FALSE otherwise */ public static function checkString($item) { // robustness!! RequireStringy::check($item, E4xx_UnsupportedType::class); // make sure we have a dot somewhere we like if (!self::hasDotInAcceptablePlace((string) $item)) { return false; } // if we get here, we're happy return true; }
/** * turn a single comparison strings into a ComparisonExpression object * * e.g. * * >= 1.0.0 * <2.0 * !1.5.9 * ~1.1 * * @param string $expression * the string to parse * @return ComparisonExpression */ public static function from($expression, $parser) { // robustness! RequireStringy::check($expression, E4xx_UnsupportedType::class); // make sense of what we have list($operator, $versionString) = self::tokeniseExpression($expression); $version = $parser($versionString); // send back our result return new ComparisonExpression($operator, $version); }
/** * filter an array of strings * * @param array|Traversable $data * the data to filter * @param string $columnSeparator * the column delimiter * @param array $columnNos * a list of the column numbers we are interested in * @return array * the extracted columns */ private static function filterArray($data, $columnSeparator, $columnNos) { $retval = []; foreach ($data as $line) { RequireStringy::checkMixed($line, E4xx_UnsupportedType::class); $retval[] = self::filterLine($line, $columnSeparator, $columnNos); } return $retval; }
/** * remove leading and trailing whitespace from $data * * @param array|Traversable $data * the data that needs trimming * @return array * the (possibly) changed $data */ private static function fromArray($data) { $retval = []; foreach ($data as $datum) { RequireStringy::check($datum, E4xx_UnsupportedType::class); $retval[] = trim($datum); } return $retval; }
/** * @covers ::__construct * @covers ::__toString * @dataProvider provideVersionNumbers */ public function testCanConvertToString($versionNumber) { // ---------------------------------------------------------------- // setup your test $obj = new HashedVersion($versionNumber); // ---------------------------------------------------------------- // perform the change $actualResult = (string) $obj; // ---------------------------------------------------------------- // test the results RequireStringy::check($obj); $this->assertTrue(is_string($actualResult)); $this->assertEquals($versionNumber, $actualResult); }
/** * @covers ::check * @covers ::checkMixed * @dataProvider provideNonStringys * @expectedException GanbaroDigital\Reflection\Exceptions\E4xx_UnsupportedType */ public function testRejectsNonStringysWhenCalledStatically($item) { // ---------------------------------------------------------------- // setup your test // ---------------------------------------------------------------- // perform the change RequireStringy::check($item); }
/** * search and replace on data * * @param array|Traversable $data * the data to be changed * @param array|string $match * the item(s) to search for * @param array|string $replacement * the item(s) to replace with * @return array * the (possibly) changed data */ private static function inArray($data, $match, $replacement) { $retval = []; foreach ($data as $datum) { RequireStringy::check($datum, E4xx_UnsupportedType::class); $retval[] = str_replace($match, $replacement, $datum); } return $retval; }
/** * convert a string in the form 'X.Y[.Z][-<preRelease>][+R]' into an * array of version parts * * @param string $versionString * the string to parse * * @return SemanticVersion * * @throws E4xx_BadVersionString * if we cannot parse $versionString * * @throws E4xx_NotAVersionString * if we're asked to parse something that isn't a string */ public static function from($versionString) { // do we have something we can safely attempt to parse? RequireStringy::check($versionString, E4xx_NotAVersionString::class); $matches = []; if (!preg_match(self::getRegex(), $versionString, $matches)) { // if we get here, then nothing matched throw new E4xx_BadVersionString($versionString); } // we need to sanitise the regex result before returning // our return value $parts = self::cleanupMatches($matches); return new SemanticVersion($parts['major'], $parts['minor'], $parts['patchLevel'], $parts['preRelease'], $parts['build']); }
/** * search an array for values that do not contain the search string * * @param array|Traversable $data * the array to search * @param string $searchString * the string to search for * @return array * only those values of $data that do not contain the search string */ private static function matchArray($data, $searchString) { $retval = []; foreach ($data as $line) { RequireStringy::checkMixed($line, E4xx_UnsupportedType::class); $match = self::matchLine($line, $searchString); if (!empty($match)) { $retval[] = $match; } } // all done return $retval; }
/** * is $data compatible with $constraint? * * @param string $data * the class name to check * @param string|object $constraint * the class or object that $data must be compatible with * @return boolean * TRUE if $data is compatible * FALSE otherwise */ public static function checkString($data, $constraint) { // defensive programming! RequireStringy::check($data, E4xx_UnsupportedType::class); RequireAnyOneOf::check([new IsObject(), new IsStringy()], [$constraint], E4xx_UnsupportedType::class); $compatibleTypes = AllMatchingTypesList::from($data); if (is_object($constraint)) { $constraint = get_class($constraint); } // is our constraint in the list of data types that $data can be? if (in_array($constraint, $compatibleTypes)) { return true; } // if we get here, we have run out of ideas return false; }
/** * turn one or more comparison strings into a VersionRangeList object * * e.g. * * >= 1.0.0, <2.0, !1.5.9 * ~1.1 * * @param string $expression * the string to parse * @param VersionParser $parser * the parser to use on the version numbers * @return VersionRange */ public static function from($expression, VersionParser $parser) { // robustness! RequireStringy::check($expression, E4xx_UnsupportedType::class); // our final list $list = []; $parts = explode(",", (string) $expression); $parts = FilterOutEmptyValues::from($parts); foreach ($parts as $part) { $list[] = ParseComparisonExpression::from(trim($part), $parser); } return new VersionRange($list); }
/** * descend inside an object, using dot.notation.support, and optionally * extending the object if the end of the dot.notation.path is missing * * @param object $obj * the object to dig into * @param string $property * the dot.notation.support path to descend * @param array|callable|string|null $extendingItem * if we need to extend, what data type do we extend using? * @return mixed */ public static function &intoObject($obj, $property, $extendingItem = null) { // robustness! RequireAssignable::check($obj, E4xx_UnsupportedType::class); RequireStringy::check($property, E4xx_UnsupportedType::class); if (strlen($property) === 0) { throw new \InvalidArgumentException("'\$property' cannot be empty string"); } $retval =& self::getPathFromRoot($obj, $property, $extendingItem); return $retval; }
/** * expand a range in the form "n-m" * * @param string $data * the range to expand * @return array * the values are the range */ public static function fromString($data) { RequireStringy::checkMixed($data, E4xx_UnsupportedType::class); return self::parseString($data); }
/** * convert a string in the form '[A-Za-z0-9]{4,}' into an * array of version parts * * @param string $versionString * the string to parse * * @return HashedVersion * * @throws E4xx_BadVersionString * if we cannot parse $versionString * * @throws E4xx_NotAVersionString * if we're asked to parse something that isn't a string */ public static function from($versionString) { // do we have something we can safely attempt to parse? RequireStringy::check($versionString, E4xx_NotAVersionString::class); $matches = []; if (!preg_match(self::getRegex(), $versionString, $matches)) { // if we get here, then nothing matched throw new E4xx_BadVersionString($versionString); } return new HashedVersion($matches['version']); }