PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.34.2
MailPoet – Newsletters, Email Marketing, and Automation v5.34.2
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 / Newsletter / Renderer / Blocks / Text.php
mailpoet / lib / Newsletter / Renderer / Blocks Last commit date
AbandonedCartContent.php 1 year ago AutomatedLatestContentBlock.php 3 years ago Button.php 1 year ago Coupon.php 3 years ago Divider.php 2 years ago DynamicProductsBlock.php 11 months ago Footer.php 2 months ago Header.php 2 months ago Image.php 3 years ago Placeholder.php 4 years ago Renderer.php 2 months ago Social.php 2 months ago Spacer.php 3 years ago Text.php 2 months ago index.php 3 years ago
Text.php
197 lines
1 <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
2
3 namespace MailPoet\Newsletter\Renderer\Blocks;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Newsletter\Editor\PostContentManager;
9 use MailPoet\Newsletter\Renderer\EscapeHelper as EHelper;
10 use MailPoet\Newsletter\Renderer\StylesHelper;
11 use MailPoet\Util\pQuery\pQuery;
12
13 class Text {
14 public function render($element, bool $isRtl = false) {
15 $html = $element['text'];
16 // replace &nbsp; with spaces
17 $html = str_replace('&nbsp;', ' ', $html);
18 $html = str_replace('\xc2\xa0', ' ', $html);
19 $html = $this->convertBlockquotesToTables($html, $isRtl);
20 $html = $this->convertParagraphsToTables($html, $isRtl);
21 $html = $this->styleLists($html, $isRtl);
22 $html = $this->styleHeadings($html, $isRtl);
23 $html = $this->removeLastLineBreak($html);
24 $template = '
25 <tr>
26 <td class="mailpoet_text mailpoet_padded_vertical mailpoet_padded_side" valign="top" style="word-break:break-word;word-wrap:break-word;">
27 ' . $html . '
28 </td>
29 </tr>';
30 return $template;
31 }
32
33 public function convertBlockquotesToTables($html, bool $isRtl = false) {
34 $dOMParser = new pQuery();
35 $DOM = $dOMParser->parseStr($html);
36 $blockquotes = $DOM->query('blockquote');
37 foreach ($blockquotes as $blockquote) {
38 $contents = [];
39 $paragraphs = $blockquote->query('p, h1, h2, h3, h4', 0);
40 foreach ($paragraphs as $index => $paragraph) {
41 if (preg_match('/h\d/', $paragraph->getTag())) {
42 $contents[] = $paragraph->getOuterText();
43 } else {
44 $contents[] = $paragraph->toString(true, true, 1);
45 }
46 if ($index + 1 < $paragraphs->count()) $contents[] = '<br />';
47 $paragraph->remove();
48 }
49 if (empty($contents)) continue;
50 $blockquote->setTag('table');
51 $blockquote->addClass('mailpoet_blockquote');
52 $blockquote->width = '100%';
53 $blockquote->spacing = 0;
54 $blockquote->border = 0;
55 $blockquote->cellpadding = 0;
56 $blockquote->html('
57 <tbody>
58 <tr>
59 <td width="2" bgcolor="#565656"></td>
60 <td width="10"></td>
61 <td valign="top">
62 <table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0">
63 <tr>
64 <td class="mailpoet_blockquote">
65 ' . implode('', $contents) . '
66 </td>
67 </tr>
68 </table>
69 </td>
70 </tr>
71 </tbody>');
72 $blockquote = $this->insertLineBreak($blockquote);
73 }
74 return $DOM->__toString();
75 }
76
77 public function convertParagraphsToTables($html, bool $isRtl = false) {
78 $dOMParser = new pQuery();
79 $DOM = $dOMParser->parseStr($html);
80 $paragraphs = $DOM->query('p');
81 if (!$paragraphs->count()) return $html;
82 foreach ($paragraphs as $paragraph) {
83 // process empty paragraphs
84 if (!trim($paragraph->html())) {
85 $nextElement = ($paragraph->getNextSibling()) ?
86 trim($paragraph->getNextSibling()->text()) :
87 false;
88 $previousElement = ($paragraph->getPreviousSibling()) ?
89 trim($paragraph->getPreviousSibling()->text()) :
90 false;
91 $previousElementTag = ($previousElement) ?
92 $paragraph->getPreviousSibling()->tag :
93 false;
94 // if previous or next paragraphs are empty OR previous paragraph
95 // is a heading, insert a break line
96 if (
97 !$nextElement ||
98 !$previousElement ||
99 (preg_match('/h\d+/', $previousElementTag))
100 ) {
101 $paragraph = $this->insertLineBreak($paragraph);
102 }
103 $paragraph->remove();
104 continue;
105 }
106 $style = (string)$paragraph->style;
107 if (!preg_match('/text-align/i', $style)) {
108 $style = 'text-align: ' . ($isRtl ? 'right' : 'left') . ';' . $style;
109 } elseif (
110 $isRtl
111 && preg_match('/text-align\s*:\s*left/i', $style)
112 && !preg_match('/text-align\s*:\s*(center|justify|right)/i', $style)
113 ) {
114 $style = StylesHelper::joinStyles($style, 'text-align: right;');
115 }
116 $contents = $paragraph->toString(true, true, 1);
117 $paragraph->setTag('table');
118 $paragraph->style = 'border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;';
119 $paragraph->width = '100%';
120 $paragraph->cellpadding = 0;
121 $nextElement = $paragraph->getNextSibling();
122 // unless this is the last element in column, add double line breaks
123 $lineBreaks = ($nextElement && !trim($nextElement->text())) ?
124 '<br /><br />' :
125 '';
126 // if this element is followed by a list, add single line break
127 $lineBreaks = ($nextElement && preg_match('/<li/i', $nextElement->getOuterText())) ?
128 '<br />' :
129 $lineBreaks;
130 if ($paragraph->hasClass(PostContentManager::WP_POST_CLASS)) {
131 $paragraph->removeClass(PostContentManager::WP_POST_CLASS);
132 // if this element is followed by a paragraph or heading, add double line breaks
133 $lineBreaks = ($nextElement && preg_match('/<(p|h[1-6]{1})/i', $nextElement->getOuterText())) ?
134 '<br /><br />' :
135 $lineBreaks;
136 }
137 $paragraph->html('
138 <tr>
139 <td class="mailpoet_paragraph" style="word-break:break-word;word-wrap:break-word;' . EHelper::escapeHtmlStyleAttr($style) . '">
140 ' . $contents . $lineBreaks . '
141 </td>
142 </tr>');
143 }
144 return $DOM->__toString();
145 }
146
147 public function styleLists($html, bool $isRtl = false) {
148 $dOMParser = new pQuery();
149 $DOM = $dOMParser->parseStr($html);
150 $lists = $DOM->query('ol, ul, li');
151 if (!$lists->count()) return $html;
152 foreach ($lists as $list) {
153 if ($list->tag === 'li') {
154 $list->setInnertext($list->toString(true, true, 1));
155 $list->class = 'mailpoet_paragraph';
156 } else {
157 $list->class = 'mailpoet_paragraph';
158 $list->style = StylesHelper::joinStyles($list->style, 'padding-top:0;padding-bottom:0;margin-top:10px;');
159 }
160 $list->style = StylesHelper::applyTextAlignment($list->style, $isRtl ? 'right' : 'left');
161 $list->style = StylesHelper::joinStyles($list->style, 'margin-bottom:10px;');
162 $list->style = EHelper::escapeHtmlStyleAttr($list->style);
163 }
164 return $DOM->__toString();
165 }
166
167 public function styleHeadings($html, bool $isRtl = false) {
168 $dOMParser = new pQuery();
169 $DOM = $dOMParser->parseStr($html);
170 $headings = $DOM->query('h1, h2, h3, h4');
171 if (!$headings->count()) return $html;
172 foreach ($headings as $heading) {
173 $heading->style = StylesHelper::applyTextAlignment($heading->style, $isRtl ? 'right' : 'left');
174 $heading->style = StylesHelper::joinStyles($heading->style, 'padding:0;font-style:normal;font-weight:normal;');
175 $heading->style = EHelper::escapeHtmlStyleAttr($heading->style);
176 }
177 return $DOM->__toString();
178 }
179
180 public function removeLastLineBreak($html) {
181 return preg_replace('/(^)?(<br[^>]*?\/?>)+$/i', '', $html);
182 }
183
184 public function insertLineBreak($element) {
185 if (!$element->parent) return $element;
186 $element->parent->insertChild(
187 [
188 'tag_name' => 'br',
189 'self_close' => true,
190 'attributes' => [],
191 ],
192 $element->index() + 1
193 );
194 return $element;
195 }
196 }
197