and & become hexadecimal * escapes, so no value can close the script element or start a comment. * * @var int */ private const SCRIPT_FLAGS = JSON_HEX_TAG | JSON_HEX_AMP; /** * The flags for a configuration object, which also turns ' and " into * hexadecimal escapes, so it stays safe inside a quoted string or an * HTML attribute as well. * * @var int */ private const CONFIG_FLAGS = self::SCRIPT_FLAGS | JSON_HEX_APOS | JSON_HEX_QUOT; /** * Encodes a value as a JavaScript expression for an inline script. * * @param mixed $value The value to encode. * @return string The JSON, or the literal null for a value JSON cannot hold. */ public static function for_script( mixed $value ): string { return self::encode( $value, self::SCRIPT_FLAGS ); } /** * Encodes a configuration object for an inline script, with ' and " * escaped as well. * * @param mixed $value The value to encode. * @return string The JSON, or the literal null for a value JSON cannot hold. */ public static function for_config( mixed $value ): string { return self::encode( $value, self::CONFIG_FLAGS ); } /** * Encodes with wp_json_encode(), so invalid UTF-8 is repaired the way * WordPress does it, and never returns a string that would break the * script around it. * * @param mixed $value The value to encode. * @param int $flags The json_encode() flags. */ private static function encode( mixed $value, int $flags ): string { $json = wp_json_encode( $value, $flags ); return false === $json ? 'null' : $json; } }