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
4 hours ago
hustle-module-front.php
4 hours 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
4 hours ago
hustle-renderer-sshare.php
495 lines
| 1 | <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName |
| 2 | /** |
| 3 | * Hustle_Renderer_Sshare |
| 4 | * |
| 5 | * @package Hustle |
| 6 | */ |
| 7 | |
| 8 | /** |
| 9 | * Class Hustle_Renderer_Sshare |
| 10 | * Used to render Social sharing modules. |
| 11 | * |
| 12 | * @since 4.0 |
| 13 | */ |
| 14 | class Hustle_Renderer_Sshare extends Hustle_Renderer_Abstract { |
| 15 | |
| 16 | /** |
| 17 | * Get the content container tag. |
| 18 | * |
| 19 | * @since 4.0 |
| 20 | * @param string $subtype Sub type. |
| 21 | * @param string $custom_classes Custom classes. |
| 22 | * @return string |
| 23 | */ |
| 24 | protected function get_wrapper_main( $subtype, $custom_classes ) { |
| 25 | |
| 26 | $module_id = $this->module->module_id; |
| 27 | $display = $this->module->display; |
| 28 | |
| 29 | // Tracking enabled data. |
| 30 | $tracking_enabled_data = $this->module->is_tracking_enabled( $subtype ) ? 'enabled' : 'disabled'; |
| 31 | |
| 32 | // Type of module |
| 33 | // Applies for all except "float" modules. |
| 34 | $module_type = 'inline'; |
| 35 | |
| 36 | // Main data attributes for module. |
| 37 | $module_data = sprintf( |
| 38 | ' |
| 39 | data-id="%s" |
| 40 | data-render-id="%d" |
| 41 | data-tracking="%s" |
| 42 | data-sub-type="%s" |
| 43 | ', |
| 44 | esc_attr( $module_id ), |
| 45 | self::$render_ids[ $module_id ], |
| 46 | esc_attr( $tracking_enabled_data ), |
| 47 | esc_attr( $subtype ) |
| 48 | ); |
| 49 | |
| 50 | // If this instance is a floating module. |
| 51 | // This happens when floating is enabled in either desktop or mobile. |
| 52 | if ( Hustle_SShare_Model::FLOAT_MODULE === $subtype ) { |
| 53 | |
| 54 | $module_type = 'float'; |
| 55 | |
| 56 | // Check if the module has floating active for desktop. |
| 57 | if ( self::$is_preview ) { |
| 58 | $module_data .= 'data-desktop="true"'; |
| 59 | } elseif ( $this->module->is_display_type_active( Hustle_SShare_Model::FLOAT_DESKTOP ) ) { |
| 60 | |
| 61 | $offset = 'css_selector' === $display->float_desktop_offset ? 'selector' : $display->float_desktop_offset; |
| 62 | $selector = 'selector' === $offset ? trim( $display->float_desktop_css_selector ) : ''; |
| 63 | $position_x = $display->float_desktop_position; |
| 64 | $position_y = $display->float_desktop_position_y; |
| 65 | |
| 66 | $module_data .= sprintf( |
| 67 | ' |
| 68 | data-desktop="true" |
| 69 | data-desktop-offset="%s" |
| 70 | data-desktop-selector="%s" |
| 71 | data-desktop-positionX="%s" |
| 72 | data-desktop-positionY="%s" |
| 73 | ', |
| 74 | esc_attr( $offset ), |
| 75 | esc_attr( $selector ), |
| 76 | esc_attr( $position_x ), |
| 77 | esc_attr( $position_y ) |
| 78 | ); |
| 79 | } else { |
| 80 | $module_data .= 'data-desktop="false"'; |
| 81 | } |
| 82 | |
| 83 | // Check if the module has floating active for mobile. |
| 84 | if ( $this->module->is_display_type_active( Hustle_SShare_Model::FLOAT_MOBILE ) ) { |
| 85 | |
| 86 | $offset = 'css_selector' === $display->float_mobile_offset ? 'selector' : $display->float_mobile_offset; |
| 87 | $selector = 'selector' === $offset ? trim( $display->float_mobile_css_selector ) : ''; |
| 88 | $position_x = $display->float_mobile_position; |
| 89 | $position_y = $display->float_mobile_position_y; |
| 90 | |
| 91 | $module_data .= sprintf( |
| 92 | ' |
| 93 | data-mobiles="true" |
| 94 | data-mobiles-offset="%s" |
| 95 | data-mobiles-selector="%s" |
| 96 | data-mobiles-positionX="%s" |
| 97 | data-mobiles-positionY="%s" |
| 98 | ', |
| 99 | esc_attr( $offset ), |
| 100 | esc_attr( $selector ), |
| 101 | esc_attr( $position_x ), |
| 102 | esc_attr( $position_y ) |
| 103 | ); |
| 104 | } else { |
| 105 | $module_data .= 'data-mobiles="false"'; |
| 106 | } |
| 107 | } else { |
| 108 | |
| 109 | $module_data .= sprintf( |
| 110 | ' |
| 111 | data-delay="%s" |
| 112 | data-intro="%s" |
| 113 | ', |
| 114 | '0', |
| 115 | 'no_animation' |
| 116 | ); |
| 117 | |
| 118 | if ( Hustle_SShare_Model::INLINE_MODULE === $subtype ) { |
| 119 | |
| 120 | $module_data .= sprintf( |
| 121 | 'data-alignment="%s"', |
| 122 | esc_attr( $display->inline_align ) |
| 123 | ); |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | $inline_style = ! self::$is_preview ? 'style="opacity:0;"' : 'style="opacity:1;"'; |
| 128 | |
| 129 | if ( self::$is_preview ) { |
| 130 | $custom_classes .= ' hustle-displaying-in-large'; |
| 131 | } |
| 132 | |
| 133 | $html = sprintf( |
| 134 | '<div class="hustle-ui hustle-%s hustle_module_id_%d %s" %s %s>', |
| 135 | esc_attr( $module_type ), |
| 136 | $this->module->module_id, |
| 137 | esc_attr( $custom_classes ), |
| 138 | $module_data, |
| 139 | $inline_style |
| 140 | ); |
| 141 | |
| 142 | return $html; |
| 143 | } |
| 144 | |
| 145 | /** |
| 146 | * Get the wrapper content. |
| 147 | * |
| 148 | * @since 4.0 |
| 149 | * |
| 150 | * @param string $subtype Sub type. |
| 151 | * @return string |
| 152 | */ |
| 153 | protected function get_wrapper_content( $subtype ) { |
| 154 | |
| 155 | $module_type = 'inline'; |
| 156 | |
| 157 | if ( Hustle_SShare_Model::FLOAT_MODULE === $subtype ) { |
| 158 | $module_type = 'float'; |
| 159 | } |
| 160 | |
| 161 | $html = sprintf( |
| 162 | '<div class="hustle-%s-content">', |
| 163 | $module_type |
| 164 | ); |
| 165 | |
| 166 | return $html; |
| 167 | } |
| 168 | |
| 169 | /** |
| 170 | * Get the body content. |
| 171 | * |
| 172 | * @since 4.0 |
| 173 | * |
| 174 | * @param string $subtype Sub type. |
| 175 | * @return string |
| 176 | */ |
| 177 | protected function get_module_body( $subtype ) { |
| 178 | |
| 179 | $html = ''; |
| 180 | |
| 181 | $module_id = $this->module->module_id; |
| 182 | |
| 183 | // Prevent php error messages on wizard preview when no services are active. |
| 184 | $content = $this->module->content; |
| 185 | $display = $this->module->display; |
| 186 | $design = $this->module->design; |
| 187 | |
| 188 | $icons_design = $design->icon_style; |
| 189 | $icons_custom_color = 'false'; |
| 190 | $icons_grid_desktop = 'inline'; |
| 191 | $icons_grid_mobiles = 'inline'; |
| 192 | $icons_counter = 'none'; |
| 193 | $icons_animated = false; |
| 194 | $icons_animation = 'zoom'; |
| 195 | |
| 196 | if ( 'flat' === $icons_design ) { |
| 197 | $icons_design = 'default'; |
| 198 | } elseif ( 'outline' === $icons_design ) { |
| 199 | $icons_design = 'outlined'; |
| 200 | } |
| 201 | |
| 202 | if ( Hustle_SShare_Model::FLOAT_MODULE === $subtype ) { |
| 203 | |
| 204 | // Check if icons custom color is enabled. |
| 205 | $icons_custom_color = ( '1' === $design->floating_customize_colors ) ? 'true' : 'false'; |
| 206 | |
| 207 | // Check if the module has floating active for desktop. |
| 208 | if ( $this->module->is_display_type_active( Hustle_SShare_Model::FLOAT_DESKTOP ) ) { |
| 209 | |
| 210 | $position_x = $display->float_desktop_position; |
| 211 | $position_y = $display->float_desktop_position_y; |
| 212 | |
| 213 | if ( 'center' !== $display->float_desktop_position ) { |
| 214 | $icons_grid_desktop = 'stacked'; |
| 215 | } |
| 216 | |
| 217 | if ( 'center' === $position_x ) { |
| 218 | |
| 219 | if ( 'top' === $position_y ) { |
| 220 | $icons_animation = 'bounceDownUp'; |
| 221 | } else { |
| 222 | $icons_animation = 'bounceUpDown'; |
| 223 | } |
| 224 | } |
| 225 | } |
| 226 | |
| 227 | // Check if the module has floating active for mobile. |
| 228 | if ( $this->module->is_display_type_active( Hustle_SShare_Model::FLOAT_MOBILE ) ) { |
| 229 | |
| 230 | $position_x = $display->float_mobile_position; |
| 231 | $position_y = $display->float_mobile_position_y; |
| 232 | |
| 233 | if ( 'center' !== $display->float_mobile_position ) { |
| 234 | $icons_grid_mobiles = 'stacked'; |
| 235 | } |
| 236 | |
| 237 | if ( 'center' === $position_x ) { |
| 238 | |
| 239 | if ( 'top' === $position_y ) { |
| 240 | $icons_animation = 'bounceDownUp'; |
| 241 | } else { |
| 242 | $icons_animation = 'bounceUpDown'; |
| 243 | } |
| 244 | } |
| 245 | } |
| 246 | |
| 247 | if ( self::$is_preview ) { |
| 248 | $icons_grid_desktop = 'stacked'; |
| 249 | $icons_grid_mobiles = 'stacked'; |
| 250 | } |
| 251 | |
| 252 | // Check if counter is enabled. |
| 253 | if ( '1' === $content->counter_enabled ) { |
| 254 | $icons_counter = ( '1' === $design->floating_inline_count ) ? 'inline' : 'stacked'; |
| 255 | } |
| 256 | |
| 257 | // Check if icons are animated. |
| 258 | if ( '1' === $design->floating_animate_icons ) { |
| 259 | $icons_animated = true; |
| 260 | } |
| 261 | } else { |
| 262 | |
| 263 | // Check if icons custom color is enabled. |
| 264 | $icons_custom_color = ( '1' === $design->widget_customize_colors ) ? 'true' : 'false'; |
| 265 | |
| 266 | // Check if counter is enabled. |
| 267 | if ( '1' === $content->counter_enabled ) { |
| 268 | $icons_counter = ( '1' === $design->widget_inline_count ) ? 'inline' : 'stacked'; |
| 269 | } |
| 270 | |
| 271 | // Check if icons are animated. |
| 272 | if ( '1' === $design->widget_animate_icons ) { |
| 273 | $icons_animated = true; |
| 274 | } |
| 275 | } |
| 276 | |
| 277 | $html .= sprintf( |
| 278 | '<div class="hustle-social hustle-social--%s" data-custom="%s" data-grid-desktop="%s" data-grid-mobiles="%s">', |
| 279 | esc_attr( $icons_design ), |
| 280 | esc_attr( $icons_custom_color ), |
| 281 | esc_attr( $icons_grid_desktop ), |
| 282 | esc_attr( $icons_grid_mobiles ) |
| 283 | ); |
| 284 | |
| 285 | $html .= sprintf( |
| 286 | '<ul class="hustle-counter--%s%s"%s>', |
| 287 | esc_attr( $icons_counter ), |
| 288 | ( true === $icons_animated ? ' hustle-animated' : '' ), |
| 289 | ( true === $icons_animated ? ' data-animation="' . esc_attr( $icons_animation ) . '"' : '' ) |
| 290 | ); |
| 291 | |
| 292 | $social_icons = $content->social_icons; |
| 293 | |
| 294 | /** |
| 295 | * Filters the icons to be shown. |
| 296 | * Here you can add custom icons to be printed. It only works for networks |
| 297 | * using custom links (non-native ones), and without counters. |
| 298 | * The icon and visual attributes must be handled via custom CSS. |
| 299 | * |
| 300 | * @since 4.1.2 |
| 301 | * |
| 302 | * @param array $social_icons { |
| 303 | * Selected social networks for the module. |
| 304 | * Contains an array for each platform. The platform's slug is the key of its array. |
| 305 | * The array for each platform must contain: |
| 306 | * |
| 307 | * @type string 'platform' The network's slug. Same as the array key. Lowercase, no spaces nor special chars. |
| 308 | * @type string 'label' The network's display name. |
| 309 | * @type string 'type' click|native Whether the counter would be retrieved from clicks or an API. Use 'click'. |
| 310 | * @type string 'link' The URL to which the user will go when clicking the icon. Required if a sharing |
| 311 | * endpoint isn't especified in the filter @see hustle_native_share_enpoints. |
| 312 | * @type int 'counter' The default number for the counter. This will be static, it won't increase for now. |
| 313 | * } |
| 314 | */ |
| 315 | $social_icons = apply_filters( 'hustle_social_sharing_get_selected_networks', $social_icons, $this->module ); |
| 316 | |
| 317 | // Extra indentation to mimic html tree. |
| 318 | if ( ! empty( $social_icons ) ) { |
| 319 | |
| 320 | $fb_script_printed = false; |
| 321 | foreach ( $social_icons as $icon => $data ) { |
| 322 | |
| 323 | $type = isset( $data['type'] ) ? $data['type'] : ''; |
| 324 | $label = isset( $data['label'] ) ? $data['label'] : ''; |
| 325 | $link = isset( $data['link'] ) ? $data['link'] : ''; |
| 326 | |
| 327 | if ( 'facebook' === $data['platform'] ) { |
| 328 | $type = 'click'; |
| 329 | |
| 330 | // Build the Facebook share URL when no custom link is provided. |
| 331 | if ( '' === $link ) { |
| 332 | global $wp; |
| 333 | $current_url = home_url( $wp->request ); |
| 334 | |
| 335 | if ( ! empty( $data['app_id'] ) && ! $fb_script_printed ) { |
| 336 | // Use the Share Dialog when an App ID is available. |
| 337 | $link = '#'; |
| 338 | // Print the Facebook SDK script only once per page. |
| 339 | $fb_script_printed = true; |
| 340 | |
| 341 | $script = sprintf( |
| 342 | '<script type="text/javascript"> |
| 343 | window.fbAsyncInit = function() { |
| 344 | FB.init({ |
| 345 | appId: \'%1$s\', |
| 346 | cookie: true, |
| 347 | xfbml: true, |
| 348 | version: \'v25.0\' |
| 349 | }); |
| 350 | |
| 351 | FB.AppEvents.logPageView(); |
| 352 | }; |
| 353 | |
| 354 | (function(d, s, id){ |
| 355 | var js, fjs = d.getElementsByTagName(s)[0]; |
| 356 | if (d.getElementById(id)) {return;} |
| 357 | js = d.createElement(s); js.id = id; |
| 358 | js.src = "https://connect.facebook.net/en_US/sdk.js"; |
| 359 | fjs.parentNode.insertBefore(js, fjs); |
| 360 | }(document, \'script\', \'facebook-jssdk\')); |
| 361 | </script>', |
| 362 | $data['app_id'], |
| 363 | $current_url |
| 364 | ); |
| 365 | |
| 366 | $html .= $script; |
| 367 | } else { |
| 368 | // Fallback for existing entries saved before the App ID field was added. |
| 369 | $link = 'https://www.facebook.com/sharer/sharer.php?u=' . $current_url; |
| 370 | } |
| 371 | } |
| 372 | } |
| 373 | |
| 374 | if ( '' === $link && 'email' !== $icon ) { |
| 375 | |
| 376 | $href_value = 'href="#"'; |
| 377 | $link_type = 'native'; |
| 378 | |
| 379 | } else { |
| 380 | // Check if is email to insert mailto. |
| 381 | if ( 'email' === $icon ) { |
| 382 | |
| 383 | $query_args = array( |
| 384 | 'subject' => rawurlencode( Opt_In_Utils::replace_global_placeholders( $data['title'] ) ), |
| 385 | 'body' => rawurlencode( Opt_In_Utils::replace_global_placeholders( $data['message'] ) ), |
| 386 | ); |
| 387 | $mail_url = add_query_arg( $query_args, 'mailto:' ); |
| 388 | $href_value = 'href="' . esc_url( $mail_url ) . '"'; |
| 389 | $title = apply_filters( 'hustle_social_share_platform_title', rawurlencode( html_entity_decode( esc_html( get_the_title() ) ) ) ); |
| 390 | |
| 391 | } else { |
| 392 | $link = apply_filters( 'hustle_social_share_custom_link', $link, $data, $this->module ); |
| 393 | $href_value = 'href="' . esc_url( $link ) . '" target="_blank" rel="noopener"'; |
| 394 | } |
| 395 | |
| 396 | $link_type = 'custom'; |
| 397 | |
| 398 | } |
| 399 | |
| 400 | if ( 'fivehundredpx' === $icon ) { |
| 401 | $icon = '500px'; |
| 402 | $network = 'fivehundredpx'; |
| 403 | } else { |
| 404 | $network = $icon; |
| 405 | } |
| 406 | |
| 407 | $html .= '<li>'; |
| 408 | |
| 409 | $html .= sprintf( |
| 410 | '<a %1$s class="hustle-share-icon hustle-share--%2$s" data-network="%3$s" data-counter="%4$s" data-link="%5$s" data-count="%6$s">', |
| 411 | $href_value, |
| 412 | esc_attr( $icon ), |
| 413 | esc_attr( $network ), |
| 414 | '0' === $content->counter_enabled ? 'none' : esc_attr( $type ), |
| 415 | esc_attr( $link_type ), |
| 416 | esc_attr( $data['counter'] ) |
| 417 | ); |
| 418 | |
| 419 | $html .= sprintf( |
| 420 | '<i class="hustle-icon-social-%s" aria-hidden="true"></i>', |
| 421 | esc_attr( $icon ) |
| 422 | ); |
| 423 | |
| 424 | if ( '1' === $content->counter_enabled ) { |
| 425 | |
| 426 | if ( 'native' === $type && ! self::$is_preview ) { |
| 427 | $counter_content = '<i class="hustle-icon-loader hustle-loading-icon" aria-hidden="true"></i>'; |
| 428 | |
| 429 | } else { |
| 430 | $counter_content = ( '' !== $data['counter'] ) ? esc_attr( $data['counter'] ) : '0'; |
| 431 | } |
| 432 | |
| 433 | $html .= sprintf( |
| 434 | '<span class="hustle-counter" aria-hidden="true">%s</span>', |
| 435 | $counter_content |
| 436 | ); |
| 437 | } |
| 438 | |
| 439 | $html .= sprintf( |
| 440 | '<span class="hustle-screen-reader">Share on %s</span>', |
| 441 | esc_html( $label ) |
| 442 | ); |
| 443 | |
| 444 | $html .= '</a>'; |
| 445 | |
| 446 | $html .= '</li>'; |
| 447 | |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | $html .= '</ul>'; |
| 452 | |
| 453 | $html .= '</div>'; |
| 454 | |
| 455 | return $html; |
| 456 | } |
| 457 | |
| 458 | /** |
| 459 | * Handle AJAX display |
| 460 | * |
| 461 | * @since 4.0 |
| 462 | * @param Hustle_Sshare_Model $module Module. |
| 463 | * @param array $data Data. |
| 464 | * @param bool $is_preview Is preview. |
| 465 | * @return string |
| 466 | */ |
| 467 | public function ajax_display( Hustle_Sshare_Model $module, $data = array(), $is_preview = true ) { |
| 468 | |
| 469 | self::$is_preview = $is_preview; |
| 470 | |
| 471 | if ( ! empty( $data ) ) { |
| 472 | $this->module = $module->load_preview( $data ); |
| 473 | } else { |
| 474 | $this->module = $module->load(); |
| 475 | } |
| 476 | |
| 477 | $response = array( |
| 478 | 'style' => array(), |
| 479 | 'script' => array(), |
| 480 | 'module' => $this->module, |
| 481 | ); |
| 482 | |
| 483 | $response['floatingHtml'] = $this->get_module( Hustle_SShare_Model::FLOAT_MODULE, 'hustle-show', $is_preview ); |
| 484 | $response['widgetHtml'] = $this->get_module( Hustle_SShare_Model::WIDGET_MODULE, 'hustle-show', $is_preview ); |
| 485 | |
| 486 | // This might be used later for ajax loading. |
| 487 | ob_start(); |
| 488 | $this->print_styles( $is_preview ); |
| 489 | $styles = ob_get_clean(); |
| 490 | $response['style'] = $styles; |
| 491 | |
| 492 | return $response; |
| 493 | } |
| 494 | } |
| 495 |