Add form placement options for homepage, archives
MAILPOET-4897
This commit is contained in:
committed by
Aschepikov
parent
acbd7fe723
commit
481f5585a0
@@ -57,8 +57,25 @@ function PlacementSettings({ settingsPlacementKey }: Props): JSX.Element {
|
|||||||
prefix = 'preview';
|
prefix = 'preview';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const placementSupportsArchives = settingsPlacementKey !== 'belowPosts';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{placementSupportsArchives && (
|
||||||
|
<ToggleControl
|
||||||
|
label={MailPoet.I18n.t('placeFormOnHomepage')}
|
||||||
|
checked={formSettings.formPlacement[settingsPlacementKey].homepage}
|
||||||
|
onChange={(newValue): void => {
|
||||||
|
compose([
|
||||||
|
changeFormSettings,
|
||||||
|
assocPath(
|
||||||
|
`formPlacement.${settingsPlacementKey}.homepage`,
|
||||||
|
newValue,
|
||||||
|
),
|
||||||
|
])(formSettings);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<ToggleControl
|
<ToggleControl
|
||||||
label={MailPoet.I18n.t('placeFormOnAllPages')}
|
label={MailPoet.I18n.t('placeFormOnAllPages')}
|
||||||
checked={formSettings.formPlacement[settingsPlacementKey].pages.all}
|
checked={formSettings.formPlacement[settingsPlacementKey].pages.all}
|
||||||
@@ -332,6 +349,171 @@ function PlacementSettings({ settingsPlacementKey }: Props): JSX.Element {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{placementSupportsArchives && (
|
||||||
|
<>
|
||||||
|
<ToggleControl
|
||||||
|
label={MailPoet.I18n.t('displayOnAllTagArchives')}
|
||||||
|
checked={
|
||||||
|
formSettings.formPlacement[settingsPlacementKey].tagArchives.all
|
||||||
|
}
|
||||||
|
onChange={(newValue): void => {
|
||||||
|
compose([
|
||||||
|
changeFormSettings,
|
||||||
|
assocPath(
|
||||||
|
`formPlacement.${settingsPlacementKey}.tagArchives.all`,
|
||||||
|
newValue,
|
||||||
|
),
|
||||||
|
cond([
|
||||||
|
[
|
||||||
|
// condition, if the predicate function is true the next compose is run
|
||||||
|
(): boolean => newValue,
|
||||||
|
compose([
|
||||||
|
assocPath(
|
||||||
|
`formPlacement.${settingsPlacementKey}.tagArchives.selected`,
|
||||||
|
[],
|
||||||
|
), // if enabled clear selected tags
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
[(): boolean => !newValue, identity], // if disabled do nothing
|
||||||
|
]),
|
||||||
|
])(formSettings);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div data-automation-id="form-placement-select-archive-tags">
|
||||||
|
<div className="form-editor-placement-selection">
|
||||||
|
<Selection
|
||||||
|
dropDownParent={
|
||||||
|
isPreviewShown ? '.mailpoet-modal-content' : undefined
|
||||||
|
}
|
||||||
|
item={{
|
||||||
|
id: `${prefix}${formSettings.formPlacement[
|
||||||
|
settingsPlacementKey
|
||||||
|
].tagArchives.selected.join()}`,
|
||||||
|
}}
|
||||||
|
onValueChange={(e): void => {
|
||||||
|
const selected =
|
||||||
|
formSettings.formPlacement[settingsPlacementKey].tagArchives
|
||||||
|
.selected;
|
||||||
|
if (isEqual(selected, e.target.value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
compose([
|
||||||
|
changeFormSettings,
|
||||||
|
assocPath(
|
||||||
|
`formPlacement.${settingsPlacementKey}.tagArchives.selected`,
|
||||||
|
e.target.value,
|
||||||
|
),
|
||||||
|
cond([
|
||||||
|
[
|
||||||
|
// only disable "All pages" toggle if not empty
|
||||||
|
(): boolean => !!e.target.value.length,
|
||||||
|
assocPath(
|
||||||
|
`formPlacement.${settingsPlacementKey}.tagArchives.all`,
|
||||||
|
false,
|
||||||
|
), // disable all if some pages are selected
|
||||||
|
],
|
||||||
|
[(): boolean => !e.target.value.length, identity],
|
||||||
|
]),
|
||||||
|
])(formSettings);
|
||||||
|
}}
|
||||||
|
field={{
|
||||||
|
id: `${prefix}tagArchives`,
|
||||||
|
name: 'tagArchives',
|
||||||
|
values: tags,
|
||||||
|
multiple: true,
|
||||||
|
placeholder: MailPoet.I18n.t('selectSpecificArchiveTags'),
|
||||||
|
getLabel: (tag): void => tag.name,
|
||||||
|
selected: (): void =>
|
||||||
|
formSettings.formPlacement[settingsPlacementKey].tagArchives
|
||||||
|
.selected,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ToggleControl
|
||||||
|
label={MailPoet.I18n.t('displayOnAllCategoryArchives')}
|
||||||
|
checked={
|
||||||
|
formSettings.formPlacement[settingsPlacementKey].categoryArchives
|
||||||
|
.all
|
||||||
|
}
|
||||||
|
onChange={(newValue): void => {
|
||||||
|
compose([
|
||||||
|
changeFormSettings,
|
||||||
|
assocPath(
|
||||||
|
`formPlacement.${settingsPlacementKey}.categoryArchives.all`,
|
||||||
|
newValue,
|
||||||
|
),
|
||||||
|
cond([
|
||||||
|
[
|
||||||
|
// condition, if the predicate function is true the next compose is run
|
||||||
|
(): boolean => newValue,
|
||||||
|
compose([
|
||||||
|
assocPath(
|
||||||
|
`formPlacement.${settingsPlacementKey}.categoryArchives.selected`,
|
||||||
|
[],
|
||||||
|
), // if enabled clear selected categories
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
[(): boolean => !newValue, identity], // if disabled do nothing
|
||||||
|
]),
|
||||||
|
])(formSettings);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div data-automation-id="form-placement-select-archive-categories">
|
||||||
|
<div className="form-editor-placement-selection">
|
||||||
|
<Selection
|
||||||
|
dropDownParent={
|
||||||
|
isPreviewShown ? '.mailpoet-modal-content' : undefined
|
||||||
|
}
|
||||||
|
item={{
|
||||||
|
id: `${prefix}${formSettings.formPlacement[
|
||||||
|
settingsPlacementKey
|
||||||
|
].categoryArchives.selected.join()}`,
|
||||||
|
}}
|
||||||
|
onValueChange={(e): void => {
|
||||||
|
const selected =
|
||||||
|
formSettings.formPlacement[settingsPlacementKey]
|
||||||
|
.categoryArchives.selected;
|
||||||
|
if (isEqual(selected, e.target.value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
compose([
|
||||||
|
changeFormSettings,
|
||||||
|
assocPath(
|
||||||
|
`formPlacement.${settingsPlacementKey}.categoryArchives.selected`,
|
||||||
|
e.target.value,
|
||||||
|
),
|
||||||
|
cond([
|
||||||
|
[
|
||||||
|
// only disable "All pages" toggle if not empty
|
||||||
|
(): boolean => !!e.target.value.length,
|
||||||
|
assocPath(
|
||||||
|
`formPlacement.${settingsPlacementKey}.categoryArchives.all`,
|
||||||
|
false,
|
||||||
|
), // disable all if some pages are selected
|
||||||
|
],
|
||||||
|
[(): boolean => !e.target.value.length, identity],
|
||||||
|
]),
|
||||||
|
])(formSettings);
|
||||||
|
}}
|
||||||
|
field={{
|
||||||
|
id: `${prefix}categoryArchives`,
|
||||||
|
name: 'categoryArchives',
|
||||||
|
values: categories,
|
||||||
|
multiple: true,
|
||||||
|
placeholder: MailPoet.I18n.t(
|
||||||
|
'selectSpecificArchiveCategories',
|
||||||
|
),
|
||||||
|
getLabel: (tag): void => tag.name,
|
||||||
|
selected: (): void =>
|
||||||
|
formSettings.formPlacement[settingsPlacementKey]
|
||||||
|
.categoryArchives.selected,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,9 @@ type FormPlacementBase = {
|
|||||||
tags: string[] | number[];
|
tags: string[] | number[];
|
||||||
posts: { all: boolean | '' | '1'; selected: string[] };
|
posts: { all: boolean | '' | '1'; selected: string[] };
|
||||||
pages: { all: boolean | '' | '1'; selected: string[] };
|
pages: { all: boolean | '' | '1'; selected: string[] };
|
||||||
|
homepage: boolean | '' | '1';
|
||||||
|
tagArchives: { all: boolean | '' | '1'; selected: string[] };
|
||||||
|
categoryArchives: { all: boolean | '' | '1'; selected: string[] };
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FormSettingsType = {
|
export type FormSettingsType = {
|
||||||
|
@@ -45,6 +45,25 @@ export function mapFormDataAfterLoading(data) {
|
|||||||
? data.settings.form_placement?.popup?.pages?.selected
|
? data.settings.form_placement?.popup?.pages?.selected
|
||||||
: [],
|
: [],
|
||||||
},
|
},
|
||||||
|
homepage: data.settings.form_placement?.popup?.homepage === '1',
|
||||||
|
tagArchives: {
|
||||||
|
all: data.settings.form_placement?.popup?.tagArchives?.all === '1',
|
||||||
|
selected: Array.isArray(
|
||||||
|
data.settings.form_placement?.popup?.tagArchives?.selected,
|
||||||
|
)
|
||||||
|
? data.settings.form_placement?.popup?.tagArchives?.selected
|
||||||
|
: [],
|
||||||
|
},
|
||||||
|
categoryArchives: {
|
||||||
|
all:
|
||||||
|
data.settings.form_placement?.popup?.categoryArchives?.all ===
|
||||||
|
'1',
|
||||||
|
selected: Array.isArray(
|
||||||
|
data.settings.form_placement?.popup?.categoryArchives?.selected,
|
||||||
|
)
|
||||||
|
? data.settings.form_placement?.popup?.categoryArchives?.selected
|
||||||
|
: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fixedBar: {
|
fixedBar: {
|
||||||
enabled: data.settings.form_placement?.fixed_bar?.enabled === '1',
|
enabled: data.settings.form_placement?.fixed_bar?.enabled === '1',
|
||||||
@@ -85,6 +104,28 @@ export function mapFormDataAfterLoading(data) {
|
|||||||
? data.settings.form_placement?.fixed_bar?.pages?.selected
|
? data.settings.form_placement?.fixed_bar?.pages?.selected
|
||||||
: [],
|
: [],
|
||||||
},
|
},
|
||||||
|
homepage: data.settings.form_placement?.fixed_bar?.homepage === '1',
|
||||||
|
tagArchives: {
|
||||||
|
all:
|
||||||
|
data.settings.form_placement?.fixed_bar?.tagArchives?.all === '1',
|
||||||
|
selected: Array.isArray(
|
||||||
|
data.settings.form_placement?.fixed_bar?.tagArchives?.selected,
|
||||||
|
)
|
||||||
|
? data.settings.form_placement?.fixed_bar?.tagArchives?.selected
|
||||||
|
: [],
|
||||||
|
},
|
||||||
|
categoryArchives: {
|
||||||
|
all:
|
||||||
|
data.settings.form_placement?.fixed_bar?.categoryArchives?.all ===
|
||||||
|
'1',
|
||||||
|
selected: Array.isArray(
|
||||||
|
data.settings.form_placement?.fixed_bar?.categoryArchives
|
||||||
|
?.selected,
|
||||||
|
)
|
||||||
|
? data.settings.form_placement?.fixed_bar?.categoryArchives
|
||||||
|
?.selected
|
||||||
|
: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
belowPosts: {
|
belowPosts: {
|
||||||
enabled: data.settings.form_placement?.below_posts?.enabled === '1',
|
enabled: data.settings.form_placement?.below_posts?.enabled === '1',
|
||||||
@@ -151,6 +192,28 @@ export function mapFormDataAfterLoading(data) {
|
|||||||
? data.settings.form_placement?.slide_in?.pages?.selected
|
? data.settings.form_placement?.slide_in?.pages?.selected
|
||||||
: [],
|
: [],
|
||||||
},
|
},
|
||||||
|
homepage: data.settings.form_placement?.slide_in?.homepage === '1',
|
||||||
|
tagArchives: {
|
||||||
|
all:
|
||||||
|
data.settings.form_placement?.slide_in?.tagArchives?.all === '1',
|
||||||
|
selected: Array.isArray(
|
||||||
|
data.settings.form_placement?.slide_in?.tagArchives?.selected,
|
||||||
|
)
|
||||||
|
? data.settings.form_placement?.slide_in?.tagArchives?.selected
|
||||||
|
: [],
|
||||||
|
},
|
||||||
|
categoryArchives: {
|
||||||
|
all:
|
||||||
|
data.settings.form_placement?.slide_in?.categoryArchives?.all ===
|
||||||
|
'1',
|
||||||
|
selected: Array.isArray(
|
||||||
|
data.settings.form_placement?.slide_in?.categoryArchives
|
||||||
|
?.selected,
|
||||||
|
)
|
||||||
|
? data.settings.form_placement?.slide_in?.categoryArchives
|
||||||
|
?.selected
|
||||||
|
: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
others: {
|
others: {
|
||||||
styles: {
|
styles: {
|
||||||
|
@@ -32,6 +32,23 @@ export function mapFormDataBeforeSaving(data) {
|
|||||||
: '',
|
: '',
|
||||||
selected: data.settings.formPlacement?.popup?.pages?.selected,
|
selected: data.settings.formPlacement?.popup?.pages?.selected,
|
||||||
},
|
},
|
||||||
|
homepage:
|
||||||
|
data.settings.formPlacement?.popup?.homepage === true ? '1' : '',
|
||||||
|
tagArchives: {
|
||||||
|
all:
|
||||||
|
data.settings.formPlacement?.popup?.tagArchives?.all === true
|
||||||
|
? '1'
|
||||||
|
: '',
|
||||||
|
selected: data.settings.formPlacement?.popup?.tagArchives?.selected,
|
||||||
|
},
|
||||||
|
categoryArchives: {
|
||||||
|
all:
|
||||||
|
data.settings.formPlacement?.popup?.categoryArchives?.all === true
|
||||||
|
? '1'
|
||||||
|
: '',
|
||||||
|
selected:
|
||||||
|
data.settings.formPlacement?.popup?.categoryArchives?.selected,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fixed_bar: {
|
fixed_bar: {
|
||||||
enabled:
|
enabled:
|
||||||
@@ -58,6 +75,25 @@ export function mapFormDataBeforeSaving(data) {
|
|||||||
: '',
|
: '',
|
||||||
selected: data.settings.formPlacement?.fixedBar?.pages?.selected,
|
selected: data.settings.formPlacement?.fixedBar?.pages?.selected,
|
||||||
},
|
},
|
||||||
|
homepage:
|
||||||
|
data.settings.formPlacement?.fixedBar?.homepage === true ? '1' : '',
|
||||||
|
tagArchives: {
|
||||||
|
all:
|
||||||
|
data.settings.formPlacement?.fixedBar?.tagArchives?.all === true
|
||||||
|
? '1'
|
||||||
|
: '',
|
||||||
|
selected:
|
||||||
|
data.settings.formPlacement?.fixedBar?.tagArchives?.selected,
|
||||||
|
},
|
||||||
|
categoryArchives: {
|
||||||
|
all:
|
||||||
|
data.settings.formPlacement?.fixedBar?.categoryArchives?.all ===
|
||||||
|
true
|
||||||
|
? '1'
|
||||||
|
: '',
|
||||||
|
selected:
|
||||||
|
data.settings.formPlacement?.fixedBar?.categoryArchives?.selected,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
below_posts: {
|
below_posts: {
|
||||||
enabled:
|
enabled:
|
||||||
@@ -107,6 +143,25 @@ export function mapFormDataBeforeSaving(data) {
|
|||||||
: '',
|
: '',
|
||||||
selected: data.settings.formPlacement?.slideIn?.pages?.selected,
|
selected: data.settings.formPlacement?.slideIn?.pages?.selected,
|
||||||
},
|
},
|
||||||
|
homepage:
|
||||||
|
data.settings.formPlacement?.slideIn?.homepage === true ? '1' : '',
|
||||||
|
tagArchives: {
|
||||||
|
all:
|
||||||
|
data.settings.formPlacement?.slideIn?.tagArchives?.all === true
|
||||||
|
? '1'
|
||||||
|
: '',
|
||||||
|
selected:
|
||||||
|
data.settings.formPlacement?.slideIn?.tagArchives?.selected,
|
||||||
|
},
|
||||||
|
categoryArchives: {
|
||||||
|
all:
|
||||||
|
data.settings.formPlacement?.slideIn?.categoryArchives?.all ===
|
||||||
|
true
|
||||||
|
? '1'
|
||||||
|
: '',
|
||||||
|
selected:
|
||||||
|
data.settings.formPlacement?.slideIn?.categoryArchives?.selected,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
others: {
|
others: {
|
||||||
styles: data.settings.formPlacement?.others?.styles,
|
styles: data.settings.formPlacement?.others?.styles,
|
||||||
|
@@ -234,6 +234,10 @@ class Hooks {
|
|||||||
'woocommerce_product_loop_end',
|
'woocommerce_product_loop_end',
|
||||||
[$this->displayFormInWPContent, 'wooProductListDisplay']
|
[$this->displayFormInWPContent, 'wooProductListDisplay']
|
||||||
);
|
);
|
||||||
|
$this->wp->addAction(
|
||||||
|
'wp_footer',
|
||||||
|
[$this->displayFormInWPContent, 'maybeRenderFormsInFooter']
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setupMailer() {
|
public function setupMailer() {
|
||||||
|
@@ -61,6 +61,8 @@ class DisplayFormInWPContent {
|
|||||||
|
|
||||||
private $inWooProductLoop = false;
|
private $inWooProductLoop = false;
|
||||||
|
|
||||||
|
private $renderedDisplayTypes = [];
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
WPFunctions $wp,
|
WPFunctions $wp,
|
||||||
FormsRepository $formsRepository,
|
FormsRepository $formsRepository,
|
||||||
@@ -81,43 +83,69 @@ class DisplayFormInWPContent {
|
|||||||
$this->woocommerceHelper = $woocommerceHelper;
|
$this->woocommerceHelper = $woocommerceHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private function getFormMarkup(): string {
|
||||||
* This takes input from an action and any plugin or theme can pass anything.
|
$formMarkup = '';
|
||||||
* We return string for regular content otherwise we just pass thru what comes.
|
|
||||||
* @param mixed $content
|
|
||||||
* @return string|mixed
|
|
||||||
*/
|
|
||||||
private function display($content = null) {
|
|
||||||
if (!is_string($content) || !$this->shouldDisplay()) return $content;
|
|
||||||
|
|
||||||
$forms = $this->getForms();
|
$forms = $this->getForms();
|
||||||
if (count($forms) === 0) {
|
if (count($forms) === 0) {
|
||||||
return $content;
|
return $formMarkup;
|
||||||
|
}
|
||||||
|
foreach ($forms as $displayType => $form) {
|
||||||
|
$formMarkup .= $this->getContentBellow($form, $displayType);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assetsController->setupFrontEndDependencies();
|
return $formMarkup;
|
||||||
$result = $content;
|
|
||||||
foreach ($forms as $displayType => $form) {
|
|
||||||
$result .= $this->getContentBellow($form, $displayType);
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hooked to the_content filter
|
||||||
|
*/
|
||||||
public function contentDisplay($content = null) {
|
public function contentDisplay($content = null) {
|
||||||
$this->inWooProductLoop = false;
|
$this->inWooProductLoop = false;
|
||||||
return $this->display($content);
|
return $this->getContentWithFormMarkup($content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hooked to woocommerce_product_loop_end filter
|
||||||
|
*/
|
||||||
public function wooProductListDisplay($content = null) {
|
public function wooProductListDisplay($content = null) {
|
||||||
$this->inWooProductLoop = true;
|
$this->inWooProductLoop = true;
|
||||||
return $this->display($content);
|
return $this->getContentWithFormMarkup($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getContentWithFormMarkup($content = null) {
|
||||||
|
if (!is_string($content) || !$this->shouldDisplay()) {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
$formsMarkup = $this->getFormMarkup();
|
||||||
|
if ($formsMarkup === '') {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
$this->assetsController->setupFrontEndDependencies();
|
||||||
|
return $content . $formsMarkup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hooked to wp_footer action.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function maybeRenderFormsInFooter(): void {
|
||||||
|
if ($this->wp->isArchive() || $this->wp->isFrontPage()) {
|
||||||
|
$formMarkup = $this->getFormMarkup();
|
||||||
|
if (!empty($formMarkup)) {
|
||||||
|
$this->assetsController->setupFrontEndDependencies();
|
||||||
|
// We are in control of the template and the data can be considered safe at this point
|
||||||
|
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, WordPressDotOrg.sniffs.OutputEscaping.UnescapedOutputParameter
|
||||||
|
echo $formMarkup;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
// This is to make sure we only display once for each page
|
// This is to make sure we only display once for each page
|
||||||
// Yast plugin calls `get_the_excerpt` which also triggers hook `the_content` we don't want to include our form in that
|
// Yoast plugin calls `get_the_excerpt` which also triggers hook `the_content` we don't want to include our form in that
|
||||||
// Shapely calls the hook `the_content` multiple times on the page as well and we would display popup multiple times - not ideal
|
// Shapely calls the hook `the_content` multiple times on the page as well and we would display popup multiple times - not ideal
|
||||||
if (!$this->wp->inTheLoop() || !$this->wp->isMainQuery()) {
|
if (!$this->wp->inTheLoop() || !$this->wp->isMainQuery()) {
|
||||||
$result = $this->wp->applyFilters('mailpoet_display_form_is_main_loop', false);
|
$result = $this->wp->applyFilters('mailpoet_display_form_is_main_loop', false);
|
||||||
@@ -228,6 +256,7 @@ class DisplayFormInWPContent {
|
|||||||
|
|
||||||
// add API version
|
// add API version
|
||||||
$templateData['api_version'] = API::CURRENT_VERSION;
|
$templateData['api_version'] = API::CURRENT_VERSION;
|
||||||
|
$this->renderedDisplayTypes[] = $displayType;
|
||||||
return $this->templateRenderer->render('form/front_end_form.html', $templateData);
|
return $this->templateRenderer->render('form/front_end_form.html', $templateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +280,9 @@ class DisplayFormInWPContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function shouldDisplayFormType(FormEntity $form, string $formType): bool {
|
private function shouldDisplayFormType(FormEntity $form, string $formType): bool {
|
||||||
|
if ($this->wasDisplayTypeAlreadyRendered($formType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$settings = $form->getSettings();
|
$settings = $form->getSettings();
|
||||||
// check the structure just to be sure
|
// check the structure just to be sure
|
||||||
|
|
||||||
@@ -267,6 +299,10 @@ class DisplayFormInWPContent {
|
|||||||
|
|
||||||
if (!$this->shouldDisplayFormForWPUser($form, $formType)) return false;
|
if (!$this->shouldDisplayFormForWPUser($form, $formType)) return false;
|
||||||
|
|
||||||
|
if ($this->wp->isFrontPage() && $this->shouldDisplayFormOnFrontPage($setup)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->wp->isSingular($this->wp->applyFilters('mailpoet_display_form_supported_post_types', self::SUPPORTED_POST_TYPES))) {
|
if ($this->wp->isSingular($this->wp->applyFilters('mailpoet_display_form_supported_post_types', self::SUPPORTED_POST_TYPES))) {
|
||||||
if ($this->shouldDisplayFormOnPost($setup, 'posts')) return true;
|
if ($this->shouldDisplayFormOnPost($setup, 'posts')) return true;
|
||||||
if ($this->shouldDisplayFormOnCategory($setup)) return true;
|
if ($this->shouldDisplayFormOnCategory($setup)) return true;
|
||||||
@@ -277,6 +313,14 @@ class DisplayFormInWPContent {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->wp->isTag() || $this->wp->isTax('product_tag')) {
|
||||||
|
if ($this->shouldDisplayFormOnTagArchive($setup)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->wp->isCategory() || $this->wp->isTax('product_cat')) {
|
||||||
|
if ($this->shouldDisplayFormOnCategoryArchive($setup)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->displayFormInProductListPage()) {
|
if ($this->displayFormInProductListPage()) {
|
||||||
// Allow form display on Woo Shop listing page
|
// Allow form display on Woo Shop listing page
|
||||||
if (is_null($this->wooShopPageId)) return false;
|
if (is_null($this->wooShopPageId)) return false;
|
||||||
@@ -313,4 +357,28 @@ class DisplayFormInWPContent {
|
|||||||
if ($this->wp->hasTerm($setup['tags'], 'product_tag')) return true;
|
if ($this->wp->hasTerm($setup['tags'], 'product_tag')) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function shouldDisplayFormOnFrontPage(array $setup): bool {
|
||||||
|
return ($setup['homepage'] ?? false) === '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
private function shouldDisplayFormOnCategoryArchive($setup): bool {
|
||||||
|
if (!isset($setup['categoryArchives'])) return false;
|
||||||
|
if (($setup['categoryArchives']['all'] ?? false) === '1') return true;
|
||||||
|
$selectedCategories = $setup['categoryArchives']['selected'] ?? [];
|
||||||
|
if ($selectedCategories === []) return false;
|
||||||
|
return $this->wp->hasCategory($selectedCategories) || $this->wp->hasTerm($selectedCategories, 'product_cat');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function shouldDisplayFormOnTagArchive($setup): bool {
|
||||||
|
if (!isset($setup['tagArchives'])) return false;
|
||||||
|
if (($setup['tagArchives']['all'] ?? false) === '1') return true;
|
||||||
|
$selectedTags = $setup['tagArchives']['selected'] ?? [];
|
||||||
|
if ($selectedTags === []) return false;
|
||||||
|
return $this->wp->hasTag($selectedTags) || $this->wp->hasTerm($selectedTags, 'product_tag');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function wasDisplayTypeAlreadyRendered(string $displayType): bool {
|
||||||
|
return in_array($displayType, $this->renderedDisplayTypes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -643,6 +643,10 @@ class Functions {
|
|||||||
return is_main_query();
|
return is_main_query();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isFrontPage(): bool {
|
||||||
|
return is_front_page();
|
||||||
|
}
|
||||||
|
|
||||||
public function getPrivacyPolicyUrl(): string {
|
public function getPrivacyPolicyUrl(): string {
|
||||||
return get_privacy_policy_url();
|
return get_privacy_policy_url();
|
||||||
}
|
}
|
||||||
@@ -693,6 +697,18 @@ class Functions {
|
|||||||
return is_archive();
|
return is_archive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isTag($tag = '') {
|
||||||
|
return is_tag($tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isCategory($category = '') {
|
||||||
|
return is_category($category);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isTax($taxonomy = '', $term = '') {
|
||||||
|
return is_tax($taxonomy, $term);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the query is for an existing post type archive page.
|
* Determines whether the query is for an existing post type archive page.
|
||||||
*
|
*
|
||||||
|
@@ -522,6 +522,198 @@ class DisplayFormInWPContentTest extends \MailPoetUnitTest {
|
|||||||
expect($result)->endsWith($formHtml);
|
expect($result)->endsWith($formHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDisplayFormOnAllTagArchives(): void {
|
||||||
|
$formHtml = '<form id="test-form"></form>';
|
||||||
|
$this->wp->expects($this->any())->method('isTag')->willReturn(true);
|
||||||
|
$this->wp->expects($this->any())->method('isArchive')->willReturn(true);
|
||||||
|
$this->assetsController->expects($this->once())->method('setupFrontEndDependencies');
|
||||||
|
$this->templateRenderer->expects($this->once())->method('render')->willReturn($formHtml);
|
||||||
|
$form = new FormEntity('My Form');
|
||||||
|
$form->setSettings([
|
||||||
|
'segments' => ['3'],
|
||||||
|
'form_placement' => [
|
||||||
|
'popup' => ['enabled' => '1', '', 'tagArchives' => ['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();
|
||||||
|
expect($renderedFormHtml)->equals($formHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItRendersOnlyForSpecificTagArchive(): void {
|
||||||
|
$formHtml = '<form id="test-form"></form>';
|
||||||
|
$this->wp->expects($this->any())->method('isArchive')->willReturn(true);
|
||||||
|
$this->wp->expects($this->any())->method('isTag')->willReturn(true);
|
||||||
|
$this->wp->expects($this->any())->method('hasTag')->willReturnCallback(function(array $tags) {
|
||||||
|
if (in_array('10', $tags)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$this->assetsController->expects($this->once())->method('setupFrontEndDependencies');
|
||||||
|
$this->templateRenderer->expects($this->once())->method('render')->willReturn($formHtml);
|
||||||
|
$form = new FormEntity('My Form');
|
||||||
|
$form->setSettings([
|
||||||
|
'segments' => ['3'],
|
||||||
|
'form_placement' => [
|
||||||
|
'popup' => ['enabled' => '1', '', 'tagArchives' => ['all' => '', 'selected' => ['10']]],
|
||||||
|
],
|
||||||
|
'success_message' => 'Hello',
|
||||||
|
]);
|
||||||
|
$form->setBody([['type' => 'submit', 'params' => ['label' => 'Subscribe!'], 'id' => 'submit', 'name' => 'Submit']]);
|
||||||
|
$this->repository->expects($this->any())->method('findBy')->willReturn([$form]);
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
$this->hook->maybeRenderFormsInFooter();
|
||||||
|
$renderedFormHtml = ob_get_clean();
|
||||||
|
expect($renderedFormHtml)->equals($formHtml);
|
||||||
|
|
||||||
|
$form->setSettings([
|
||||||
|
'segments' => ['3'],
|
||||||
|
'form_placement' => [
|
||||||
|
'popup' => ['enabled' => '1', '', 'categoryArchives' => ['all' => '', 'selected' => ['15']]],
|
||||||
|
],
|
||||||
|
'success_message' => 'Hello',
|
||||||
|
]);
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
$this->hook->maybeRenderFormsInFooter();
|
||||||
|
$renderedFormHtml = ob_get_clean();
|
||||||
|
expect($renderedFormHtml)->equals('');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItDoesNotDisplayOnTagListingIfNotEnabled(): void {
|
||||||
|
$this->wp->expects($this->any())->method('isTag')->willReturn(true);
|
||||||
|
$this->wp->expects($this->any())->method('isArchive')->willReturn(true);
|
||||||
|
$this->assetsController->expects($this->never())->method('setupFrontEndDependencies');
|
||||||
|
$form = new FormEntity('My Form');
|
||||||
|
$form->setSettings([
|
||||||
|
'segments' => ['3'],
|
||||||
|
'form_placement' => [
|
||||||
|
'popup' => ['enabled' => '1', '', 'tagArchives' => ['all' => '']],
|
||||||
|
],
|
||||||
|
'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();
|
||||||
|
expect($renderedFormHtml)->equals('');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDisplayFormOnAllCategoryArchives(): void {
|
||||||
|
$formHtml = '<form id="test-form"></form>';
|
||||||
|
$this->wp->expects($this->any())->method('isArchive')->willReturn(true);
|
||||||
|
$this->wp->expects($this->any())->method('isCategory')->willReturn(true);
|
||||||
|
$this->assetsController->expects($this->once())->method('setupFrontEndDependencies');
|
||||||
|
$this->templateRenderer->expects($this->once())->method('render')->willReturn($formHtml);
|
||||||
|
$form = new FormEntity('My Form');
|
||||||
|
$form->setSettings([
|
||||||
|
'segments' => ['3'],
|
||||||
|
'form_placement' => [
|
||||||
|
'popup' => ['enabled' => '1', '', 'categoryArchives' => ['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();
|
||||||
|
expect($renderedFormHtml)->equals($formHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItRendersOnlyForSpecificCategoryArchive(): void {
|
||||||
|
$formHtml = '<form id="test-form"></form>';
|
||||||
|
$this->wp->expects($this->any())->method('isArchive')->willReturn(true);
|
||||||
|
$this->wp->expects($this->any())->method('isCategory')->willReturn(true);
|
||||||
|
$this->wp->expects($this->any())->method('hasCategory')->willReturnCallback(function(array $categories) {
|
||||||
|
return in_array('10', $categories);
|
||||||
|
});
|
||||||
|
$this->assetsController->expects($this->once())->method('setupFrontEndDependencies');
|
||||||
|
$this->templateRenderer->expects($this->once())->method('render')->willReturn($formHtml);
|
||||||
|
$form = new FormEntity('My Form');
|
||||||
|
$form->setSettings([
|
||||||
|
'segments' => ['3'],
|
||||||
|
'form_placement' => [
|
||||||
|
'popup' => ['enabled' => '1', '', 'categoryArchives' => ['all' => '', 'selected' => ['10']]],
|
||||||
|
],
|
||||||
|
'success_message' => 'Hello',
|
||||||
|
]);
|
||||||
|
$form->setBody([['type' => 'submit', 'params' => ['label' => 'Subscribe!'], 'id' => 'submit', 'name' => 'Submit']]);
|
||||||
|
$this->repository->expects($this->any())->method('findBy')->willReturn([$form]);
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
$this->hook->maybeRenderFormsInFooter();
|
||||||
|
$renderedFormHtml = ob_get_clean();
|
||||||
|
expect($renderedFormHtml)->equals($formHtml);
|
||||||
|
|
||||||
|
$form->setSettings([
|
||||||
|
'segments' => ['3'],
|
||||||
|
'form_placement' => [
|
||||||
|
'popup' => ['enabled' => '1', '', 'categoryArchives' => ['all' => '', 'selected' => ['15']]],
|
||||||
|
],
|
||||||
|
'success_message' => 'Hello',
|
||||||
|
]);
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
$this->hook->maybeRenderFormsInFooter();
|
||||||
|
$renderedFormHtml = ob_get_clean();
|
||||||
|
expect($renderedFormHtml)->equals('');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItDoesNotDisplayOnCategoryListingIfNotEnabled(): void {
|
||||||
|
$this->wp->expects($this->any())->method('isArchive')->willReturn(true);
|
||||||
|
$this->wp->expects($this->any())->method('isCategory')->willReturn(true);
|
||||||
|
$this->assetsController->expects($this->never())->method('setupFrontEndDependencies');
|
||||||
|
$form = new FormEntity('My Form');
|
||||||
|
$form->setSettings([
|
||||||
|
'segments' => ['3'],
|
||||||
|
'form_placement' => [
|
||||||
|
'popup' => ['enabled' => '1', '', 'categoryArchives' => ['all' => '']],
|
||||||
|
],
|
||||||
|
'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();
|
||||||
|
expect($renderedFormHtml)->equals('');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testItDisplaysOnHomepage(): void {
|
||||||
|
$formHtml = '<form id="test-form"></form>';
|
||||||
|
$this->wp->expects($this->any())->method('isFrontPage')->willReturn(true);
|
||||||
|
$this->assetsController->expects($this->once())->method('setupFrontEndDependencies');
|
||||||
|
$this->templateRenderer->expects($this->once())->method('render')->willReturn($formHtml);
|
||||||
|
$form = new FormEntity('My Form');
|
||||||
|
$form->setSettings([
|
||||||
|
'segments' => ['3'],
|
||||||
|
'form_placement' => [
|
||||||
|
'popup' => ['enabled' => '1', 'homepage' => '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();
|
||||||
|
expect($renderedFormHtml)->equals($formHtml);
|
||||||
|
}
|
||||||
|
|
||||||
public function testDoesNotAppendPopupFormIfLoggedInAndSubscribed() {
|
public function testDoesNotAppendPopupFormIfLoggedInAndSubscribed() {
|
||||||
$formHtml = '<form id="test-form"></form>';
|
$formHtml = '<form id="test-form"></form>';
|
||||||
$subscriber = new SubscriberEntity();
|
$subscriber = new SubscriberEntity();
|
||||||
@@ -532,16 +724,16 @@ class DisplayFormInWPContentTest extends \MailPoetUnitTest {
|
|||||||
$this->assetsController->expects($this->never())->method('setupFrontEndDependencies');
|
$this->assetsController->expects($this->never())->method('setupFrontEndDependencies');
|
||||||
$this->templateRenderer->expects($this->never())->method('render')->willReturn($formHtml);
|
$this->templateRenderer->expects($this->never())->method('render')->willReturn($formHtml);
|
||||||
$this->wp
|
$this->wp
|
||||||
->expects($this->never())
|
->expects($this->never())
|
||||||
->method('setTransient');
|
->method('setTransient');
|
||||||
$form = new FormEntity('My Form');
|
$form = new FormEntity('My Form');
|
||||||
$form->setSettings([
|
$form->setSettings([
|
||||||
'segments' => ['3'],
|
'segments' => ['3'],
|
||||||
'form_placement' => [
|
'form_placement' => [
|
||||||
'below_posts' => ['enabled' => '', 'pages' => ['all' => ''], 'posts' => ['all' => '']],
|
'below_posts' => ['enabled' => '', 'pages' => ['all' => ''], 'posts' => ['all' => '']],
|
||||||
'popup' => ['enabled' => '1', 'pages' => ['all' => '1'], 'posts' => ['all' => '']],
|
'popup' => ['enabled' => '1', 'pages' => ['all' => '1'], 'posts' => ['all' => '']],
|
||||||
],
|
],
|
||||||
'success_message' => 'Hello',
|
'success_message' => 'Hello',
|
||||||
]);
|
]);
|
||||||
$form->setBody([['type' => 'submit', 'params' => ['label' => 'Subscribe!'], 'id' => 'submit', 'name' => 'Submit']]);
|
$form->setBody([['type' => 'submit', 'params' => ['label' => 'Subscribe!'], 'id' => 'submit', 'name' => 'Submit']]);
|
||||||
$this->repository->expects($this->once())->method('findBy')->willReturn([$form]);
|
$this->repository->expects($this->once())->method('findBy')->willReturn([$form]);
|
||||||
|
@@ -95,6 +95,7 @@
|
|||||||
'placeFormBellowPagesDescription': __('This form placement allows you to add this form at the end of all the pages or posts, below the content.'),
|
'placeFormBellowPagesDescription': __('This form placement allows you to add this form at the end of all the pages or posts, below the content.'),
|
||||||
'placeFormOnAllPages': _x('Display on all pages', 'This is a text on a switch if a form should be displayed bellow all pages'),
|
'placeFormOnAllPages': _x('Display on all pages', 'This is a text on a switch if a form should be displayed bellow all pages'),
|
||||||
'placeFormOnAllPosts': _x('Display on all posts/products', 'This is a text on a switch if a form should be displayed bellow all posts'),
|
'placeFormOnAllPosts': _x('Display on all posts/products', 'This is a text on a switch if a form should be displayed bellow all posts'),
|
||||||
|
'placeFormOnHomepage': __('Display on the homepage'),
|
||||||
'placeFormOthers': _x('Others (widget)', 'Placement of the form using theme widget'),
|
'placeFormOthers': _x('Others (widget)', 'Placement of the form using theme widget'),
|
||||||
'formPlacementDelay': _x('Display with a delay of', 'Label on a selection of different times'),
|
'formPlacementDelay': _x('Display with a delay of', 'Label on a selection of different times'),
|
||||||
'formPlacementPlacementPosition': _x('Position', 'Placement of a fixed bar form, on top of the page or on the bottom'),
|
'formPlacementPlacementPosition': _x('Position', 'Placement of a fixed bar form, on top of the page or on the bottom'),
|
||||||
@@ -133,7 +134,11 @@
|
|||||||
'customFieldTypeSelect': _x('Select', 'Form input type'),
|
'customFieldTypeSelect': _x('Select', 'Form input type'),
|
||||||
'selectPage': _x('Select', 'It is a placeholder in the select box - verb'),
|
'selectPage': _x('Select', 'It is a placeholder in the select box - verb'),
|
||||||
'displayOnCategories': __('Display on posts with these categories'),
|
'displayOnCategories': __('Display on posts with these categories'),
|
||||||
|
'displayOnAllCategoryArchives': __('Display on all post/product category archives'),
|
||||||
'displayOnTags': __('Display on posts with these tags'),
|
'displayOnTags': __('Display on posts with these tags'),
|
||||||
|
'displayOnAllTagArchives': __('Display on all post/product tag archives'),
|
||||||
|
'selectSpecificArchiveTags': __('Select specific tags'),
|
||||||
|
'selectSpecificArchiveCategories': __('Select specific categories'),
|
||||||
'customFieldTypeDate': __('Date'),
|
'customFieldTypeDate': __('Date'),
|
||||||
'customFieldDateType': __('Type of date'),
|
'customFieldDateType': __('Type of date'),
|
||||||
'customFieldDateFormat': __('Order'),
|
'customFieldDateFormat': __('Order'),
|
||||||
|
Reference in New Issue
Block a user