PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.37.0
MailPoet – Newsletters, Email Marketing, and Automation v5.37.0
5.37.0 5.36.1 5.36.0 5.35.1 5.35.0 5.34.3 5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / lib / AdminPages / Pages / FormEditor.php
mailpoet / lib / AdminPages / Pages Last commit date
AbstractAutomationEmbed.php 7 months ago Automation.php 2 years ago AutomationAnalytics.php 3 months ago AutomationEditor.php 3 months ago AutomationFlowEmbed.php 7 months ago AutomationPreviewEmbed.php 3 months ago AutomationTemplates.php 2 years ago CustomFields.php 3 months ago DynamicSegments.php 3 months ago ExperimentalFeatures.php 3 years ago FormEditor.php 2 days ago Forms.php 3 months ago Help.php 2 days ago Homepage.php 2 years ago Landingpage.php 2 years ago Logs.php 2 months ago NewsletterEditor.php 2 days ago Newsletters.php 3 months ago Settings.php 6 months ago StaticSegments.php 3 months ago Subscribers.php 1 week ago SubscribersExport.php 3 years ago SubscribersImport.php 3 months ago Tags.php 4 months ago Upgrade.php 1 year ago WelcomeWizard.php 3 months ago WooCommerceSetup.php 3 months ago index.php 3 years ago
FormEditor.php
435 lines
1 <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
2
3 namespace MailPoet\AdminPages\Pages;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\AdminPages\AssetsController;
9 use MailPoet\AdminPages\PageRenderer;
10 use MailPoet\API\JSON\ResponseBuilders\CustomFieldsResponseBuilder;
11 use MailPoet\Config\Localizer;
12 use MailPoet\CustomFields\CustomFieldsRepository;
13 use MailPoet\Entities\FormEntity;
14 use MailPoet\Entities\SegmentEntity;
15 use MailPoet\Form\Block;
16 use MailPoet\Form\FormsRepository;
17 use MailPoet\Form\Renderer as FormRenderer;
18 use MailPoet\Form\Templates\TemplateRepository;
19 use MailPoet\Form\Templates\Templates\Template10BelowPages;
20 use MailPoet\Form\Templates\Templates\Template10FixedBar;
21 use MailPoet\Form\Templates\Templates\Template10Popup;
22 use MailPoet\Form\Templates\Templates\Template10SlideIn;
23 use MailPoet\Form\Templates\Templates\Template10Widget;
24 use MailPoet\Form\Templates\Templates\Template11BelowPages;
25 use MailPoet\Form\Templates\Templates\Template11FixedBar;
26 use MailPoet\Form\Templates\Templates\Template11Popup;
27 use MailPoet\Form\Templates\Templates\Template11SlideIn;
28 use MailPoet\Form\Templates\Templates\Template11Widget;
29 use MailPoet\Form\Templates\Templates\Template12BelowPages;
30 use MailPoet\Form\Templates\Templates\Template12FixedBar;
31 use MailPoet\Form\Templates\Templates\Template12Popup;
32 use MailPoet\Form\Templates\Templates\Template12SlideIn;
33 use MailPoet\Form\Templates\Templates\Template12Widget;
34 use MailPoet\Form\Templates\Templates\Template13BelowPages;
35 use MailPoet\Form\Templates\Templates\Template13FixedBar;
36 use MailPoet\Form\Templates\Templates\Template13Popup;
37 use MailPoet\Form\Templates\Templates\Template13SlideIn;
38 use MailPoet\Form\Templates\Templates\Template13Widget;
39 use MailPoet\Form\Templates\Templates\Template14BelowPages;
40 use MailPoet\Form\Templates\Templates\Template14FixedBar;
41 use MailPoet\Form\Templates\Templates\Template14Popup;
42 use MailPoet\Form\Templates\Templates\Template14SlideIn;
43 use MailPoet\Form\Templates\Templates\Template14Widget;
44 use MailPoet\Form\Templates\Templates\Template17BelowPages;
45 use MailPoet\Form\Templates\Templates\Template17FixedBar;
46 use MailPoet\Form\Templates\Templates\Template17Popup;
47 use MailPoet\Form\Templates\Templates\Template17SlideIn;
48 use MailPoet\Form\Templates\Templates\Template17Widget;
49 use MailPoet\Form\Templates\Templates\Template18BelowPages;
50 use MailPoet\Form\Templates\Templates\Template18FixedBar;
51 use MailPoet\Form\Templates\Templates\Template18Popup;
52 use MailPoet\Form\Templates\Templates\Template18SlideIn;
53 use MailPoet\Form\Templates\Templates\Template18Widget;
54 use MailPoet\Form\Templates\Templates\Template1BelowPages;
55 use MailPoet\Form\Templates\Templates\Template1FixedBar;
56 use MailPoet\Form\Templates\Templates\Template1Popup;
57 use MailPoet\Form\Templates\Templates\Template1SlideIn;
58 use MailPoet\Form\Templates\Templates\Template1Widget;
59 use MailPoet\Form\Templates\Templates\Template3BelowPages;
60 use MailPoet\Form\Templates\Templates\Template3FixedBar;
61 use MailPoet\Form\Templates\Templates\Template3Popup;
62 use MailPoet\Form\Templates\Templates\Template3SlideIn;
63 use MailPoet\Form\Templates\Templates\Template3Widget;
64 use MailPoet\Form\Templates\Templates\Template4BelowPages;
65 use MailPoet\Form\Templates\Templates\Template4FixedBar;
66 use MailPoet\Form\Templates\Templates\Template4Popup;
67 use MailPoet\Form\Templates\Templates\Template4SlideIn;
68 use MailPoet\Form\Templates\Templates\Template4Widget;
69 use MailPoet\Form\Templates\Templates\Template6BelowPages;
70 use MailPoet\Form\Templates\Templates\Template6FixedBar;
71 use MailPoet\Form\Templates\Templates\Template6Popup;
72 use MailPoet\Form\Templates\Templates\Template6SlideIn;
73 use MailPoet\Form\Templates\Templates\Template6Widget;
74 use MailPoet\Form\Templates\Templates\Template7BelowPages;
75 use MailPoet\Form\Templates\Templates\Template7FixedBar;
76 use MailPoet\Form\Templates\Templates\Template7Popup;
77 use MailPoet\Form\Templates\Templates\Template7SlideIn;
78 use MailPoet\Form\Templates\Templates\Template7Widget;
79 use MailPoet\Form\Util\CustomFonts;
80 use MailPoet\Form\Util\Export;
81 use MailPoet\NotFoundException;
82 use MailPoet\Router\Endpoints\FormPreview;
83 use MailPoet\Router\Router;
84 use MailPoet\Segments\SegmentsSimpleListRepository;
85 use MailPoet\Settings\Pages;
86 use MailPoet\Settings\UserFlagsController;
87 use MailPoet\Subscribers\TrackingConsentCapture;
88 use MailPoet\WP\AutocompletePostListLoader as WPPostListLoader;
89 use MailPoet\WP\Functions as WPFunctions;
90
91 class FormEditor {
92 /** @var PageRenderer */
93 private $pageRenderer;
94
95 /** @var CustomFieldsRepository */
96 private $customFieldsRepository;
97
98 /** @var CustomFieldsResponseBuilder */
99 private $customFieldsResponseBuilder;
100
101 /** @var FormRenderer */
102 private $formRenderer;
103
104 /** @var Block\Date */
105 private $dateBlock;
106
107 /** @var WPFunctions */
108 private $wp;
109
110 /** @var Localizer */
111 private $localizer;
112
113 /** @var TemplateRepository */
114 private $templatesRepository;
115
116 /** @var UserFlagsController */
117 private $userFlags;
118
119 /** @var WPPostListLoader */
120 private $wpPostListLoader;
121
122 /** @var SegmentsSimpleListRepository */
123 private $segmentsListRepository;
124
125 /** @var FormsRepository */
126 private $formsRepository;
127
128 private $activeTemplates = [
129 FormEntity::DISPLAY_TYPE_POPUP => [
130 Template1Popup::ID,
131 Template3Popup::ID,
132 Template4Popup::ID,
133 Template6Popup::ID,
134 Template7Popup::ID,
135 Template10Popup::ID,
136 Template11Popup::ID,
137 Template12Popup::ID,
138 Template13Popup::ID,
139 Template14Popup::ID,
140 Template17Popup::ID,
141 Template18Popup::ID,
142 ],
143 FormEntity::DISPLAY_TYPE_SLIDE_IN => [
144 Template1SlideIn::ID,
145 Template3SlideIn::ID,
146 Template4SlideIn::ID,
147 Template6SlideIn::ID,
148 Template7SlideIn::ID,
149 Template10SlideIn::ID,
150 Template11SlideIn::ID,
151 Template12SlideIn::ID,
152 Template13SlideIn::ID,
153 Template14SlideIn::ID,
154 Template17SlideIn::ID,
155 Template18SlideIn::ID,
156 ],
157 FormEntity::DISPLAY_TYPE_FIXED_BAR => [
158 Template1FixedBar::ID,
159 Template3FixedBar::ID,
160 Template4FixedBar::ID,
161 Template6FixedBar::ID,
162 Template7FixedBar::ID,
163 Template10FixedBar::ID,
164 Template11FixedBar::ID,
165 Template12FixedBar::ID,
166 Template13FixedBar::ID,
167 Template14FixedBar::ID,
168 Template17FixedBar::ID,
169 Template18FixedBar::ID,
170 ],
171 FormEntity::DISPLAY_TYPE_BELOW_POST => [
172 Template1BelowPages::ID,
173 Template3BelowPages::ID,
174 Template4BelowPages::ID,
175 Template6BelowPages::ID,
176 Template7BelowPages::ID,
177 Template10BelowPages::ID,
178 Template11BelowPages::ID,
179 Template12BelowPages::ID,
180 Template13BelowPages::ID,
181 Template14BelowPages::ID,
182 Template17BelowPages::ID,
183 Template18BelowPages::ID,
184 ],
185 FormEntity::DISPLAY_TYPE_OTHERS => [
186 Template1Widget::ID,
187 Template3Widget::ID,
188 Template4Widget::ID,
189 Template6Widget::ID,
190 Template7Widget::ID,
191 Template10Widget::ID,
192 Template11Widget::ID,
193 Template12Widget::ID,
194 Template13Widget::ID,
195 Template14Widget::ID,
196 Template17Widget::ID,
197 Template18Widget::ID,
198 ],
199 ];
200
201 /** @var AssetsController */
202 private $assetsController;
203
204 /** @var TrackingConsentCapture */
205 private $trackingConsentCapture;
206
207 public function __construct(
208 AssetsController $assetsController,
209 PageRenderer $pageRenderer,
210 CustomFieldsRepository $customFieldsRepository,
211 CustomFieldsResponseBuilder $customFieldsResponseBuilder,
212 FormRenderer $formRenderer,
213 Block\Date $dateBlock,
214 WPFunctions $wp,
215 Localizer $localizer,
216 UserFlagsController $userFlags,
217 WPPostListLoader $wpPostListLoader,
218 TemplateRepository $templateRepository,
219 FormsRepository $formsRepository,
220 SegmentsSimpleListRepository $segmentsListRepository,
221 TrackingConsentCapture $trackingConsentCapture
222 ) {
223 $this->assetsController = $assetsController;
224 $this->pageRenderer = $pageRenderer;
225 $this->customFieldsRepository = $customFieldsRepository;
226 $this->customFieldsResponseBuilder = $customFieldsResponseBuilder;
227 $this->formRenderer = $formRenderer;
228 $this->dateBlock = $dateBlock;
229 $this->wp = $wp;
230 $this->localizer = $localizer;
231 $this->templatesRepository = $templateRepository;
232 $this->userFlags = $userFlags;
233 $this->wpPostListLoader = $wpPostListLoader;
234 $this->segmentsListRepository = $segmentsListRepository;
235 $this->formsRepository = $formsRepository;
236 $this->trackingConsentCapture = $trackingConsentCapture;
237 }
238
239 public function render() {
240 if (!isset($_GET['id']) && !isset($_GET['action']) && !isset($_GET['template_id'])) {
241 $this->renderTemplateSelection();
242 return;
243 }
244 if (is_string($_GET['template_id'] ?? null)) {
245 $template = $this->templatesRepository->getFormTemplate(sanitize_text_field(wp_unslash($_GET['template_id'])));
246 $form = $template->toFormEntity();
247 } else {
248 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- is_numeric guard plus int cast is the sanitization
249 $idParam = $_GET['id'] ?? null;
250 $form = $this->getFormData(is_numeric($idParam) ? (int)$idParam : 0);
251 }
252 $customFields = $this->customFieldsRepository->findAllActive();
253 if (!$form instanceof FormEntity) {
254 throw new NotFoundException('Form does not exist');
255 }
256 $dateTypes = $this->dateBlock->getDateTypes();
257 $data = [
258 'form' => $form->toArray(),
259 'form_exports' => [
260 'php' => Export::get('php'),
261 'iframe' => Export::get('iframe'),
262 'shortcode' => Export::get('shortcode'),
263 ],
264 'segments' => $this->segmentsListRepository->getListWithSubscribedSubscribersCounts([SegmentEntity::TYPE_DEFAULT]),
265 'styles' => $this->formRenderer->getCustomStyles($form),
266 'date_types' => array_map(function ($label, $value) {
267 return [
268 'label' => $label,
269 'value' => $value,
270 ];
271 }, $dateTypes, array_keys($dateTypes)),
272 'date_formats' => $this->dateBlock->getDateFormats(),
273 'month_names' => $this->dateBlock->getMonthNames(),
274 'custom_fields' => $this->customFieldsResponseBuilder->buildBatch($customFields),
275 'editor_tutorial_seen' => $this->userFlags->get('form_editor_tutorial_seen'),
276 'preview_page_url' => $this->getPreviewPageUrl(),
277 'custom_fonts' => CustomFonts::FONTS,
278 'editor_color_palette' => $this->getEditorColorPalette(),
279 'translations' => $this->getGutenbergScriptsTranslations(),
280 'posts' => $this->wpPostListLoader->getPosts(),
281 'pages' => $this->wpPostListLoader->getPages(),
282 'categories' => $this->wpPostListLoader->getCategories(),
283 'tags' => $this->wpPostListLoader->getTags(),
284 'products' => $this->wpPostListLoader->getProducts(),
285 'product_categories' => $this->wpPostListLoader->getWooCommerceCategories(),
286 'product_tags' => $this->wpPostListLoader->getWooCommerceTags(),
287 'is_administrator' => $this->wp->currentUserCan('administrator'),
288 'tracking_consent_capture_enabled' => $this->trackingConsentCapture->isCaptureEnabled(),
289 'theme_support_widgets' => $this->wp->wpGetThemeSupport('widgets'),
290 'theme_support_fse' => $this->wp->wpGetTheme()->is_block_theme(),
291 ];
292 $this->wp->wpEnqueueMedia();
293 $this->assetsController->setupFormEditorDependencies();
294 $this->pageRenderer->displayPage('form/editor.html', $data);
295 }
296
297 private function getEditorColorPalette(): array {
298 $palette = $this->normalizeColorPalette(
299 $this->wp->wpGetGlobalSettings(['color', 'palette', 'theme'])
300 );
301 if ($palette) {
302 return $palette;
303 }
304 return $this->normalizeColorPalette(
305 $this->wp->wpGetThemeSupport('editor-color-palette')
306 );
307 }
308
309 private function normalizeColorPalette($palette): array {
310 if (!is_array($palette)) {
311 return [];
312 }
313 if (
314 isset($palette[0])
315 && is_array($palette[0])
316 && !isset($palette[0]['color'])
317 ) {
318 $palette = $palette[0];
319 }
320
321 $normalizedPalette = [];
322 foreach ($palette as $color) {
323 if (!is_array($color)) {
324 continue;
325 }
326 $name = isset($color['name']) && is_scalar($color['name'])
327 ? $this->wp->sanitizeTextField((string)$color['name'])
328 : '';
329 $slug = isset($color['slug']) && is_scalar($color['slug'])
330 ? $this->wp->sanitizeKey((string)$color['slug'])
331 : '';
332 $colorValue = isset($color['color']) && is_scalar($color['color'])
333 ? $this->wp->sanitizeTextField((string)$color['color'])
334 : '';
335 if (!$name || !$slug || !$colorValue) {
336 continue;
337 }
338 $normalizedPalette[] = [
339 'name' => $name,
340 'slug' => $slug,
341 'color' => $colorValue,
342 ];
343 }
344 return $normalizedPalette;
345 }
346
347 public function renderTemplateSelection() {
348 $templatesData = [];
349 foreach ($this->activeTemplates as $formType => $templateIds) {
350 $templateForms = $this->templatesRepository->getFormTemplates($this->activeTemplates[$formType]);
351 $templatesData[$formType] = [];
352 foreach ($templateForms as $templateId => $form) {
353 $templatesData[$formType][] = [
354 'id' => $templateId,
355 'name' => $form->getName(),
356 'thumbnail' => $form->getThumbnailUrl(),
357 ];
358 }
359 }
360 $data = [
361 'templates' => $templatesData,
362 ];
363 $this->assetsController->setupFormEditorDependencies();
364 $this->pageRenderer->displayPage('form/template_selection.html', $data);
365 }
366
367 private function getPreviewPageUrl() {
368 $mailpoetPage = Pages::getMailPoetPage(Pages::PAGE_SUBSCRIPTIONS);
369 if (!$mailpoetPage) {
370 return null;
371 }
372 $url = $this->wp->getPermalink($mailpoetPage);
373 $params = [
374 Router::NAME,
375 'endpoint=' . FormPreview::ENDPOINT,
376 'action=' . FormPreview::ACTION_VIEW,
377 ];
378 $url .= (parse_url($url, PHP_URL_QUERY) ? '&' : '?') . join('&', $params);
379 return $url;
380 }
381
382 /**
383 * JS Translations are distributed and loaded per script. We can't use wp_set_script_translations
384 * because translation filename is determined based on script filename and path.
385 * This function loads JSON files with Gutenberg script's translations distributed within WordPress.
386 * Implemented based on load_script_textdomain function
387 * @see https://developer.wordpress.org/reference/functions/load_script_textdomain/
388 * @return string[]
389 */
390 private function getGutenbergScriptsTranslations() {
391 $locale = $this->localizer->locale();
392 if (!$locale) {
393 return [];
394 }
395 // List of scripts - relative path to translations directory (default: wp-content/languages)
396 $translationsToLoad = [
397 'wp-includes/js/dist/blocks.js',
398 'wp-includes/js/dist/components.js',
399 'wp-includes/js/dist/block-editor.js',
400 'wp-includes/js/dist/block-library.js',
401 'wp-includes/js/dist/editor.js',
402 'wp-includes/js/dist/media-utils.js',
403 'wp-includes/js/dist/format-library.js',
404 'wp-includes/js/dist/edit-post.js',
405 ];
406
407 $translations = [];
408 foreach ($translationsToLoad as $translation) {
409 $file = WP_LANG_DIR . '/' . $locale . '-' . md5($translation) . '.json';
410 if (!file_exists($file)) {
411 continue;
412 }
413 $translationsData = file_get_contents($file);
414 if ($translationsData) {
415 $translations[] = $translationsData;
416 }
417 }
418 return $translations;
419 }
420
421 private function getFormData(int $id): ?FormEntity {
422 $form = $this->formsRepository->findOneById($id);
423 if (!$form instanceof FormEntity) {
424 return null;
425 }
426 $form->setStyles($this->formRenderer->getCustomStyles($form));
427 // Use empty settings in case they are corrupted or missing
428 if (!is_array($form->getSettings())) {
429 $initialFormTemplate = $this->templatesRepository->getFormTemplate(TemplateRepository::INITIAL_FORM_TEMPLATE);
430 $form->setSettings($initialFormTemplate->getSettings());
431 }
432 return $form;
433 }
434 }
435