Delete dead helpers/OutputHelper.php (#54)

Zero callers anywhere in the app — confirmed via grep for
"OutputHelper::" across the whole codebase. Every view actually calls
htmlspecialchars() directly instead, which a prior audit confirmed is
done consistently, so escaping was never actually at risk. This was
just a misleading, unused class that README.md's file reference
implied was part of the app's active XSS-prevention story. Removed the
file and its README Project Structure entry.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MGDKHiU5RJdo3dqQUDow3X
This commit is contained in:
2026-09-08 11:58:58 -04:00
co-authored by Claude Sonnet 5
parent 1e972fe7dc
commit 70ef42c311
2 changed files with 0 additions and 213 deletions
-1
View File
@@ -362,7 +362,6 @@ tinker_tickets/
│ ├── Database.php # Centralized mysqli connection
│ ├── ErrorHandler.php # Global error/exception handler
│ ├── NotificationHelper.php # Matrix hookshot webhook events
│ ├── OutputHelper.php # Safe HTML output helpers
│ ├── ResponseHelper.php # JSON API response helpers
│ ├── SynapseHelper.php # Resolves usernames → Matrix IDs via Synapse admin API
│ └── UrlHelper.php # Canonical ticket URLs using APP_DOMAIN
-212
View File
@@ -1,212 +0,0 @@
<?php
/**
* OutputHelper - Consistent output escaping utilities
*
* Provides secure HTML escaping functions to prevent XSS attacks.
* Use these functions when outputting user-controlled data.
*/
class OutputHelper
{
/**
* Escape string for HTML output
*
* Use for text content inside HTML elements.
* Example: <p><?= OutputHelper::h($userInput) ?></p>
*
* @param string|null $string The string to escape
* @param int $flags htmlspecialchars flags (default: ENT_QUOTES | ENT_HTML5)
* @return string Escaped string
*/
public static function h(?string $string, int $flags = ENT_QUOTES | ENT_HTML5): string
{
if ($string === null) {
return '';
}
return htmlspecialchars($string, $flags, 'UTF-8');
}
/**
* Escape string for HTML attribute context
*
* Use for values inside HTML attributes.
* Example: <input value="<?= OutputHelper::attr($userInput) ?>">
*
* @param string|null $string The string to escape
* @return string Escaped string
*/
public static function attr(?string $string): string
{
if ($string === null) {
return '';
}
// More aggressive escaping for attribute context
return htmlspecialchars($string, ENT_QUOTES | ENT_HTML5 | ENT_SUBSTITUTE, 'UTF-8');
}
/**
* Encode data as JSON for JavaScript context
*
* Use when embedding data in JavaScript.
* Example: <script>const data = <?= OutputHelper::json($data) ?>;</script>
*
* @param mixed $data The data to encode
* @param int $flags json_encode flags
* @return string JSON encoded string (safe for script context)
*/
public static function json($data, int $flags = 0): string
{
// Use HEX encoding for safety in HTML context
$safeFlags = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | $flags;
return json_encode($data, $safeFlags);
}
/**
* URL encode a string
*
* Use for values in URL query strings.
* Example: <a href="/search?q=<?= OutputHelper::url($query) ?>">
*
* @param string|null $string The string to encode
* @return string URL encoded string
*/
public static function url(?string $string): string
{
if ($string === null) {
return '';
}
return rawurlencode($string);
}
/**
* Escape for CSS context
*
* Use for values in inline CSS.
* Example: <div style="color: <?= OutputHelper::css($color) ?>;">
*
* @param string|null $string The string to escape
* @return string Escaped string (only allows safe characters)
*/
public static function css(?string $string): string
{
if ($string === null) {
return '';
}
// Only allow alphanumeric, hyphens, underscores, spaces, and common CSS values
if (!preg_match('/^[a-zA-Z0-9_\-\s#.,()%]+$/', $string)) {
return '';
}
return $string;
}
/**
* Format a number safely
*
* Ensures output is always a valid number.
*
* @param mixed $number The number to format
* @param int $decimals Number of decimal places
* @return string Formatted number
*/
public static function number($number, int $decimals = 0): string
{
return number_format((float)$number, $decimals, '.', ',');
}
/**
* Format an integer safely
*
* @param mixed $value The value to format
* @return int Integer value
*/
public static function int($value): int
{
return (int)$value;
}
/**
* Truncate string with ellipsis
*
* @param string|null $string The string to truncate
* @param int $length Maximum length
* @param string $suffix Suffix to add if truncated
* @return string Truncated and escaped string
*/
public static function truncate(?string $string, int $length = 100, string $suffix = '...'): string
{
if ($string === null) {
return '';
}
if (mb_strlen($string, 'UTF-8') <= $length) {
return self::h($string);
}
return self::h(mb_substr($string, 0, $length, 'UTF-8')) . self::h($suffix);
}
/**
* Format a date safely
*
* @param string|int|null $date Date string, timestamp, or null
* @param string $format PHP date format
* @return string Formatted date
*/
public static function date($date, string $format = 'Y-m-d H:i:s'): string
{
if ($date === null || $date === '') {
return '';
}
if (is_numeric($date)) {
return date($format, (int)$date);
}
$timestamp = strtotime($date);
if ($timestamp === false) {
return '';
}
return date($format, $timestamp);
}
/**
* Check if a string is safe for use as a CSS class name
*
* @param string $class The class name to validate
* @return bool True if safe
*/
public static function isValidCssClass(string $class): bool
{
return preg_match('/^[a-zA-Z_][a-zA-Z0-9_-]*$/', $class) === 1;
}
/**
* Sanitize CSS class name(s)
*
* @param string|null $classes Space-separated class names
* @return string Sanitized class names
*/
public static function cssClass(?string $classes): string
{
if ($classes === null || $classes === '') {
return '';
}
$classList = explode(' ', $classes);
$validClasses = array_filter($classList, [self::class, 'isValidCssClass']);
return implode(' ', $validClasses);
}
}
/**
* Shorthand function for HTML escaping
*
* @param string|null $string The string to escape
* @return string Escaped string
*/
function h(?string $string): string
{
return OutputHelper::h($string);
}