2020-07-26 14:52:41 +02:00
|
|
|
<?PHP
|
|
|
|
/**
|
|
|
|
* Provides type-safe overrides of default PHP functions.
|
|
|
|
*/
|
|
|
|
declare(strict_types = 1);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Standard class providing overrides of default PHP functions as static
|
|
|
|
* functions.
|
|
|
|
*/
|
|
|
|
class MD_STD {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrapper around file_get_contents, that provides catches errors on it and returns
|
|
|
|
* with type safety.
|
|
|
|
*
|
|
|
|
* @param string $filename Filepath of the file to read.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function file_get_contents(string $filename):string {
|
|
|
|
|
|
|
|
if (substr($filename, 0, 4) !== 'http' && !file_exists($filename)) {
|
|
|
|
throw new MDFileDoesNotExist("There is no file {$filename}");
|
|
|
|
}
|
|
|
|
|
|
|
|
$contents = file_get_contents($filename);
|
|
|
|
|
|
|
|
if (is_bool($contents)) {
|
|
|
|
throw new MDFileIsNotReadable("File {$filename} is not readable");
|
|
|
|
}
|
|
|
|
|
|
|
|
return $contents;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-05 14:01:26 +02:00
|
|
|
/**
|
|
|
|
* Returns the real path of a relative file path. Throws an error rather than
|
|
|
|
* returning the default false.
|
|
|
|
*
|
|
|
|
* @param string $path File path to convert.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function realpath(string $path):string {
|
|
|
|
|
|
|
|
$output = realpath($path);
|
|
|
|
if (!is_string($output)) throw new MDFileDoesNotExist("The file {$path} does not exist or is not readable.");
|
|
|
|
return $output;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-07-26 14:52:41 +02:00
|
|
|
/**
|
|
|
|
* Gets contents of a folder.
|
|
|
|
*
|
|
|
|
* @param string $filepath Directory path.
|
|
|
|
*
|
|
|
|
* @return array<string>
|
|
|
|
*/
|
|
|
|
public static function scandir(string $filepath):array {
|
|
|
|
|
|
|
|
if (!is_dir($filepath) || ($output = scandir($filepath)) === false) {
|
2020-07-26 15:13:03 +02:00
|
|
|
throw new MDFileDoesNotExist("There is no file {$filepath}");
|
2020-07-26 14:52:41 +02:00
|
|
|
}
|
|
|
|
|
2020-08-07 18:32:44 +02:00
|
|
|
return array_values(array_diff($output, ['.', '..', '.git']));
|
2020-07-26 14:52:41 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-05 15:31:29 +02:00
|
|
|
/**
|
|
|
|
* Type safe wrapper around ob_get_clean(): Gets the current buffer
|
|
|
|
* contents and delete current output buffer.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function ob_get_clean():string {
|
|
|
|
|
|
|
|
$output = ob_get_clean();
|
|
|
|
if ($output === false) throw new MDOutputBufferNotStarted("Output buffer was not started");
|
|
|
|
return $output;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-05 09:06:28 +02:00
|
|
|
/**
|
|
|
|
* Function checking if a string starts with another.
|
|
|
|
*
|
|
|
|
* @param string $haystack String to check.
|
|
|
|
* @param string $needle Potential start of $haystack.
|
|
|
|
*
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public static function startsWith(string $haystack, string $needle):bool {
|
|
|
|
|
|
|
|
if (substr($haystack, 0, strlen($needle)) == $needle) return true;
|
|
|
|
else return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function checking if a string starts with any input from the input array.
|
|
|
|
*
|
|
|
|
* @param string $haystack String to check.
|
|
|
|
* @param string[] $needles Array containing potential start values of $haystack.
|
|
|
|
*
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public static function startsWithAny(string $haystack, array $needles):bool {
|
|
|
|
|
|
|
|
$output = false;
|
|
|
|
foreach ($needles as $needle) {
|
|
|
|
$output = self::startsWith($haystack, $needle);
|
|
|
|
if ($output == true) return $output;
|
|
|
|
}
|
|
|
|
return $output;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-05 17:02:03 +02:00
|
|
|
/**
|
|
|
|
* Type-safe wrapper around json_encode.
|
|
|
|
*
|
|
|
|
* @see https://www.php.net/manual/en/function.json-encode.php
|
|
|
|
*
|
|
|
|
* @param array<mixed> $value The value being encoded. Can be any type except a resource.
|
|
|
|
* @param integer $options Bitmask consisting of JSON_FORCE_OBJECT, JSON_HEX_QUOT ...
|
|
|
|
* @param integer $depth Depth of coding.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function json_encode(array $value, int $options = 0, int $depth = 512):string {
|
|
|
|
|
|
|
|
$output = json_encode($value, $options, $depth);
|
|
|
|
if ($output === false) throw new Exception("JSON output could not be generated");
|
|
|
|
return $output;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-05 16:36:02 +02:00
|
|
|
/**
|
|
|
|
* Wrapper for curling contents from the web.
|
|
|
|
*
|
|
|
|
* @param string $url URL to query.
|
|
|
|
* @param integer $timeout Timeout in milliseconds.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function runCurl(string $url, int $timeout = 1200):string {
|
|
|
|
|
|
|
|
$curl = curl_init();
|
|
|
|
|
|
|
|
curl_setopt($curl, CURLOPT_URL, $url);
|
|
|
|
curl_setopt($curl, CURLOPT_HEADER, false);
|
|
|
|
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT_MS, $timeout); //timeout in seconds
|
|
|
|
curl_setopt($curl, CURLOPT_TIMEOUT_MS, $timeout); //timeout in seconds
|
|
|
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
|
|
|
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
|
|
|
|
curl_setopt($curl, CURLOPT_USERAGENT, 'md-bot/1.0');
|
|
|
|
$result = curl_exec($curl);
|
|
|
|
|
|
|
|
curl_close($curl);
|
|
|
|
if (is_bool($result)) return "";
|
|
|
|
return $result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-07-26 14:52:41 +02:00
|
|
|
}
|