Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Character Encoding: Remove meta tag after injecting Form #748

Merged
merged 3 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 17 additions & 13 deletions includes/class-convertkit-output.php
Original file line number Diff line number Diff line change
Expand Up @@ -391,27 +391,30 @@ public function append_form_to_content( $content ) {
*/
private function inject_form_after_element( $content, $tag, $index, $form ) {

// Define the meta tag.
$meta_tag = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';

// Wrap content in <html>, <head> and <body> tags now, so we can inject the UTF-8 Content-Type meta tag.
$content = '<html><head></head><body>' . $content . '</body></html>';
$modified_content = '<html><head></head><body>' . $content . '</body></html>';

// Forcibly tell DOMDocument that this HTML uses the UTF-8 charset.
// <meta charset="utf-8"> isn't enough, as DOMDocument still interprets the HTML as ISO-8859, which breaks character encoding
// Use of mb_convert_encoding() with HTML-ENTITIES is deprecated in PHP 8.2, so we have to use this method.
// If we don't, special characters render incorrectly.
$content = str_replace( '<head>', '<head>' . "\n" . '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">', $content );
$modified_content = str_replace( '<head>', '<head>' . "\n" . $meta_tag, $modified_content );

// Load Page / Post content into DOMDocument.
libxml_use_internal_errors( true );
$html = new DOMDocument();
$html->loadHTML( $content, LIBXML_HTML_NODEFDTD );
$html->loadHTML( $modified_content, LIBXML_HTML_NODEFDTD );

// Find the element to append the form to.
// item() is a zero based index.
$element_node = $html->getElementsByTagName( $tag )->item( $index - 1 );

// If the element could not be found, either the number of elements by tag name is less
// than the requested position the form be inserted in, or no element exists.
// Append the form to the content and return.
// Append the form to the original content and return.
if ( is_null( $element_node ) ) {
return $content . $form;
}
Expand All @@ -424,19 +427,20 @@ private function inject_form_after_element( $content, $tag, $index, $form ) {
$element_node->parentNode->insertBefore( $html->importNode( $form_node->documentElement, true ), $element_node->nextSibling ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase

// Fetch HTML string.
$content = $html->saveHTML();
$modified_content = $html->saveHTML();

// Remove some HTML tags that DOMDocument adds, returning the output.
// We do this instead of using LIBXML_HTML_NOIMPLIED in loadHTML(), because Legacy Forms are not always contained in
// a single root / outer element, which is required for LIBXML_HTML_NOIMPLIED to correctly work.
$content = str_replace( '<html>', '', $content );
$content = str_replace( '</html>', '', $content );
$content = str_replace( '<head>', '', $content );
$content = str_replace( '</head>', '', $content );
$content = str_replace( '<body>', '', $content );
$content = str_replace( '</body>', '', $content );

return $content;
$modified_content = str_replace( '<html>', '', $modified_content );
$modified_content = str_replace( '</html>', '', $modified_content );
$modified_content = str_replace( '<head>', '', $modified_content );
$modified_content = str_replace( '</head>', '', $modified_content );
$modified_content = str_replace( '<body>', '', $modified_content );
$modified_content = str_replace( '</body>', '', $modified_content );
$modified_content = str_replace( $meta_tag, '', $modified_content );

return $modified_content;

}

Expand Down
12 changes: 12 additions & 0 deletions tests/acceptance/forms/post-types/CPTFormCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@ public function testAddNewCPTUsingDefaultFormAfterParagraphElement(AcceptanceTes

// Confirm character encoding is not broken due to using DOMDocument.
$I->seeInSource('Adhaésionés altéram improbis mi pariendarum sit stulti triarium');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
}

/**
Expand Down Expand Up @@ -356,6 +359,9 @@ public function testAddNewCPTUsingDefaultFormAfterHeadingElement(AcceptanceTeste

// Confirm character encoding is not broken due to using DOMDocument.
$I->seeInSource('Adhaésionés altéram improbis mi pariendarum sit stulti triarium');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
}

/**
Expand Down Expand Up @@ -395,6 +401,9 @@ public function testAddNewCPTUsingDefaultFormAfterImageElement(AcceptanceTester

// Confirm character encoding is not broken due to using DOMDocument.
$I->seeInSource('Adhaésionés altéram improbis mi pariendarum sit stulti triarium');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
}

/**
Expand Down Expand Up @@ -435,6 +444,9 @@ public function testAddNewCPTUsingDefaultFormAfterOutOfBoundsElement(AcceptanceT

// Confirm character encoding is not broken due to using DOMDocument.
$I->seeInSource('Adhaésionés altéram improbis mi pariendarum sit stulti triarium');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
}

/**
Expand Down
15 changes: 15 additions & 0 deletions tests/acceptance/forms/post-types/PageFormCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,9 @@ public function testAddNewPageUsingDefaultFormAfterParagraphElement(AcceptanceTe

// Confirm character encoding is not broken due to using DOMDocument.
$I->seeInSource('Adhaésionés altéram improbis mi pariendarum sit stulti triarium');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
}

/**
Expand Down Expand Up @@ -280,6 +283,9 @@ public function testAddNewPageUsingDefaultFormAfterHeadingElement(AcceptanceTest

// Confirm character encoding is not broken due to using DOMDocument.
$I->seeInSource('Adhaésionés altéram improbis mi pariendarum sit stulti triarium');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
}

/**
Expand Down Expand Up @@ -319,6 +325,12 @@ public function testAddNewPageUsingDefaultFormAfterImageElement(AcceptanceTester

// Confirm character encoding is not broken due to using DOMDocument.
$I->seeInSource('Adhaésionés altéram improbis mi pariendarum sit stulti triarium');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
}

/**
Expand Down Expand Up @@ -359,6 +371,9 @@ public function testAddNewPageUsingDefaultFormAfterOutOfBoundsElement(Acceptance

// Confirm character encoding is not broken due to using DOMDocument.
$I->seeInSource('Adhaésionés altéram improbis mi pariendarum sit stulti triarium');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
}

/**
Expand Down
12 changes: 12 additions & 0 deletions tests/acceptance/forms/post-types/PostFormCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ public function testAddNewPostUsingDefaultFormAfterParagraphElement(AcceptanceTe

// Confirm character encoding is not broken due to using DOMDocument.
$I->seeInSource('Adhaésionés altéram improbis mi pariendarum sit stulti triarium');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
}

/**
Expand Down Expand Up @@ -279,6 +282,9 @@ public function testAddNewPostUsingDefaultFormAfterHeadingElement(AcceptanceTest

// Confirm character encoding is not broken due to using DOMDocument.
$I->seeInSource('Adhaésionés altéram improbis mi pariendarum sit stulti triarium');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
}

/**
Expand Down Expand Up @@ -318,6 +324,9 @@ public function testAddNewPostUsingDefaultFormAfterImageElement(AcceptanceTester

// Confirm character encoding is not broken due to using DOMDocument.
$I->seeInSource('Adhaésionés altéram improbis mi pariendarum sit stulti triarium');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
}

/**
Expand Down Expand Up @@ -358,6 +367,9 @@ public function testAddNewPostUsingDefaultFormAfterOutOfBoundsElement(Acceptance

// Confirm character encoding is not broken due to using DOMDocument.
$I->seeInSource('Adhaésionés altéram improbis mi pariendarum sit stulti triarium');

// Confirm no meta tag exists within the content.
$I->dontSeeInSource('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">');
}

/**
Expand Down