Config::MAX_FILENAME_LENGTH ) { $base = mb_substr( $base, 0, Config::MAX_FILENAME_LENGTH ); } return trim( $base . $extension, '.-_' ); } /** * Stripping the extension from a filename. * * @param string $filename Filename, with or without an extension. * * @return string Filename without its trailing extension. */ public static function without_extension( string $filename ): string { return (string) preg_replace( '/\.[^.]+$/', '', $filename ); } /** * Checking whether one string occurs inside another (PHP 7.4 stand-in for str_contains()). * * @param string $haystack String to search. * @param string $needle String to look for. * * @return bool Whether the needle occurs in the haystack. */ public static function contains( string $haystack, string $needle ): bool { return '' === $needle || false !== strpos( $haystack, $needle ); } /** * Checking whether a string opens with another (PHP 7.4 stand-in for str_starts_with()). * * @param string $haystack String to search. * @param string $needle Prefix to look for. * * @return bool Whether the haystack starts with the needle. */ public static function starts_with( string $haystack, string $needle ): bool { return '' === $needle || 0 === strpos( $haystack, $needle ); } /** * Collapsing every run of whitespace into a single space. * * @param string $value Raw value from Kordiam. * * @return string Value with whitespace runs collapsed and the ends trimmed. */ public static function collapse_whitespace( string $value ): string { return trim( (string) preg_replace( '/\s+/u', ' ', $value ) ); } /** * Shortening a string to a character (not byte) budget. * * @param string $value Value to shorten. * @param int $limit Maximum length in characters, ellipsis excluded. * @param string $ellipsis Appended when the value is shortened. * * @return string Value, shortened only if it exceeded the limit. */ public static function truncate( string $value, int $limit, string $ellipsis = '...' ): string { if ( $limit < 1 || mb_strlen( $value ) <= $limit ) { return $value; } return mb_substr( $value, 0, $limit ) . $ellipsis; } /** * Checking whether a value is a JSON document. * * @param mixed $value Value to inspect. * * @return bool Whether the value is a string holding valid JSON. */ public static function is_json( $value ): bool { if ( ! is_string( $value ) || '' === trim( $value ) ) { return false; } json_decode( $value ); return JSON_ERROR_NONE === json_last_error(); } /** * Decoding a JSON document into an array. * * @param mixed $value Value to decode. * * @return array|null Decoded array, or null when the value is not a JSON array. */ public static function json_to_array( $value ): ?array { if ( is_array( $value ) ) { return $value; } if ( ! self::is_json( $value ) ) { return null; } $decoded = json_decode( (string) $value, true ); return is_array( $decoded ) ? $decoded : null; } }