Show forms on empty product pages

The current logic for form rendering assumes that a single product page
will trigger the filter `the_content`. This is not always true. In cases
where the product has no description, WooCommerce does not render the
description tab at all, which is where that filter usually fires (in my
testing).

This change ensures that we still give these forms a chance to render on
 such pages.

MAILPOET-5859
This commit is contained in:
John Oleksowicz
2024-02-07 14:52:29 -06:00
committed by Aschepikov
parent f6d8eb41b4
commit 0ab2be782d
3 changed files with 52 additions and 1 deletions

View File

@@ -130,7 +130,7 @@ class DisplayFormInWPContent {
* @return void * @return void
*/ */
public function maybeRenderFormsInFooter(): void { public function maybeRenderFormsInFooter(): void {
if ($this->wp->isArchive() || $this->wp->isFrontPage() || $this->wp->isHome()) { if ($this->wp->isArchive() || $this->wp->isFrontPage() || $this->wp->isHome() || $this->isWooProductPageWithoutContent()) {
$formMarkup = $this->getFormMarkup(); $formMarkup = $this->getFormMarkup();
if (!empty($formMarkup)) { if (!empty($formMarkup)) {
$this->assetsController->setupFrontEndDependencies(); $this->assetsController->setupFrontEndDependencies();
@@ -141,6 +141,20 @@ class DisplayFormInWPContent {
} }
} }
/**
* @return bool
*/
public function isWooProductPageWithoutContent(): bool {
if (
!$this->wp->isSingular('product')
|| !$this->wp->didAction('wp_footer')
) {
return false;
}
return !$this->wp->didFilter('the_content');
}
private function shouldDisplay(): bool { private function shouldDisplay(): bool {
$result = true; $result = true;
// This is a fix Yoast plugin and Shapely theme compatibility // This is a fix Yoast plugin and Shapely theme compatibility

View File

@@ -41,6 +41,14 @@ class Functions {
return did_action($hookName); return did_action($hookName);
} }
/**
* @param string $hookName
* @return int
*/
public function didFilter($hookName) {
return did_filter($hookName);
}
public function trailingslashit(string $url) { public function trailingslashit(string $url) {
return trailingslashit($url); return trailingslashit($url);
} }

View File

@@ -894,6 +894,35 @@ class DisplayFormInWPContentTest extends \MailPoetUnitTest {
verify($result)->stringEndsWith($formHtml); verify($result)->stringEndsWith($formHtml);
} }
public function testFormRendersOnProductPageWithoutContent(): void {
$formHtml = '<form id="test-form"></form>';
$this->wp->expects($this->any())->method('isSingular')->willReturn(true);
$this->wp->expects($this->once())->method('didAction')->with($this->equalTo('wp_footer'))->willReturn(true);
$this->wp->expects($this->once())->method('didFilter')->with($this->equalTo('the_content'))->willReturn(false);
$this->assetsController->expects($this->once())->method('setupFrontEndDependencies');
$this->templateRenderer->expects($this->once())->method('render')->willReturn($formHtml);
$this->wp
->expects($this->never())
->method('setTransient');
$form = new FormEntity('My Form');
$form->setSettings([
'segments' => ['3'],
'form_placement' => [
'below_posts' => ['enabled' => '', 'pages' => ['all' => ''], 'posts' => ['all' => '']],
'popup' => ['enabled' => '1', 'pages' => ['all' => ''], 'posts' => ['all' => '']],
'fixed_bar' => ['enabled' => '1', 'pages' => ['all' => '1'], 'posts' => ['all' => '1']]],
'success_message' => 'Hello',
]);
$form->setBody([['type' => 'submit', 'params' => ['label' => 'Subscribe!'], 'id' => 'submit', 'name' => 'Submit']]);
$this->repository->expects($this->once())->method('findBy')->willReturn([$form]);
ob_start();
$this->hook->maybeRenderFormsInFooter();
$renderedFormHtml = ob_get_clean();
verify($renderedFormHtml)->notEquals('content');
verify($renderedFormHtml)->stringEndsWith($formHtml);
}
public function _after() { public function _after() {
parent::_after(); parent::_after();
WPFunctions::set(new WPFunctions()); WPFunctions::set(new WPFunctions());