'; } $placeholder = ''; return '
' . $photoTag . $placeholder . '
'; } /** * Relative date for a row — "5 mins ago" while recent, the site's date * format once it is a month old. * * @param string $createdAt * @return string */ public static function relativeDate($createdAt): string { if (!$createdAt) { return ''; } $createdTimestamp = strtotime($createdAt); if (!$createdTimestamp) { return ''; } $secondsAgo = time() - $createdTimestamp; if ($secondsAgo < MINUTE_IN_SECONDS) { return __('just now', 'fluent-cart'); } if ($secondsAgo < MONTH_IN_SECONDS) { /* translators: 1: human readable time difference, e.g. "5 mins" */ $relative = sprintf(__('%1$s ago', 'fluent-cart'), human_time_diff($createdTimestamp)); return $relative; } return DateTime::gmtToTimezone($createdAt, wp_timezone_string())->format(get_option('date_format')); } /** * Star row with its screen-reader label, matching the storefront list. * * @param int $rating * @return string */ public static function starsHtml($rating): string { $rating = (int) $rating; /* translators: 1: the star rating, e.g. "Rated 4 out of 5" */ $srLabel = sprintf(__('Rated %1$d out of 5', 'fluent-cart'), $rating); $srLabel = esc_html($srLabel); $html = '' . $srLabel . ''; for ($i = 1; $i <= 5; $i++) { $html .= ''; } return $html; } /** * The one star glyph every review surface draws — an SVG filled with * currentColor, so the existing colour classes keep working. * * @return string */ /** * One review media item's markup, shared by the list and the modal. * * The default preserves the contract every consumer of these payloads * has always had: type "video" renders a