Changeset 3023121
- Timestamp:
- 01/17/2024 07:21:25 PM (2 years ago)
- Location:
- shared-counts
- Files:
-
- 16 edited
- 1 copied
-
tags/1.5.0 (copied) (copied from shared-counts/trunk)
-
tags/1.5.0/CHANGELOG.md (modified) (1 diff)
-
tags/1.5.0/assets/js/shared-counts.js (modified) (2 diffs)
-
tags/1.5.0/assets/js/shared-counts.min.js (modified) (1 diff)
-
tags/1.5.0/includes/class-shared-counts-admin.php (modified) (3 diffs)
-
tags/1.5.0/includes/class-shared-counts-core.php (modified) (1 diff)
-
tags/1.5.0/includes/class-shared-counts-front.php (modified) (7 diffs)
-
tags/1.5.0/readme.txt (modified) (4 diffs)
-
tags/1.5.0/shared-counts.php (modified) (2 diffs)
-
trunk/CHANGELOG.md (modified) (1 diff)
-
trunk/assets/js/shared-counts.js (modified) (2 diffs)
-
trunk/assets/js/shared-counts.min.js (modified) (1 diff)
-
trunk/includes/class-shared-counts-admin.php (modified) (3 diffs)
-
trunk/includes/class-shared-counts-core.php (modified) (1 diff)
-
trunk/includes/class-shared-counts-front.php (modified) (7 diffs)
-
trunk/readme.txt (modified) (4 diffs)
-
trunk/shared-counts.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
shared-counts/tags/1.5.0/CHANGELOG.md
r2836327 r3023121 1 1 # Change Log 2 2 All notable changes to this project will be documented in this file, formatted via [this recommendation](http://keepachangelog.com/). 3 4 ## [1.5.0] = 2024-01-17 5 ### Changed 6 - Replaced server side email with a mailto link to remove the possibility of spam, see #131 7 - Updated the Twitter logo to X, see #129 8 - Removed jQuery dependency, see #113 9 - Use `esc_url()` for sharing links, see #130 3 10 4 11 ## [1.4.1] = 2022-12-19 -
shared-counts/tags/1.5.0/assets/js/shared-counts.js
r2087195 r3023121 1 /* global shared_counts, grecaptcha */ 2 3 'use strict'; 4 5 jQuery( document ).ready(function($){ 6 7 var modalOpen = false, 8 shared_counts_id, 9 shared_counts_nonce; 10 11 /** 12 * Close email sharing modal. 13 * 14 * @since 1.0.0 15 */ 16 function modalClose() { 17 18 modalOpen = false; 19 20 $( '#shared-counts-modal-recipient, #shared-counts-modal-name, #shared-counts-modal-email' ).val( '' ); 21 $( '#shared-counts-modal-wrap' ).fadeOut(); 22 $( '#shared-counts-modal-sent' ).hide(); 23 } 1 document.addEventListener('DOMContentLoaded', function() { 24 2 25 3 // Google Analytics Social tracking. 26 $( document ).on( 'click', '.shared-counts-button', function() { 4 document.addEventListener('click', function(event) { 5 var target = event.target; 27 6 28 if ( shared_counts.social_tracking) {7 if (target.classList.contains('shared-counts-button')) { 29 8 30 var $this = $( this ), 31 network = $this.data( 'social-network' ), 32 action = $this.data( 'social-action' ), 33 target = $this.data( 'social-target' ); 9 if (shared_counts.social_tracking) { 34 10 35 if ( network && action && target ) { 36 if ( 'function' === typeof ga ) { 37 // Default GA. 38 ga( 'send', 'social', network, action, target ); 39 } else if ( 'function' === typeof __gaTracker ) { 40 // MonsterInsights. 41 __gaTracker( 'send', 'social', network, action, target ); 11 var network = target.getAttribute('data-social-network'), 12 action = target.getAttribute('data-social-action'), 13 targetValue = target.getAttribute('data-social-target'); 14 15 if (network && action && targetValue) { 16 if (typeof ga === 'function') { 17 // Default GA. 18 ga('send', 'social', network, action, targetValue); 19 } else if (typeof __gaTracker === 'function') { 20 // MonsterInsights. 21 __gaTracker('send', 'social', network, action, targetValue); 22 } 42 23 } 43 24 } … … 46 27 47 28 // Share button click. 48 $( document ).on( 'click', '.shared-counts-button[target="_blank"]:not(.no-js)', function( event ) { 29 document.addEventListener('click', function(event) { 30 var target = event.target; 49 31 50 event.preventDefault();32 if (target.classList.contains('shared-counts-button') && target.getAttribute('target') === '_blank' && !target.classList.contains('no-js')) { 51 33 52 var window_size = '', 53 url = this.href, 54 domain = url.split( '/' )[2]; 34 event.preventDefault(); 55 35 56 switch ( domain ) { 57 case 'www.facebook.com': 58 window_size = 'width=585,height=368'; 59 break; 60 case 'twitter.com': 61 window_size = 'width=585,height=261'; 62 break; 63 case 'pinterest.com': 64 window_size = 'width=750,height=550'; 65 break; 66 default: 67 window_size = 'width=585,height=515'; 68 } 69 window.open( url, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,' + window_size ); 36 var window_size = '', 37 url = target.href, 38 domain = url.split('/')[2]; 70 39 71 $( this ).trigger( 'shared-counts-click' ); 72 }); 40 switch (domain) { 41 case 'www.facebook.com': 42 window_size = 'width=585,height=368'; 43 break; 44 case 'twitter.com': 45 window_size = 'width=585,height=261'; 46 break; 47 case 'pinterest.com': 48 window_size = 'width=750,height=550'; 49 break; 50 default: 51 window_size = 'width=585,height=515'; 52 } 53 window.open(url, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,' + window_size); 73 54 74 // Email share button, opens email modal. 75 $( document ).on( 'click', 'a[href*="#shared-counts-email"]', function( event ) { 76 77 event.preventDefault(); 78 79 modalOpen = true; 80 81 // Show modal and focus on first field. 82 $( '#shared-counts-modal-wrap' ).fadeIn(); 83 $( '#shared-counts-modal-recipient' ).focus(); 84 85 // Set data needed to send. 86 shared_counts_id = $( this ).data( 'postid' ); 87 shared_counts_nonce = $( this ).data( 'nonce' ); 88 89 // Maybe load reCAPTCHA. 90 if ( shared_counts.recaptchaSitekey ) { 91 grecaptcha.render( 'shared-counts-modal-recaptcha', { 92 sitekey: shared_counts.recaptchaSitekey 93 } ); 55 target.dispatchEvent(new Event('shared-counts-click')); 94 56 } 95 57 }); 96 58 97 // Close email modal by overlay or close button click.98 $( document ).on( 'click', '#shared-counts-modal-close, #shared-counts-modal-wrap', function( event ) {99 100 // If the modal wrap was clicked, verify it was the actual element, and101 // not something inside it.102 if ( 'shared-counts-modal-wrap' === $( this ).attr( 'id' ) && ! $( event.target ).is( '#shared-counts-modal-wrap' ) ) {103 return;104 }105 106 event.preventDefault();107 108 modalClose();109 });110 111 // Close email modal if Esc key is pressed while it is open.112 $( document ).keyup( function( event ) {113 if ( modalOpen && event.keyCode === 27 ) {114 modalClose();115 }116 });117 118 // Submit email share via email modal.119 $( document ).on( 'click', '#shared-counts-modal-submit', function( event ) {120 121 event.preventDefault();122 123 var empty = false,124 $this = $( this ),125 $recipient = $( '#shared-counts-modal-recipient' ),126 $name = $( '#shared-counts-modal-name' ),127 $email = $( '#shared-counts-modal-email' ),128 $validation = $( '#shared-counts-modal-validation' ),129 $recaptcha = $( '#g-recaptcha-response' ),130 data = {131 action: 'shared_counts_email',132 postid: shared_counts_id,133 recipient: $recipient.val(),134 name: $name.val(),135 email: $email.val(),136 validation: $validation.val(),137 recaptcha: $recaptcha.val(),138 nonce: shared_counts_nonce139 };140 141 // Check if any of the required fields are empty.142 $( $recipient, $name, $email ).each(function() {143 if ( ! $( this ).val() || $( this ).val() === '' ) {144 empty = true;145 }146 });147 148 // If an empty field was found, alert user and stop.149 if ( empty ) {150 alert( shared_counts.email_fields_required );151 return;152 }153 154 // Disable submit to prevent duplicates.155 $( this ).prop( 'disabled', true );156 157 // AJAX post.158 $.post( shared_counts.ajaxurl, data, function( res ) {159 160 if ( res.success ){161 console.log( shared_counts.email_sent );162 163 modalClose();164 }165 166 // Enable submit button.167 $this.prop( 'disabled', false );168 169 }).fail( function( xhr ) {170 console.log( xhr.responseText );171 });172 });173 59 }); -
shared-counts/tags/1.5.0/assets/js/shared-counts.min.js
r2087195 r3023121 1 "use strict";jQuery(document).ready(function(d){var l,u,e=!1;function h(){e=!1,d("#shared-counts-modal-recipient, #shared-counts-modal-name, #shared-counts-modal-email").val(""),d("#shared-counts-modal-wrap").fadeOut(),d("#shared-counts-modal-sent").hide()}d(document).on("click",".shared-counts-button",function(){if(shared_counts.social_tracking){var a=d(this),e=a.data("social-network"),t=a.data("social-action"),o=a.data("social-target");e&&t&&o&&("function"==typeof ga?ga("send","social",e,t,o):"function"==typeof __gaTracker&&__gaTracker("send","social",e,t,o))}}),d(document).on("click",'.shared-counts-button[target="_blank"]:not(.no-js)',function(a){a.preventDefault();var e="",t=this.href;switch(t.split("/")[2]){case"www.facebook.com":e="width=585,height=368";break;case"twitter.com":e="width=585,height=261";break;case"pinterest.com":e="width=750,height=550";break;default:e="width=585,height=515"}window.open(t,"","menubar=no,toolbar=no,resizable=yes,scrollbars=yes,"+e),d(this).trigger("shared-counts-click")}),d(document).on("click",'a[href*="#shared-counts-email"]',function(a){a.preventDefault(),e=!0,d("#shared-counts-modal-wrap").fadeIn(),d("#shared-counts-modal-recipient").focus(),l=d(this).data("postid"),u=d(this).data("nonce"),shared_counts.recaptchaSitekey&&grecaptcha.render("shared-counts-modal-recaptcha",{sitekey:shared_counts.recaptchaSitekey})}),d(document).on("click","#shared-counts-modal-close, #shared-counts-modal-wrap",function(a){("shared-counts-modal-wrap"!==d(this).attr("id")||d(a.target).is("#shared-counts-modal-wrap"))&&(a.preventDefault(),h())}),d(document).keyup(function(a){e&&27===a.keyCode&&h()}),d(document).on("click","#shared-counts-modal-submit",function(a){a.preventDefault();var e=!1,t=d(this),o=d("#shared-counts-modal-recipient"),s=d("#shared-counts-modal-name"),n=d("#shared-counts-modal-email"),c=d("#shared-counts-modal-validation"),i=d("#g-recaptcha-response"),r={action:"shared_counts_email",postid:l,recipient:o.val(),name:s.val(),email:n.val(),validation:c.val(),recaptcha:i.val(),nonce:u};d(o,s,n).each(function(){d(this).val()&&""!==d(this).val()||(e=!0)}),e?alert(shared_counts.email_fields_required):(d(this).prop("disabled",!0),d.post(shared_counts.ajaxurl,r,function(a){a.success&&(console.log(shared_counts.email_sent),h()),t.prop("disabled",!1)}).fail(function(a){console.log(a.responseText)}))})});1 document.addEventListener("DOMContentLoaded",function(){document.addEventListener("click",function(t){var e=t.target;if(e.classList.contains("shared-counts-button")&&shared_counts.social_tracking){var a=e.getAttribute("data-social-network"),i=e.getAttribute("data-social-action"),n=e.getAttribute("data-social-target");a&&i&&n&&("function"==typeof ga?ga("send","social",a,i,n):"function"==typeof __gaTracker&&__gaTracker("send","social",a,i,n))}}),document.addEventListener("click",function(t){var e=t.target;if(e.classList.contains("shared-counts-button")&&"_blank"===e.getAttribute("target")&&!e.classList.contains("no-js")){t.preventDefault();var a="",i=e.href,n=i.split("/")[2];switch(n){case"www.facebook.com":a="width=585,height=368";break;case"twitter.com":a="width=585,height=261";break;case"pinterest.com":a="width=750,height=550";break;default:a="width=585,height=515"}window.open(i,"","menubar=no,toolbar=no,resizable=yes,scrollbars=yes,"+a),e.dispatchEvent(new Event("shared-counts-click"))}})}); -
shared-counts/tags/1.5.0/includes/class-shared-counts-admin.php
r2836328 r3023121 366 366 ); 367 367 ?> 368 </p>369 </td>370 </tr>371 372 <!-- Enable Email reCAPTCHA (if email button is configured) -->373 <tr valign="top" id="shared-counts-setting-row-recaptcha">374 <th scope="row"><label for="shared-counts-setting-recaptcha"><?php esc_html_e( 'Enable Email reCAPTCHA', 'shared-counts' ); ?></label></th>375 <td>376 <input type="checkbox" name="shared_counts_options[recaptcha]" value="1" id="shared-counts-setting-recaptcha" <?php checked( $this->settings_value( 'recaptcha' ), 1 ); ?>>377 <p class="description">378 <?php esc_html_e( 'Highly recommended, Google\'s v2 reCAPTCHA will protect the email sharing feature from abuse.', 'shared-counts' ); ?>379 </p>380 </td>381 </tr>382 383 <!-- Google reCAPTCHA Site key (if recaptcha is enabled) -->384 <tr valign="top" id="shared-counts-setting-row-recaptcha_site_key">385 <th scope="row"><label for="shared-counts-setting-recaptcha_site_key"><?php esc_html_e( 'reCAPTCHA Site Key', 'shared-counts' ); ?></label></th>386 <td>387 <input type="text" name="shared_counts_options[recaptcha_site_key]" value="<?php echo esc_attr( $this->settings_value( 'recaptcha_site_key' ) ); ?>" id="shared-counts-setting-recaptcha_site_key" class="regular-text" />388 <p class="description">389 <?php esc_html_e( 'After signing up for Google\'s v2 reCAPTCHA (free), provide your site key here.', 'shared-counts' ); ?><br><a href="https://www.google.com/recaptcha/" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Learn more.', 'shared-counts' ); ?></a>390 </p>391 </td>392 </tr>393 394 <!-- Google reCAPTCHA Secret key (if recaptcha is enabled) -->395 <tr valign="top" id="shared-counts-setting-row-recaptcha_secret_key">396 <th scope="row"><label for="shared-counts-setting-recaptcha_secret_key"><?php esc_html_e( 'reCAPTCHA Secret Key', 'shared-counts' ); ?></label></th>397 <td>398 <input type="text" name="shared_counts_options[recaptcha_secret_key]" value="<?php echo esc_attr( $this->settings_value( 'recaptcha_secret_key' ) ); ?>" id="shared-counts-setting-recaptcha_secret_key" class="regular-text" />399 <p class="description">400 <?php esc_html_e( 'After signing up for Google\'s v2 reCAPTCHA (free), provide your secret key here.', 'shared-counts' ); ?>401 368 </p> 402 369 </td> … … 605 572 'included_services' => [ 'facebook', 'twitter', 'pinterest' ], 606 573 'query_services' => [], 607 'recaptcha' => '',608 'recpatcha_site_key' => '',609 'recaptcha_secret_key' => '',610 574 ]; 611 575 } … … 692 656 $input['theme_location'] = sanitize_text_field( $input['theme_location'] ); 693 657 $input['included_services'] = ! empty( $input['included_services'] ) ? array_map( 'sanitize_text_field', $input['included_services'] ) : []; 694 $input['recaptcha'] = ! empty( $input['recaptcha'] ) ? '1' : '';695 $input['recaptcha_site_key'] = sanitize_text_field( $input['recaptcha_site_key'] );696 $input['recaptcha_secret_key'] = sanitize_text_field( $input['recaptcha_secret_key'] );697 698 658 return $input; 699 659 } -
shared-counts/tags/1.5.0/includes/class-shared-counts-core.php
r2836327 r3023121 42 42 */ 43 43 public function __construct() { 44 45 add_action( 'wp_ajax_shared_counts_email', [ $this, 'email_ajax' ] );46 add_action( 'wp_ajax_nopriv_shared_counts_email', [ $this, 'email_ajax' ] );47 44 add_action( 'shutdown', [ $this, 'shutdown_update_share_counts' ] ); 48 }49 50 /**51 * Process and send email share AJAX requests.52 *53 * @since 1.0.054 */55 public function email_ajax() {56 57 $data = $_POST; // phpcs:ignore58 59 // Check spam honeypot.60 if ( ! empty( $data['validation'] ) ) {61 wp_send_json_error( __( 'Honeypot triggered.', 'shared-counts' ) );62 }63 64 // Check required fields.65 if ( empty( $data['recipient'] ) || empty( $data['name'] ) || empty( $data['email'] ) ) {66 wp_send_json_error( __( 'Required field missing.', 'shared-counts' ) );67 }68 69 // Check email addresses.70 if ( ! is_email( $data['recipient'] ) || ! is_email( $data['email'] ) ) {71 wp_send_json_error( __( 'Invalid email.', 'shared-counts' ) );72 }73 74 $options = shared_counts()->admin->options();75 76 // Confirm email sharing is enabled.77 if ( ! in_array( 'email', $options['included_services'], true ) ) {78 wp_send_json_error( __( 'Email not enabled.', 'shared-counts' ) );79 }80 81 // Check if reCAPTCHA is enabled.82 $recaptcha = ! empty( $options['recaptcha'] ) && ! empty( $options['recaptcha_site_key'] ) && ! empty( $options['recaptcha_secret_key'] );83 84 // reCAPTCHA is enabled, so verify it.85 if ( $recaptcha ) {86 87 if ( empty( $data['recaptcha'] ) ) {88 wp_send_json_error( __( 'reCAPTCHA is required.', 'shared-counts' ) );89 }90 91 $api_results = wp_remote_get( 'https://www.google.com/recaptcha/api/siteverify?secret=' . $options['recaptcha_secret_key'] . '&response=' . $data['recaptcha'] );92 $results = json_decode( wp_remote_retrieve_body( $api_results ) );93 if ( empty( $results->success ) ) {94 wp_send_json_error( __( 'Incorrect reCAPTCHA, please try again.', 'shared-counts' ) );95 }96 }97 98 $post_id = absint( $data['postid'] );99 $recipient = sanitize_text_field( $data['recipient'] );100 $from_email = sanitize_text_field( $data['email'] );101 $from_name = sanitize_text_field( $data['name'] );102 $site_name = html_entity_decode( wp_strip_all_tags( get_bloginfo( 'name' ) ), ENT_QUOTES );103 $site_root = strtolower( $_SERVER['SERVER_NAME'] ); //phpcs:ignore104 if ( substr( $site_root, 0, 4 ) === 'www.' ) {105 $site_root = substr( $site_root, 4 );106 }107 108 $headers = [109 sprintf( 'From: %s <noreply@%s>', $site_name, $site_root ),110 sprintf( 'Reply-To: %s <%s>', $from_name, $from_email ),111 ];112 /* translators: %1$s - Name of the person who shared the article. */113 $subject = sprintf( esc_html__( 'Your friend %1$s has shared an article with you.', 'shared-counts' ), $from_name );114 $body = html_entity_decode( get_the_title( $post_id ), ENT_QUOTES ) . "\r\n";115 $body .= get_permalink( $post_id ) . "\r\n";116 117 wp_mail(118 $recipient,119 apply_filters( 'shared_counts_email_subject', $subject, $post_id, $recipient, $from_name, $from_email ),120 apply_filters( 'shared_counts_email_body', $body, $post_id, $recipient, $from_name, $from_email ),121 apply_filters( 'shared_counts_email_headers', $headers, $post_id, $recipient, $from_name, $from_email )122 );123 124 // Don't track email shares if plugin is configured to omit counts.125 if ( ! empty( $options['count_source'] ) && 'none' !== $options['count_source'] ) {126 $count = absint( get_post_meta( $post_id, 'shared_counts_email', true ) );127 $update = update_post_meta( $post_id, 'shared_counts_email', ++$count );128 }129 130 wp_send_json_success();131 45 } 132 46 -
shared-counts/tags/1.5.0/includes/class-shared-counts-front.php
r2727404 r3023121 42 42 add_action( 'wp_enqueue_scripts', [ $this, 'header_assets' ], 9 ); 43 43 add_action( 'wp_footer', [ $this, 'load_assets' ], 1 ); 44 add_action( 'wp_footer', [ $this, 'email_modal' ], 50 );45 44 add_shortcode( 'shared_counts', [ $this, 'shortcode' ] ); 46 45 add_action( 'admin_bar_menu', [ $this, 'admin_bar' ], 999 ); … … 150 149 'shared-counts', 151 150 SHARED_COUNTS_URL . 'assets/js/shared-counts' . $suffix . '.js', 152 [ 'jquery'],151 [], 153 152 SHARED_COUNTS_VERSION, 154 153 true … … 180 179 } 181 180 182 $options = shared_counts()->admin->options();183 $recaptcha = ! empty( $options['recaptcha'] ) && ! empty( $options['recaptcha_site_key'] ) && ! empty( $options['recaptcha_secret_key'] );184 185 181 // Load CSS. 186 182 if ( apply_filters( 'shared_counts_load_css', true ) ) { … … 193 189 wp_enqueue_script( 'shared-counts' ); 194 190 195 if ( $recaptcha ) {196 wp_enqueue_script(197 'recaptcha',198 'https://www.google.com/recaptcha/api.js',199 [],200 '2.0',201 true202 );203 }204 191 } 205 192 206 193 // Localize JS strings. 207 194 $args = [ 208 'email_fields_required' => esc_html__( 'Please complete out all 3 fields to email this article.', 'shared-counts' ),209 'email_sent' => esc_html__( 'Article successfully shared.', 'shared-counts' ),210 'ajaxurl' => esc_url_raw( admin_url( 'admin-ajax.php' ) ),211 195 'social_tracking' => apply_filters( 'shared_counts_social_tracking', true ), 212 196 ]; 213 197 214 // Localize recaptcha site key if enabled.215 if ( $recaptcha ) {216 $args['recaptchaSitekey'] = sanitize_text_field( $options['recaptcha_site_key'] );217 }218 219 198 wp_localize_script( 'shared-counts', 'shared_counts', $args ); 220 }221 222 /**223 * Email modal pop-up.224 *225 * This popup is output (and hidden) in the site footer if the Email226 * service is configured in the plugin settings.227 *228 * @since 1.0.0229 */230 public function email_modal() {231 232 // Only continue if a share link is on the page.233 if ( ! $this->share_link ) {234 return;235 }236 237 // Filter to disable email modal238 if( apply_filters( 'shared_counts_disable_email_modal', false ) ) {239 return;240 }241 242 // Check to see the email button is configured or being overriden. The243 // filter can be used to enable the modal in use cases where the share244 // button is manually being called.245 $options = shared_counts()->admin->options();246 247 if ( ! in_array( 'email', $options['included_services'], true ) && ! apply_filters( 'shared_counts_email_modal', false ) ) {248 return;249 }250 251 // Check for reCAPTCHA settings.252 $recaptcha = ! empty( $options['recaptcha'] ) && ! empty( $options['recaptcha_site_key'] ) && ! empty( $options['recaptcha_secret_key'] );253 254 // Labels, filterable of course.255 $labels = apply_filters(256 'shared_counts_email_labels',257 [258 'title' => esc_html__( 'Share this Article', 'shared-counts' ),259 'subtitle' => esc_html__( 'Like this article? Email it to a friend!', 'shared-counts' ),260 'title_icon' => '<svg xmlns="http://www.w3.org/2000/svg" width="48" height="45" viewBox="0 0 48 45"><path fill-rule="evenodd" d="M31.7849302,27.028093 L27.9750698,27.028093 L27.9750698,19.6751628 C27.9750698,18.7821395 27.9940465,17.9650233 28.0331163,17.2249302 C27.7986977,17.5095814 27.5062326,17.8065116 27.1579535,18.1179535 L25.5806512,19.4195349 L23.6327442,17.024 L28.4026047,13.1393488 L31.7849302,13.1393488 L31.7849302,27.028093 Z M22.6392558,21.4422326 L19.104,21.4422326 L19.104,24.8714419 L16.5488372,24.8714419 L16.5488372,21.4422326 L13.015814,21.4422326 L13.015814,18.896 L16.5488372,18.896 L16.5488372,15.4098605 L19.104,15.4098605 L19.104,18.896 L22.6392558,18.896 L22.6392558,21.4422326 Z M43.5996279,2 L4.40037209,2 C1.9735814,2 0,3.97469767 0,6.40037209 L0,32.8003721 C0,35.2260465 1.9735814,37.1996279 4.40037209,37.1996279 L22.3791628,37.1996279 L33.2796279,45.92 C33.5843721,46.1633488 33.9505116,46.2883721 34.3211163,46.2883721 C34.5689302,46.2883721 34.8178605,46.2325581 35.0511628,46.119814 C35.636093,45.8385116 36,45.2591628 36,44.6106047 L36,37.1996279 L43.5996279,37.1996279 C46.0253023,37.1996279 48,35.2260465 48,32.8003721 L48,6.40037209 C48,3.97469767 46.0253023,2 43.5996279,2 Z" transform="translate(0 -2)"/></svg>',261 'recipient' => esc_html__( 'Friend\'s Email Address', 'shared-counts' ),262 'name' => esc_html__( 'Your Name', 'shared-counts' ),263 'email' => esc_html__( 'Your Email Address', 'shared-counts' ),264 'validation' => esc_html__( 'Comments', 'shared-counts' ),265 'close' => '<span class="close-icon"><svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">266 <path fill="#FFF" fill-rule="evenodd" d="M338,11.0149385 L340.805644,8.20929447 C341.000906,8.01403233 341.317489,8.01403233 341.512751,8.20929447 L341.790706,8.48724919 C341.985968,8.68251134 341.985968,8.99909383 341.790706,9.19435597 L338.985062,12 L341.790706,14.805644 C341.985968,15.0009062 341.985968,15.3174887 341.790706,15.5127508 L341.512751,15.7907055 C341.317489,15.9859677 341.000906,15.9859677 340.805644,15.7907055 L338,12.9850615 L335.194356,15.7907055 C334.999094,15.9859677 334.682511,15.9859677 334.487249,15.7907055 L334.209294,15.5127508 C334.014032,15.3174887 334.014032,15.0009062 334.209294,14.805644 L337.014938,12 L334.209294,9.19435597 C334.014032,8.99909383 334.014032,8.68251134 334.209294,8.48724919 L334.487249,8.20929447 C334.682511,8.01403233 334.999094,8.01403233 335.194356,8.20929447 L338,11.0149385 Z" transform="translate(-334 -8)"/>267 </svg></span>',268 'submit' => esc_html__( 'Send Email', 'shared-counts' ),269 ]270 );271 ?>272 <div id="shared-counts-modal-wrap" style="display:none;">273 <div class="shared-counts-modal">274 <a href="#" id="shared-counts-modal-close" aria-label="Close the share by email popup"><?php echo $labels['close']; // phpcs:ignore ?></a>275 <div class="shared-counts-modal-header">276 <?php277 if ( ! empty( $labels['title_icon'] ) ) {278 echo '<span class="shared-counts-modal-icon">' . $labels['title_icon'] . '</span>'; // phpcs:ignore279 }280 if ( ! empty( $labels['title'] ) ) {281 echo '<span class="shared-counts-modal-title">' . esc_html( $labels['title'] ) . '</span>';282 }283 if ( ! empty( $labels['subtitle'] ) ) {284 echo '<span class="shared-counts-modal-subtitle">' . esc_html( $labels['subtitle'] ) . '</span>';285 }286 ?>287 </div>288 <div class="shared-counts-modal-content">289 <p>290 <label for="shared-counts-modal-recipient"><?php echo esc_html( $labels['recipient'] ); ?></label>291 <input type="email" id="shared-counts-modal-recipient" placeholder="<?php echo esc_html( $labels['recipient'] ); ?>">292 </p>293 <p>294 <label for="shared-counts-modal-name"><?php echo esc_html( $labels['name'] ); ?></label>295 <input type="text" id="shared-counts-modal-name" placeholder="<?php echo esc_html( $labels['name'] ); ?>">296 </p>297 <p>298 <label for="shared-counts-modal-email"><?php echo esc_html( $labels['email'] ); ?></label>299 <input type="email" id="shared-counts-modal-email" placeholder="<?php echo esc_html( $labels['email'] ); ?>">300 </p>301 <?php302 if ( $recaptcha ) {303 echo '<div id="shared-counts-modal-recaptcha"></div>';304 }305 ?>306 <p class="shared-counts-modal-validation">307 <label for="shared-counts-modal-validation"><?php echo esc_html( $labels['validation'] ); ?></label>308 <input type="text" id="shared-counts-modal-validation" autocomplete="off">309 </p>310 <p class="shared-counts-modal-submit">311 <button id="shared-counts-modal-submit"><?php echo $labels['submit']; // phpcs:ignore ?></button>312 </p>313 <div id="shared-counts-modal-sent"><?php esc_html_e( 'Email sent!', 'shared-counts' ); ?></div>314 </div>315 </div>316 </div>317 <?php318 199 } 319 200 … … 537 418 $link['link'] = 'https://twitter.com/share?url=' . $link['url'] . '&text=' . htmlspecialchars( rawurlencode( html_entity_decode( $link['title'], ENT_COMPAT, 'UTF-8' ) ), ENT_COMPAT, 'UTF-8' ); 538 419 $link['label'] = esc_html__( 'Tweet', 'shared-counts' ); 539 $link['icon'] = '<svg v ersion="1.1" xmlns="http://www.w3.org/2000/svg" width="29.71875" height="32" viewBox="0 0 951 1024"><path d="M925.714 233.143q-38.286 56-92.571 95.429 0.571 8 0.571 24 0 74.286-21.714 148.286t-66 142-105.429 120.286-147.429 83.429-184.571 31.143q-154.857 0-283.429-82.857 20 2.286 44.571 2.286 128.571 0 229.143-78.857-60-1.143-107.429-36.857t-65.143-91.143q18.857 2.857 34.857 2.857 24.571 0 48.571-6.286-64-13.143-106-63.714t-42-117.429v-2.286q38.857 21.714 83.429 23.429-37.714-25.143-60-65.714t-22.286-88q0-50.286 25.143-93.143 69.143 85.143 168.286 136.286t212.286 56.857q-4.571-21.714-4.571-42.286 0-76.571 54-130.571t130.571-54q80 0 134.857 58.286 62.286-12 117.143-44.571-21.143 65.714-81.143 101.714 53.143-5.714 106.286-28.571z"></path></svg>';420 $link['icon'] = '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M13.8944 10.4695L21.3345 2H19.5716L13.1085 9.35244L7.95022 2H1.99936L9.80147 13.1192L1.99936 22H3.76218L10.5832 14.2338L16.0318 22H21.9827L13.8944 10.4695ZM11.4792 13.2168L10.6875 12.1089L4.39789 3.30146H7.10594L12.1833 10.412L12.9717 11.5199L19.5708 20.7619H16.8628L11.4792 13.2168Z" /></svg>'; 540 421 $link['target'] = '_blank'; 541 422 $link['rel'] = 'nofollow noopener noreferrer'; … … 588 469 break; 589 470 case 'email': 590 $link['link'] = '#shared-counts-email'; 471 $subject = esc_html__( 'Your friend has shared an article with you.', 'shared-counts' ); 472 $subject = apply_filters( 'shared_counts_amp_email_subject', $subject, $id ); 473 $body = html_entity_decode( get_the_title( $id ), ENT_QUOTES ) . "\r\n"; 474 $body .= get_permalink( $id ) . "\r\n"; 475 $body = apply_filters( 'shared_counts_amp_email_body', $body, $id ); 476 $link['link'] = 'mailto:?subject=' . rawurlencode( $subject ) . '&body=' . rawurlencode( $body ); 591 477 $link['label'] = esc_html__( 'Email', 'shared-counts' ); 592 478 $link['icon'] = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path d="M1024 405.714v453.714q0 37.714-26.857 64.571t-64.571 26.857h-841.143q-37.714 0-64.571-26.857t-26.857-64.571v-453.714q25.143 28 57.714 49.714 206.857 140.571 284 197.143 32.571 24 52.857 37.429t54 27.429 62.857 14h1.143q29.143 0 62.857-14t54-27.429 52.857-37.429q97.143-70.286 284.571-197.143 32.571-22.286 57.143-49.714zM1024 237.714q0 45.143-28 86.286t-69.714 70.286q-214.857 149.143-267.429 185.714-5.714 4-24.286 17.429t-30.857 21.714-29.714 18.571-32.857 15.429-28.571 5.143h-1.143q-13.143 0-28.571-5.143t-32.857-15.429-29.714-18.571-30.857-21.714-24.286-17.429q-52-36.571-149.714-104.286t-117.143-81.429q-35.429-24-66.857-66t-31.429-78q0-44.571 23.714-74.286t67.714-29.714h841.143q37.143 0 64.286 26.857t27.143 64.571z"></path></svg>'; … … 683 569 $elements['wrap_open'] = sprintf( 684 570 '<a href="%s"%s%s%s class="%s"%s>', 685 esc_ attr( $link['link'] ),571 esc_url( $link['link'] ), 686 572 $attr_title, 687 573 $target, -
shared-counts/tags/1.5.0/readme.txt
r2980287 r3023121 1 1 === Shared Counts - Social Media Share Buttons === 2 Contributors: jaredatch, billerickson , cdils2 Contributors: jaredatch, billerickson 3 3 Tags: sharing, share buttons, social buttons, share counts, social, facebook, linkedin, pinterest, twitter 4 4 Requires at least: 4.6 5 Tested up to: 6. 16 Stable tag: 1. 4.15 Tested up to: 6.4 6 Stable tag: 1.5.0 7 7 Requires PHP: 5.6 8 8 License: GPLv2 or later … … 20 20 - Yummly Button 21 21 - Twitter Tweet Button (using the third-party Twitcount.com API) 22 - Email Sharing (with reCAPTCHA support to prevent abuse)22 - Email Sharing 23 23 - Share Count Total 24 24 - Print Button … … 75 75 If you would like to include Twitter share counts, you can sign up for a free account at [twitcount.com](https://twitcount.com). 76 76 77 If you use the Email share button, we recommend you enable Google's reCAPTCHA to prevent spam. [Sign up here](https://www.google.com/recaptcha/intro/android.html) (free) to get your Site Key and Secret Key.78 79 77 == Screenshots == 80 78 … … 82 80 83 81 == Changelog == 82 83 **1.5.0** 84 - Changed: Replaced server side email with a mailto link to remove the possibility of spam, see #131 85 - Changed: Updated the Twitter logo to X, see #129 86 - Changed: Removed jQuery dependency, see #113 87 - Changed: Use `esc_url()` for sharing links, see #130 84 88 85 89 **1.4.0** -
shared-counts/tags/1.5.0/shared-counts.php
r2836327 r3023121 5 5 * Description: Social sharing buttons that look great and keep your site loading fast. 6 6 * Author: Bill Erickson & Jared Atchison 7 * Version: 1. 4.17 * Version: 1.5.0 8 8 * 9 9 * Shared Counts is free software: you can redistribute it and/or modify … … 36 36 */ 37 37 // Version. 38 define( 'SHARED_COUNTS_VERSION', '1. 4.1' );38 define( 'SHARED_COUNTS_VERSION', '1.5.0' ); 39 39 40 40 // Directory path. -
shared-counts/trunk/CHANGELOG.md
r2836327 r3023121 1 1 # Change Log 2 2 All notable changes to this project will be documented in this file, formatted via [this recommendation](http://keepachangelog.com/). 3 4 ## [1.5.0] = 2024-01-17 5 ### Changed 6 - Replaced server side email with a mailto link to remove the possibility of spam, see #131 7 - Updated the Twitter logo to X, see #129 8 - Removed jQuery dependency, see #113 9 - Use `esc_url()` for sharing links, see #130 3 10 4 11 ## [1.4.1] = 2022-12-19 -
shared-counts/trunk/assets/js/shared-counts.js
r2087195 r3023121 1 /* global shared_counts, grecaptcha */ 2 3 'use strict'; 4 5 jQuery( document ).ready(function($){ 6 7 var modalOpen = false, 8 shared_counts_id, 9 shared_counts_nonce; 10 11 /** 12 * Close email sharing modal. 13 * 14 * @since 1.0.0 15 */ 16 function modalClose() { 17 18 modalOpen = false; 19 20 $( '#shared-counts-modal-recipient, #shared-counts-modal-name, #shared-counts-modal-email' ).val( '' ); 21 $( '#shared-counts-modal-wrap' ).fadeOut(); 22 $( '#shared-counts-modal-sent' ).hide(); 23 } 1 document.addEventListener('DOMContentLoaded', function() { 24 2 25 3 // Google Analytics Social tracking. 26 $( document ).on( 'click', '.shared-counts-button', function() { 4 document.addEventListener('click', function(event) { 5 var target = event.target; 27 6 28 if ( shared_counts.social_tracking) {7 if (target.classList.contains('shared-counts-button')) { 29 8 30 var $this = $( this ), 31 network = $this.data( 'social-network' ), 32 action = $this.data( 'social-action' ), 33 target = $this.data( 'social-target' ); 9 if (shared_counts.social_tracking) { 34 10 35 if ( network && action && target ) { 36 if ( 'function' === typeof ga ) { 37 // Default GA. 38 ga( 'send', 'social', network, action, target ); 39 } else if ( 'function' === typeof __gaTracker ) { 40 // MonsterInsights. 41 __gaTracker( 'send', 'social', network, action, target ); 11 var network = target.getAttribute('data-social-network'), 12 action = target.getAttribute('data-social-action'), 13 targetValue = target.getAttribute('data-social-target'); 14 15 if (network && action && targetValue) { 16 if (typeof ga === 'function') { 17 // Default GA. 18 ga('send', 'social', network, action, targetValue); 19 } else if (typeof __gaTracker === 'function') { 20 // MonsterInsights. 21 __gaTracker('send', 'social', network, action, targetValue); 22 } 42 23 } 43 24 } … … 46 27 47 28 // Share button click. 48 $( document ).on( 'click', '.shared-counts-button[target="_blank"]:not(.no-js)', function( event ) { 29 document.addEventListener('click', function(event) { 30 var target = event.target; 49 31 50 event.preventDefault();32 if (target.classList.contains('shared-counts-button') && target.getAttribute('target') === '_blank' && !target.classList.contains('no-js')) { 51 33 52 var window_size = '', 53 url = this.href, 54 domain = url.split( '/' )[2]; 34 event.preventDefault(); 55 35 56 switch ( domain ) { 57 case 'www.facebook.com': 58 window_size = 'width=585,height=368'; 59 break; 60 case 'twitter.com': 61 window_size = 'width=585,height=261'; 62 break; 63 case 'pinterest.com': 64 window_size = 'width=750,height=550'; 65 break; 66 default: 67 window_size = 'width=585,height=515'; 68 } 69 window.open( url, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,' + window_size ); 36 var window_size = '', 37 url = target.href, 38 domain = url.split('/')[2]; 70 39 71 $( this ).trigger( 'shared-counts-click' ); 72 }); 40 switch (domain) { 41 case 'www.facebook.com': 42 window_size = 'width=585,height=368'; 43 break; 44 case 'twitter.com': 45 window_size = 'width=585,height=261'; 46 break; 47 case 'pinterest.com': 48 window_size = 'width=750,height=550'; 49 break; 50 default: 51 window_size = 'width=585,height=515'; 52 } 53 window.open(url, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,' + window_size); 73 54 74 // Email share button, opens email modal. 75 $( document ).on( 'click', 'a[href*="#shared-counts-email"]', function( event ) { 76 77 event.preventDefault(); 78 79 modalOpen = true; 80 81 // Show modal and focus on first field. 82 $( '#shared-counts-modal-wrap' ).fadeIn(); 83 $( '#shared-counts-modal-recipient' ).focus(); 84 85 // Set data needed to send. 86 shared_counts_id = $( this ).data( 'postid' ); 87 shared_counts_nonce = $( this ).data( 'nonce' ); 88 89 // Maybe load reCAPTCHA. 90 if ( shared_counts.recaptchaSitekey ) { 91 grecaptcha.render( 'shared-counts-modal-recaptcha', { 92 sitekey: shared_counts.recaptchaSitekey 93 } ); 55 target.dispatchEvent(new Event('shared-counts-click')); 94 56 } 95 57 }); 96 58 97 // Close email modal by overlay or close button click.98 $( document ).on( 'click', '#shared-counts-modal-close, #shared-counts-modal-wrap', function( event ) {99 100 // If the modal wrap was clicked, verify it was the actual element, and101 // not something inside it.102 if ( 'shared-counts-modal-wrap' === $( this ).attr( 'id' ) && ! $( event.target ).is( '#shared-counts-modal-wrap' ) ) {103 return;104 }105 106 event.preventDefault();107 108 modalClose();109 });110 111 // Close email modal if Esc key is pressed while it is open.112 $( document ).keyup( function( event ) {113 if ( modalOpen && event.keyCode === 27 ) {114 modalClose();115 }116 });117 118 // Submit email share via email modal.119 $( document ).on( 'click', '#shared-counts-modal-submit', function( event ) {120 121 event.preventDefault();122 123 var empty = false,124 $this = $( this ),125 $recipient = $( '#shared-counts-modal-recipient' ),126 $name = $( '#shared-counts-modal-name' ),127 $email = $( '#shared-counts-modal-email' ),128 $validation = $( '#shared-counts-modal-validation' ),129 $recaptcha = $( '#g-recaptcha-response' ),130 data = {131 action: 'shared_counts_email',132 postid: shared_counts_id,133 recipient: $recipient.val(),134 name: $name.val(),135 email: $email.val(),136 validation: $validation.val(),137 recaptcha: $recaptcha.val(),138 nonce: shared_counts_nonce139 };140 141 // Check if any of the required fields are empty.142 $( $recipient, $name, $email ).each(function() {143 if ( ! $( this ).val() || $( this ).val() === '' ) {144 empty = true;145 }146 });147 148 // If an empty field was found, alert user and stop.149 if ( empty ) {150 alert( shared_counts.email_fields_required );151 return;152 }153 154 // Disable submit to prevent duplicates.155 $( this ).prop( 'disabled', true );156 157 // AJAX post.158 $.post( shared_counts.ajaxurl, data, function( res ) {159 160 if ( res.success ){161 console.log( shared_counts.email_sent );162 163 modalClose();164 }165 166 // Enable submit button.167 $this.prop( 'disabled', false );168 169 }).fail( function( xhr ) {170 console.log( xhr.responseText );171 });172 });173 59 }); -
shared-counts/trunk/assets/js/shared-counts.min.js
r2087195 r3023121 1 "use strict";jQuery(document).ready(function(d){var l,u,e=!1;function h(){e=!1,d("#shared-counts-modal-recipient, #shared-counts-modal-name, #shared-counts-modal-email").val(""),d("#shared-counts-modal-wrap").fadeOut(),d("#shared-counts-modal-sent").hide()}d(document).on("click",".shared-counts-button",function(){if(shared_counts.social_tracking){var a=d(this),e=a.data("social-network"),t=a.data("social-action"),o=a.data("social-target");e&&t&&o&&("function"==typeof ga?ga("send","social",e,t,o):"function"==typeof __gaTracker&&__gaTracker("send","social",e,t,o))}}),d(document).on("click",'.shared-counts-button[target="_blank"]:not(.no-js)',function(a){a.preventDefault();var e="",t=this.href;switch(t.split("/")[2]){case"www.facebook.com":e="width=585,height=368";break;case"twitter.com":e="width=585,height=261";break;case"pinterest.com":e="width=750,height=550";break;default:e="width=585,height=515"}window.open(t,"","menubar=no,toolbar=no,resizable=yes,scrollbars=yes,"+e),d(this).trigger("shared-counts-click")}),d(document).on("click",'a[href*="#shared-counts-email"]',function(a){a.preventDefault(),e=!0,d("#shared-counts-modal-wrap").fadeIn(),d("#shared-counts-modal-recipient").focus(),l=d(this).data("postid"),u=d(this).data("nonce"),shared_counts.recaptchaSitekey&&grecaptcha.render("shared-counts-modal-recaptcha",{sitekey:shared_counts.recaptchaSitekey})}),d(document).on("click","#shared-counts-modal-close, #shared-counts-modal-wrap",function(a){("shared-counts-modal-wrap"!==d(this).attr("id")||d(a.target).is("#shared-counts-modal-wrap"))&&(a.preventDefault(),h())}),d(document).keyup(function(a){e&&27===a.keyCode&&h()}),d(document).on("click","#shared-counts-modal-submit",function(a){a.preventDefault();var e=!1,t=d(this),o=d("#shared-counts-modal-recipient"),s=d("#shared-counts-modal-name"),n=d("#shared-counts-modal-email"),c=d("#shared-counts-modal-validation"),i=d("#g-recaptcha-response"),r={action:"shared_counts_email",postid:l,recipient:o.val(),name:s.val(),email:n.val(),validation:c.val(),recaptcha:i.val(),nonce:u};d(o,s,n).each(function(){d(this).val()&&""!==d(this).val()||(e=!0)}),e?alert(shared_counts.email_fields_required):(d(this).prop("disabled",!0),d.post(shared_counts.ajaxurl,r,function(a){a.success&&(console.log(shared_counts.email_sent),h()),t.prop("disabled",!1)}).fail(function(a){console.log(a.responseText)}))})});1 document.addEventListener("DOMContentLoaded",function(){document.addEventListener("click",function(t){var e=t.target;if(e.classList.contains("shared-counts-button")&&shared_counts.social_tracking){var a=e.getAttribute("data-social-network"),i=e.getAttribute("data-social-action"),n=e.getAttribute("data-social-target");a&&i&&n&&("function"==typeof ga?ga("send","social",a,i,n):"function"==typeof __gaTracker&&__gaTracker("send","social",a,i,n))}}),document.addEventListener("click",function(t){var e=t.target;if(e.classList.contains("shared-counts-button")&&"_blank"===e.getAttribute("target")&&!e.classList.contains("no-js")){t.preventDefault();var a="",i=e.href,n=i.split("/")[2];switch(n){case"www.facebook.com":a="width=585,height=368";break;case"twitter.com":a="width=585,height=261";break;case"pinterest.com":a="width=750,height=550";break;default:a="width=585,height=515"}window.open(i,"","menubar=no,toolbar=no,resizable=yes,scrollbars=yes,"+a),e.dispatchEvent(new Event("shared-counts-click"))}})}); -
shared-counts/trunk/includes/class-shared-counts-admin.php
r2836328 r3023121 366 366 ); 367 367 ?> 368 </p>369 </td>370 </tr>371 372 <!-- Enable Email reCAPTCHA (if email button is configured) -->373 <tr valign="top" id="shared-counts-setting-row-recaptcha">374 <th scope="row"><label for="shared-counts-setting-recaptcha"><?php esc_html_e( 'Enable Email reCAPTCHA', 'shared-counts' ); ?></label></th>375 <td>376 <input type="checkbox" name="shared_counts_options[recaptcha]" value="1" id="shared-counts-setting-recaptcha" <?php checked( $this->settings_value( 'recaptcha' ), 1 ); ?>>377 <p class="description">378 <?php esc_html_e( 'Highly recommended, Google\'s v2 reCAPTCHA will protect the email sharing feature from abuse.', 'shared-counts' ); ?>379 </p>380 </td>381 </tr>382 383 <!-- Google reCAPTCHA Site key (if recaptcha is enabled) -->384 <tr valign="top" id="shared-counts-setting-row-recaptcha_site_key">385 <th scope="row"><label for="shared-counts-setting-recaptcha_site_key"><?php esc_html_e( 'reCAPTCHA Site Key', 'shared-counts' ); ?></label></th>386 <td>387 <input type="text" name="shared_counts_options[recaptcha_site_key]" value="<?php echo esc_attr( $this->settings_value( 'recaptcha_site_key' ) ); ?>" id="shared-counts-setting-recaptcha_site_key" class="regular-text" />388 <p class="description">389 <?php esc_html_e( 'After signing up for Google\'s v2 reCAPTCHA (free), provide your site key here.', 'shared-counts' ); ?><br><a href="https://www.google.com/recaptcha/" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Learn more.', 'shared-counts' ); ?></a>390 </p>391 </td>392 </tr>393 394 <!-- Google reCAPTCHA Secret key (if recaptcha is enabled) -->395 <tr valign="top" id="shared-counts-setting-row-recaptcha_secret_key">396 <th scope="row"><label for="shared-counts-setting-recaptcha_secret_key"><?php esc_html_e( 'reCAPTCHA Secret Key', 'shared-counts' ); ?></label></th>397 <td>398 <input type="text" name="shared_counts_options[recaptcha_secret_key]" value="<?php echo esc_attr( $this->settings_value( 'recaptcha_secret_key' ) ); ?>" id="shared-counts-setting-recaptcha_secret_key" class="regular-text" />399 <p class="description">400 <?php esc_html_e( 'After signing up for Google\'s v2 reCAPTCHA (free), provide your secret key here.', 'shared-counts' ); ?>401 368 </p> 402 369 </td> … … 605 572 'included_services' => [ 'facebook', 'twitter', 'pinterest' ], 606 573 'query_services' => [], 607 'recaptcha' => '',608 'recpatcha_site_key' => '',609 'recaptcha_secret_key' => '',610 574 ]; 611 575 } … … 692 656 $input['theme_location'] = sanitize_text_field( $input['theme_location'] ); 693 657 $input['included_services'] = ! empty( $input['included_services'] ) ? array_map( 'sanitize_text_field', $input['included_services'] ) : []; 694 $input['recaptcha'] = ! empty( $input['recaptcha'] ) ? '1' : '';695 $input['recaptcha_site_key'] = sanitize_text_field( $input['recaptcha_site_key'] );696 $input['recaptcha_secret_key'] = sanitize_text_field( $input['recaptcha_secret_key'] );697 698 658 return $input; 699 659 } -
shared-counts/trunk/includes/class-shared-counts-core.php
r2836327 r3023121 42 42 */ 43 43 public function __construct() { 44 45 add_action( 'wp_ajax_shared_counts_email', [ $this, 'email_ajax' ] );46 add_action( 'wp_ajax_nopriv_shared_counts_email', [ $this, 'email_ajax' ] );47 44 add_action( 'shutdown', [ $this, 'shutdown_update_share_counts' ] ); 48 }49 50 /**51 * Process and send email share AJAX requests.52 *53 * @since 1.0.054 */55 public function email_ajax() {56 57 $data = $_POST; // phpcs:ignore58 59 // Check spam honeypot.60 if ( ! empty( $data['validation'] ) ) {61 wp_send_json_error( __( 'Honeypot triggered.', 'shared-counts' ) );62 }63 64 // Check required fields.65 if ( empty( $data['recipient'] ) || empty( $data['name'] ) || empty( $data['email'] ) ) {66 wp_send_json_error( __( 'Required field missing.', 'shared-counts' ) );67 }68 69 // Check email addresses.70 if ( ! is_email( $data['recipient'] ) || ! is_email( $data['email'] ) ) {71 wp_send_json_error( __( 'Invalid email.', 'shared-counts' ) );72 }73 74 $options = shared_counts()->admin->options();75 76 // Confirm email sharing is enabled.77 if ( ! in_array( 'email', $options['included_services'], true ) ) {78 wp_send_json_error( __( 'Email not enabled.', 'shared-counts' ) );79 }80 81 // Check if reCAPTCHA is enabled.82 $recaptcha = ! empty( $options['recaptcha'] ) && ! empty( $options['recaptcha_site_key'] ) && ! empty( $options['recaptcha_secret_key'] );83 84 // reCAPTCHA is enabled, so verify it.85 if ( $recaptcha ) {86 87 if ( empty( $data['recaptcha'] ) ) {88 wp_send_json_error( __( 'reCAPTCHA is required.', 'shared-counts' ) );89 }90 91 $api_results = wp_remote_get( 'https://www.google.com/recaptcha/api/siteverify?secret=' . $options['recaptcha_secret_key'] . '&response=' . $data['recaptcha'] );92 $results = json_decode( wp_remote_retrieve_body( $api_results ) );93 if ( empty( $results->success ) ) {94 wp_send_json_error( __( 'Incorrect reCAPTCHA, please try again.', 'shared-counts' ) );95 }96 }97 98 $post_id = absint( $data['postid'] );99 $recipient = sanitize_text_field( $data['recipient'] );100 $from_email = sanitize_text_field( $data['email'] );101 $from_name = sanitize_text_field( $data['name'] );102 $site_name = html_entity_decode( wp_strip_all_tags( get_bloginfo( 'name' ) ), ENT_QUOTES );103 $site_root = strtolower( $_SERVER['SERVER_NAME'] ); //phpcs:ignore104 if ( substr( $site_root, 0, 4 ) === 'www.' ) {105 $site_root = substr( $site_root, 4 );106 }107 108 $headers = [109 sprintf( 'From: %s <noreply@%s>', $site_name, $site_root ),110 sprintf( 'Reply-To: %s <%s>', $from_name, $from_email ),111 ];112 /* translators: %1$s - Name of the person who shared the article. */113 $subject = sprintf( esc_html__( 'Your friend %1$s has shared an article with you.', 'shared-counts' ), $from_name );114 $body = html_entity_decode( get_the_title( $post_id ), ENT_QUOTES ) . "\r\n";115 $body .= get_permalink( $post_id ) . "\r\n";116 117 wp_mail(118 $recipient,119 apply_filters( 'shared_counts_email_subject', $subject, $post_id, $recipient, $from_name, $from_email ),120 apply_filters( 'shared_counts_email_body', $body, $post_id, $recipient, $from_name, $from_email ),121 apply_filters( 'shared_counts_email_headers', $headers, $post_id, $recipient, $from_name, $from_email )122 );123 124 // Don't track email shares if plugin is configured to omit counts.125 if ( ! empty( $options['count_source'] ) && 'none' !== $options['count_source'] ) {126 $count = absint( get_post_meta( $post_id, 'shared_counts_email', true ) );127 $update = update_post_meta( $post_id, 'shared_counts_email', ++$count );128 }129 130 wp_send_json_success();131 45 } 132 46 -
shared-counts/trunk/includes/class-shared-counts-front.php
r2727404 r3023121 42 42 add_action( 'wp_enqueue_scripts', [ $this, 'header_assets' ], 9 ); 43 43 add_action( 'wp_footer', [ $this, 'load_assets' ], 1 ); 44 add_action( 'wp_footer', [ $this, 'email_modal' ], 50 );45 44 add_shortcode( 'shared_counts', [ $this, 'shortcode' ] ); 46 45 add_action( 'admin_bar_menu', [ $this, 'admin_bar' ], 999 ); … … 150 149 'shared-counts', 151 150 SHARED_COUNTS_URL . 'assets/js/shared-counts' . $suffix . '.js', 152 [ 'jquery'],151 [], 153 152 SHARED_COUNTS_VERSION, 154 153 true … … 180 179 } 181 180 182 $options = shared_counts()->admin->options();183 $recaptcha = ! empty( $options['recaptcha'] ) && ! empty( $options['recaptcha_site_key'] ) && ! empty( $options['recaptcha_secret_key'] );184 185 181 // Load CSS. 186 182 if ( apply_filters( 'shared_counts_load_css', true ) ) { … … 193 189 wp_enqueue_script( 'shared-counts' ); 194 190 195 if ( $recaptcha ) {196 wp_enqueue_script(197 'recaptcha',198 'https://www.google.com/recaptcha/api.js',199 [],200 '2.0',201 true202 );203 }204 191 } 205 192 206 193 // Localize JS strings. 207 194 $args = [ 208 'email_fields_required' => esc_html__( 'Please complete out all 3 fields to email this article.', 'shared-counts' ),209 'email_sent' => esc_html__( 'Article successfully shared.', 'shared-counts' ),210 'ajaxurl' => esc_url_raw( admin_url( 'admin-ajax.php' ) ),211 195 'social_tracking' => apply_filters( 'shared_counts_social_tracking', true ), 212 196 ]; 213 197 214 // Localize recaptcha site key if enabled.215 if ( $recaptcha ) {216 $args['recaptchaSitekey'] = sanitize_text_field( $options['recaptcha_site_key'] );217 }218 219 198 wp_localize_script( 'shared-counts', 'shared_counts', $args ); 220 }221 222 /**223 * Email modal pop-up.224 *225 * This popup is output (and hidden) in the site footer if the Email226 * service is configured in the plugin settings.227 *228 * @since 1.0.0229 */230 public function email_modal() {231 232 // Only continue if a share link is on the page.233 if ( ! $this->share_link ) {234 return;235 }236 237 // Filter to disable email modal238 if( apply_filters( 'shared_counts_disable_email_modal', false ) ) {239 return;240 }241 242 // Check to see the email button is configured or being overriden. The243 // filter can be used to enable the modal in use cases where the share244 // button is manually being called.245 $options = shared_counts()->admin->options();246 247 if ( ! in_array( 'email', $options['included_services'], true ) && ! apply_filters( 'shared_counts_email_modal', false ) ) {248 return;249 }250 251 // Check for reCAPTCHA settings.252 $recaptcha = ! empty( $options['recaptcha'] ) && ! empty( $options['recaptcha_site_key'] ) && ! empty( $options['recaptcha_secret_key'] );253 254 // Labels, filterable of course.255 $labels = apply_filters(256 'shared_counts_email_labels',257 [258 'title' => esc_html__( 'Share this Article', 'shared-counts' ),259 'subtitle' => esc_html__( 'Like this article? Email it to a friend!', 'shared-counts' ),260 'title_icon' => '<svg xmlns="http://www.w3.org/2000/svg" width="48" height="45" viewBox="0 0 48 45"><path fill-rule="evenodd" d="M31.7849302,27.028093 L27.9750698,27.028093 L27.9750698,19.6751628 C27.9750698,18.7821395 27.9940465,17.9650233 28.0331163,17.2249302 C27.7986977,17.5095814 27.5062326,17.8065116 27.1579535,18.1179535 L25.5806512,19.4195349 L23.6327442,17.024 L28.4026047,13.1393488 L31.7849302,13.1393488 L31.7849302,27.028093 Z M22.6392558,21.4422326 L19.104,21.4422326 L19.104,24.8714419 L16.5488372,24.8714419 L16.5488372,21.4422326 L13.015814,21.4422326 L13.015814,18.896 L16.5488372,18.896 L16.5488372,15.4098605 L19.104,15.4098605 L19.104,18.896 L22.6392558,18.896 L22.6392558,21.4422326 Z M43.5996279,2 L4.40037209,2 C1.9735814,2 0,3.97469767 0,6.40037209 L0,32.8003721 C0,35.2260465 1.9735814,37.1996279 4.40037209,37.1996279 L22.3791628,37.1996279 L33.2796279,45.92 C33.5843721,46.1633488 33.9505116,46.2883721 34.3211163,46.2883721 C34.5689302,46.2883721 34.8178605,46.2325581 35.0511628,46.119814 C35.636093,45.8385116 36,45.2591628 36,44.6106047 L36,37.1996279 L43.5996279,37.1996279 C46.0253023,37.1996279 48,35.2260465 48,32.8003721 L48,6.40037209 C48,3.97469767 46.0253023,2 43.5996279,2 Z" transform="translate(0 -2)"/></svg>',261 'recipient' => esc_html__( 'Friend\'s Email Address', 'shared-counts' ),262 'name' => esc_html__( 'Your Name', 'shared-counts' ),263 'email' => esc_html__( 'Your Email Address', 'shared-counts' ),264 'validation' => esc_html__( 'Comments', 'shared-counts' ),265 'close' => '<span class="close-icon"><svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">266 <path fill="#FFF" fill-rule="evenodd" d="M338,11.0149385 L340.805644,8.20929447 C341.000906,8.01403233 341.317489,8.01403233 341.512751,8.20929447 L341.790706,8.48724919 C341.985968,8.68251134 341.985968,8.99909383 341.790706,9.19435597 L338.985062,12 L341.790706,14.805644 C341.985968,15.0009062 341.985968,15.3174887 341.790706,15.5127508 L341.512751,15.7907055 C341.317489,15.9859677 341.000906,15.9859677 340.805644,15.7907055 L338,12.9850615 L335.194356,15.7907055 C334.999094,15.9859677 334.682511,15.9859677 334.487249,15.7907055 L334.209294,15.5127508 C334.014032,15.3174887 334.014032,15.0009062 334.209294,14.805644 L337.014938,12 L334.209294,9.19435597 C334.014032,8.99909383 334.014032,8.68251134 334.209294,8.48724919 L334.487249,8.20929447 C334.682511,8.01403233 334.999094,8.01403233 335.194356,8.20929447 L338,11.0149385 Z" transform="translate(-334 -8)"/>267 </svg></span>',268 'submit' => esc_html__( 'Send Email', 'shared-counts' ),269 ]270 );271 ?>272 <div id="shared-counts-modal-wrap" style="display:none;">273 <div class="shared-counts-modal">274 <a href="#" id="shared-counts-modal-close" aria-label="Close the share by email popup"><?php echo $labels['close']; // phpcs:ignore ?></a>275 <div class="shared-counts-modal-header">276 <?php277 if ( ! empty( $labels['title_icon'] ) ) {278 echo '<span class="shared-counts-modal-icon">' . $labels['title_icon'] . '</span>'; // phpcs:ignore279 }280 if ( ! empty( $labels['title'] ) ) {281 echo '<span class="shared-counts-modal-title">' . esc_html( $labels['title'] ) . '</span>';282 }283 if ( ! empty( $labels['subtitle'] ) ) {284 echo '<span class="shared-counts-modal-subtitle">' . esc_html( $labels['subtitle'] ) . '</span>';285 }286 ?>287 </div>288 <div class="shared-counts-modal-content">289 <p>290 <label for="shared-counts-modal-recipient"><?php echo esc_html( $labels['recipient'] ); ?></label>291 <input type="email" id="shared-counts-modal-recipient" placeholder="<?php echo esc_html( $labels['recipient'] ); ?>">292 </p>293 <p>294 <label for="shared-counts-modal-name"><?php echo esc_html( $labels['name'] ); ?></label>295 <input type="text" id="shared-counts-modal-name" placeholder="<?php echo esc_html( $labels['name'] ); ?>">296 </p>297 <p>298 <label for="shared-counts-modal-email"><?php echo esc_html( $labels['email'] ); ?></label>299 <input type="email" id="shared-counts-modal-email" placeholder="<?php echo esc_html( $labels['email'] ); ?>">300 </p>301 <?php302 if ( $recaptcha ) {303 echo '<div id="shared-counts-modal-recaptcha"></div>';304 }305 ?>306 <p class="shared-counts-modal-validation">307 <label for="shared-counts-modal-validation"><?php echo esc_html( $labels['validation'] ); ?></label>308 <input type="text" id="shared-counts-modal-validation" autocomplete="off">309 </p>310 <p class="shared-counts-modal-submit">311 <button id="shared-counts-modal-submit"><?php echo $labels['submit']; // phpcs:ignore ?></button>312 </p>313 <div id="shared-counts-modal-sent"><?php esc_html_e( 'Email sent!', 'shared-counts' ); ?></div>314 </div>315 </div>316 </div>317 <?php318 199 } 319 200 … … 537 418 $link['link'] = 'https://twitter.com/share?url=' . $link['url'] . '&text=' . htmlspecialchars( rawurlencode( html_entity_decode( $link['title'], ENT_COMPAT, 'UTF-8' ) ), ENT_COMPAT, 'UTF-8' ); 538 419 $link['label'] = esc_html__( 'Tweet', 'shared-counts' ); 539 $link['icon'] = '<svg v ersion="1.1" xmlns="http://www.w3.org/2000/svg" width="29.71875" height="32" viewBox="0 0 951 1024"><path d="M925.714 233.143q-38.286 56-92.571 95.429 0.571 8 0.571 24 0 74.286-21.714 148.286t-66 142-105.429 120.286-147.429 83.429-184.571 31.143q-154.857 0-283.429-82.857 20 2.286 44.571 2.286 128.571 0 229.143-78.857-60-1.143-107.429-36.857t-65.143-91.143q18.857 2.857 34.857 2.857 24.571 0 48.571-6.286-64-13.143-106-63.714t-42-117.429v-2.286q38.857 21.714 83.429 23.429-37.714-25.143-60-65.714t-22.286-88q0-50.286 25.143-93.143 69.143 85.143 168.286 136.286t212.286 56.857q-4.571-21.714-4.571-42.286 0-76.571 54-130.571t130.571-54q80 0 134.857 58.286 62.286-12 117.143-44.571-21.143 65.714-81.143 101.714 53.143-5.714 106.286-28.571z"></path></svg>';420 $link['icon'] = '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M13.8944 10.4695L21.3345 2H19.5716L13.1085 9.35244L7.95022 2H1.99936L9.80147 13.1192L1.99936 22H3.76218L10.5832 14.2338L16.0318 22H21.9827L13.8944 10.4695ZM11.4792 13.2168L10.6875 12.1089L4.39789 3.30146H7.10594L12.1833 10.412L12.9717 11.5199L19.5708 20.7619H16.8628L11.4792 13.2168Z" /></svg>'; 540 421 $link['target'] = '_blank'; 541 422 $link['rel'] = 'nofollow noopener noreferrer'; … … 588 469 break; 589 470 case 'email': 590 $link['link'] = '#shared-counts-email'; 471 $subject = esc_html__( 'Your friend has shared an article with you.', 'shared-counts' ); 472 $subject = apply_filters( 'shared_counts_amp_email_subject', $subject, $id ); 473 $body = html_entity_decode( get_the_title( $id ), ENT_QUOTES ) . "\r\n"; 474 $body .= get_permalink( $id ) . "\r\n"; 475 $body = apply_filters( 'shared_counts_amp_email_body', $body, $id ); 476 $link['link'] = 'mailto:?subject=' . rawurlencode( $subject ) . '&body=' . rawurlencode( $body ); 591 477 $link['label'] = esc_html__( 'Email', 'shared-counts' ); 592 478 $link['icon'] = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path d="M1024 405.714v453.714q0 37.714-26.857 64.571t-64.571 26.857h-841.143q-37.714 0-64.571-26.857t-26.857-64.571v-453.714q25.143 28 57.714 49.714 206.857 140.571 284 197.143 32.571 24 52.857 37.429t54 27.429 62.857 14h1.143q29.143 0 62.857-14t54-27.429 52.857-37.429q97.143-70.286 284.571-197.143 32.571-22.286 57.143-49.714zM1024 237.714q0 45.143-28 86.286t-69.714 70.286q-214.857 149.143-267.429 185.714-5.714 4-24.286 17.429t-30.857 21.714-29.714 18.571-32.857 15.429-28.571 5.143h-1.143q-13.143 0-28.571-5.143t-32.857-15.429-29.714-18.571-30.857-21.714-24.286-17.429q-52-36.571-149.714-104.286t-117.143-81.429q-35.429-24-66.857-66t-31.429-78q0-44.571 23.714-74.286t67.714-29.714h841.143q37.143 0 64.286 26.857t27.143 64.571z"></path></svg>'; … … 683 569 $elements['wrap_open'] = sprintf( 684 570 '<a href="%s"%s%s%s class="%s"%s>', 685 esc_ attr( $link['link'] ),571 esc_url( $link['link'] ), 686 572 $attr_title, 687 573 $target, -
shared-counts/trunk/readme.txt
r2980287 r3023121 1 1 === Shared Counts - Social Media Share Buttons === 2 Contributors: jaredatch, billerickson , cdils2 Contributors: jaredatch, billerickson 3 3 Tags: sharing, share buttons, social buttons, share counts, social, facebook, linkedin, pinterest, twitter 4 4 Requires at least: 4.6 5 Tested up to: 6. 16 Stable tag: 1. 4.15 Tested up to: 6.4 6 Stable tag: 1.5.0 7 7 Requires PHP: 5.6 8 8 License: GPLv2 or later … … 20 20 - Yummly Button 21 21 - Twitter Tweet Button (using the third-party Twitcount.com API) 22 - Email Sharing (with reCAPTCHA support to prevent abuse)22 - Email Sharing 23 23 - Share Count Total 24 24 - Print Button … … 75 75 If you would like to include Twitter share counts, you can sign up for a free account at [twitcount.com](https://twitcount.com). 76 76 77 If you use the Email share button, we recommend you enable Google's reCAPTCHA to prevent spam. [Sign up here](https://www.google.com/recaptcha/intro/android.html) (free) to get your Site Key and Secret Key.78 79 77 == Screenshots == 80 78 … … 82 80 83 81 == Changelog == 82 83 **1.5.0** 84 - Changed: Replaced server side email with a mailto link to remove the possibility of spam, see #131 85 - Changed: Updated the Twitter logo to X, see #129 86 - Changed: Removed jQuery dependency, see #113 87 - Changed: Use `esc_url()` for sharing links, see #130 84 88 85 89 **1.4.0** -
shared-counts/trunk/shared-counts.php
r2836327 r3023121 5 5 * Description: Social sharing buttons that look great and keep your site loading fast. 6 6 * Author: Bill Erickson & Jared Atchison 7 * Version: 1. 4.17 * Version: 1.5.0 8 8 * 9 9 * Shared Counts is free software: you can redistribute it and/or modify … … 36 36 */ 37 37 // Version. 38 define( 'SHARED_COUNTS_VERSION', '1. 4.1' );38 define( 'SHARED_COUNTS_VERSION', '1.5.0' ); 39 39 40 40 // Directory path.
Note: See TracChangeset
for help on using the changeset viewer.