Aucune description

Text.php 6.7KB

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