fix: card ordering - process cards in document order
OLD BEHAVIOR (broken): parse_cards processed ALL [card:type] syntax FIRST, then [card type=...] This caused cards to render out of order when syntaxes were mixed. NEW BEHAVIOR (fixed): Using a unified regex that matches BOTH syntaxes simultaneously: /\[card(?::(\w+)|([^\]]*)?)\](.*?)\[\/card\]/s Each match includes: - Group 1: Card type from new syntax [card:type] - Group 2: Attributes from old syntax [card type='...'] - Group 3: Card content Cards now render in exact document order regardless of syntax used.
This commit is contained in:
@@ -288,45 +288,37 @@ class EmailRenderer {
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function parse_cards($content) {
|
private function parse_cards($content) {
|
||||||
$html = '';
|
// Use a single unified regex to match BOTH syntaxes in document order
|
||||||
$has_cards = false;
|
// This ensures cards are rendered in the order they appear
|
||||||
|
$combined_pattern = '/\[card(?::(\w+)|([^\]]*)?)\](.*?)\[\/card\]/s';
|
||||||
|
|
||||||
// Match NEW syntax [card:type]...[/card] first
|
preg_match_all($combined_pattern, $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
|
||||||
preg_match_all('/\[card:(\w+)\](.*?)\[\/card\]/s', $content, $new_matches, PREG_SET_ORDER);
|
|
||||||
|
|
||||||
if (!empty($new_matches)) {
|
if (empty($matches)) {
|
||||||
$has_cards = true;
|
|
||||||
foreach ($new_matches as $match) {
|
|
||||||
$attributes = ['type' => $match[1]];
|
|
||||||
$card_content = $match[2];
|
|
||||||
|
|
||||||
$html .= $this->render_card($card_content, $attributes);
|
|
||||||
$html .= $this->render_card_spacing();
|
|
||||||
|
|
||||||
// Remove matched content to avoid double processing
|
|
||||||
$content = str_replace($match[0], '', $content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match OLD syntax [card type="..."]...[/card]
|
|
||||||
preg_match_all('/\[card([^\]]*)\](.*?)\[\/card\]/s', $content, $old_matches, PREG_SET_ORDER);
|
|
||||||
|
|
||||||
if (!empty($old_matches)) {
|
|
||||||
$has_cards = true;
|
|
||||||
foreach ($old_matches as $match) {
|
|
||||||
$attributes = $this->parse_card_attributes($match[1]);
|
|
||||||
$card_content = $match[2];
|
|
||||||
|
|
||||||
$html .= $this->render_card($card_content, $attributes);
|
|
||||||
$html .= $this->render_card_spacing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$has_cards) {
|
|
||||||
// No cards found, wrap entire content in a single card
|
// No cards found, wrap entire content in a single card
|
||||||
return $this->render_card($content, []);
|
return $this->render_card($content, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$html = '';
|
||||||
|
foreach ($matches as $match) {
|
||||||
|
// Determine which syntax was matched
|
||||||
|
$full_match = $match[0][0];
|
||||||
|
$new_syntax_type = !empty($match[1][0]) ? $match[1][0] : null; // [card:type] format
|
||||||
|
$old_syntax_attrs = $match[2][0] ?? ''; // [card type="..."] format
|
||||||
|
$card_content = $match[3][0];
|
||||||
|
|
||||||
|
if ($new_syntax_type) {
|
||||||
|
// NEW syntax [card:type]
|
||||||
|
$attributes = ['type' => $new_syntax_type];
|
||||||
|
} else {
|
||||||
|
// OLD syntax [card type="..."] or [card]
|
||||||
|
$attributes = $this->parse_card_attributes($old_syntax_attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
$html .= $this->render_card($card_content, $attributes);
|
||||||
|
$html .= $this->render_card_spacing();
|
||||||
|
}
|
||||||
|
|
||||||
// Remove last spacing
|
// Remove last spacing
|
||||||
$html = preg_replace('/<table[^>]*class="card-spacing"[^>]*>.*?<\/table>\s*$/s', '', $html);
|
$html = preg_replace('/<table[^>]*class="card-spacing"[^>]*>.*?<\/table>\s*$/s', '', $html);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user