1<?php 2 3/** 4 * This file is part of the Nette Framework (https://nette.org) 5 * Copyright (c) 2004 David Grudl (https://davidgrudl.com) 6 */ 7 8declare(strict_types=1); 9 10namespace Nette\Utils; 11 12use Nette; 13 14 15class Helpers 16{ 17 /** 18 * Executes a callback and returns the captured output as a string. 19 */ 20 public static function capture(callable $func): string 21 { 22 ob_start(function () {}); 23 try { 24 $func(); 25 return ob_get_clean(); 26 } catch (\Throwable $e) { 27 ob_end_clean(); 28 throw $e; 29 } 30 } 31 32 33 /** 34 * Returns the last occurred PHP error or an empty string if no error occurred. Unlike error_get_last(), 35 * it is nit affected by the PHP directive html_errors and always returns text, not HTML. 36 */ 37 public static function getLastError(): string 38 { 39 $message = error_get_last()['message'] ?? ''; 40 $message = ini_get('html_errors') ? Html::htmlToText($message) : $message; 41 $message = preg_replace('#^\w+\(.*?\): #', '', $message); 42 return $message; 43 } 44 45 46 /** 47 * Converts false to null, does not change other values. 48 */ 49 public static function falseToNull(mixed $value): mixed 50 { 51 return $value === false ? null : $value; 52 } 53 54 55 /** 56 * Returns value clamped to the inclusive range of min and max. 57 */ 58 public static function clamp(int|float $value, int|float $min, int|float $max): int|float 59 { 60 if ($min > $max) { 61 throw new Nette\InvalidArgumentException("Minimum ($min) is not less than maximum ($max)."); 62 } 63 64 return min(max($value, $min), $max); 65 } 66 67 68 /** 69 * Looks for a string from possibilities that is most similar to value, but not the same (for 8-bit encoding). 70 * @param string[] $possibilities 71 */ 72 public static function getSuggestion(array $possibilities, string $value): ?string 73 { 74 $best = null; 75 $min = (strlen($value) / 4 + 1) * 10 + .1; 76 foreach (array_unique($possibilities) as $item) { 77 if ($item !== $value && ($len = levenshtein($item, $value, 10, 11, 10)) < $min) { 78 $min = $len; 79 $best = $item; 80 } 81 } 82 83 return $best; 84 } 85 86 87 /** 88 * Compares two values in the same way that PHP does. Recognizes operators: >, >=, <, <=, =, ==, ===, !=, !==, <> 89 */ 90 public static function compare(mixed $left, string $operator, mixed $right): bool 91 { 92 return match ($operator) { 93 '>' => $left > $right, 94 '>=' => $left >= $right, 95 '<' => $left < $right, 96 '<=' => $left <= $right, 97 '=', '==' => $left == $right, 98 '===' => $left === $right, 99 '!=', '<>' => $left != $right, 100 '!==' => $left !== $right, 101 default => throw new Nette\InvalidArgumentException("Unknown operator '$operator'"), 102 }; 103 } 104} 105