diff --git a/app/Liquid/Filters/Date.php b/app/Liquid/Filters/Date.php index 6bc81fc..2f730ac 100644 --- a/app/Liquid/Filters/Date.php +++ b/app/Liquid/Filters/Date.php @@ -2,7 +2,6 @@ namespace App\Liquid\Filters; -use App\Liquid\Utils\ExpressionUtils; use Carbon\Carbon; use Keepsuit\Liquid\Filters\FiltersProvider; @@ -23,33 +22,4 @@ class Date extends FiltersProvider return Carbon::now()->subDays($days)->toDateString(); } - - /** - * Format a date string with ordinal day (1st, 2nd, 3rd, etc.) - * - * @param string $dateStr The date string to parse - * @param string $strftimeExp The strftime format string with <> placeholder - * @return string The formatted date with ordinal day - */ - public function ordinalize(string $dateStr, string $strftimeExp): string - { - $date = Carbon::parse($dateStr); - $ordinalDay = $date->ordinal('day'); - - // Convert strftime format to PHP date format - $phpFormat = ExpressionUtils::strftimeToPhpFormat($strftimeExp); - - // Split the format string by the ordinal day placeholder - $parts = explode('<>', $phpFormat); - - if (count($parts) === 2) { - $before = $date->format($parts[0]); - $after = $date->format($parts[1]); - - return $before.$ordinalDay.$after; - } - - // Fallback: if no placeholder found, just format normally - return $date->format($phpFormat); - } } diff --git a/app/Liquid/Utils/ExpressionUtils.php b/app/Liquid/Utils/ExpressionUtils.php index 8a5bdb0..9ed70d2 100644 --- a/app/Liquid/Utils/ExpressionUtils.php +++ b/app/Liquid/Utils/ExpressionUtils.php @@ -84,7 +84,6 @@ class ExpressionUtils if (self::evaluateCondition($condition['left'], $variable, $object)) { return true; } - return self::evaluateCondition($condition['right'], $variable, $object); case 'comparison': @@ -159,52 +158,4 @@ class ExpressionUtils return $expression; } - - /** - * Convert strftime format string to PHP date format string - * - * @param string $strftimeFormat The strftime format string - * @return string The PHP date format string - */ - public static function strftimeToPhpFormat(string $strftimeFormat): string - { - $conversions = [ - // Special Ruby format cases - '%N' => 'u', // Microseconds (Ruby) -> microseconds (PHP) - '%u' => 'u', // Microseconds (Ruby) -> microseconds (PHP) - '%-m' => 'n', // Month without leading zero (Ruby) -> month without leading zero (PHP) - '%-d' => 'j', // Day without leading zero (Ruby) -> day without leading zero (PHP) - '%-H' => 'G', // Hour without leading zero (Ruby) -> hour without leading zero (PHP) - '%-I' => 'g', // Hour 12h without leading zero (Ruby) -> hour 12h without leading zero (PHP) - '%-M' => 'i', // Minute without leading zero (Ruby) -> minute without leading zero (PHP) - '%-S' => 's', // Second without leading zero (Ruby) -> second without leading zero (PHP) - '%z' => 'O', // Timezone offset (Ruby) -> timezone offset (PHP) - '%Z' => 'T', // Timezone name (Ruby) -> timezone name (PHP) - - // Standard strftime conversions - '%A' => 'l', // Full weekday name - '%a' => 'D', // Abbreviated weekday name - '%B' => 'F', // Full month name - '%b' => 'M', // Abbreviated month name - '%Y' => 'Y', // Full year (4 digits) - '%y' => 'y', // Year without century (2 digits) - '%m' => 'm', // Month as decimal number (01-12) - '%d' => 'd', // Day of month as decimal number (01-31) - '%H' => 'H', // Hour in 24-hour format (00-23) - '%I' => 'h', // Hour in 12-hour format (01-12) - '%M' => 'i', // Minute as decimal number (00-59) - '%S' => 's', // Second as decimal number (00-59) - '%p' => 'A', // AM/PM - '%P' => 'a', // am/pm - '%j' => 'z', // Day of year as decimal number (001-366) - '%w' => 'w', // Weekday as decimal number (0-6, Sunday is 0) - '%U' => 'W', // Week number of year (00-53, Sunday is first day) - '%W' => 'W', // Week number of year (00-53, Monday is first day) - '%c' => 'D M j H:i:s Y', // Date and time representation - '%x' => 'm/d/Y', // Date representation - '%X' => 'H:i:s', // Time representation - ]; - - return str_replace(array_keys($conversions), array_values($conversions), $strftimeFormat); - } } diff --git a/app/Models/Plugin.php b/app/Models/Plugin.php index b372cdd..2fd3718 100644 --- a/app/Models/Plugin.php +++ b/app/Models/Plugin.php @@ -216,15 +216,15 @@ class Plugin extends Model */ private function applyLiquidReplacements(string $template): string { - - $replacements = []; + $replacements = [ + 'date: "%N"' => 'date: "u"', + 'date: "%u"' => 'date: "u"', + '%-m/%-d/%Y' => 'm/d/Y', + ]; // Apply basic replacements $template = str_replace(array_keys($replacements), array_values($replacements), $template); - // Convert Ruby/strftime date formats to PHP date formats - $template = $this->convertDateFormats($template); - // Convert {% render "template" with %} syntax to {% render "template", %} syntax $template = preg_replace( '/{%\s*render\s+([^}]+?)\s+with\s+/i', @@ -237,7 +237,7 @@ class Plugin extends Model // Converts to: {% assign temp_filtered = collection | filter: "key", "value" %}{% for item in temp_filtered %} $template = preg_replace_callback( '/{%\s*for\s+(\w+)\s+in\s+([^|%}]+)\s*\|\s*([^%}]+)%}/', - function (array $matches): string { + function ($matches): string { $variableName = mb_trim($matches[1]); $collection = mb_trim($matches[2]); $filter = mb_trim($matches[3]); @@ -251,40 +251,6 @@ class Plugin extends Model return $template; } - /** - * Convert Ruby/strftime date formats to PHP date formats in Liquid templates - */ - private function convertDateFormats(string $template): string - { - // Handle date filter formats: date: "format" or date: 'format' - $template = preg_replace_callback( - '/date:\s*(["\'])([^"\']+)\1/', - function (array $matches): string { - $quote = $matches[1]; - $format = $matches[2]; - $convertedFormat = \App\Liquid\Utils\ExpressionUtils::strftimeToPhpFormat($format); - - return 'date: '.$quote.$convertedFormat.$quote; - }, - $template - ); - - // Handle l_date filter formats: l_date: "format" or l_date: 'format' - $template = preg_replace_callback( - '/l_date:\s*(["\'])([^"\']+)\1/', - function (array $matches): string { - $quote = $matches[1]; - $format = $matches[2]; - $convertedFormat = \App\Liquid\Utils\ExpressionUtils::strftimeToPhpFormat($format); - - return 'l_date: '.$quote.$convertedFormat.$quote; - }, - (string) $template - ); - - return $template; - } - /** * Resolve Liquid variables in a template string using the Liquid template engine * @@ -347,9 +313,6 @@ class Plugin extends Model 'config' => $this->configuration ?? [], ...(is_array($this->data_payload) ? $this->data_payload : []), 'trmnl' => [ - 'system' => [ - 'timestamp_utc' => now()->utc()->timestamp, - ], 'user' => [ 'utc_offset' => '0', 'name' => $this->user->name ?? 'Unknown User', diff --git a/app/Notifications/BatteryLow.php b/app/Notifications/BatteryLow.php index 17fb1da..e590398 100644 --- a/app/Notifications/BatteryLow.php +++ b/app/Notifications/BatteryLow.php @@ -36,7 +36,7 @@ class BatteryLow extends Notification return (new MailMessage)->markdown('mail.battery-low', ['device' => $this->device]); } - public function toWebhook(object $notifiable): WebhookMessage + public function toWebhook(object $notifiable): \App\Notifications\Messages\WebhookMessage { return WebhookMessage::create() ->data([ diff --git a/tests/Unit/Liquid/Filters/DateTest.php b/tests/Unit/Liquid/Filters/DateTest.php index 7de8949..d967951 100644 --- a/tests/Unit/Liquid/Filters/DateTest.php +++ b/tests/Unit/Liquid/Filters/DateTest.php @@ -30,65 +30,3 @@ test('days_ago filter with large number works correctly', function (): void { expect($filter->days_ago(100))->toBe($hundredDaysAgo); }); - -test('ordinalize filter formats date with ordinal day', function (): void { - $filter = new Date(); - - expect($filter->ordinalize('2025-10-02', '%A, %B <>, %Y')) - ->toBe('Thursday, October 2nd, 2025'); -}); - -test('ordinalize filter handles datetime string with timezone', function (): void { - $filter = new Date(); - - expect($filter->ordinalize('2025-12-31 16:50:38 -0400', '%A, %b <>')) - ->toBe('Wednesday, Dec 31st'); -}); - -test('ordinalize filter handles different ordinal suffixes', function (): void { - $filter = new Date(); - - // 1st - expect($filter->ordinalize('2025-01-01', '<>')) - ->toBe('1st'); - - // 2nd - expect($filter->ordinalize('2025-01-02', '<>')) - ->toBe('2nd'); - - // 3rd - expect($filter->ordinalize('2025-01-03', '<>')) - ->toBe('3rd'); - - // 4th - expect($filter->ordinalize('2025-01-04', '<>')) - ->toBe('4th'); - - // 11th (special case) - expect($filter->ordinalize('2025-01-11', '<>')) - ->toBe('11th'); - - // 12th (special case) - expect($filter->ordinalize('2025-01-12', '<>')) - ->toBe('12th'); - - // 13th (special case) - expect($filter->ordinalize('2025-01-13', '<>')) - ->toBe('13th'); - - // 21st - expect($filter->ordinalize('2025-01-21', '<>')) - ->toBe('21st'); - - // 22nd - expect($filter->ordinalize('2025-01-22', '<>')) - ->toBe('22nd'); - - // 23rd - expect($filter->ordinalize('2025-01-23', '<>')) - ->toBe('23rd'); - - // 24th - expect($filter->ordinalize('2025-01-24', '<>')) - ->toBe('24th'); -});