PluginProbe ʕ •ᴥ•ʔ
Hustle – Email Marketing, Lead Generation, Optins, Popups / 7.8.14.1
Hustle – Email Marketing, Lead Generation, Optins, Popups v7.8.14.1
7.8.14 7.8.14.1 7.8.13 7.8.13.1 trunk 3.0 3.1 3.1.1 3.1.2 3.1.3 3.1.4 4.3.2 4.4.4 4.4.5 4.4.5.1 4.4.5.4 4.6 4.6.1.1 4.6.1.4 4.7.0.2 4.7.0.3 4.7.0.7 4.7.0.9 4.7.1.0 4.7.1.1 4.8.0.0 5.0.0 5.0.1 5.0.1.1 5.0.1.2 5.1 5.1.1 5.1.2 5.1.3 5.1.3.1 5.1.3.2 5.1.4 5.1.5 6.0 6.0.1 6.0.2 6.0.3 6.0.4.2 6.0.5 6.0.6.1 6.0.7 6.0.8.1 6.0.9 7.0.0.1 7.0.2 7.0.3 7.0.4 7.1.0 7.1.1 7.2.0 7.2.1 7.3.0 7.3.1 7.3.3 7.3.5 7.3.6 7.3.7 7.4.0 7.4.1 7.4.11 7.4.13 7.4.13.1 7.4.2 7.4.3 7.4.4 7.4.5 7.4.5.1 7.4.5.2 7.4.6 7.4.7 7.5.0 7.6.0 7.6.1 7.6.3 7.6.4 7.6.6 7.7.0 7.7.1 7.8.0 7.8.1 7.8.10 7.8.10.1 7.8.10.2 7.8.11 7.8.12 7.8.12.1 7.8.2 7.8.3 7.8.4 7.8.5 7.8.6 7.8.7 7.8.8 7.8.9 7.8.9.1 7.8.9.2 7.8.9.3
wordpress-popup / inc / hustle-sshare-model.php
wordpress-popup / inc Last commit date
display-conditions 5 months ago front 2 days ago helpers 1 month ago metas 3 months ago multisite 5 months ago palettes 3 years ago provider 1 month ago providers 2 days ago templates 3 years ago update 5 months ago class-hustle-admin-page-abstract.php 1 month ago class-hustle-auth-token.php 5 months ago class-hustle-condition-factory.php 6 years ago class-hustle-cross-sell.php 10 months ago class-hustle-dashboard-admin.php 1 month ago class-hustle-data.php 1 month ago class-hustle-db.php 2 years ago class-hustle-installer.php 4 years ago class-hustle-meta.php 3 years ago class-hustle-module-admin.php 1 month ago class-hustle-module-collection.php 5 months ago class-hustle-module-fields.php 3 months ago class-hustle-module-page-abstract.php 1 month ago class-hustle-module-validator.php 3 months ago class-hustle-notifications.php 2 days ago class-hustle-settings-admin.php 1 month ago class-hustle-wp-dashboard-page.php 5 months ago class-opt-in.php 2 days ago hustle-background-conversion-log.php 3 months ago hustle-deletion.php 3 months ago hustle-embedded-admin.php 3 years ago hustle-entries-admin.php 5 months ago hustle-entry-model.php 1 month ago hustle-general-data-protection.php 5 months ago hustle-init.php 1 month ago hustle-mail.php 5 months ago hustle-migration.php 5 months ago hustle-model.php 2 days ago hustle-module-model.php 1 month ago hustle-module-widget-legacy.php 5 months ago hustle-module-widget.php 5 months ago hustle-modules-common-admin-ajax.php 1 month ago hustle-popup-admin.php 3 years ago hustle-providers-admin.php 1 month ago hustle-providers.php 5 months ago hustle-settings-admin-ajax.php 1 month ago hustle-settings-page.php 3 years ago hustle-slidein-admin.php 3 years ago hustle-sshare-admin.php 2 days ago hustle-sshare-model.php 2 days ago hustle-tracking-model.php 3 months ago interface-hustle-auth-provider.php 5 months ago opt-in-geo.php 5 months ago opt-in-utils.php 2 days ago opt-in-wpmudev-api.php 5 months ago
hustle-sshare-model.php
754 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Test CPT conditions
4 *
5 * @package Hustle
6 */
7
8 /**
9 * Hustle_SShare_Model class
10 */
11 class Hustle_SShare_Model extends Hustle_Model {
12
13 const SETTINGS_KEY = 'sshare_counters';
14 const COUNTER_META_KEY = 'hustle_shares';
15 const TIMESTAMP_META_KEY = 'hustle_timestamp';
16 const REFRESH_OPTION_KEY = 'hustle_ss_refresh_counters';
17 const FLOAT_DESKTOP = 'float_desktop';
18 const FLOAT_MOBILE = 'float_mobile';
19 const FLOAT_MODULE = 'floating';
20
21 /**
22 * Display settings
23 *
24 * @var array
25 */
26 public $display;
27
28 /**
29 * Get the sub-types for this module.
30 *
31 * @since 4.2.0
32 * @param bool $with_titles With titles.
33 *
34 * @return array
35 */
36 public static function get_sshare_types( $with_titles = false ) {
37 if ( ! $with_titles ) {
38 return array( self::FLOAT_MODULE, 'inline', 'widget', 'shortcode' );
39 } else {
40 return array(
41 self::FLOAT_MODULE => __( 'Floating', 'hustle' ),
42 'inline' => __( 'Inline', 'hustle' ),
43 'widget' => __( 'Widget', 'hustle' ),
44 'shortcode' => __( 'Shortcode', 'hustle' ),
45 );
46 }
47 }
48
49 /**
50 * Get content
51 *
52 * @return \Hustle_SShare_Content
53 */
54 public function get_content() {
55 return new Hustle_SShare_Content( $this->get_settings_meta( self::KEY_CONTENT ), $this );
56 }
57
58 /**
59 * Get design
60 *
61 * @return \Hustle_SShare_Design
62 */
63 public function get_design() {
64 return new Hustle_SShare_Design( $this->get_settings_meta( self::KEY_DESIGN ), $this );
65 }
66
67 /**
68 * Get the stored settings for the "Display" tab.
69 *
70 * @since 4.0
71 *
72 * @return Hustle_SShare_Display
73 */
74 public function get_display() {
75 return new Hustle_SShare_Display( $this->get_settings_meta( self::KEY_DISPLAY_OPTIONS ), $this );
76 }
77
78 /**
79 * Gets the instance of the decorator class for this module type.
80 *
81 * @since 4.3.0
82 *
83 * @return Hustle_Decorator_Sshare
84 */
85 public function get_decorator_instance() {
86 return new Hustle_Decorator_Sshare( $this );
87 }
88
89 /**
90 * Create a new module of the provided mode and type.
91 *
92 * @since 4.0
93 *
94 * @param array $data Must contain the Module's 'mode', 'name' and 'type.
95 * @return int|false Module ID if successfully saved. False otherwise.
96 */
97 public function create_new( $data ) {
98 // Verify it's a valid module type.
99 if ( self::SOCIAL_SHARING_MODULE !== $data['module_type'] ) {
100 return false;
101 }
102
103 // Save to modules table.
104 $this->module_name = sanitize_text_field( $data['module_name'] );
105 $this->module_type = $data['module_type'];
106 $this->active = 0;
107 $this->module_mode = '';
108 $this->save();
109
110 // Save the new module's meta.
111 $this->store_new_module_meta( $data );
112
113 return $this->id;
114 }
115
116 /**
117 * Store the defaults meta when creating a new module.
118 *
119 * @since 4.0.0
120 *
121 * @param array $data Data to store.
122 */
123 private function store_new_module_meta( $data ) {
124 $def_content = apply_filters( 'hustle_module_get_' . self::KEY_CONTENT . '_defaults', $this->get_content()->to_array(), $this, $data );
125 $content_data = empty( $data['content'] ) ? $def_content : array_merge( $def_content, $data['content'] );
126
127 $def_design = apply_filters( 'hustle_module_get_' . self::KEY_DESIGN . '_defaults', $this->get_design()->to_array(), $this, $data );
128 $design_data = empty( $data['design'] ) ? $def_design : array_merge( $def_design, $data['design'] );
129
130 // Visibility settings.
131 $def_visibility = apply_filters( 'hustle_module_get_' . self::KEY_VISIBILITY . '_defaults', $this->get_visibility()->to_array(), $this, $data );
132 $visibility_data = empty( $data['visibility'] ) ? $def_visibility : array_merge( $def_visibility, $data['visibility'] );
133
134 // Display options.
135 $def_display = apply_filters( 'hustle_module_get_' . self::KEY_DISPLAY_OPTIONS . '_defaults', $this->get_display()->to_array(), $this, $data );
136 $display_data = empty( $data['display'] ) ? $def_display : array_merge( $def_display, $data['display'] );
137
138 // Save to meta table.
139 $this->update_meta( self::KEY_CONTENT, $content_data );
140 $this->update_meta( self::KEY_DESIGN, $design_data );
141 $this->update_meta( self::KEY_VISIBILITY, $visibility_data );
142 $this->update_meta( self::KEY_DISPLAY_OPTIONS, $display_data );
143
144 $this->enable_type_track_mode( $this->module_type, true );
145 }
146
147 /**
148 * Sanitize/Replace the module's data.
149 *
150 * @param array $data Data to sanitize.
151 * @return array Sanitized data.
152 */
153 public function sanitize_module( $data ) {
154 $data = Opt_In_Utils::validate_and_sanitize_fields( $data );
155 return $data;
156 }
157
158 /**
159 * Validates the module's data.
160 *
161 * @since 4.0.3
162 *
163 * @param array $data Data to validate.
164 * @return array
165 */
166 public function validate_module( $data ) {
167
168 $icons = isset( $data['content']['social_icons'] ) ? $data['content']['social_icons'] : array();
169 $display = $data['display'];
170 $selector = array(
171 'desktop' => isset( $display['float_desktop_offset'] ) ? $display['float_desktop_offset'] : '',
172 'mobile' => isset( $display['float_mobile_offset'] ) ? $display['float_mobile_offset'] : '',
173 );
174
175 $errors = array();
176
177 // Name validation.
178 if ( empty( sanitize_text_field( $data['module']['module_name'] ) ) ) {
179 $errors['error']['name_error'] = __( 'This field is required', 'hustle' );
180 }
181
182 // Social platform url check.
183 if ( ! empty( $icons ) ) {
184 foreach ( $icons as $key => $icon ) {
185 $icon_with_enpoints = self::get_sharing_endpoints();
186 if ( ! in_array( $icon['platform'], $icon_with_enpoints, true ) && empty( $icon['link'] ) ) {
187 $errors['error']['icon_error'][] = $icon['platform'];
188 }
189
190 // Facebook App ID is required.
191 if ( 'facebook' === $icon['platform'] && empty( $icon['app_id'] ) ) {
192 $errors['error']['facebook_app_id_error'] = __( 'Facebook App ID is required.', 'hustle' );
193 }
194 }
195 }
196
197 // css selector check.
198 if ( ! empty( $selector ) ) {
199 if ( 'css_selector' === $selector['desktop'] && empty( $display['float_desktop_css_selector'] )
200 && ! empty( $display['float_desktop_enabled'] ) ) {
201 $errors['error']['selector_error'][] = 'float_desktop';
202 }
203 if ( 'css_selector' === $selector['mobile'] && empty( $display['float_mobile_css_selector'] ) && ! empty( $display['float_mobile_enabled'] ) ) {
204 $errors['error']['selector_error'][] = 'float_mobile';
205 }
206 }
207
208 // return errors if any.
209 if ( ! empty( $errors ) ) {
210 $errors['success'] = false;
211 return $errors;
212 }
213
214 return true;
215 }
216
217 /**
218 * Updates the metas specific for Social Sharing modules.
219 *
220 * @since 4.3.0
221 * @param array $data Data to save.
222 * @return void
223 */
224 protected function update_module_metas( $data ) {
225 // Meta used in all module types.
226 if ( isset( $data['content'] ) ) {
227 $this->update_meta( self::KEY_CONTENT, $data['content'] );
228 }
229 // Meta used in all module types.
230 if ( isset( $data['visibility'] ) ) {
231 $this->update_meta( self::KEY_VISIBILITY, $data['visibility'] );
232 }
233
234 if ( isset( $data['design'] ) ) {
235 $this->update_meta( self::KEY_DESIGN, $data['design'] );
236 }
237
238 if ( isset( $data['display'] ) ) {
239 $this->update_meta( self::KEY_DISPLAY_OPTIONS, $data['display'] );
240 }
241
242 // Force all counters to retrieve the data from the APIs.
243 self::refresh_all_counters();
244 }
245
246 /**
247 * Get the module's data. Used to display it.
248 *
249 * @since 4.3.0
250 *
251 * @return array
252 */
253 public function get_module_data_to_display() {
254 return $this->get_data();
255 }
256
257 /**
258 * Get the sub-types for this module.
259 *
260 * @since 4.3.1
261 * @param bool $with_titles With titles.
262 *
263 * @return array
264 */
265 public function get_sub_types( $with_titles = false ) {
266 return self::get_sshare_types( $with_titles );
267 }
268
269 /**
270 * Return whether or not the requested counter type is enabled
271 *
272 * @since 3.0.3
273 *
274 * @param string $type Type.
275 * @return boolean
276 */
277 public function is_click_counter_type_enabled( $type ) {
278 $content = $this->get_content()->to_array();
279 if ( isset( $content['click_counter'] ) && $content['click_counter'] === $type ) {
280 return true;
281 } else {
282 return false;
283 }
284 }
285
286 /**
287 * Get social patform names
288 *
289 * @return array
290 */
291 public static function get_social_platform_names() {
292 $social_platform_names = array(
293 'facebook' => esc_html__( 'Facebook', 'hustle' ),
294 'twitter' => esc_html__( 'X', 'hustle' ),
295 'pinterest' => esc_html__( 'Pinterest', 'hustle' ),
296 'reddit' => esc_html__( 'Reddit', 'hustle' ),
297 'linkedin' => esc_html__( 'LinkedIn', 'hustle' ),
298 'vkontakte' => esc_html__( 'Vkontakte', 'hustle' ),
299 'fivehundredpx' => esc_html__( '500px', 'hustle' ),
300 'houzz' => esc_html__( 'Houzz', 'hustle' ),
301 'instagram' => esc_html__( 'Instagram', 'hustle' ),
302 'twitch' => esc_html__( 'Twitch', 'hustle' ),
303 'youtube' => esc_html__( 'YouTube', 'hustle' ),
304 'telegram' => esc_html__( 'Telegram', 'hustle' ),
305 'whatsapp' => esc_html__( 'WhatsApp', 'hustle' ),
306 'email' => esc_html__( 'Email', 'hustle' ),
307 );
308
309 /**
310 * Social networks list
311 *
312 * @since 4.0.4
313 *
314 * @param array $social_platform_names {slug} => {name}
315 */
316 return apply_filters( 'hustle_social_platform_names', $social_platform_names );
317 }
318
319 /**
320 * Get the stored counter of each network.
321 *
322 * @since 3.0.3
323 *
324 * @param integer $post_id Post ID.
325 * @return array
326 */
327 public function get_stored_network_shares( $post_id ) {
328
329 if ( 0 !== $post_id ) {
330 $stored_counters = get_post_meta( $post_id, self::COUNTER_META_KEY, true );
331
332 } else {
333 $sshare_networks_option = Hustle_Settings_Admin::get_hustle_settings( self::SETTINGS_KEY );
334
335 $stored_counters = ! empty( $sshare_networks_option[ self::COUNTER_META_KEY ] ) ? $sshare_networks_option[ self::COUNTER_META_KEY ] : array();
336 }
337
338 return $stored_counters;
339 }
340
341 /**
342 * Check if stored values should be used.
343 *
344 * @since 3.0.3
345 *
346 * @param integer $post_id Post ID.
347 * @param bool $check_expiration_time Optional. Check expiration time or not.
348 * @return bool
349 */
350 public function should_use_stored( $post_id, $check_expiration_time = false ) {
351
352 // If we're in a page/post...
353 if ( 0 !== $post_id ) {
354
355 // Don't use stored if we don't have anything stored in this post.
356 if ( ! get_post_meta( $post_id, self::COUNTER_META_KEY, true ) ) {
357 return false;
358 }
359
360 // If we're in somewhere that's not a page/post...
361 } else {
362
363 // Don't use stored if we don't have anything stored in the options.
364 $sshare_networks_option = Hustle_Settings_Admin::get_hustle_settings( self::SETTINGS_KEY );
365 if ( empty( $sshare_networks_option ) || empty( $sshare_networks_option[ self::COUNTER_META_KEY ] ) ) {
366 return false;
367 }
368 }
369
370 // Do use stored values if traffic is a crawler/bot.
371 $user_agent = filter_input( INPUT_SERVER, 'HTTP_USER_AGENT', FILTER_SANITIZE_SPECIAL_CHARS );
372 if ( $user_agent && preg_match( '/bot|crawler|ia_archiver|mediapartners-google|80legs|wget|voyager|baiduspider|curl|yahoo!|slurp/i', $user_agent ) ) {
373 return true;
374 }
375
376 if ( $check_expiration_time ) {
377
378 if ( 0 !== $post_id ) {
379 $timestamp = intval( get_post_meta( $post_id, self::TIMESTAMP_META_KEY, true ) );
380 } else {
381 $timestamp = isset( $sshare_networks_option[ self::TIMESTAMP_META_KEY ] ) ? $sshare_networks_option[ self::TIMESTAMP_META_KEY ] : 'true';
382 }
383
384 // Don't use stored if the expiration time of the counter already passed.
385 if ( 'true' === $timestamp || time() > ( $timestamp + ( 6 * 60 * 60 ) ) ) {
386 return false;
387 }
388
389 // Don't use stored if the counter hasn't beeen updated after the last time that all counters were cleared.
390 $clear_counters_time = get_option( self::REFRESH_OPTION_KEY, false );
391 if ( $clear_counters_time && $timestamp < intval( $clear_counters_time ) ) {
392 return false;
393 }
394 }
395 return true;
396 }
397
398 /**
399 * Set the number of shares of each network in an array. Like $result[facebook] = 44
400 *
401 * @since 3.0.3
402 * @since 4.0
403 *
404 * @param array $networks Networks.
405 * @param integer $post_id Post ID.
406 * @return array
407 */
408 public function retrieve_networks_shares( $networks, $post_id ) {
409
410 // TODO: handle homepage when post_id is not a specific page.
411 $post_id = apply_filters( 'hustle_network_shares_post_id', $post_id );
412
413 $current_link = ( 0 !== $post_id && get_permalink( $post_id ) ) ? get_permalink( $post_id ) : home_url();
414 // We share URL without trailing slash, So we need to remove slash when we fetch from API.
415 $current_link = untrailingslashit( $current_link );
416 $current_link = apply_filters( 'hustle_network_shares_from_url', $current_link );
417
418 // If we should use the stored values instead of retrieving them from the API.
419 $should_use_stored = apply_filters( 'hustle_sshare_should_use_stored_counters', $this->should_use_stored( $post_id, true ), $post_id, $current_link );
420 if ( $should_use_stored ) {
421
422 $networks_info = $this->get_stored_network_shares( $post_id );
423
424 // Call the API for the networks we don't have the value stored.
425 $missing_networks = array_diff( $networks, array_keys( $networks_info ) );
426 if ( ! empty( $missing_networks ) ) {
427 $missing_info = $this->get_refreshed_counters( $current_link, $missing_networks, $post_id );
428
429 $networks_info = array_merge( $networks_info, $missing_info );
430 }
431 } else {
432 $networks_info = $this->get_refreshed_counters( $current_link, $networks, $post_id );
433 }
434
435 return $networks_info;
436 }
437
438 /**
439 * Get the counter from the APIs, store it in the post_meta, and store the current time for expiration.
440 *
441 * @since 4.0
442 *
443 * @param string $current_link Current link.
444 * @param array $networks Networks.
445 * @param id $post_id Post ID.
446 * @return array
447 */
448 public function get_refreshed_counters( $current_link, $networks, $post_id ) {
449
450 // Get array with json formatted data for each active network.
451 $networks_info = $this->get_networks_data_from_api( $current_link, $networks );
452 $networks_info = $this->format_networks_api_raw_data( $networks_info, false );
453
454 // Store the values for "caching".
455 if ( 0 !== $post_id ) {
456
457 // Store the values of all new networks.
458 $stored_info = get_post_meta( $post_id, self::COUNTER_META_KEY, true );
459 if ( ! empty( $stored_info ) ) {
460 $networks_info = array_merge( $stored_info, $networks_info );
461 }
462
463 // Set the counters values for current post.
464 update_post_meta( $post_id, self::COUNTER_META_KEY, $networks_info );
465
466 // Set the counter update time.
467 update_post_meta( $post_id, self::TIMESTAMP_META_KEY, time() );
468
469 } else {
470
471 // Store the values of all new networks.
472 $stored_info = Hustle_Settings_Admin::get_hustle_settings( self::SETTINGS_KEY );
473 if ( ! empty( $stored_info[ self::COUNTER_META_KEY ] ) ) {
474 $networks_info = array_merge( $stored_info[ self::COUNTER_META_KEY ], $networks_info );
475 }
476
477 // Set global option for pages that are not a post.
478 $networks_data = array(
479 self::COUNTER_META_KEY => $networks_info,
480 self::TIMESTAMP_META_KEY => time(),
481 );
482
483 Hustle_Settings_Admin::update_hustle_settings( $networks_data, self::SETTINGS_KEY );
484 }
485
486 return $networks_info;
487 }
488
489 /**
490 * Get the data from each network's API
491 *
492 * @since 3.0.3
493 *
494 * @param string $current_link Current Link.
495 * @param array $social_networks Social networks.
496 * @param array $options Options.
497 * @return array
498 */
499 private function get_networks_data_from_api( $current_link, $social_networks = array(), $options = array() ) {
500 $result = array();
501
502 $networks_endpoint = self::get_networks_counter_endpoint( false, $current_link );
503
504 foreach ( $social_networks as $network ) {
505
506 if ( isset( $networks_endpoint[ $network ] ) ) {
507 $url = $networks_endpoint[ $network ];
508 } else {
509 continue;
510 }
511
512 $response = wp_remote_get( $url );
513 $response_body = wp_remote_retrieve_body( $response );
514
515 if ( $response_body ) {
516 $result[ $network ] = $response_body;
517 }
518 }
519
520 return $result;
521 }
522
523 /**
524 * Get the API URL for each network, or the name of the networks with a counter endpoint.
525 *
526 * @since 4.0
527 *
528 * @param string $networks_only Networks only.
529 * @param string $current_link Current link.
530 * @return array
531 */
532 public static function get_networks_counter_endpoint( $networks_only = true, $current_link = '' ) {
533
534 if ( $networks_only ) {
535 return apply_filters(
536 'hustle_networks_with_counter_endpoint',
537 array( 'twitter', 'reddit', 'vkontakte' )
538 );
539 }
540
541 $current_link = rawurlencode( $current_link );
542
543 return apply_filters(
544 'hustle_native_share_counter_enpoints',
545 array(
546 // FB stopped working without an app token.
547 // 'facebook' => 'https://graph.facebook.com/?fields=og_object{engagement{count}}&id=' . $current_link,
548 // There's no official twitter api for doing this. This alternative requires signing in.
549 'twitter' => 'https://counts.twitcount.com/counts.php?url=' . $current_link,
550 'reddit' => 'https://www.reddit.com/api/info.json?url=' . $current_link,
551 'vkontakte' => 'https://vk.com/share.php?act=count&url=' . untrailingslashit( $current_link ),
552 )
553 );
554 }
555
556 /**
557 * Format the raw response from the networks so it can be displayed in front.
558 *
559 * @since 4.0
560 *
561 * @param array $networks_data Networks data.
562 * @param boolean $shorten_count If true, 1000 shares would be formatted to 1K.
563 * @return array
564 */
565 private function format_networks_api_raw_data( $networks_data, $shorten_count = true ) {
566
567 $formatted = array();
568
569 foreach ( $networks_data as $network => $response ) {
570
571 // Get "count" from each network's response and add the "count" number to $formatted array.
572 $get_formatted_response = 'format_' . $network . '_api_response';
573 if ( ! is_callable( array( $this, $get_formatted_response ) ) ) {
574 continue;
575 }
576
577 $formatted[ $network ] = $this->{$get_formatted_response}( $networks_data[ $network ] );
578
579 if ( $shorten_count ) {
580 $formatted[ $network ] = $this->shorten_count( $formatted[ $network ] );
581 }
582 }
583
584 return $formatted;
585 }
586
587 /**
588 * Format a given number to display it nicely. 10K instead of 10093
589 *
590 * @since 3.0.3
591 *
592 * @param integer $count Count.
593 * @return string
594 */
595 private function shorten_count( $count ) {
596 $count = intval( $count );
597 if ( $count < 1000 ) {
598 return $count;
599 } elseif ( $count < 1000000 ) {
600 return round( $count / 1000, 1, PHP_ROUND_HALF_DOWN ) . __( ' K', 'hustle' );
601 } else {
602 return round( $count / 1000000, 1, PHP_ROUND_HALF_DOWN ) . __( ' M', 'hustle' );
603 }
604 }
605
606 /**
607 * Set option to trigger the refresh of the counters
608 *
609 * @since 3.0.3
610 */
611 public static function refresh_all_counters() {
612 update_option( self::REFRESH_OPTION_KEY, time() );
613 }
614
615 /**
616 * Format the response of each API to get the counter
617 *
618 * @since 3.0.3
619 *
620 * @param string $response Response.
621 * @return integer
622 */
623 private function format_facebook_api_response( $response ) {
624 $response = json_decode( $response, true );
625 $engagement = ! empty( $response['og_object'] ) && ! empty( $response['og_object']['engagement']['count'] ) ? intval( $response['og_object']['engagement']['count'] ) : 0;
626
627 return $engagement;
628 }
629
630 /**
631 * Format twitter api response
632 *
633 * @param string $response Response.
634 * @return int
635 */
636 private function format_twitter_api_response( $response ) {
637 $response = json_decode( $response, true );
638 return isset( $response['count'] ) ? intval( $response['count'] ) : 0;
639 }
640
641 /**
642 * Format pinterest api response
643 *
644 * @param string $response Response.
645 * @return int
646 */
647 private function format_pinterest_api_response( $response ) {
648 preg_match( '/^receiveCount\((.*)\)$/', $response, $match );
649 if ( ! isset( $match[1] ) ) {
650 return 0;
651 }
652 $response = json_decode( $match[1], true );
653 return isset( $response['count'] ) ? intval( $response['count'] ) : 0;
654 }
655
656 /**
657 * Format reddit api response
658 *
659 * @param string $response Response.
660 * @return int
661 */
662 private function format_reddit_api_response( $response ) {
663 $response = json_decode( $response, true );
664 if ( ! isset( $response['data']['children'] ) ) {
665 return 0;
666 }
667 $data = $response['data']['children'];
668 $counter = 0;
669 foreach ( $data as $sub ) {
670 if ( ! isset( $sub['data']['subreddit_subscribers'] ) ) {
671 continue;
672 }
673 $counter = $counter + intval( $sub['data']['subreddit_subscribers'] );
674 }
675 return $counter;
676 }
677
678 /**
679 * Format vkontakte api response
680 *
681 * @param string $response Response.
682 * @return int
683 */
684 private function format_vkontakte_api_response( $response ) {
685 preg_match( '/^VK\.Share\.count\(.{1,3}(.*)\)/', $response, $match );
686 if ( ! isset( $match[1] ) ) {
687 return 0;
688 }
689 return intval( $match[1] );
690 }
691
692 /**
693 * Get the network's sharing endpoints.
694 *
695 * @since 4.0
696 *
697 * @param bool $networks_only Networks only.
698 * @return array
699 */
700 public static function get_sharing_endpoints( $networks_only = true ) {
701
702 if ( $networks_only ) {
703 return apply_filters(
704 'hustle_networks_with_share_enpoints',
705 array(
706 'facebook',
707 'twitter',
708 'pinterest',
709 'reddit',
710 'linkedin',
711 'vkontakte',
712 'whatsapp',
713 'email',
714 'telegram',
715 )
716 );
717
718 }
719
720 global $wp;
721 $current_url = rawurlencode( home_url( $wp->request ) );
722
723 // let users filter the title.
724 $title = apply_filters( 'hustle_social_share_platform_title', rawurlencode( html_entity_decode( esc_html( get_the_title() ) ) ) );
725
726 return apply_filters(
727 'hustle_native_share_enpoints',
728 array(
729
730 'facebook' => 'https://www.facebook.com/sharer/sharer.php?u=' . $current_url,
731 'twitter' => 'https://twitter.com/intent/tweet?url=' . $current_url . '&text=' . $title,
732 'pinterest' => 'https://www.pinterest.com/pin/create/button/?url=' . $current_url,
733 'reddit' => 'https://www.reddit.com/submit?url=' . $current_url,
734 'linkedin' => 'https://www.linkedin.com/shareArticle?mini=true&url=' . $current_url,
735 'vkontakte' => 'https://vk.com/share.php?url=' . $current_url,
736 'whatsapp' => 'https://api.whatsapp.com/send?text=' . $current_url,
737 'telegram' => 'https://t.me/share/url?url=' . $current_url . '&text=' . $title,
738 'email' => 'mailto:?subject=' . $title . '&body=' . $current_url,
739
740 ),
741 $current_url
742 );
743 }
744
745 /**
746 * Get renderer
747 *
748 * @return \Hustle_Renderer_Sshare
749 */
750 public function get_renderer() {
751 return new Hustle_Renderer_Sshare();
752 }
753 }
754