non-sshare-styles
1 month ago
class-hustle-decorator-non-sshare.php
3 months ago
class-hustle-decorator-sshare.php
3 months ago
class-hustle-decorator_abstract.php
3 years ago
class-hustle-module-preview.php
1 year ago
hustle-module-front-ajax.php
3 days ago
hustle-module-front.php
3 days ago
hustle-module-inline-style-queue.php
3 months ago
hustle-module-renderer.php
1 month ago
hustle-renderer-abstract.php
3 months ago
hustle-renderer-sshare.php
3 days ago
class-hustle-decorator-non-sshare.php
468 lines
| 1 | <?php |
| 2 | /** |
| 3 | * File for Hustle_Decorator_Non_Sshare class. |
| 4 | * |
| 5 | * @package Hustle |
| 6 | * @since 4.3.0 |
| 7 | */ |
| 8 | |
| 9 | /** |
| 10 | * Class Hustle_Decorator_Non_Sshare. |
| 11 | * Handles the styling for the Non Social Sharing modules. Pop-ups, Slide-ins, and Embeds. |
| 12 | * |
| 13 | * @since 4.3.0 |
| 14 | */ |
| 15 | class Hustle_Decorator_Non_Sshare extends Hustle_Decorator_Abstract { |
| 16 | |
| 17 | /** |
| 18 | * Names of the files for optin modules. |
| 19 | * It's in the order to be queued. |
| 20 | * |
| 21 | * @since 4.3.0 |
| 22 | * @var array |
| 23 | */ |
| 24 | private $optin_files_list = array( |
| 25 | 'module-size-popup', |
| 26 | 'module-size-embed', |
| 27 | 'module-size-slidein', |
| 28 | 'general-01--module-container', // .hustle-popup or .hustle-slidein |
| 29 | 'general-02--main-layout', // .hustle-layout or .hustle-layout-body |
| 30 | 'general-03--layout-header', // .hustle-layout-header |
| 31 | 'general-04--layout-content', // .hustle-layout-content |
| 32 | 'general-05--layout-footer', // .hustle-layout-footer |
| 33 | 'general-06--image-size', // .hustle-image |
| 34 | 'general-07--image-fitting', // .hustle-image |
| 35 | 'general-08--image-position', // .hustle-image |
| 36 | 'general-09--content-wrapper', // .hustle-content |
| 37 | 'general-10--title', // .hustle-title |
| 38 | 'general-11--subtitle', // .hustle-subtitle |
| 39 | 'general-12--content', // .hustle-group-content |
| 40 | 'general-13--cta-container', // .hustle-cta-container |
| 41 | 'general-19--cta-helper-text', // .hustle-cta-helper-text |
| 42 | 'general-14--cta-button', // .hustle-button-cta |
| 43 | 'general-15--cta-alignment', // .hustle-content-wrap |
| 44 | 'general-16--nsa-link', // .hustle-nsa-link |
| 45 | 'general-17--close-button', // .hustle-button-close |
| 46 | 'general-18--popup-mask', // .hustle-popup-mask |
| 47 | 'form-01--form-container', // .hustle-layout-form |
| 48 | 'form-02--form-fields', // .hustle-form-fields |
| 49 | 'form-03--input', // .hustle-input |
| 50 | 'form-04--select2', // .hustle-select2 |
| 51 | 'form-05--select2-dropdown', // .hustle-dropdown |
| 52 | 'form-06--timepicker-dropdown', // .hustle-timepicker |
| 53 | 'form-07--radio', // .hustle-radio |
| 54 | 'form-08--checkbox', // .hustle-checkbox |
| 55 | 'form-09--calendar', // .hustle-calendar |
| 56 | 'form-10--submit', // .hustle-button-submit |
| 57 | 'form-11--options-container', // .hustle-form-options |
| 58 | 'form-12--options-title', // .hustle-group-title |
| 59 | 'form-13--gdpr', // .hustle-gdpr |
| 60 | 'form-14--error-message', // .hustle-error-message |
| 61 | 'form-15--success-message', // .hustle-success |
| 62 | 'form-16--recaptcha', // .hustle-recaptcha-copy |
| 63 | ); |
| 64 | |
| 65 | /** |
| 66 | * Names of the files for informational modules. |
| 67 | * It's in the order to be queued. |
| 68 | * |
| 69 | * @since 4.3.0 |
| 70 | * @var array |
| 71 | */ |
| 72 | private $info_files_list = array( |
| 73 | 'module-size-popup', |
| 74 | 'module-size-embed', |
| 75 | 'module-size-slidein', |
| 76 | 'general-01--module-container', // .hustle-popup or .hustle-slidein |
| 77 | 'general-02--main-layout', // .hustle-layout or .hustle-layout-body |
| 78 | 'general-03--layout-header', // .hustle-layout-header |
| 79 | 'general-04--layout-content', // .hustle-layout-content |
| 80 | 'general-05--layout-footer', // .hustle-layout-footer |
| 81 | 'general-06--image-size', // .hustle-image |
| 82 | 'general-07--image-fitting', // .hustle-image |
| 83 | 'general-08--image-position', // .hustle-image |
| 84 | 'general-09--content-wrapper', // .hustle-content |
| 85 | 'general-10--title', // .hustle-title |
| 86 | 'general-11--subtitle', // .hustle-subtitle |
| 87 | 'general-12--content', // .hustle-group-content |
| 88 | 'general-13--cta-container', // .hustle-cta-container |
| 89 | 'general-19--cta-helper-text', // .hustle-cta-helper-text |
| 90 | 'general-14--cta-button', // .hustle-button-cta |
| 91 | 'general-15--cta-alignment', // .hustle-content-wrap |
| 92 | 'general-16--nsa-link', // .hustle-nsa-link |
| 93 | 'general-17--close-button', // .hustle-button-close |
| 94 | 'general-18--popup-mask', // .hustle-popup-mask |
| 95 | ); |
| 96 | |
| 97 | /** |
| 98 | * Get styles |
| 99 | * |
| 100 | * @return string |
| 101 | */ |
| 102 | protected function get_styles() { |
| 103 | $styles = $this->get_common_styles(); |
| 104 | $styles .= $this->get_custom_css(); |
| 105 | |
| 106 | return $styles; |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Get common styles |
| 111 | * |
| 112 | * @return string |
| 113 | */ |
| 114 | private function get_common_styles() { |
| 115 | |
| 116 | // Global prefix. |
| 117 | // @todo @Danae Remove once all styles moved into new prefixes. |
| 118 | $prefix = '.hustle-ui.module_id_' . $this->module->module_id . ' '; |
| 119 | |
| 120 | // Small prefix. |
| 121 | $prefix_mobile = '.hustle-ui.module_id_' . $this->module->module_id . ' '; |
| 122 | |
| 123 | // Desktop prefix. |
| 124 | // Applies styles to modules without `hustle-size--small` class on large screens. |
| 125 | // @note It should be used along with $breakpoint. |
| 126 | $prefix_desktop = '.hustle-ui:not(.hustle-size--small).module_id_' . $this->module->module_id . ' '; |
| 127 | |
| 128 | // Applies styles to screens larger than 783px. |
| 129 | // Use it in conjunction with $prefix_desktop. |
| 130 | $breakpoint = '@media screen and (min-width: ' . $this->bp_desktop . 'px)'; |
| 131 | $breakpoint_sm = '@media screen and (max-width: ' . $this->bp_mobile . 'px)'; |
| 132 | |
| 133 | // IE Support. |
| 134 | $support_ie = '@media all and (-ms-high-contrast: none), (-ms-high-contrast: active)'; |
| 135 | $breakpoint_ie = '@media all and (min-width: ' . $this->bp_desktop . 'px) and (-ms-high-contrast: none), (-ms-high-contrast: active)'; |
| 136 | |
| 137 | $elements = $this->get_prefixed_popup_stylable_elements( $prefix ); |
| 138 | |
| 139 | // NEW VARIABLES. |
| 140 | // @todo re-arrange to avoid unnecessary vars. |
| 141 | $design = $this->design; |
| 142 | $layout_info = $design['style']; |
| 143 | $layout_optin = $design['form_layout']; |
| 144 | $is_optin = ( 'optin' === $this->module->module_mode ); |
| 145 | $is_popup = ( Hustle_Module_Model::POPUP_MODULE === $this->module->module_type ); |
| 146 | $is_slidein = ( Hustle_Module_Model::SLIDEIN_MODULE === $this->module->module_type ); |
| 147 | $is_embed = ( Hustle_Module_Model::EMBEDDED_MODULE === $this->module->module_type ); |
| 148 | $is_mobile_enabled = ( '1' === $design['enable_mobile_settings'] ); |
| 149 | $is_vanilla = '1' === $this->design['use_vanilla']; |
| 150 | $form_fields = $this->module->get_form_fields(); |
| 151 | |
| 152 | $default_typography = ( '0' === $design['customize_typography_mobile'] ); // Applies for mobile settings only. |
| 153 | $default_advanced = ( '0' === $design['customize_border_shadow_spacing_mobile'] ); // Applies for mobile settings only. |
| 154 | |
| 155 | $behavior = array(); |
| 156 | $content = (array) $this->module->content; |
| 157 | if ( $is_optin ) { |
| 158 | $emails = (array) $this->module->emails; |
| 159 | } |
| 160 | if ( $is_slidein ) { |
| 161 | $behavior = (array) $this->module->settings; |
| 162 | } |
| 163 | |
| 164 | // Get the defaults. |
| 165 | $colors = Hustle_Palettes_Helper::get_palette_array( $design['color_palette'], $is_optin ); |
| 166 | $advanced = $this->design_meta->get_border_spacing_shadow_defaults( 'desktop' ); |
| 167 | $advanced_mobile = $this->design_meta->get_border_spacing_shadow_defaults( 'mobile' ); |
| 168 | $typography = $this->design_meta->get_typography_defaults( 'desktop' ); |
| 169 | $typography_mobile = $this->design_meta->get_typography_defaults( 'mobile' ); |
| 170 | |
| 171 | // Get custom values if enabled. |
| 172 | if ( ! $is_vanilla ) { |
| 173 | |
| 174 | // Sets colors for the decorator. |
| 175 | if ( '1' === $design['customize_colors'] || empty( $colors ) ) { |
| 176 | // The custom palette might not exist in the site. Grab the colors from the module if so. |
| 177 | if ( empty( $colors ) ) { |
| 178 | $colors = Hustle_Palettes_Helper::get_palette_array( 'gray_slate', $is_optin ); |
| 179 | } |
| 180 | $colors = array_intersect_key( $design, $colors ); |
| 181 | } |
| 182 | |
| 183 | // Sets Border, spacing, shadow settings. |
| 184 | if ( '1' === $design['customize_border_shadow_spacing'] ) { |
| 185 | $advanced = array_intersect_key( $design, $advanced ); |
| 186 | } |
| 187 | |
| 188 | if ( '1' === $design['customize_border_shadow_spacing_mobile'] ) { |
| 189 | $advanced_mobile = array_intersect_key( $design, $advanced_mobile ); |
| 190 | } |
| 191 | |
| 192 | // Sets typography settings. |
| 193 | if ( '1' === $design['customize_typography'] ) { |
| 194 | $typography = array_intersect_key( $design, $typography ); |
| 195 | } |
| 196 | |
| 197 | if ( '1' === $design['customize_typography_mobile'] ) { |
| 198 | $typography_mobile = array_intersect_key( $design, $typography_mobile ); |
| 199 | } |
| 200 | } |
| 201 | $advanced += $advanced_mobile; |
| 202 | $typography += $typography_mobile; |
| 203 | |
| 204 | $style = ''; |
| 205 | |
| 206 | if ( $is_optin ) { |
| 207 | foreach ( $this->optin_files_list as $file_name ) { |
| 208 | include Opt_In::$plugin_path . 'inc/front/non-sshare-styles/' . $file_name . '.php'; |
| 209 | } |
| 210 | } else { |
| 211 | foreach ( $this->info_files_list as $file_name ) { |
| 212 | include Opt_In::$plugin_path . 'inc/front/non-sshare-styles/' . $file_name . '.php'; |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | $styles = $style; |
| 217 | |
| 218 | $stylable_elements = $this->get_popup_stylable_elements(); |
| 219 | |
| 220 | /** |
| 221 | * Colors Palette. |
| 222 | * Works for opt-in and informational modules. |
| 223 | * |
| 224 | * @since 4.0 |
| 225 | */ |
| 226 | |
| 227 | // **************************************** |
| 228 | // 2.1. DEFAULT |
| 229 | |
| 230 | // Blockquote border. |
| 231 | if ( '' !== $content['main_content'] ) { |
| 232 | $styles .= ' '; |
| 233 | $styles .= $prefix . $stylable_elements['layout_content'] . ' blockquote {'; |
| 234 | $styles .= 'border-left-color: ' . $colors['blockquote_border'] . ';'; |
| 235 | $styles .= '}'; |
| 236 | } |
| 237 | |
| 238 | return $styles; |
| 239 | } |
| 240 | |
| 241 | /** |
| 242 | * Get stylable element with prefix |
| 243 | * |
| 244 | * @param string $prefix Prefix. |
| 245 | * @return array |
| 246 | */ |
| 247 | private function get_prefixed_popup_stylable_elements( $prefix ) { |
| 248 | |
| 249 | return array( |
| 250 | 'layout_content' => $prefix . '.hustle-layout .hustle-group-content', |
| 251 | ); |
| 252 | } |
| 253 | |
| 254 | /** |
| 255 | * Get stylable element |
| 256 | * |
| 257 | * @return array |
| 258 | */ |
| 259 | private function get_popup_stylable_elements() { |
| 260 | |
| 261 | return array( |
| 262 | 'layout_content' => '.hustle-layout .hustle-group-content', |
| 263 | ); |
| 264 | } |
| 265 | |
| 266 | /** |
| 267 | * Get the module's custom CSS. |
| 268 | * |
| 269 | * @since 4.0.3 |
| 270 | * @return string |
| 271 | */ |
| 272 | private function get_custom_css() { |
| 273 | |
| 274 | $styles = ''; |
| 275 | $prefix_alt = '.hustle-ui.hustle_module_id_' . $this->module->module_id . '[data-id="' . $this->module->module_id . '"]'; |
| 276 | |
| 277 | /** |
| 278 | * Custom CSS |
| 279 | * Works for both opt-in and informational modules. |
| 280 | * |
| 281 | * @since 4.0 |
| 282 | */ |
| 283 | |
| 284 | // for Desktop. |
| 285 | if ( '1' === $this->design['customize_css'] && ! empty( $this->design['custom_css'] ) ) { |
| 286 | $styles .= $this->prepare_css( $this->design['custom_css'], $prefix_alt, false, true ); |
| 287 | } |
| 288 | |
| 289 | return $styles; |
| 290 | } |
| 291 | |
| 292 | /** |
| 293 | * Prepares the custom css string |
| 294 | * |
| 295 | * @since 1.0.0 |
| 296 | * @since 4.2.0 Moved from the class Opt_In to here. Scope changed from 'public static' to 'private'. |
| 297 | * |
| 298 | * @param string $css_string Raw CSS string. |
| 299 | * @param string $prefix Prefix for the rules. |
| 300 | * @param bool $as_array Whether to return the prepared css as an array or as a string. |
| 301 | * @param bool $separate_prefix Whether the prefix must be separated. |
| 302 | * @param string $wildcard The sibling class of target selector. |
| 303 | * @return array|string |
| 304 | */ |
| 305 | private function prepare_css( $css_string, $prefix, $as_array = false, $separate_prefix = true, $wildcard = '' ) { |
| 306 | |
| 307 | // Master array to hold all values. |
| 308 | $css_array = array(); |
| 309 | $elements = explode( '}', $css_string ); |
| 310 | |
| 311 | // Output is the final processed CSS string. |
| 312 | $output = ''; |
| 313 | $prepared = ''; |
| 314 | $have_media = false; |
| 315 | $media_names = array(); |
| 316 | $media_names_key = 0; |
| 317 | $index = 0; |
| 318 | |
| 319 | foreach ( $elements as $element ) { |
| 320 | |
| 321 | $check_element = trim( $element ); |
| 322 | |
| 323 | if ( empty( $check_element ) ) { |
| 324 | ++$index; // Still increment $index even if empty. |
| 325 | continue; |
| 326 | } |
| 327 | |
| 328 | // get the name of the CSS element. |
| 329 | $a_name = explode( '{', $element ); |
| 330 | $name = $a_name[0]; |
| 331 | |
| 332 | // check if @media is present. |
| 333 | $media_name = ''; |
| 334 | |
| 335 | if ( strpos( $name, '@media' ) !== false && isset( $a_name[1] ) ) { |
| 336 | |
| 337 | $have_media = true; |
| 338 | $media_name = $name; |
| 339 | $media_names[ $media_names_key ] = array( |
| 340 | 'name' => $media_name, |
| 341 | ); |
| 342 | $name = $a_name[1]; |
| 343 | ++$media_names_key; |
| 344 | |
| 345 | } |
| 346 | |
| 347 | if ( $have_media ) { |
| 348 | $prepared = ''; |
| 349 | } |
| 350 | |
| 351 | // get all the key:value pair styles. |
| 352 | $a_styles = explode( ';', $element ); |
| 353 | |
| 354 | // remove element name from first property element. |
| 355 | $remove_element_name = ( ! empty( $media_name ) ) ? $media_name . '{' . $name : $name; |
| 356 | $a_styles[0] = str_replace( $remove_element_name . '{', '', $a_styles[0] ); |
| 357 | $names = explode( ',', $name ); |
| 358 | |
| 359 | foreach ( $names as $name ) { |
| 360 | |
| 361 | if ( $separate_prefix && empty( $wildcard ) ) { |
| 362 | $space_needed = true; |
| 363 | } elseif ( $separate_prefix && ! empty( $wildcard ) ) { |
| 364 | |
| 365 | // wildcard is the sibling class of target selector e.g. "wph-modal". |
| 366 | if ( strpos( $name, $wildcard ) ) { |
| 367 | $space_needed = false; |
| 368 | } else { |
| 369 | $space_needed = true; |
| 370 | } |
| 371 | } else { |
| 372 | $space_needed = false; |
| 373 | } |
| 374 | |
| 375 | $maybe_put_space = ( $space_needed ) ? ' ' : ''; |
| 376 | |
| 377 | $prepared .= ( $prefix . $maybe_put_space . trim( $name ) . ',' ); |
| 378 | |
| 379 | } |
| 380 | |
| 381 | $prepared = trim( $prepared, ',' ); |
| 382 | $prepared .= '{'; |
| 383 | |
| 384 | // loop through each style and split apart the key from the value. |
| 385 | $count = count( $a_styles ); |
| 386 | |
| 387 | for ( $a = 0;$a < $count; $a++ ) { |
| 388 | |
| 389 | if ( trim( $a_styles[ $a ] ) ) { |
| 390 | |
| 391 | $a_key_value = explode( ':', $a_styles[ $a ] ); |
| 392 | |
| 393 | // build the master css array. |
| 394 | if ( count( $a_key_value ) > 2 ) { |
| 395 | $a_key_value_to_join = array_slice( $a_key_value, 1 ); |
| 396 | $a_key_value[1] = implode( ':', $a_key_value_to_join ); |
| 397 | } |
| 398 | |
| 399 | if ( ! isset( $a_key_value[1] ) ) { |
| 400 | continue; |
| 401 | } |
| 402 | |
| 403 | $css_array[ $name ][ $a_key_value[0] ] = $a_key_value[1]; |
| 404 | $prepared .= ( $a_key_value[0] . ': ' . $a_key_value[1] ); |
| 405 | |
| 406 | if ( '' === $a_key_value[1] ) { |
| 407 | $prepared .= ''; |
| 408 | } |
| 409 | |
| 410 | $prepared .= ';'; |
| 411 | } |
| 412 | } |
| 413 | |
| 414 | $prepared .= '}'; |
| 415 | |
| 416 | // if have @media earlier, append these styles. |
| 417 | $prev_media_names_key = $media_names_key - 1; |
| 418 | |
| 419 | if ( isset( $media_names[ $prev_media_names_key ] ) ) { |
| 420 | |
| 421 | if ( isset( $media_names[ $prev_media_names_key ]['styles'] ) ) { |
| 422 | |
| 423 | // See if there were two closing '}' or just one. |
| 424 | // (each element is exploded/split on '}' symbol, so having two empty strings afterward in the elements array means two '}'s. |
| 425 | $next_element = isset( $elements[ $index + 2 ] ) ? trim( $elements[ $index + 2 ] ) : false; |
| 426 | |
| 427 | // If inside @media block. |
| 428 | if ( false !== $next_element ) { |
| 429 | $media_names[ $prev_media_names_key ]['styles'] .= $prepared; |
| 430 | } else { |
| 431 | // If outside of @media block, add to output. |
| 432 | $output .= $prepared; |
| 433 | // reset $prepared for next styles. |
| 434 | $prepared = ''; |
| 435 | } |
| 436 | } else { |
| 437 | $media_names[ $prev_media_names_key ]['styles'] = $prepared; |
| 438 | } |
| 439 | } else { |
| 440 | |
| 441 | // If no @media, add styles to $output outside @media. |
| 442 | $output .= $prepared; |
| 443 | // reset $prepared for next styles. |
| 444 | $prepared = ''; |
| 445 | } |
| 446 | |
| 447 | // Increase index. |
| 448 | ++$index; |
| 449 | } |
| 450 | |
| 451 | // if have @media, populate styles using $media_names. |
| 452 | if ( $have_media ) { |
| 453 | |
| 454 | // reset first $prepared styles. |
| 455 | $prepared = ''; |
| 456 | |
| 457 | foreach ( $media_names as $media ) { |
| 458 | $prepared .= $media['name'] . '{ ' . $media['styles'] . ' }'; |
| 459 | } |
| 460 | |
| 461 | // Add @media styles to output. |
| 462 | $output .= $prepared; |
| 463 | } |
| 464 | |
| 465 | return $as_array ? $css_array : $output; |
| 466 | } |
| 467 | } |
| 468 |