Нема описа

Styles.php 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. namespace MailPoet\Form\Util;
  3. if (!defined('ABSPATH')) exit;
  4. use MailPoet\Entities\FormEntity;
  5. use MailPoetVendor\Sabberworm\CSS\Parser as CSSParser;
  6. class Styles {
  7. public function prefixStyles($stylesheet, $prefix = '') {
  8. if (!$stylesheet) return;
  9. $styles = new CSSParser($stylesheet);
  10. $styles = $styles->parse();
  11. $formattedStyles = [];
  12. foreach ($styles->getAllDeclarationBlocks() as $styleDeclaration) {
  13. $selectors = array_map(function($selector) use ($prefix) {
  14. return sprintf('%s %s', $prefix, $selector->__toString());
  15. }, $styleDeclaration->getSelectors());
  16. $selectors = implode(', ', $selectors);
  17. $rules = array_map(function($rule) {
  18. return $rule->__toString();
  19. }, $styleDeclaration->getRules());
  20. $rules = sprintf('{ %s }', implode(' ', $rules));
  21. $formattedStyles[] = sprintf('%s %s', $selectors, $rules);
  22. }
  23. return implode(PHP_EOL, $formattedStyles);
  24. }
  25. public function renderFormSettingsStyles(FormEntity $form, string $selector, string $displayType): string {
  26. if (!is_array($form->getSettings())) return '';
  27. $formSettings = $form->getSettings();
  28. // Wrapper styles
  29. $styles = [];
  30. if (isset($formSettings['border_size']) && isset($formSettings['border_color'])) {
  31. $styles[] = 'border: ' . $formSettings['border_size'] . 'px solid ' . $formSettings['border_color'];
  32. }
  33. if (isset($formSettings['border_radius'])) {
  34. $styles[] = 'border-radius: ' . $formSettings['border_radius'] . 'px';
  35. }
  36. $backgrounds = [];
  37. $mobileBackgrounds = [];
  38. if (isset($formSettings['background_image_url']) && $formSettings['background_image_url']) {
  39. $backgroundPosition = 'center';
  40. $backgroundRepeat = 'no-repeat';
  41. $backgroundSize = 'cover';
  42. if (isset($formSettings['background_image_display']) && $formSettings['background_image_display'] === 'fit') {
  43. $backgroundPosition = 'center top';
  44. $backgroundSize = 'contain';
  45. }
  46. if (isset($formSettings['background_image_display']) && $formSettings['background_image_display'] === 'tile') {
  47. $backgroundRepeat = 'repeat';
  48. $backgroundSize = 'auto';
  49. }
  50. $backgrounds[] = "url(" . trim($formSettings['background_image_url']) . ") $backgroundPosition / $backgroundSize $backgroundRepeat";
  51. }
  52. if (!empty($formSettings['gradient'])) {
  53. $backgrounds[] = trim($formSettings['gradient']);
  54. $mobileBackgrounds[] = trim($formSettings['gradient']);
  55. }
  56. if (!empty($formSettings['backgroundColor']) ) {
  57. $backgrounds[] = trim($formSettings['backgroundColor']);
  58. $mobileBackgrounds[] = trim($formSettings['backgroundColor']);
  59. }
  60. if ($backgrounds) {
  61. $styles[] = 'background: ' . join(', ', $backgrounds);
  62. }
  63. if (isset($formSettings['fontColor'])) {
  64. $styles[] = 'color: ' . trim($formSettings['fontColor']);
  65. }
  66. if (isset($formSettings['alignment'])) {
  67. $styles[] = 'text-align: ' . $formSettings['alignment'];
  68. }
  69. $formWrapperStyles = $selector . '{' . join(';', $styles) . ';}';
  70. // Media styles for mobile
  71. $media = $this->getMobileStyles($selector, $displayType, $mobileBackgrounds);
  72. // Form element styles
  73. $formStyles = [];
  74. if (isset($formSettings['form_padding'])) {
  75. if (in_array(
  76. $displayType,
  77. [FormEntity::DISPLAY_TYPE_POPUP, FormEntity::DISPLAY_TYPE_FIXED_BAR, FormEntity::DISPLAY_TYPE_SLIDE_IN]
  78. )) {
  79. $padding = $formSettings['form_padding'];
  80. $media .= " @media (min-width: 500px) {{$selector} {padding: {$padding}px;}} ";
  81. } else {
  82. $formStyles[] = 'padding: ' . $formSettings['form_padding'] . 'px';
  83. }
  84. }
  85. $formElementStyles = '';
  86. if ($formStyles) {
  87. $formElementStyles = $selector . ' form.mailpoet_form {' . join(';', $formStyles) . ';}';
  88. }
  89. // Width styles
  90. $widthStyles = $this->renderWidthStyles($formSettings, $selector, $displayType);
  91. $typeSpecificStyles = $this->getFormTypeSpecificStyles($selector, $displayType);
  92. $messagesStyles = $this->renderMessagesStyles($formSettings, $selector);
  93. $additionalStyles = $selector . ' .mailpoet_paragraph.last {margin-bottom: 0} ';
  94. $media .= " @media (min-width: 500px) {{$selector} .last .mailpoet_paragraph:last-child {margin-bottom: 0}} ";
  95. $media .= " @media (max-width: 500px) {{$selector} .mailpoet_form_column:last-child .mailpoet_paragraph:last-child {margin-bottom: 0}} ";
  96. return $formWrapperStyles
  97. . $formElementStyles
  98. . $widthStyles
  99. . $messagesStyles
  100. . $typeSpecificStyles
  101. . $additionalStyles
  102. . $media;
  103. }
  104. private function renderWidthStyles(array $formSettings, string $selector, string $displayType): string {
  105. $styles = [];
  106. if (isset($formSettings['form_placement'][$displayType]['styles']['width'])) {
  107. $width = $this->getWidthValue($formSettings['form_placement'][$displayType]['styles']['width']);
  108. }
  109. if ($displayType === FormEntity::DISPLAY_TYPE_POPUP) {
  110. if (isset($width)) {
  111. $styles[] = "width: $width";
  112. $styles[] = "max-width: 100vw";
  113. } else { // BC compatibilty
  114. $styles[] = 'width: 560px';
  115. $styles[] = 'max-width: 560px';
  116. }
  117. } elseif ($displayType === FormEntity::DISPLAY_TYPE_SLIDE_IN) {
  118. if (isset($width)) {
  119. $styles[] = "width: $width";
  120. $styles[] = "max-width: 100vw";
  121. } else { // BC compatibilty
  122. $styles[] = 'max-width: 600px';
  123. $styles[] = 'min-width: 350px';
  124. }
  125. } elseif ($displayType === FormEntity::DISPLAY_TYPE_FIXED_BAR) {
  126. if (isset($width)) {
  127. $styles[] = "width: $width";
  128. $styles[] = "max-width: 100%";
  129. } else { // BC compatibilty
  130. $styles[] = 'max-width: 960px';
  131. }
  132. } elseif ($displayType === FormEntity::DISPLAY_TYPE_BELOW_POST) {
  133. if (isset($width)) {
  134. $styles[] = "width: $width";
  135. }
  136. } elseif ($displayType === FormEntity::DISPLAY_TYPE_OTHERS) {
  137. if (isset($width)) {
  138. $styles[] = "width: $width";
  139. }
  140. }
  141. $widthSelector = $selector;
  142. $widthSelector .= $displayType === FormEntity::DISPLAY_TYPE_FIXED_BAR ? ' form.mailpoet_form' : '';
  143. if (!$styles) {
  144. return '';
  145. }
  146. return $widthSelector . '{' . join(';', $styles) . ';}';
  147. }
  148. private function getWidthValue(array $width) {
  149. return $width['value'] . ($width['unit'] === 'percent' ? '%' : 'px');
  150. }
  151. private function renderMessagesStyles(array $formSettings, string $selector): string {
  152. $styles = "$selector .mailpoet_message {margin: 0; padding: 0 20px;}";
  153. if (isset($formSettings['success_validation_color']) && $formSettings['success_validation_color']) {
  154. $success = $formSettings['success_validation_color'];
  155. $styles .= "
  156. $selector .mailpoet_validate_success {color: $success}
  157. $selector input.parsley-success {color: $success}
  158. $selector select.parsley-success {color: $success}
  159. $selector textarea.parsley-success {color: $success}
  160. ";
  161. }
  162. if (isset($formSettings['error_validation_color']) && $formSettings['error_validation_color']) {
  163. $error = $formSettings['error_validation_color'];
  164. $styles .= "
  165. $selector .mailpoet_validate_error {color: $error}
  166. $selector input.parsley-error {color: $error}
  167. $selector select.parsley-error {color: $error}
  168. $selector textarea.textarea.parsley-error {color: $error}
  169. $selector .parsley-errors-list {color: $error}
  170. $selector .parsley-required {color: $error}
  171. $selector .parsley-custom-error-message {color: $error}
  172. ";
  173. }
  174. return $styles;
  175. }
  176. private function getFormTypeSpecificStyles(string $selector, string $displayType): string {
  177. $styles = [];
  178. if ($displayType === FormEntity::DISPLAY_TYPE_SLIDE_IN) {
  179. $styles[] = $selector . '.mailpoet_form_slide_in { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }';
  180. $styles[] = $selector . '.mailpoet_form_position_right { border-top-right-radius: 0; }';
  181. $styles[] = $selector . '.mailpoet_form_position_left { border-top-left-radius: 0; }';
  182. }
  183. return join('', $styles);
  184. }
  185. private function getMobileStyles(string $selector, string $displayType, array $mobileBackgrounds): string {
  186. $wrapperStyles = [];
  187. if ($mobileBackgrounds) {
  188. $wrapperStyles[] = 'background: ' . join(', ', $mobileBackgrounds) . ';';
  189. } else {
  190. $wrapperStyles[] = 'background-image: none;';
  191. }
  192. if (in_array(
  193. $displayType,
  194. [FormEntity::DISPLAY_TYPE_POPUP, FormEntity::DISPLAY_TYPE_FIXED_BAR, FormEntity::DISPLAY_TYPE_SLIDE_IN]
  195. )) {
  196. $wrapperStyles = array_merge($wrapperStyles, [
  197. 'animation: none;',
  198. 'border: none;',
  199. 'border-radius: 0;',
  200. 'bottom: 0;',
  201. 'left: 0;',
  202. 'max-height: 40%;',
  203. 'padding: 20px;',
  204. 'right: 0;',
  205. 'top: auto;',
  206. 'transform: none;',
  207. 'width: 100%;',
  208. 'min-width: 100%;',
  209. ]);
  210. }
  211. return "@media (max-width: 500px) {{$selector} {" . join('', $wrapperStyles) . "}}";
  212. }
  213. }