157 lines
5.3 KiB
PHP
157 lines
5.3 KiB
PHP
<?php
|
|
|
|
namespace App\Helpers;
|
|
|
|
class StringHelper
|
|
{
|
|
/**
|
|
* Transform the string: capitalize the first letter, lowercase the rest and ensure it ends with a full stop.
|
|
*
|
|
* @param string $value
|
|
* @return string
|
|
*/
|
|
public static function SentenceCase(string $value): string
|
|
{
|
|
$value = strtolower($value);
|
|
$value = ucfirst($value);
|
|
if (substr($value, -1) !== '.') {
|
|
$value .= '.';
|
|
}
|
|
return $value;
|
|
}
|
|
|
|
|
|
/**
|
|
* Transform the string: capitalize the first letter, lowercase the rest and ensure it ends without a full stop.
|
|
*
|
|
* @param string $value
|
|
* @return string
|
|
*/
|
|
public static function DutchTitleCase(string $value): string
|
|
{
|
|
return ucfirst(strtolower($value));
|
|
}
|
|
|
|
/**
|
|
* Get the translated page title for the current route.
|
|
* Maps route names to page title translation keys.
|
|
*
|
|
* @param string|null $routeName
|
|
* @return string
|
|
*/
|
|
public static function getPageTitle(?string $routeName = null): string
|
|
{
|
|
$routeName = $routeName ?: \Route::currentRouteName();
|
|
|
|
// Map route names to page title translation keys
|
|
$routeMap = [
|
|
'welcome' => 'page_title.welcome',
|
|
'dashboard' => 'page_title.dashboard',
|
|
'search' => 'page_title.search',
|
|
'search.results' => 'page_title.search',
|
|
'transactions.index' => 'page_title.transactions',
|
|
'transactions.show' => 'page_title.transactions',
|
|
'profile.show' => 'page_title.profile',
|
|
'profile.edit' => 'page_title.profile',
|
|
'profile.settings' => 'page_title.settings',
|
|
'user-profile-information.update' => 'page_title.settings',
|
|
'login' => 'page_title.login',
|
|
'register' => 'page_title.register',
|
|
'post.index' => 'page_title.posts',
|
|
'post.show' => 'page_title.posts',
|
|
'admin.index' => 'page_title.admin',
|
|
'contacts' => 'Contacts',
|
|
'static-faq' => 'FAQ',
|
|
'static-getting-started' => 'Getting started',
|
|
'static-privacy' => 'Privacy',
|
|
'static-organizations' => 'Organizations',
|
|
'static-principles' => 'Principles',
|
|
'static-report-issue' => 'Report an issue',
|
|
'static-events' => 'Events',
|
|
'static-messenger' => 'Messages',
|
|
'static-report-error' => 'Report an error',
|
|
];
|
|
|
|
// Get the translation key for this route, or default to welcome
|
|
$translationKey = $routeMap[$routeName] ?? 'page_title.welcome';
|
|
|
|
return __($translationKey);
|
|
}
|
|
|
|
/**
|
|
* Sanitize HTML content to prevent XSS attacks while preserving rich text formatting.
|
|
* Allows safe HTML tags like paragraphs, headings, links, images, lists, etc.
|
|
*
|
|
* IMPORTANT: This method uses Laravel's cache directory for HTMLPurifier cache,
|
|
* avoiding permission issues with the vendor directory on production servers.
|
|
*
|
|
* @param string|null $html
|
|
* @return string
|
|
*/
|
|
public static function sanitizeHtml(?string $html): string
|
|
{
|
|
if (empty($html)) {
|
|
return '';
|
|
}
|
|
|
|
// Create HTMLPurifier configuration
|
|
$config = \HTMLPurifier_Config::createDefault();
|
|
|
|
// Use Laravel's cache directory instead of vendor directory
|
|
// This avoids "Directory not writable" errors on production servers
|
|
$cacheDir = storage_path('framework/cache/htmlpurifier');
|
|
|
|
// Create cache directory if it doesn't exist
|
|
if (!is_dir($cacheDir)) {
|
|
mkdir($cacheDir, 0755, true);
|
|
}
|
|
|
|
$config->set('Cache.SerializerPath', $cacheDir);
|
|
|
|
// Allow target="_blank" for links - must be set before getHTMLDefinition()
|
|
$config->set('Attr.AllowedFrameTargets', ['_blank']);
|
|
|
|
// Enable HTML5 mode and allow data-* attributes
|
|
$config->set('HTML.DefinitionID', 'html5-definitions');
|
|
$config->set('HTML.DefinitionRev', 1);
|
|
|
|
// Allow rich text formatting elements including data-list attribute
|
|
$config->set('HTML.Allowed',
|
|
'p,br,strong,b,em,i,u,strike,del,ins,' .
|
|
'h1,h2,h3,h4,h5,h6,' .
|
|
'ul,ol,li[data-list],' .
|
|
'a[href|target|title|rel],' .
|
|
'img[src|alt|width|height|title],' .
|
|
'blockquote,pre,code,' .
|
|
'table,thead,tbody,tr,th,td,' .
|
|
'span[class|contenteditable],div[class]'
|
|
);
|
|
|
|
// Get HTML definition and add custom data-list attribute
|
|
// Use maybeGetRawHTMLDefinition to avoid caching warnings
|
|
if ($def = $config->maybeGetRawHTMLDefinition()) {
|
|
// Add data-list as an enumerated attribute with specific allowed values
|
|
$def->addAttribute('li', 'data-list', new \HTMLPurifier_AttrDef_Enum(
|
|
array('bullet', 'ordered')
|
|
));
|
|
}
|
|
|
|
// Create purifier and clean the HTML
|
|
$purifier = new \HTMLPurifier($config);
|
|
return $purifier->purify($html);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the translated page title for the current route.
|
|
*
|
|
* @param string|null $routeName
|
|
* @return string
|
|
*/
|
|
if (!function_exists('page_title')) {
|
|
function page_title(?string $routeName = null): string
|
|
{
|
|
return \App\Helpers\StringHelper::getPageTitle($routeName);
|
|
}
|
|
}
|