WordPress Social Tools, Related Posts, Monetization – Shareaholic - Version 8.13.14

Version Description

We update this plugin regularly so we can make it better for you. Update to the latest version for all of the available features and improvements. Thanks for using Shareaholic!

Download this release

Release Info

Developer shareaholic
Plugin Icon 128x128 WordPress Social Tools, Related Posts, Monetization – Shareaholic
Version 8.13.14
Comparing to
See all releases

Code changes from version 8.13.13 to 8.13.14

admin.php CHANGED
@@ -12,110 +12,113 @@
12
  */
13
  class ShareaholicAdmin {
14
 
15
- const ACTIVATE_TIMESTAMP_OPTION = 'shareaholic_activate_timestamp';
16
- const REVIEW_DISMISS_OPTION = 'shareaholic_review_notice';
17
- const REVIEW_FIRST_PERIOD = 518400; // 6 days in seconds
18
- const REVIEW_LATER_PERIOD = 7776000; // 3 months in seconds
19
- const REVIEW_FOREVER_PERIOD = 63113904; // 2 years in seconds
20
-
21
- /**
22
- * Loads before all else
23
- */
24
- public static function admin_init() {
25
- ShareaholicUtilities::check_for_other_plugin();
26
- // workaround: http://codex.wordpress.org/Function_Reference/register_activation_hook
27
- if (is_admin() && get_option( 'Activated_Plugin_Shareaholic') == 'shareaholic') {
28
- delete_option('Activated_Plugin_Shareaholic');
29
- /* do stuff once right after activation */
30
- if (has_action('wp_ajax_nopriv_shareaholic_share_counts_api') && has_action('wp_ajax_shareaholic_share_counts_api')) {
31
- ShareaholicUtilities::share_counts_api_connectivity_check();
32
- }
33
- self::activation_redirect();
34
- }
35
-
36
- self::check_redirect_url();
37
- self::check_review_dismissal();
38
- self::check_plugin_review();
39
- }
40
-
41
- /**
42
- * Check review notice status for current user
43
- *
44
- */
45
- public static function check_review_dismissal() {
46
-
47
- global $current_user;
48
- $user_id = $current_user->ID;
49
-
50
- if (!is_admin() ||
51
- !current_user_can('publish_posts') ||
52
- !isset($_GET['_wpnonce']) ||
53
- !wp_verify_nonce($_GET['_wpnonce'], 'review-nonce') ||
54
- !isset($_GET['shr_defer_t']) ||
55
- !isset($_GET[self::REVIEW_DISMISS_OPTION])) {
56
- return;
57
- }
58
-
59
- $the_meta_array = array (
60
- 'dismiss_defer_period' => $_GET["shr_defer_t"],
61
- 'dismiss_timestamp' => time()
62
- );
63
-
64
- update_user_meta($user_id, self::REVIEW_DISMISS_OPTION, $the_meta_array);
65
- }
66
-
67
- /**
68
- * Check if we should display the review notice
69
- *
70
- */
71
- public static function check_plugin_review() {
72
-
73
- global $current_user;
74
- $user_id = $current_user->ID;
75
-
76
- $show_review_notice = false;
77
- $activation_timestamp = get_site_option(self::ACTIVATE_TIMESTAMP_OPTION);
78
- $review_dismissal_array = get_user_meta($user_id, self::REVIEW_DISMISS_OPTION, true);
79
- $dismiss_defer_period = isset($review_dismissal_array['dismiss_defer_period']) ? $review_dismissal_array['dismiss_defer_period'] : 0;
80
- $dismiss_timestamp = isset($review_dismissal_array['dismiss_timestamp']) ? $review_dismissal_array['dismiss_timestamp'] : time();
81
-
82
- if ($dismiss_timestamp + $dismiss_defer_period <= time()) {
83
- $show_review_notice = true;
84
- }
85
-
86
- if (!$activation_timestamp) {
87
- $activation_timestamp = time();
88
- add_site_option(self::ACTIVATE_TIMESTAMP_OPTION, $activation_timestamp);
89
- }
90
-
91
- // display review message after a certain period of time after activation
92
- if ((time() - $activation_timestamp > self::REVIEW_FIRST_PERIOD) && $show_review_notice == true) {
93
- add_action('admin_notices', array('ShareaholicAdmin', 'display_review_notice'));
94
- }
95
- }
96
-
97
- public static function display_review_notice() {
98
-
99
- if (ShareaholicUtilities::get_option('disable_review_notice') == "on")
100
- return;
101
-
102
- $dismiss_forever = add_query_arg( array(
103
- self::REVIEW_DISMISS_OPTION => true,
104
- 'shr_defer_t' => self::REVIEW_FOREVER_PERIOD
105
- ));
106
-
107
- $dismiss_forlater = add_query_arg( array(
108
- self::REVIEW_DISMISS_OPTION => true,
109
- 'shr_defer_t' => self::REVIEW_LATER_PERIOD
110
- ));
111
-
112
- $dismiss_forever_url = wp_nonce_url($dismiss_forever, 'review-nonce');
113
- $dismiss_forlater_url = wp_nonce_url($dismiss_forlater, 'review-nonce');
114
-
115
- echo '
 
 
 
116
  <style>
117
  .shareaholic-review-notice {
118
- background-size: contain; background-position: right bottom; background-repeat: no-repeat; background-image: url(' . plugins_url('assets/img/icon-256x256.png', __FILE__) . ');
119
  }
120
  .shareaholic-review-notice-text {
121
  background: rgba(255, 255, 255, 0.9); text-shadow: white 0px 0px 10px; margin-right: 8em !important;
@@ -144,616 +147,657 @@ class ShareaholicAdmin {
144
  </script>
145
 
146
  <div class="notice notice-info is-dismissible shareaholic-review-notice">
147
- <p class="shareaholic-review-notice-text">' . __('Hey there! We noticed that you have had success using ', 'shareaholic') . '<a href="' . admin_url('admin.php?page=shareaholic-settings') . '">Shareaholic</a>' . __(' — awesome! Could you please do us a BIG favor and give us a quick 5-star rating on WordPress? It would help us spread the word and boost our motivation. We would really appreciate it 🙂 ~ Your friends @ Shareaholic', 'shareaholic') . '
148
  <br />
149
  <br />
150
- <a onClick="' . "shr_openWindowReload('https://wordpress.org/support/plugin/shareaholic/reviews/?rate=5#new-post', '$dismiss_forever_url')" . '" class="button button-primary">' . __('Ok, you deserve it', 'shareaholic') . '</a> &nbsp;
151
- <a href="' . $dismiss_forlater_url . '">' . __('No, not good enough', 'shareaholic') . '</a> &nbsp;
152
- <a href="' . $dismiss_forever_url . '">' . __('I already did', 'shareaholic') . '</a> &nbsp;
153
- <a href="' . $dismiss_forever_url . '">' . __('Dismiss', 'yarpp') . '</a>
154
  </p>
155
  </div>';
156
- }
157
-
158
- /**
159
- * Sends user to the Settings page on activation of Shareaholic plugin
160
- *
161
- */
162
-
163
- public static function activation_redirect() {
164
- // Bail if no activation redirect transient
165
- if (!get_transient('_shr_activation_redirect')){
166
- return;
167
- }
168
-
169
- delete_transient('_shr_activation_redirect');
170
-
171
- // Bail if activating from multisite, network, or bulk
172
- if( is_multisite() || is_network_admin() || isset($_GET['activate-multi']) ){
173
- return;
174
- }
175
-
176
- wp_safe_redirect( add_query_arg( array( 'page' => 'shareaholic-settings' ), admin_url( 'admin.php' ) ) );
177
- }
178
-
179
-
180
- /**
181
- * Redirect to Plans
182
- *
183
- */
184
- public static function go_premium() {
185
- echo <<<JQUERY
186
- <script type="text/javascript">
187
- window.location = "https://www.shareaholic.com/plans";
188
- </script>
189
- JQUERY;
190
- }
191
-
192
- /**
193
- * Redirection Utility (used by SDK - Badge)
194
- *
195
- */
196
- public static function check_redirect_url() {
197
-
198
- $redirect_url = isset($_GET['shareaholic_redirect_url']) ? strtolower($_GET['shareaholic_redirect_url']) : NULL;
199
-
200
- if ($redirect_url != NULL) {
201
-
202
- // Support redirect URLs with no scheme; default to httpS
203
- $parsed = parse_url($redirect_url);
204
- if (empty($parsed['scheme'])) {
205
- $redirect_url = 'https://' . ltrim($redirect_url);
206
- }
207
-
208
- // exit if redirect is not to shareaholic.com
209
- $redirect_url_host = parse_url($redirect_url, PHP_URL_HOST);
210
-
211
- if ($redirect_url_host != "shareaholic.com" && $redirect_url_host != "stageaholic.com" && $redirect_url_host != "spreadaholic.com") {
212
- wp_redirect(admin_url('admin.php?page=shareaholic-settings'));
213
- exit;
214
- }
215
-
216
- // Get User Email
217
- if (function_exists('wp_get_current_user')) {
218
- $current_user = wp_get_current_user();
219
- $user_email = urlencode($current_user->user_email);
220
- } else {
221
- $user_email = '';
222
- }
223
-
224
- // Pass verification_key only if current wp user has permission to the key
225
- if (current_user_can('activate_plugins')) {
226
- $verification_key = ShareaholicUtilities::get_option('verification_key');
227
- } else {
228
- $verification_key = "unauthorized";
229
- }
230
-
231
- $enriched_redirect_url = add_query_arg( array(
232
- 'site_id' => ShareaholicUtilities::get_option('api_key'),
233
- 'verification_key' => $verification_key,
234
- 'email' => $user_email,
235
- 'ref' => 'wordpress',
236
- ), $redirect_url);
237
-
238
- wp_redirect($enriched_redirect_url);
239
- exit;
240
- }
241
- }
242
-
243
- /**
244
- * The function called during the admin_head action.
245
- *
246
- */
247
- public static function admin_header() {
248
- ShareaholicAdmin::include_remote_js();
249
- }
250
-
251
- /**
252
- * Load the terms of service notice that shows up
253
- * at the top of the admin pages.
254
- */
255
- public static function show_terms_of_service() {
256
- ShareaholicUtilities::load_template('terms_of_service_notice');
257
- }
258
-
259
- /**
260
- * Renders footer
261
- */
262
- public static function show_footer() {
263
- ShareaholicUtilities::load_template('footer');
264
- }
265
-
266
- /**
267
- * Renders header
268
- */
269
- public static function show_header() {
270
- $settings = ShareaholicUtilities::get_settings();
271
- $settings['base_link'] = Shareaholic::URL . '/publisher_tools/' . $settings['api_key'] . '/';
272
- ShareaholicUtilities::load_template('header', array(
273
- 'settings' => $settings
274
- ));
275
- }
276
-
277
- /**
278
- * Renders Chat
279
- */
280
- public static function include_chat() {
281
- ShareaholicUtilities::load_template('script_chat');
282
- }
283
-
284
- /**
285
- * Adds meta boxes for post and page options
286
- */
287
- public static function add_meta_boxes() {
288
- $post_types = get_post_types();
289
- // $post_types = array( 'post', 'page', 'product' );
290
- foreach ($post_types as $post_type) {
291
- add_meta_box(
292
- 'shareaholic',
293
- 'Shareaholic',
294
- array('ShareaholicAdmin', 'meta_box'),
295
- $post_type,
296
- 'side',
297
- 'low'
298
- );
299
- }
300
- }
301
-
302
- /**
303
- * This is the wp ajax callback for when a user
304
- * checks a checkbox for a location that doesn't
305
- * already have a location_id. After it has been
306
- * successfully created the id needs to be stored,
307
- * which is what this method does.
308
- */
309
- public static function add_location() {
310
- $location = $_POST['location'];
311
- $app_name = $location['app_name'];
312
-
313
- // if location id is not numeric throw bad request
314
- // or user lacks permissions
315
- // or does not have the nonce token
316
- // otherwise forcibly change it to a number
317
- if (!wp_verify_nonce( $_REQUEST['nonce'], 'shareaholic_add_location') ||
318
- !current_user_can('publish_posts') || !is_numeric($location['id'])) {
319
- header('HTTP/1.1 400 Bad Request', true, 400);
320
- die();
321
- } else {
322
- $location['id'] = intval($location['id']);
323
- }
324
-
325
- ShareaholicUtilities::update_options(array(
326
- 'location_name_ids' => array(
327
- $app_name => array(
328
- $location['name'] => $location['id']
329
- ),
330
- ),
331
- $app_name => array(
332
- $location['name'] => 'on'
333
- )
334
- ));
335
-
336
- echo json_encode(array(
337
- 'status' => "successfully created a new {$location['app_name']} location",
338
- 'id' => $location['id']
339
- ));
340
-
341
- die();
342
- }
343
-
344
- /**
345
- * Shows the message about failing to create an api key
346
- */
347
- public static function failed_to_create_api_key() {
348
- // ShareaholicUtilities::load_template('failed_to_create_api_key');
349
- if (isset($_GET['page']) && preg_match('/shareaholic-settings/', $_GET['page'])) {
350
- ShareaholicUtilities::load_template('failed_to_create_api_key_modal');
351
- }
352
- }
353
-
354
- /**
355
- * The actual function in charge of drawing the meta boxes.
356
- */
357
- public static function meta_box() {
358
- global $post;
359
- $settings = ShareaholicUtilities::get_settings();
360
- ShareaholicUtilities::load_template('meta_boxes', array(
361
- 'settings' => $settings,
362
- 'post' => $post
363
- ));
364
- }
365
-
366
- /**
367
- * This function fires when a post is saved
368
- *
369
- * @param int $post_id
370
- */
371
- public static function save_post($post_id) {
372
- // wordpress does something silly where save_post is fired twice,
373
- // once with the id of a revision and once with the actual id. This
374
- // filters out revision ids (which we don't want)
375
- if (!wp_is_post_revision($post_id)) {
376
- self::disable_post_attributes($post_id);
377
- }
378
- }
379
-
380
- /**
381
- * For each of the things that a user can disable or exclude per post,
382
- * we iterate through and turn add the post meta, or make it false
383
- * if it *used* to be true, but did not come through in $_POST
384
- * (because unchecked boxes are not submitted).
385
- *
386
- * @param int $post_id
387
- */
388
- private static function disable_post_attributes($post_id) {
389
- foreach (array(
390
- 'disable_share_buttons',
391
- 'disable_open_graph_tags',
392
- 'exclude_recommendations',
393
- 'disable_recommendations'
394
- ) as $attribute) {
395
- $key = 'shareaholic_' . $attribute;
396
- if (isset($_POST['shareaholic'][$attribute]) &&
397
- $_POST['shareaholic'][$attribute] == 'on') {
398
- update_post_meta($post_id, $key, true);
399
- } elseif (get_post_meta($post_id, $key, true)) {
400
- update_post_meta($post_id, $key, false);
401
- }
402
- }
403
- }
404
-
405
- /**
406
- * Enqueue local styles and scripts for the admin panel
407
- *
408
- * @since 7.0.2.0
409
- */
410
- public static function enqueue_scripts() {
411
- if (isset($_GET['page']) && preg_match('/shareaholic/', $_GET['page'])) {
412
- wp_enqueue_style('shareaholic_bootstrap_css', plugins_url('assets/css/bootstrap.css', __FILE__), false, ShareaholicUtilities::get_version());
413
- wp_enqueue_style('shareaholic_common_css', plugins_url('assets/css/common.css', __FILE__), false, ShareaholicUtilities::get_version());
414
- wp_enqueue_style('shareaholic_reveal_css', plugins_url('assets/css/reveal.css', __FILE__), false, ShareaholicUtilities::get_version());
415
- wp_enqueue_style('shareaholic_main_css', plugins_url('assets/css/main.css', __FILE__), false, ShareaholicUtilities::get_version());
416
- wp_enqueue_script('shareholic_bootstrap_js', plugins_url('assets/js/bootstrap.min.js', __FILE__), false, ShareaholicUtilities::get_version());
417
- wp_enqueue_script('shareholic_jquery_custom_js', plugins_url('assets/js/jquery_custom.js', __FILE__), false, ShareaholicUtilities::get_version());
418
- wp_enqueue_script('shareholic_jquery_ui_custom_js', plugins_url('assets/js/jquery_ui_custom.js', __FILE__), array('shareholic_jquery_custom_js'), ShareaholicUtilities::get_version());
419
- wp_enqueue_script('shareholic_modified_reveal_js', plugins_url('assets/js/jquery.reveal.modified.js', __FILE__), array('shareholic_jquery_custom_js', 'shareholic_jquery_ui_custom_js'), ShareaholicUtilities::get_version());
420
- wp_enqueue_script('shareholic_main_js', plugins_url('assets/js/main.js', __FILE__), false, ShareaholicUtilities::get_version());
421
- }
422
- }
423
-
424
- /**
425
- * Include remote styles and scripts for the admin panel.
426
- *
427
- * This addresses a conflict with 3rd party plugins that force modify the paths of
428
- * scripts that are passed through to wp_enqueue_script
429
- *
430
- * @since 8.12.1
431
- */
432
- public static function include_remote_js() {
433
- if (isset($_GET['page']) && preg_match('/shareaholic/', $_GET['page'])) {
434
- echo "\n<script src='" . ShareaholicUtilities::asset_url_admin('assets/pub/utilities.js') . '?' . ShareaholicUtilities::get_version() . "'></script>\n";
435
- }
436
- }
437
-
438
- /**
439
- * Puts a new menu item under Settings.
440
- */
441
- public static function admin_menu() {
442
-
443
- $icon_svg = ShareaholicUtilities::get_icon_svg();
444
-
445
- add_menu_page(
446
- __('Shareaholic Settings', 'shareaholic'),
447
- __('Shareaholic', 'shareaholic'),
448
- 'manage_options',
449
- 'shareaholic-settings',
450
- array('ShareaholicAdmin', 'admin'),
451
- $icon_svg
452
- );
453
- add_submenu_page(
454
- 'shareaholic-settings',
455
- __('App Manager', 'shareaholic'),
456
- __('App Manager', 'shareaholic'),
457
- 'manage_options',
458
- 'shareaholic-settings',
459
- array('ShareaholicAdmin', 'admin')
460
- );
461
- add_submenu_page(
462
- 'shareaholic-settings',
463
- __('App Manager [legacy]', 'shareaholic'),
464
- __('App Manager [legacy]', 'shareaholic'),
465
- 'manage_options',
466
- 'shareaholic-settings-legacy',
467
- array('ShareaholicAdmin', 'admin_legacy')
468
- );
469
- add_submenu_page(
470
- 'shareaholic-settings',
471
- __('Advanced Settings', 'shareaholic'),
472
- __('Advanced Settings', 'shareaholic'),
473
- 'manage_options',
474
- 'shareaholic-advanced',
475
- array('ShareaholicAdmin', 'advanced_admin')
476
- );
477
- add_submenu_page(
478
- 'shareaholic-settings',
479
- __('Go Premium', 'shareaholic'),
480
- __('<span style="color: #FCB214;">Go Premium</span>', 'shareaholic'),
481
- 'activate_plugins',
482
- 'shareaholic-premium',
483
- array('ShareaholicAdmin', 'go_premium')
484
- );
485
- }
486
-
487
- /**
488
- * Updates the information if passed in and sets save message.
489
- */
490
- public static function admin_legacy() {
491
- $settings = ShareaholicUtilities::get_settings();
492
- $action = str_replace( '%7E', '~', $_SERVER['REQUEST_URI']);
493
- if(isset($_POST['already_submitted']) && $_POST['already_submitted'] == 'Y' &&
494
- check_admin_referer($action, 'nonce_field')) {
495
- echo "<div class='updated settings_updated'><p><strong>". sprintf(__('Settings successfully saved', 'shareaholic')) . "</strong></p></div>";
496
-
497
- /*
498
- * only checked check boxes are submitted, so we have to iterate
499
- * through the existing app locations and if they exist in the settings
500
- * but not in $_POST, it must have been unchecked, and it
501
- * should be set to 'off'
502
- */
503
- foreach (array('share_buttons', 'recommendations') as $app) {
504
- if (isset($settings[$app])) {
505
- foreach ($settings[$app] as $location => $on) {
506
- if (!isset($_POST[$app][$location]) && $on == 'on') {
507
- $_POST[$app][$location] = 'off';
508
- }
509
- }
510
- }
511
- if (!isset($_POST[$app])) {
512
- $_POST[$app] = array();
513
- }
514
- }
515
-
516
- foreach (array('share_buttons_display_on_excerpts', 'recommendations_display_on_excerpts') as $setting) {
517
- if (isset($settings[$setting]) &&
518
- !isset($_POST['shareaholic'][$setting]) &&
519
- $settings[$setting] == 'on') {
520
- $_POST['shareaholic'][$setting] = 'off';
521
- } elseif (!isset($_POST['shareaholic'][$setting])) {
522
- $_POST['shareaholic'][$setting] = array();
523
- }
524
- }
525
-
526
- // Save "Locations" related preferences
527
- ShareaholicUtilities::update_options(array(
528
- 'share_buttons' => $_POST['share_buttons'],
529
- 'recommendations' => $_POST['recommendations']
530
- ));
531
-
532
- // Save "Excerpts" related preferences
533
- if (isset($_POST['shareaholic']['share_buttons_display_on_excerpts'])) {
534
- ShareaholicUtilities::update_options(array('share_buttons_display_on_excerpts' => $_POST['shareaholic']['share_buttons_display_on_excerpts']));
535
- }
536
- if (isset($_POST['shareaholic']['recommendations_display_on_excerpts'])) {
537
- ShareaholicUtilities::update_options(array('recommendations_display_on_excerpts' => $_POST['shareaholic']['recommendations_display_on_excerpts']));
538
- }
539
-
540
- ShareaholicUtilities::log_event("UpdatedSettings");
541
- // clear cache after settings update
542
- ShareaholicUtilities::clear_cache();
543
- }
544
-
545
- /*
546
- * Just in case they've added new settings on shareaholic.com
547
- */
548
- if (ShareaholicUtilities::has_accepted_terms_of_service()) {
549
- $api_key = ShareaholicUtilities::get_or_create_api_key();
550
- ShareaholicUtilities::get_new_location_name_ids($api_key);
551
- }
552
-
553
- self::draw_admin_form();
554
- self::draw_verify_api_key();
555
- }
556
-
557
- /**
558
- * The function for the App Manager Tab
559
- */
560
- public static function admin() {
561
-
562
- if (!ShareaholicUtilities::has_accepted_terms_of_service()) {
563
- ShareaholicUtilities::load_template('terms_of_service_modal', array(
564
- 'image_url' => SHAREAHOLIC_ASSET_DIR . 'img'
565
- ));
566
- }
567
-
568
- if (ShareaholicUtilities::has_accepted_terms_of_service()) {
569
- $api_key = ShareaholicUtilities::get_or_create_api_key();
570
- $jwt = ShareaholicAdmin::get_publisher_token();
571
-
572
- if ($jwt) {
573
- ShareaholicUtilities::load_template('admin', array(
574
- 'jwt' => $jwt,
575
- 'api_key' => $api_key
576
- ));
577
- } else {
578
- ShareaholicUtilities::load_template('failed_to_create_api_key_modal');
579
- ShareaholicUtilities::load_template('script_chat');
580
- }
581
- }
582
- }
583
-
584
- /**
585
- * Gets the JWT auth for React UI
586
- */
587
- private static function get_publisher_token() {
588
- $payload = array(
589
- 'site_id' => ShareaholicUtilities::get_option('api_key'),
590
- 'verification_key' => ShareaholicUtilities::get_option('verification_key'),
591
- );
592
-
593
- $response = ShareaholicCurl::post(Shareaholic::API_URL . "/api/v3/sessions", $payload, 'json');
594
-
595
- if ($response && preg_match('/20*/', $response['response']['code'])) {
596
- return $response['body']['publisher_token'];
597
- }
598
- return false;
599
- }
600
-
601
- /**
602
- * The function for the advanced admin section
603
- */
604
- public static function advanced_admin() {
605
- $settings = ShareaholicUtilities::get_settings();
606
-
607
- if (ShareaholicUtilities::has_accepted_terms_of_service()) {
608
- $api_key = ShareaholicUtilities::get_or_create_api_key();
609
- }
610
-
611
- $action = str_replace( '%7E', '~', $_SERVER['REQUEST_URI']);
612
 
613
- if (!ShareaholicUtilities::has_accepted_terms_of_service()) {
614
- ShareaholicUtilities::load_template('terms_of_service_modal', array(
615
- 'image_url' => SHAREAHOLIC_ASSET_DIR . 'img'
616
- ));
617
- }
618
-
619
- if(isset($_POST['reset_settings'])
620
- && $_POST['reset_settings'] == 'Y'
621
- && check_admin_referer($action, 'nonce_field')) {
622
- ShareaholicUtilities::reset_settings();
623
- echo "<div class='updated settings_updated'><p><strong>"
624
- . sprintf(__('Settings successfully reset. Refresh this page to complete the reset.', 'shareaholic'))
625
- . "</strong></p></div>";
626
- }
627
-
628
- if(isset($_POST['already_submitted']) && $_POST['already_submitted'] == 'Y' &&
629
- check_admin_referer($action, 'nonce_field')) {
630
- echo "<div class='updated settings_updated'><p><strong>". sprintf(__('Settings successfully saved', 'shareaholic')) . "</strong></p></div>";
631
-
632
- foreach (array('disable_og_tags', 'disable_admin_bar_menu', 'disable_review_notice', 'disable_debug_info', 'enable_user_nicename','disable_internal_share_counts_api') as $setting) {
633
- if (!isset($_POST['shareaholic'][$setting])) {
634
- // If form value is unchecked, set to off
635
- $_POST['shareaholic'][$setting] = 'off';
636
- }
637
- }
638
-
639
- if (isset($_POST['shareaholic']['api_key']) && $_POST['shareaholic']['api_key'] != $api_key) {
640
- ShareaholicUtilities::get_new_location_name_ids($_POST['shareaholic']['api_key']);
641
- }
642
 
643
- if (isset($_POST['shareaholic']['api_key'])) {
644
- ShareaholicUtilities::update_options(array('api_key' => $_POST['shareaholic']['api_key']));
645
- }
 
 
646
 
647
- if (isset($_POST['shareaholic']['disable_og_tags'])) {
648
- ShareaholicUtilities::update_options(array('disable_og_tags' => $_POST['shareaholic']['disable_og_tags']));
649
- }
650
-
651
- if (isset($_POST['shareaholic']['disable_admin_bar_menu'])) {
652
- ShareaholicUtilities::update_options(array('disable_admin_bar_menu' => $_POST['shareaholic']['disable_admin_bar_menu']));
653
- }
654
-
655
- if (isset($_POST['shareaholic']['disable_review_notice'])) {
656
- ShareaholicUtilities::update_options(array('disable_review_notice' => $_POST['shareaholic']['disable_review_notice']));
657
- }
658
-
659
- if (isset($_POST['shareaholic']['facebook_app_id'])) {
660
- ShareaholicUtilities::update_options(array('facebook_app_id' => sanitize_text_field($_POST['shareaholic']['facebook_app_id'])));
661
- }
662
-
663
- if (isset($_POST['shareaholic']['facebook_app_secret'])) {
664
- ShareaholicUtilities::update_options(array('facebook_app_secret' => sanitize_text_field($_POST['shareaholic']['facebook_app_secret'])));
665
- }
666
-
667
- if (isset($_POST['shareaholic']['disable_debug_info'])) {
668
- ShareaholicUtilities::update_options(array('disable_debug_info' => $_POST['shareaholic']['disable_debug_info']));
669
- }
670
-
671
- if (isset($_POST['shareaholic']['enable_user_nicename'])) {
672
- ShareaholicUtilities::update_options(array('enable_user_nicename' => $_POST['shareaholic']['enable_user_nicename']));
673
- }
674
-
675
- if (isset($_POST['shareaholic']['disable_internal_share_counts_api'])) {
676
- ShareaholicUtilities::update_options(array('disable_internal_share_counts_api' => $_POST['shareaholic']['disable_internal_share_counts_api']));
677
- }
678
-
679
- ShareaholicUtilities::log_event("UpdatedSettings");
680
- // clear cache after settings update
681
- ShareaholicUtilities::clear_cache();
682
- }
683
-
684
- ShareaholicUtilities::load_template('advanced_settings', array(
685
- 'settings' => ShareaholicUtilities::get_settings(),
686
- 'action' => $action
687
- ));
688
- }
689
-
690
- /**
691
- * Outputs the actual html for the form
692
- */
693
- private static function draw_admin_form() {
694
- $action = str_replace( '%7E', '~', $_SERVER['REQUEST_URI']);
695
- $settings = ShareaholicUtilities::get_settings();
696
-
697
- if (!ShareaholicUtilities::has_accepted_terms_of_service()) {
698
- ShareaholicUtilities::load_template('terms_of_service_modal', array(
699
- 'image_url' => SHAREAHOLIC_ASSET_DIR . 'img'
700
- ));
701
- }
702
-
703
- ShareaholicUtilities::load_template('settings', array(
704
- 'shareaholic_url' => Shareaholic::URL,
705
- 'settings' => $settings,
706
- 'action' => $action,
707
- 'share_buttons' => (isset($settings['share_buttons'])) ? $settings['share_buttons'] : array(),
708
- 'recommendations' => (isset($settings['recommendations'])) ? $settings['recommendations'] : array(),
709
- 'directory' => dirname(plugin_basename(__FILE__)),
710
- ));
711
- }
712
-
713
- /**
714
- * This function is in charge the logic for
715
- * showing whatever it is we want to show a user
716
- * about whether they have verified their api
717
- * key or not.
718
- */
719
- private static function draw_verify_api_key() {
720
- if (!ShareaholicUtilities::api_key_verified()) {
721
- $settings = ShareaholicUtilities::get_settings();
722
- $api_key = $settings['api_key'];
723
- $verification_key = $settings['verification_key'];
724
- ShareaholicUtilities::load_template('verify_api_key_js', array(
725
- 'verification_key' => $verification_key
726
- ));
727
- }
728
- }
729
-
730
- /**
731
- * This function is in charge of determining whether to send the "get started" email
732
- */
733
- public static function welcome_email() {
734
- // check whether email has been sent
735
- if (ShareaholicUtilities::get_option('welcome_email_sent') != "y") {
736
- // set flag that the email has been sent
737
- ShareaholicUtilities::update_options(array('welcome_email_sent' => "y"));
738
- // send email
739
- ShareaholicAdmin::send_welcome_email();
740
- }
741
- }
742
-
743
-
744
- /**
745
- * This function is in charge of sending the "get started" email
746
- */
747
- public static function send_welcome_email() {
748
- if (function_exists('wp_mail')) {
749
- $site_url = get_bloginfo('url');
750
- $api_key = ShareaholicUtilities::get_option('api_key');
751
- $payment_url = 'https://www.shareaholic.com/user-settings/payments';
752
- $shr_wp_dashboard_url = esc_url(admin_url("admin.php?page=shareaholic-settings"));
753
- $sign_up_link = esc_url(admin_url("admin.php?shareaholic_redirect_url=shareaholic.com/signup/"));
754
- $to = get_bloginfo('admin_email');
755
- $subject = 'Thank you for installing Shareaholic Plugin for WordPress!';
756
- $message = "
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
757
  <p>Hi there,</p>
758
 
759
  <p>Thank you for installing Shareaholic on $site_url! You are one step closer to growing your website. Completing your set-up is easy, just follow these three easy steps and you'll be ready to go:</p>
@@ -779,39 +823,42 @@ JQUERY;
779
  <img width='200' height='36' src='https://www.shareaholic.com/assets/layouts/shareaholic-logo.png' alt='Shareaholic' title='Shareaholic' /><br />
780
  <p style='font-size:12px;color:#C3C2C2;'>This is an automated, one-time e-mail sent by your WordPress CMS directly to the website admin</p><br />
781
  <img width='0' height='0' src='https://www.google-analytics.com/collect?v=1&tid=UA-12964573-6&cid=$api_key&t=event&ec=email&ea=open&el=$site_url-$api_key&cs=lifecycle&cm=email&cn=wp_welcome_email' />";
782
-
783
- $headers = "From: Shareaholic <hello@shareaholic.com>\r\n";
784
- $headers.= "Reply-To: Shareaholic <hello@shareaholic.com>\r\n";
785
- $headers.= "X-Mailer: PHP/" . phpversion() . "\r\n";
786
- $headers.= "MIME-Version: 1.0\r\n";
787
- $headers.= "Content-type: text/html; charset=utf-8\r\n";
788
-
789
- // Send email
790
- // wp_mail($to, $subject, $message, $headers);
791
- }
792
- }
793
-
794
- /**
795
- * This function adds our custom image type to the Media Library
796
- */
797
- public static function show_custom_sizes($sizes) {
798
- return array_merge($sizes, array(
799
- 'shareaholic-thumbnail' => __('Shareaholic'),
800
- ));
801
- }
802
-
803
- /**
804
- * This function adds a notice to Settings->Permalinks
805
- */
806
- public static function admin_notices() {
807
- $current_screen = get_current_screen();
808
-
809
- if ($current_screen->id === 'options-permalink') {
810
- $css_class = 'notice notice-warning is-dismissible';
811
- $message = 'WARNING: Updating your URL or permalink structure will reset the social share counts for your pages. <a href="https://www.shareaholic.com/plans">Upgrade Shareaholic</a> to enable <a href="https://support.shareaholic.com/hc/en-us/articles/115002083586">Share Count Recovery</a>.';
812
- echo "<div class='$css_class'><p style='font-weight: bold;'>";
813
- _e($message, 'Shareaholic');
814
- echo '</p></div>';
815
- }
816
- }
 
 
 
817
  }
12
  */
13
  class ShareaholicAdmin {
14
 
15
+ const ACTIVATE_TIMESTAMP_OPTION = 'shareaholic_activate_timestamp';
16
+ const REVIEW_DISMISS_OPTION = 'shareaholic_review_notice';
17
+ const REVIEW_FIRST_PERIOD = 518400; // 6 days in seconds
18
+ const REVIEW_LATER_PERIOD = 7776000; // 3 months in seconds
19
+ const REVIEW_FOREVER_PERIOD = 63113904; // 2 years in seconds
20
+
21
+ /**
22
+ * Loads before all else
23
+ */
24
+ public static function admin_init() {
25
+ ShareaholicUtilities::check_for_other_plugin();
26
+ // workaround: http://codex.wordpress.org/Function_Reference/register_activation_hook
27
+ if ( is_admin() && get_option( 'Activated_Plugin_Shareaholic' ) == 'shareaholic' ) {
28
+ delete_option( 'Activated_Plugin_Shareaholic' );
29
+ /* do stuff once right after activation */
30
+ if ( has_action( 'wp_ajax_nopriv_shareaholic_share_counts_api' ) && has_action( 'wp_ajax_shareaholic_share_counts_api' ) ) {
31
+ ShareaholicUtilities::share_counts_api_connectivity_check();
32
+ }
33
+ self::activation_redirect();
34
+ }
35
+
36
+ self::check_redirect_url();
37
+ self::check_review_dismissal();
38
+ self::check_plugin_review();
39
+ }
40
+
41
+ /**
42
+ * Check review notice status for current user
43
+ */
44
+ public static function check_review_dismissal() {
45
+
46
+ global $current_user;
47
+ $user_id = $current_user->ID;
48
+
49
+ if ( ! is_admin() ||
50
+ ! current_user_can( 'publish_posts' ) ||
51
+ ! isset( $_GET['_wpnonce'] ) ||
52
+ ! wp_verify_nonce( $_GET['_wpnonce'], 'review-nonce' ) ||
53
+ ! isset( $_GET['shr_defer_t'] ) ||
54
+ ! isset( $_GET[ self::REVIEW_DISMISS_OPTION ] ) ) {
55
+ return;
56
+ }
57
+
58
+ $the_meta_array = array(
59
+ 'dismiss_defer_period' => $_GET['shr_defer_t'],
60
+ 'dismiss_timestamp' => time(),
61
+ );
62
+
63
+ update_user_meta( $user_id, self::REVIEW_DISMISS_OPTION, $the_meta_array );
64
+ }
65
+
66
+ /**
67
+ * Check if we should display the review notice
68
+ */
69
+ public static function check_plugin_review() {
70
+
71
+ global $current_user;
72
+ $user_id = $current_user->ID;
73
+
74
+ $show_review_notice = false;
75
+ $activation_timestamp = get_site_option( self::ACTIVATE_TIMESTAMP_OPTION );
76
+ $review_dismissal_array = get_user_meta( $user_id, self::REVIEW_DISMISS_OPTION, true );
77
+ $dismiss_defer_period = isset( $review_dismissal_array['dismiss_defer_period'] ) ? $review_dismissal_array['dismiss_defer_period'] : 0;
78
+ $dismiss_timestamp = isset( $review_dismissal_array['dismiss_timestamp'] ) ? $review_dismissal_array['dismiss_timestamp'] : time();
79
+
80
+ if ( $dismiss_timestamp + $dismiss_defer_period <= time() ) {
81
+ $show_review_notice = true;
82
+ }
83
+
84
+ if ( ! $activation_timestamp ) {
85
+ $activation_timestamp = time();
86
+ add_site_option( self::ACTIVATE_TIMESTAMP_OPTION, $activation_timestamp );
87
+ }
88
+
89
+ // display review message after a certain period of time after activation
90
+ if ( ( time() - $activation_timestamp > self::REVIEW_FIRST_PERIOD ) && $show_review_notice == true ) {
91
+ add_action( 'admin_notices', array( 'ShareaholicAdmin', 'display_review_notice' ) );
92
+ }
93
+ }
94
+
95
+ public static function display_review_notice() {
96
+
97
+ if ( ShareaholicUtilities::get_option( 'disable_review_notice' ) == 'on' ) {
98
+ return;
99
+ }
100
+
101
+ $dismiss_forever = add_query_arg(
102
+ array(
103
+ self::REVIEW_DISMISS_OPTION => true,
104
+ 'shr_defer_t' => self::REVIEW_FOREVER_PERIOD,
105
+ )
106
+ );
107
+
108
+ $dismiss_forlater = add_query_arg(
109
+ array(
110
+ self::REVIEW_DISMISS_OPTION => true,
111
+ 'shr_defer_t' => self::REVIEW_LATER_PERIOD,
112
+ )
113
+ );
114
+
115
+ $dismiss_forever_url = wp_nonce_url( $dismiss_forever, 'review-nonce' );
116
+ $dismiss_forlater_url = wp_nonce_url( $dismiss_forlater, 'review-nonce' );
117
+
118
+ echo '
119
  <style>
120
  .shareaholic-review-notice {
121
+ background-size: contain; background-position: right bottom; background-repeat: no-repeat; background-image: url(' . plugins_url( 'assets/img/icon-256x256.png', __FILE__ ) . ');
122
  }
123
  .shareaholic-review-notice-text {
124
  background: rgba(255, 255, 255, 0.9); text-shadow: white 0px 0px 10px; margin-right: 8em !important;
147
  </script>
148
 
149
  <div class="notice notice-info is-dismissible shareaholic-review-notice">
150
+ <p class="shareaholic-review-notice-text">' . __( 'Hey there! We noticed that you have had success using ', 'shareaholic' ) . '<a href="' . admin_url( 'admin.php?page=shareaholic-settings' ) . '">Shareaholic</a>' . __( ' — awesome! Could you please do us a BIG favor and give us a quick 5-star rating on WordPress? It would help us spread the word and boost our motivation. We would really appreciate it 🙂 ~ Your friends @ Shareaholic', 'shareaholic' ) . '
151
  <br />
152
  <br />
153
+ <a onClick="' . "shr_openWindowReload('https://wordpress.org/support/plugin/shareaholic/reviews/?rate=5#new-post', '$dismiss_forever_url')" . '" class="button button-primary">' . __( 'Ok, you deserve it', 'shareaholic' ) . '</a> &nbsp;
154
+ <a href="' . $dismiss_forlater_url . '">' . __( 'No, not good enough', 'shareaholic' ) . '</a> &nbsp;
155
+ <a href="' . $dismiss_forever_url . '">' . __( 'I already did', 'shareaholic' ) . '</a> &nbsp;
156
+ <a href="' . $dismiss_forever_url . '">' . __( 'Dismiss', 'yarpp' ) . '</a>
157
  </p>
158
  </div>';
159
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
 
161
+ /**
162
+ * Sends user to the Settings page on activation of Shareaholic plugin
163
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
+ public static function activation_redirect() {
166
+ // Bail if no activation redirect transient
167
+ if ( ! get_transient( '_shr_activation_redirect' ) ) {
168
+ return;
169
+ }
170
 
171
+ delete_transient( '_shr_activation_redirect' );
172
+
173
+ // Bail if activating from multisite, network, or bulk
174
+ if ( is_multisite() || is_network_admin() || isset( $_GET['activate-multi'] ) ) {
175
+ return;
176
+ }
177
+
178
+ wp_safe_redirect( add_query_arg( array( 'page' => 'shareaholic-settings' ), admin_url( 'admin.php' ) ) );
179
+ }
180
+
181
+
182
+ /**
183
+ * Redirect to Plans
184
+ */
185
+ public static function go_premium() {
186
+ $api_key = ShareaholicUtilities::get_option( 'api_key' );
187
+ echo <<<JQUERY
188
+ <script type="text/javascript">
189
+ window.location = "https://www.shareaholic.com/plans?siteID=$api_key";
190
+ </script>
191
+ JQUERY;
192
+ }
193
+
194
+ /**
195
+ * Redirection Utility (used by SDK - Badge)
196
+ */
197
+ public static function check_redirect_url() {
198
+
199
+ $redirect_url = isset( $_GET['shareaholic_redirect_url'] ) ? strtolower( $_GET['shareaholic_redirect_url'] ) : null;
200
+
201
+ if ( $redirect_url != null ) {
202
+
203
+ // Support redirect URLs with no scheme; default to httpS
204
+ $parsed = parse_url( $redirect_url );
205
+ if ( empty( $parsed['scheme'] ) ) {
206
+ $redirect_url = 'https://' . ltrim( $redirect_url );
207
+ }
208
+
209
+ // exit if redirect is not to shareaholic.com
210
+ $redirect_url_host = parse_url( $redirect_url, PHP_URL_HOST );
211
+
212
+ if ( $redirect_url_host != 'shareaholic.com' && $redirect_url_host != 'stageaholic.com' && $redirect_url_host != 'spreadaholic.com' ) {
213
+ wp_redirect( admin_url( 'admin.php?page=shareaholic-settings' ) );
214
+ exit;
215
+ }
216
+
217
+ // Get User Email
218
+ if ( function_exists( 'wp_get_current_user' ) ) {
219
+ $current_user = wp_get_current_user();
220
+ $user_email = urlencode( $current_user->user_email );
221
+ } else {
222
+ $user_email = '';
223
+ }
224
+
225
+ // Pass verification_key only if current wp user has permission to the key
226
+ if ( current_user_can( 'activate_plugins' ) ) {
227
+ $verification_key = ShareaholicUtilities::get_option( 'verification_key' );
228
+ } else {
229
+ $verification_key = 'unauthorized';
230
+ }
231
+
232
+ $enriched_redirect_url = add_query_arg(
233
+ array(
234
+ 'site_id' => ShareaholicUtilities::get_option( 'api_key' ),
235
+ 'verification_key' => $verification_key,
236
+ 'email' => $user_email,
237
+ 'ref' => 'wordpress',
238
+ ),
239
+ $redirect_url
240
+ );
241
+
242
+ wp_redirect( $enriched_redirect_url );
243
+ exit;
244
+ }
245
+ }
246
+
247
+ /**
248
+ * The function called during the admin_head action.
249
+ */
250
+ public static function admin_header() {
251
+ self::include_remote_js();
252
+ }
253
+
254
+ /**
255
+ * Load the terms of service notice that shows up
256
+ * at the top of the admin pages.
257
+ */
258
+ public static function show_terms_of_service() {
259
+ ShareaholicUtilities::load_template( 'terms_of_service_notice' );
260
+ }
261
+
262
+ /**
263
+ * Renders footer
264
+ */
265
+ public static function show_footer() {
266
+ ShareaholicUtilities::load_template( 'footer' );
267
+ }
268
+
269
+ /**
270
+ * Renders header
271
+ */
272
+ public static function show_header() {
273
+ $settings = ShareaholicUtilities::get_settings();
274
+ $settings['base_link'] = Shareaholic::URL . '/publisher_tools/' . $settings['api_key'] . '/';
275
+ ShareaholicUtilities::load_template(
276
+ 'header',
277
+ array(
278
+ 'settings' => $settings,
279
+ )
280
+ );
281
+ }
282
+
283
+ /**
284
+ * Renders Chat
285
+ */
286
+ public static function include_chat() {
287
+ ShareaholicUtilities::load_template( 'script_chat' );
288
+ }
289
+
290
+ /**
291
+ * Adds meta boxes for post and page options
292
+ */
293
+ public static function add_meta_boxes() {
294
+ $post_types = get_post_types();
295
+ // $post_types = array( 'post', 'page', 'product' );
296
+ foreach ( $post_types as $post_type ) {
297
+ add_meta_box(
298
+ 'shareaholic',
299
+ 'Shareaholic',
300
+ array( 'ShareaholicAdmin', 'meta_box' ),
301
+ $post_type,
302
+ 'side',
303
+ 'low'
304
+ );
305
+ }
306
+ }
307
+
308
+ /**
309
+ * This is the wp ajax callback for when a user
310
+ * checks a checkbox for a location that doesn't
311
+ * already have a location_id. After it has been
312
+ * successfully created the id needs to be stored,
313
+ * which is what this method does.
314
+ */
315
+ public static function add_location() {
316
+ $location = $_POST['location'];
317
+ $app_name = $location['app_name'];
318
+
319
+ // if location id is not numeric throw bad request
320
+ // or user lacks permissions
321
+ // or does not have the nonce token
322
+ // otherwise forcibly change it to a number
323
+ if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'shareaholic_add_location' ) ||
324
+ ! current_user_can( 'publish_posts' ) || ! is_numeric( $location['id'] ) ) {
325
+ header( 'HTTP/1.1 400 Bad Request', true, 400 );
326
+ die();
327
+ } else {
328
+ $location['id'] = intval( $location['id'] );
329
+ }
330
+
331
+ ShareaholicUtilities::update_options(
332
+ array(
333
+ 'location_name_ids' => array(
334
+ $app_name => array(
335
+ $location['name'] => $location['id'],
336
+ ),
337
+ ),
338
+ $app_name => array(
339
+ $location['name'] => 'on',
340
+ ),
341
+ )
342
+ );
343
+
344
+ echo json_encode(
345
+ array(
346
+ 'status' => "successfully created a new {$location['app_name']} location",
347
+ 'id' => $location['id'],
348
+ )
349
+ );
350
+
351
+ die();
352
+ }
353
+
354
+ /**
355
+ * Shows the message about failing to create an api key
356
+ */
357
+ public static function failed_to_create_api_key() {
358
+ // ShareaholicUtilities::load_template('failed_to_create_api_key');
359
+ if ( isset( $_GET['page'] ) && preg_match( '/shareaholic-settings/', $_GET['page'] ) ) {
360
+ ShareaholicUtilities::load_template( 'failed_to_create_api_key_modal' );
361
+ }
362
+ }
363
+
364
+ /**
365
+ * The actual function in charge of drawing the meta boxes.
366
+ */
367
+ public static function meta_box() {
368
+ global $post;
369
+ $settings = ShareaholicUtilities::get_settings();
370
+ ShareaholicUtilities::load_template(
371
+ 'meta_boxes',
372
+ array(
373
+ 'settings' => $settings,
374
+ 'post' => $post,
375
+ )
376
+ );
377
+ }
378
+
379
+ /**
380
+ * This function fires when a post is saved
381
+ *
382
+ * @param int $post_id
383
+ */
384
+ public static function save_post( $post_id ) {
385
+ // WordPress does something silly where save_post is fired twice,
386
+ // once with the id of a revision and once with the actual id. This
387
+ // filters out revision ids (which we don't want)
388
+ if ( ! wp_is_post_revision( $post_id ) ) {
389
+ self::disable_post_attributes( $post_id );
390
+ }
391
+ }
392
+
393
+ /**
394
+ * For each of the things that a user can disable or exclude per post,
395
+ * we iterate through and turn add the post meta, or make it false
396
+ * if it *used* to be true, but did not come through in $_POST
397
+ * (because unchecked boxes are not submitted).
398
+ *
399
+ * @param int $post_id
400
+ */
401
+ private static function disable_post_attributes( $post_id ) {
402
+ foreach ( array(
403
+ 'disable_share_buttons',
404
+ 'disable_open_graph_tags',
405
+ 'exclude_recommendations',
406
+ 'disable_recommendations',
407
+ ) as $attribute ) {
408
+ $key = 'shareaholic_' . $attribute;
409
+ if ( isset( $_POST['shareaholic'][ $attribute ] ) &&
410
+ $_POST['shareaholic'][ $attribute ] == 'on' ) {
411
+ update_post_meta( $post_id, $key, true );
412
+ } elseif ( get_post_meta( $post_id, $key, true ) ) {
413
+ update_post_meta( $post_id, $key, false );
414
+ }
415
+ }
416
+ }
417
+
418
+ /**
419
+ * Enqueue local styles and scripts for the admin panel
420
+ *
421
+ * @since 7.0.2.0
422
+ */
423
+ public static function enqueue_scripts() {
424
+ // Exclude from React powered page
425
+ if ( isset( $_GET['page'] ) && preg_match( '/shareaholic/', $_GET['page'] ) && $_GET['page'] !== 'shareaholic-settings' ) {
426
+ wp_enqueue_style( 'shareaholic_bootstrap_css', plugins_url( 'assets/css/bootstrap.css', __FILE__ ), false, ShareaholicUtilities::get_version() );
427
+ wp_enqueue_script( 'shareholic_bootstrap_js', plugins_url( 'assets/js/bootstrap.min.js', __FILE__ ), false, ShareaholicUtilities::get_version() );
428
+ }
429
+
430
+ if ( isset( $_GET['page'] ) && preg_match( '/shareaholic/', $_GET['page'] ) ) {
431
+ wp_enqueue_style( 'shareaholic_common_css', plugins_url( 'assets/css/common.css', __FILE__ ), false, ShareaholicUtilities::get_version() );
432
+ wp_enqueue_style( 'shareaholic_reveal_css', plugins_url( 'assets/css/reveal.css', __FILE__ ), false, ShareaholicUtilities::get_version() );
433
+ wp_enqueue_style( 'shareaholic_main_css', plugins_url( 'assets/css/main.css', __FILE__ ), false, ShareaholicUtilities::get_version() );
434
+ wp_enqueue_script( 'shareholic_jquery_custom_js', plugins_url( 'assets/js/jquery_custom.js', __FILE__ ), false, ShareaholicUtilities::get_version() );
435
+ wp_enqueue_script( 'shareholic_jquery_ui_custom_js', plugins_url( 'assets/js/jquery_ui_custom.js', __FILE__ ), array( 'shareholic_jquery_custom_js' ), ShareaholicUtilities::get_version() );
436
+ wp_enqueue_script( 'shareholic_modified_reveal_js', plugins_url( 'assets/js/jquery.reveal.modified.js', __FILE__ ), array( 'shareholic_jquery_custom_js', 'shareholic_jquery_ui_custom_js' ), ShareaholicUtilities::get_version() );
437
+ wp_enqueue_script( 'shareholic_main_js', plugins_url( 'assets/js/main.js', __FILE__ ), false, ShareaholicUtilities::get_version() );
438
+ }
439
+ }
440
+
441
+ /**
442
+ * Include remote styles and scripts for the admin panel.
443
+ *
444
+ * This addresses a conflict with 3rd party plugins that force modify the paths of
445
+ * scripts that are passed through to wp_enqueue_script
446
+ *
447
+ * @since 8.12.1
448
+ */
449
+ public static function include_remote_js() {
450
+ if ( isset( $_GET['page'] ) && preg_match( '/shareaholic/', $_GET['page'] ) ) {
451
+ echo "\n<script src='" . ShareaholicUtilities::asset_url_admin( 'assets/pub/utilities.js' ) . '?' . ShareaholicUtilities::get_version() . "'></script>\n";
452
+ }
453
+ }
454
+
455
+ /**
456
+ * Puts a new menu item under Settings.
457
+ */
458
+ public static function admin_menu() {
459
+ $icon_svg = ShareaholicUtilities::get_icon_svg();
460
+ $notification_icon = '';
461
+
462
+ if ( ! ShareaholicUtilities::get_option( 'api_key' ) ) {
463
+ $notification_icon = ' <span class="update-plugins count-1"><span class="plugin-count">!</span></span>';
464
+ }
465
+
466
+ add_menu_page(
467
+ __( 'Shareaholic Settings', 'shareaholic' ),
468
+ __( 'Shareaholic', 'shareaholic' ) . $notification_icon,
469
+ 'manage_options',
470
+ 'shareaholic-settings',
471
+ array( 'ShareaholicAdmin', 'admin' ),
472
+ $icon_svg
473
+ );
474
+ add_submenu_page(
475
+ 'shareaholic-settings',
476
+ __( 'Dashboard', 'shareaholic' ),
477
+ __( 'Dashboard', 'shareaholic' ),
478
+ 'manage_options',
479
+ 'shareaholic-settings',
480
+ array( 'ShareaholicAdmin', 'admin' )
481
+ );
482
+ add_submenu_page(
483
+ 'shareaholic-settings',
484
+ __( 'Dashboard [legacy]', 'shareaholic' ),
485
+ __( 'Dashboard [legacy]', 'shareaholic' ),
486
+ 'manage_options',
487
+ 'shareaholic-settings-legacy',
488
+ array( 'ShareaholicAdmin', 'admin_legacy' )
489
+ );
490
+ add_submenu_page(
491
+ 'shareaholic-settings',
492
+ __( 'Settings', 'shareaholic' ),
493
+ __( 'Settings', 'shareaholic' ),
494
+ 'manage_options',
495
+ 'shareaholic-advanced',
496
+ array( 'ShareaholicAdmin', 'advanced_admin' )
497
+ );
498
+ add_submenu_page(
499
+ 'shareaholic-settings',
500
+ __( 'Upgrade', 'shareaholic' ),
501
+ __( '<span style="color: #FCB214;">Upgrade</span>', 'shareaholic' ),
502
+ 'activate_plugins',
503
+ 'shareaholic-premium',
504
+ array( 'ShareaholicAdmin', 'go_premium' )
505
+ );
506
+ }
507
+
508
+ /**
509
+ * Updates the information if passed in and sets save message.
510
+ */
511
+ public static function admin_legacy() {
512
+ $settings = ShareaholicUtilities::get_settings();
513
+ $action = str_replace( '%7E', '~', $_SERVER['REQUEST_URI'] );
514
+ if ( isset( $_POST['already_submitted'] ) && $_POST['already_submitted'] == 'Y' &&
515
+ check_admin_referer( $action, 'nonce_field' ) ) {
516
+ echo "<div class='updated settings_updated'><p><strong>" . sprintf( __( 'Settings successfully saved', 'shareaholic' ) ) . '</strong></p></div>';
517
+
518
+ /*
519
+ * only checked check boxes are submitted, so we have to iterate
520
+ * through the existing app locations and if they exist in the settings
521
+ * but not in $_POST, it must have been unchecked, and it
522
+ * should be set to 'off'
523
+ */
524
+ foreach ( array( 'share_buttons', 'recommendations' ) as $app ) {
525
+ if ( isset( $settings[ $app ] ) ) {
526
+ foreach ( $settings[ $app ] as $location => $on ) {
527
+ if ( ! isset( $_POST[ $app ][ $location ] ) && $on == 'on' ) {
528
+ $_POST[ $app ][ $location ] = 'off';
529
+ }
530
+ }
531
+ }
532
+ if ( ! isset( $_POST[ $app ] ) ) {
533
+ $_POST[ $app ] = array();
534
+ }
535
+ }
536
+
537
+ foreach ( array( 'share_buttons_display_on_excerpts', 'recommendations_display_on_excerpts' ) as $setting ) {
538
+ if ( isset( $settings[ $setting ] ) &&
539
+ ! isset( $_POST['shareaholic'][ $setting ] ) &&
540
+ $settings[ $setting ] == 'on' ) {
541
+ $_POST['shareaholic'][ $setting ] = 'off';
542
+ } elseif ( ! isset( $_POST['shareaholic'][ $setting ] ) ) {
543
+ $_POST['shareaholic'][ $setting ] = array();
544
+ }
545
+ }
546
+
547
+ // Save "Locations" related preferences
548
+ ShareaholicUtilities::update_options(
549
+ array(
550
+ 'share_buttons' => $_POST['share_buttons'],
551
+ 'recommendations' => $_POST['recommendations'],
552
+ )
553
+ );
554
+
555
+ // Save "Excerpts" related preferences
556
+ if ( isset( $_POST['shareaholic']['share_buttons_display_on_excerpts'] ) ) {
557
+ ShareaholicUtilities::update_options( array( 'share_buttons_display_on_excerpts' => $_POST['shareaholic']['share_buttons_display_on_excerpts'] ) );
558
+ }
559
+ if ( isset( $_POST['shareaholic']['recommendations_display_on_excerpts'] ) ) {
560
+ ShareaholicUtilities::update_options( array( 'recommendations_display_on_excerpts' => $_POST['shareaholic']['recommendations_display_on_excerpts'] ) );
561
+ }
562
+
563
+ ShareaholicUtilities::log_event( 'UpdatedSettings' );
564
+ // clear cache after settings update
565
+ ShareaholicUtilities::clear_cache();
566
+ }
567
+
568
+ /*
569
+ * Just in case they've added new settings on shareaholic.com
570
+ */
571
+ if ( ShareaholicUtilities::has_accepted_terms_of_service() ) {
572
+ $api_key = ShareaholicUtilities::get_or_create_api_key();
573
+ ShareaholicUtilities::get_new_location_name_ids( $api_key );
574
+ }
575
+
576
+ self::draw_admin_form();
577
+ self::draw_verify_api_key();
578
+ }
579
+
580
+ /**
581
+ * The function for the App Manager Tab
582
+ */
583
+ public static function admin() {
584
+
585
+ if ( ! ShareaholicUtilities::has_accepted_terms_of_service() ) {
586
+ ShareaholicUtilities::load_template(
587
+ 'terms_of_service_modal',
588
+ array(
589
+ 'image_url' => SHAREAHOLIC_ASSET_DIR . 'img',
590
+ )
591
+ );
592
+ }
593
+
594
+ if ( ShareaholicUtilities::has_accepted_terms_of_service() ) {
595
+ $api_key = ShareaholicUtilities::get_or_create_api_key();
596
+ $jwt = self::get_publisher_token();
597
+
598
+ if ( $jwt ) {
599
+ ShareaholicUtilities::load_template(
600
+ 'admin',
601
+ array(
602
+ 'jwt' => $jwt,
603
+ 'api_key' => $api_key,
604
+ )
605
+ );
606
+ } else {
607
+ ShareaholicUtilities::load_template( 'failed_to_create_api_key_modal' );
608
+ ShareaholicUtilities::load_template( 'script_chat' );
609
+ }
610
+ }
611
+ }
612
+
613
+ /**
614
+ * Gets the JWT auth for React UI
615
+ */
616
+ private static function get_publisher_token() {
617
+ $payload = array(
618
+ 'site_id' => ShareaholicUtilities::get_option( 'api_key' ),
619
+ 'verification_key' => ShareaholicUtilities::get_option( 'verification_key' ),
620
+ );
621
+
622
+ $response = ShareaholicCurl::post( Shareaholic::API_URL . '/api/v3/sessions', $payload, 'json' );
623
+
624
+ if ( $response && preg_match( '/20*/', $response['response']['code'] ) ) {
625
+ return $response['body']['publisher_token'];
626
+ }
627
+ return false;
628
+ }
629
+
630
+ /**
631
+ * The function for the advanced admin section
632
+ */
633
+ public static function advanced_admin() {
634
+ $settings = ShareaholicUtilities::get_settings();
635
+
636
+ if ( ShareaholicUtilities::has_accepted_terms_of_service() ) {
637
+ $api_key = ShareaholicUtilities::get_or_create_api_key();
638
+ }
639
+
640
+ $action = str_replace( '%7E', '~', $_SERVER['REQUEST_URI'] );
641
+
642
+ if ( ! ShareaholicUtilities::has_accepted_terms_of_service() ) {
643
+ ShareaholicUtilities::load_template(
644
+ 'terms_of_service_modal',
645
+ array(
646
+ 'image_url' => SHAREAHOLIC_ASSET_DIR . 'img',
647
+ )
648
+ );
649
+ }
650
+
651
+ if ( isset( $_POST['reset_settings'] )
652
+ && $_POST['reset_settings'] == 'Y'
653
+ && check_admin_referer( $action, 'nonce_field' ) ) {
654
+ ShareaholicUtilities::reset_settings();
655
+ echo "<div class='updated settings_updated'><p><strong>"
656
+ . sprintf( __( 'Settings successfully reset. Refresh this page to complete the reset.', 'shareaholic' ) )
657
+ . '</strong></p></div>';
658
+ }
659
+
660
+ if ( isset( $_POST['already_submitted'] ) && $_POST['already_submitted'] == 'Y' &&
661
+ check_admin_referer( $action, 'nonce_field' ) ) {
662
+ echo "<div class='updated settings_updated'><p><strong>" . sprintf( __( 'Settings successfully saved', 'shareaholic' ) ) . '</strong></p></div>';
663
+
664
+ foreach ( array( 'disable_og_tags', 'disable_admin_bar_menu', 'disable_review_notice', 'disable_debug_info', 'enable_user_nicename', 'disable_internal_share_counts_api' ) as $setting ) {
665
+ if ( ! isset( $_POST['shareaholic'][ $setting ] ) ) {
666
+ // If form value is unchecked, set to off
667
+ $_POST['shareaholic'][ $setting ] = 'off';
668
+ }
669
+ }
670
+
671
+ if ( isset( $_POST['shareaholic']['api_key'] ) && $_POST['shareaholic']['api_key'] != $api_key ) {
672
+ ShareaholicUtilities::get_new_location_name_ids( $_POST['shareaholic']['api_key'] );
673
+ }
674
+
675
+ if ( isset( $_POST['shareaholic']['api_key'] ) ) {
676
+ ShareaholicUtilities::update_options( array( 'api_key' => $_POST['shareaholic']['api_key'] ) );
677
+ }
678
+
679
+ if ( isset( $_POST['shareaholic']['disable_og_tags'] ) ) {
680
+ ShareaholicUtilities::update_options( array( 'disable_og_tags' => $_POST['shareaholic']['disable_og_tags'] ) );
681
+ }
682
+
683
+ if ( isset( $_POST['shareaholic']['disable_admin_bar_menu'] ) ) {
684
+ ShareaholicUtilities::update_options( array( 'disable_admin_bar_menu' => $_POST['shareaholic']['disable_admin_bar_menu'] ) );
685
+ }
686
+
687
+ if ( isset( $_POST['shareaholic']['disable_review_notice'] ) ) {
688
+ ShareaholicUtilities::update_options( array( 'disable_review_notice' => $_POST['shareaholic']['disable_review_notice'] ) );
689
+ }
690
+
691
+ if ( isset( $_POST['shareaholic']['facebook_app_id'] ) ) {
692
+ ShareaholicUtilities::update_options( array( 'facebook_app_id' => sanitize_text_field( $_POST['shareaholic']['facebook_app_id'] ) ) );
693
+ }
694
+
695
+ if ( isset( $_POST['shareaholic']['facebook_app_secret'] ) ) {
696
+ ShareaholicUtilities::update_options( array( 'facebook_app_secret' => sanitize_text_field( $_POST['shareaholic']['facebook_app_secret'] ) ) );
697
+ }
698
+
699
+ if ( isset( $_POST['shareaholic']['disable_debug_info'] ) ) {
700
+ ShareaholicUtilities::update_options( array( 'disable_debug_info' => $_POST['shareaholic']['disable_debug_info'] ) );
701
+ }
702
+
703
+ if ( isset( $_POST['shareaholic']['enable_user_nicename'] ) ) {
704
+ ShareaholicUtilities::update_options( array( 'enable_user_nicename' => $_POST['shareaholic']['enable_user_nicename'] ) );
705
+ }
706
+
707
+ if ( isset( $_POST['shareaholic']['disable_internal_share_counts_api'] ) ) {
708
+ ShareaholicUtilities::update_options( array( 'disable_internal_share_counts_api' => $_POST['shareaholic']['disable_internal_share_counts_api'] ) );
709
+ }
710
+
711
+ ShareaholicUtilities::log_event( 'UpdatedSettings' );
712
+ // clear cache after settings update
713
+ ShareaholicUtilities::clear_cache();
714
+ }
715
+
716
+ ShareaholicUtilities::load_template(
717
+ 'advanced_settings',
718
+ array(
719
+ 'settings' => ShareaholicUtilities::get_settings(),
720
+ 'action' => $action,
721
+ )
722
+ );
723
+ }
724
+
725
+ /**
726
+ * Outputs the actual html for the form
727
+ */
728
+ private static function draw_admin_form() {
729
+ $action = str_replace( '%7E', '~', $_SERVER['REQUEST_URI'] );
730
+ $settings = ShareaholicUtilities::get_settings();
731
+
732
+ if ( ! ShareaholicUtilities::has_accepted_terms_of_service() ) {
733
+ ShareaholicUtilities::load_template(
734
+ 'terms_of_service_modal',
735
+ array(
736
+ 'image_url' => SHAREAHOLIC_ASSET_DIR . 'img',
737
+ )
738
+ );
739
+ }
740
+
741
+ ShareaholicUtilities::load_template(
742
+ 'settings',
743
+ array(
744
+ 'shareaholic_url' => Shareaholic::URL,
745
+ 'settings' => $settings,
746
+ 'action' => $action,
747
+ 'share_buttons' => ( isset( $settings['share_buttons'] ) ) ? $settings['share_buttons'] : array(),
748
+ 'recommendations' => ( isset( $settings['recommendations'] ) ) ? $settings['recommendations'] : array(),
749
+ 'directory' => dirname( plugin_basename( __FILE__ ) ),
750
+ )
751
+ );
752
+ }
753
+
754
+ /**
755
+ * This function is in charge the logic for
756
+ * showing whatever it is we want to show a user
757
+ * about whether they have verified their api
758
+ * key or not.
759
+ */
760
+ private static function draw_verify_api_key() {
761
+ if ( ! ShareaholicUtilities::api_key_verified() ) {
762
+ $settings = ShareaholicUtilities::get_settings();
763
+ $api_key = $settings['api_key'];
764
+ $verification_key = $settings['verification_key'];
765
+ ShareaholicUtilities::load_template(
766
+ 'verify_api_key_js',
767
+ array(
768
+ 'verification_key' => $verification_key,
769
+ )
770
+ );
771
+ }
772
+ }
773
+
774
+ /**
775
+ * This function is in charge of determining whether to send the "get started" email
776
+ */
777
+ public static function welcome_email() {
778
+ // check whether email has been sent
779
+ if ( ShareaholicUtilities::get_option( 'welcome_email_sent' ) != 'y' ) {
780
+ // set flag that the email has been sent
781
+ ShareaholicUtilities::update_options( array( 'welcome_email_sent' => 'y' ) );
782
+ // send email
783
+ self::send_welcome_email();
784
+ }
785
+ }
786
+
787
+
788
+ /**
789
+ * This function is in charge of sending the "get started" email
790
+ */
791
+ public static function send_welcome_email() {
792
+ if ( function_exists( 'wp_mail' ) ) {
793
+ $site_url = get_bloginfo( 'url' );
794
+ $api_key = ShareaholicUtilities::get_option( 'api_key' );
795
+ $payment_url = 'https://www.shareaholic.com/user-settings/payments';
796
+ $shr_wp_dashboard_url = esc_url( admin_url( 'admin.php?page=shareaholic-settings' ) );
797
+ $sign_up_link = esc_url( admin_url( 'admin.php?shareaholic_redirect_url=shareaholic.com/signup/' ) );
798
+ $to = get_bloginfo( 'admin_email' );
799
+ $subject = 'Thank you for installing Shareaholic Plugin for WordPress!';
800
+ $message = "
801
  <p>Hi there,</p>
802
 
803
  <p>Thank you for installing Shareaholic on $site_url! You are one step closer to growing your website. Completing your set-up is easy, just follow these three easy steps and you'll be ready to go:</p>
823
  <img width='200' height='36' src='https://www.shareaholic.com/assets/layouts/shareaholic-logo.png' alt='Shareaholic' title='Shareaholic' /><br />
824
  <p style='font-size:12px;color:#C3C2C2;'>This is an automated, one-time e-mail sent by your WordPress CMS directly to the website admin</p><br />
825
  <img width='0' height='0' src='https://www.google-analytics.com/collect?v=1&tid=UA-12964573-6&cid=$api_key&t=event&ec=email&ea=open&el=$site_url-$api_key&cs=lifecycle&cm=email&cn=wp_welcome_email' />";
826
+
827
+ $headers = "From: Shareaholic <hello@shareaholic.com>\r\n";
828
+ $headers .= "Reply-To: Shareaholic <hello@shareaholic.com>\r\n";
829
+ $headers .= 'X-Mailer: PHP/' . phpversion() . "\r\n";
830
+ $headers .= "MIME-Version: 1.0\r\n";
831
+ $headers .= "Content-type: text/html; charset=utf-8\r\n";
832
+
833
+ // Send email
834
+ // wp_mail($to, $subject, $message, $headers);
835
+ }
836
+ }
837
+
838
+ /**
839
+ * This function adds our custom image type to the Media Library
840
+ */
841
+ public static function show_custom_sizes( $sizes ) {
842
+ return array_merge(
843
+ $sizes,
844
+ array(
845
+ 'shareaholic-thumbnail' => __( 'Shareaholic' ),
846
+ )
847
+ );
848
+ }
849
+
850
+ /**
851
+ * This function adds a notice to Settings->Permalinks
852
+ */
853
+ public static function admin_notices() {
854
+ $current_screen = get_current_screen();
855
+
856
+ if ( $current_screen->id === 'options-permalink' ) {
857
+ $css_class = 'notice notice-warning is-dismissible';
858
+ $message = 'WARNING: Updating your URL or permalink structure will reset the social share counts for your pages. <a href="https://www.shareaholic.com/plans">Upgrade Shareaholic</a> to enable <a href="https://support.shareaholic.com/hc/en-us/articles/115002083586">Share Count Recovery</a>.';
859
+ echo "<div class='$css_class'><p style='font-weight: bold;'>";
860
+ _e( $message, 'Shareaholic' );
861
+ echo '</p></div>';
862
+ }
863
+ }
864
  }
assets/css/main.css CHANGED
@@ -12,6 +12,10 @@ body {
12
  text-decoration: none;
13
  }
14
 
 
 
 
 
15
  .container-fluid {
16
  padding: 0px;
17
  clear: both;
12
  text-decoration: none;
13
  }
14
 
15
+ .btn-dark {
16
+ color: #fff !important;
17
+ }
18
+
19
  .container-fluid {
20
  padding: 0px;
21
  clear: both;
content_manager.php CHANGED
@@ -12,6 +12,6 @@
12
  */
13
  class ShareaholicContentManager {
14
 
15
- }
16
-
17
- ?>
12
  */
13
  class ShareaholicContentManager {
14
 
15
+ }
16
+
17
+
cron.php CHANGED
@@ -12,86 +12,90 @@
12
  */
13
  class ShareaholicCron {
14
 
15
- /**
16
- * Schedules the cron jobs if it does not exist
17
- */
18
- public static function activate() {
19
-
20
- // Transient Cleanup
21
- if (!wp_next_scheduled('shareaholic_remove_transients_hourly')) {
22
- // schedule the first occurrence 1 min from now
23
- wp_schedule_event(
24
- time() + 60, 'hourly', 'shareaholic_remove_transients_hourly'
25
- );
26
- ShareaholicUtilities::log('Cron: shareaholic_remove_transients_hourly is now scheduled');
27
- } else {
28
- ShareaholicUtilities::log('Cron: shareaholic_remove_transients_hourly is already scheduled');
29
- }
30
 
31
- // Content Sync Heartbeat
32
- if (!wp_next_scheduled('shareaholic_heartbeat')) {
33
- wp_schedule_event(
34
- time() + rand(1, 60), 'daily', 'shareaholic_heartbeat'
35
- );
36
- ShareaholicUtilities::log('Cron: shareaholic_heartbeat is now scheduled');
37
- } else {
38
- ShareaholicUtilities::log('Cron: shareaholic_heartbeat is already scheduled');
39
- }
40
- }
 
 
41
 
42
- /**
43
- * Remove scheduled cron jobs created by Shareaholic
44
- */
45
- public static function deactivate() {
46
- if (wp_next_scheduled('shareaholic_remove_transients_hourly')) {
47
- wp_clear_scheduled_hook('shareaholic_remove_transients_hourly');
48
- ShareaholicUtilities::log('Cron: shareaholic_remove_transients_hourly cleared');
49
- } else {
50
- ShareaholicUtilities::log('Cron: no need to clear shareaholic_remove_transients_hourly schedule');
51
- }
52
-
53
- if (wp_next_scheduled('shareaholic_heartbeat')) {
54
- wp_clear_scheduled_hook('shareaholic_heartbeat');
55
- ShareaholicUtilities::log('Cron: shareaholic_heartbeat cleared');
56
- } else {
57
- ShareaholicUtilities::log('Cron: no need to clear shareaholic_heartbeat schedule');
58
- }
59
- }
60
 
61
- public static function heartbeat() {
62
- if (ShareaholicUtilities::has_accepted_terms_of_service()) {
63
- ShareaholicUtilities::heartbeat();
64
- }
65
- }
 
 
 
 
 
66
 
67
- /**
68
- * A job that clears up the shareaholic share counts transients
69
- */
70
- public static function remove_transients() {
71
- global $wpdb;
72
- $older_than = time() - (60 * 60); // older than an hour ago
 
73
 
74
- ShareaholicUtilities::log('Start of Shareaholic transient cleanup');
 
 
 
 
75
 
76
- $query = "SELECT REPLACE(option_name, '_transient_timeout_', '') AS transient_name FROM {$wpdb->options} WHERE option_name LIKE '\_transient\_timeout\_shr\_api\_res-%%' AND option_value < %s LIMIT 5000";
77
- $transients = $wpdb->get_col($wpdb->prepare($query, $older_than));
 
 
 
 
78
 
79
- $options_names = array();
80
- foreach($transients as $transient) {
81
- $options_names[] = esc_sql('_transient_' . $transient);
82
- $options_names[] = esc_sql('_transient_timeout_' . $transient);
83
- }
84
- if ($options_names) {
85
- $options_names = "'" . implode("','", $options_names) . "'";
86
- $result = $wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name IN ({$options_names})");
87
 
88
- if (!$result) {
89
- ShareaholicUtilities::log('Transient Query Error!');
90
- }
91
- }
92
- // Cleanup leftover mutex
93
- ShareaholicUtilities::delete_mutex();
94
-
95
- ShareaholicUtilities::log('End of Shareaholic transient cleanup');
96
- }
97
- }
 
 
 
 
 
 
 
 
 
 
 
 
12
  */
13
  class ShareaholicCron {
14
 
15
+ /**
16
+ * Schedules the cron jobs if it does not exist
17
+ */
18
+ public static function activate() {
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ // Transient Cleanup
21
+ if ( ! wp_next_scheduled( 'shareaholic_remove_transients_hourly' ) ) {
22
+ // schedule the first occurrence 1 min from now
23
+ wp_schedule_event(
24
+ time() + 60,
25
+ 'hourly',
26
+ 'shareaholic_remove_transients_hourly'
27
+ );
28
+ ShareaholicUtilities::log( 'Cron: shareaholic_remove_transients_hourly is now scheduled' );
29
+ } else {
30
+ ShareaholicUtilities::log( 'Cron: shareaholic_remove_transients_hourly is already scheduled' );
31
+ }
32
 
33
+ // Content Sync Heartbeat
34
+ if ( ! wp_next_scheduled( 'shareaholic_heartbeat' ) ) {
35
+ wp_schedule_event(
36
+ time() + rand( 1, 60 ),
37
+ 'daily',
38
+ 'shareaholic_heartbeat'
39
+ );
40
+ ShareaholicUtilities::log( 'Cron: shareaholic_heartbeat is now scheduled' );
41
+ } else {
42
+ ShareaholicUtilities::log( 'Cron: shareaholic_heartbeat is already scheduled' );
43
+ }
44
+ }
 
 
 
 
 
 
45
 
46
+ /**
47
+ * Remove scheduled cron jobs created by Shareaholic
48
+ */
49
+ public static function deactivate() {
50
+ if ( wp_next_scheduled( 'shareaholic_remove_transients_hourly' ) ) {
51
+ wp_clear_scheduled_hook( 'shareaholic_remove_transients_hourly' );
52
+ ShareaholicUtilities::log( 'Cron: shareaholic_remove_transients_hourly cleared' );
53
+ } else {
54
+ ShareaholicUtilities::log( 'Cron: no need to clear shareaholic_remove_transients_hourly schedule' );
55
+ }
56
 
57
+ if ( wp_next_scheduled( 'shareaholic_heartbeat' ) ) {
58
+ wp_clear_scheduled_hook( 'shareaholic_heartbeat' );
59
+ ShareaholicUtilities::log( 'Cron: shareaholic_heartbeat cleared' );
60
+ } else {
61
+ ShareaholicUtilities::log( 'Cron: no need to clear shareaholic_heartbeat schedule' );
62
+ }
63
+ }
64
 
65
+ public static function heartbeat() {
66
+ if ( ShareaholicUtilities::has_accepted_terms_of_service() ) {
67
+ ShareaholicUtilities::heartbeat();
68
+ }
69
+ }
70
 
71
+ /**
72
+ * A job that clears up the shareaholic share counts transients
73
+ */
74
+ public static function remove_transients() {
75
+ global $wpdb;
76
+ $older_than = time() - ( 60 * 60 ); // older than an hour ago
77
 
78
+ ShareaholicUtilities::log( 'Start of Shareaholic transient cleanup' );
 
 
 
 
 
 
 
79
 
80
+ $query = "SELECT REPLACE(option_name, '_transient_timeout_', '') AS transient_name FROM {$wpdb->options} WHERE option_name LIKE '\_transient\_timeout\_shr\_api\_res-%%' AND option_value < %s LIMIT 5000";
81
+ $transients = $wpdb->get_col( $wpdb->prepare( $query, $older_than ) );
82
+
83
+ $options_names = array();
84
+ foreach ( $transients as $transient ) {
85
+ $options_names[] = esc_sql( '_transient_' . $transient );
86
+ $options_names[] = esc_sql( '_transient_timeout_' . $transient );
87
+ }
88
+ if ( $options_names ) {
89
+ $options_names = "'" . implode( "','", $options_names ) . "'";
90
+ $result = $wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name IN ({$options_names})" );
91
+
92
+ if ( ! $result ) {
93
+ ShareaholicUtilities::log( 'Transient Query Error!' );
94
+ }
95
+ }
96
+ // Cleanup leftover mutex
97
+ ShareaholicUtilities::delete_mutex();
98
+
99
+ ShareaholicUtilities::log( 'End of Shareaholic transient cleanup' );
100
+ }
101
+ }
curl.php CHANGED
@@ -5,7 +5,7 @@
5
  * @package shareaholic
6
  */
7
 
8
- require_once(SHAREAHOLIC_PATH . 'query_string_builder.php');
9
 
10
  /**
11
  * This class is a library to easily interface with PHP's native
@@ -14,238 +14,257 @@ require_once(SHAREAHOLIC_PATH . 'query_string_builder.php');
14
  * @package shareaholic
15
  */
16
  class ShareaholicCurl {
17
- /**
18
- *
19
- * Performs a POST request
20
- *
21
- * @param string $url the url you are POSTing to
22
- * @param array $data an associative array of the data you are posting
23
- * @param string $data_type defaults to nothing, you can pass in 'json'
24
- * @param bool $ignore_error whether to log a networking error
25
- *
26
- * @return array the returned data json decoded
27
- */
28
- public static function post($url, $data = array(), $data_type = '', $ignore_error = false, $timeout = 10) {
29
- return self::send_request_with_wp($url, $data, $data_type, $ignore_error, 'POST', $timeout);
30
- }
31
-
32
- /**
33
- *
34
- * Performs a GET request
35
- *
36
- * @param string $url the url you are GETing to
37
- * @param array $data an associative array of the data you are posting
38
- * @param string $data_type defaults to nothing, you can pass in 'json'
39
- * @param bool $ignore_error whether to log a networking error
40
- *
41
- * @return array the returned data json decoded
42
- */
43
- public static function get($url, $data = array(), $data_type = '', $ignore_error = false, $timeout = 10) {
44
- return self::send_request_with_wp($url, $data, $data_type, $ignore_error, 'GET', $timeout);
45
- }
46
-
47
- /**
48
- *
49
- * Performs a request using the methods built into WordPress, which account for
50
- * various PHP eccenctricities.
51
- *
52
- * @param string $url
53
- * @param array $data an associative array of the data
54
- * @param string $data_type either an empty string or 'json'
55
- * @param bool $ignore_error whether to log a networking error
56
- * @param string $method the HTTP verb to be used
57
- * @param int $timeout timeout in seconds
58
- *
59
- * @return mixed the returned data json decoded or false
60
- */
61
- private static function send_request_with_wp($url, $data, $data_type, $ignore_error, $method, $timeout = 10) {
62
- ShareaholicUtilities::log($url);
63
- ShareaholicUtilities::log($data);
64
- ShareaholicUtilities::log($data_type);
65
- ShareaholicUtilities::log($method);
66
- ShareaholicUtilities::log('-----------------');
67
- $useragent = 'WordPress/' . get_bloginfo('version') . ' ('. 'PHP/' . phpversion() . '; ' . 'SHR_WP/' . Shareaholic::VERSION . '; +' . get_bloginfo( 'url' ) . ')';
68
- if ($method == 'GET') {
69
- $request = array();
70
- if (WP_Http_Encoding::is_available()) {
71
- $request['headers']['Accept-Encoding'] = 'gzip, deflate';
72
- }
73
- $response = wp_remote_get($url, array(
74
- 'body' => $data,
75
- 'sslverify' => false,
76
- 'user-agent' => $useragent,
77
- 'timeout' => $timeout,
78
- 'headers' => $request['headers']
79
- )
80
- );
81
- } elseif ($method == 'POST') {
82
- $request = array();
83
- if ($data_type == 'json') {
84
- $request['headers'] = array(
85
- 'Content-Type' => 'application/json',
86
- );
87
- $request['body'] = json_encode($data);
88
- } else {
89
- $request['body'] = $data;
90
- }
91
- $request['headers']['Accept'] = 'application/json';
92
- if (WP_Http_Encoding::is_available()) {
93
- $request['headers']['Accept-Encoding'] = 'gzip, deflate';
94
- }
95
- $request['headers']['user-agent'] = $useragent;
96
- $request['sslverify'] = false;
97
- $request['timeout'] = $timeout;
98
- $response = wp_remote_post($url, $request);
99
- }
100
-
101
- if (is_wp_error($response)) {
102
- $error_message = $response->get_error_message();
103
- ShareaholicUtilities::log($error_message);
104
- if (!$ignore_error) {
105
- ShareaholicUtilities::log_event('CurlRequestFailure', array('error_message' => $error_message, 'url' => $url));
106
- }
107
- return false;
108
- }
109
- else {
110
- if(is_array($response) && array_key_exists('body', $response)) {
111
- $body = $response['body'];
112
-
113
- // strip out any BOM appended characters
114
- $body = self::strip_utf8_bom($body);
115
-
116
- $response['body'] = ShareaholicUtilities::object_to_array(json_decode($body)) ?
117
- ShareaholicUtilities::object_to_array(json_decode($body)) : $body;
118
- return $response;
119
- }
120
- }
121
- }
122
-
123
- /**
124
- *
125
- * Performs a request using cURL
126
- *
127
- * @param string $url the url you are GETing to
128
- * @param array $data an associative array of the data you are posting
129
- * @param string $data_type either an empty string or 'json'
130
- * @param string $method the HTTP verb to be used
131
- *
132
- * @return array the returned data json decoded
133
- */
134
- private static function send_request($url, $data, $data_type, $method) {
135
- $curl = curl_init();
136
- curl_setopt_array($curl, array(
137
- CURLOPT_URL => $url,
138
- CURLOPT_RETURNTRANSFER => 1,
139
- CURLOPT_SSL_VERIFYPEER => false,
140
- CURLOPT_SSL_VERIFYHOST => false
141
- ));
142
-
143
- /*
144
- * Because many shared hosting providers set `open_basedir` in php.ini
145
- * that means we can't always set CURLOPT_FOLLOWLOCATION.
146
- * This next block is an attempt around that by sending head requests
147
- * to determine if there will be a redirect and then following it.
148
- * Shamelessly stolen from here:
149
- * http://us2.php.net/manual/en/function.curl-setopt.php#102121
150
- */
151
- $mr = 5;
152
- if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) {
153
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, $mr > 0);
154
- curl_setopt($curl, CURLOPT_MAXREDIRS, $mr);
155
- } else {
156
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
157
- if ($mr > 0) {
158
- $newurl = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);
159
-
160
- $rch = curl_copy_handle($curl);
161
- curl_setopt($rch, CURLOPT_HEADER, true);
162
- curl_setopt($rch, CURLOPT_NOBODY, true);
163
- curl_setopt($rch, CURLOPT_FORBID_REUSE, false);
164
- curl_setopt($rch, CURLOPT_RETURNTRANSFER, true);
165
- do {
166
- curl_setopt($rch, CURLOPT_URL, $newurl);
167
- $header = curl_exec($rch);
168
- if (curl_errno($rch)) {
169
- $code = 0;
170
- } else {
171
- $code = curl_getinfo($rch, CURLINFO_HTTP_CODE);
172
- if ($code == 301 || $code == 302) {
173
- preg_match('/Location:(.*?)\n/', $header, $matches);
174
- $newurl = trim(array_pop($matches));
175
- } else {
176
- $code = 0;
177
- }
178
- }
179
- } while ($code && --$mr);
180
- curl_close($rch);
181
- if (!$mr) {
182
- if ($maxredirect === null) {
183
- trigger_error('Too many redirects. When following redirects, libcurl hit the maximum amount.', E_USER_WARNING);
184
- } else {
185
- $maxredirect = 0;
186
- }
187
- return false;
188
- }
189
- curl_setopt($curl, CURLOPT_URL, $newurl);
190
- }
191
- }
192
- /* end stolen code */
193
-
194
- if ($method == 'POST') {
195
- curl_setopt_array($curl, array(
196
- CURLOPT_POST => 1,
197
- CURLOPT_HTTPHEADER => array("Accept: application/json,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain")
198
- ));
199
-
200
- if ($data_type == 'json'){
201
- curl_setopt_array($curl, array(
202
- CURLOPT_POSTFIELDS => json_encode($data),
203
- CURLOPT_HTTPHEADER => array(
204
- 'Content-Type: application/json',
205
- 'Content-Length: ' . strlen(json_encode($data))
206
- )
207
- ));
208
- } else {
209
- curl_setopt_array($curl, array(
210
- CURLOPT_POSTFIELDS => ShareaholicQueryStringBuilder::build_query_string($data),
211
- ));
212
- }
213
- }
214
-
215
- $result = curl_exec($curl);
216
- $info = curl_getinfo($curl);
217
- ShareaholicUtilities::log(curl_error($curl));
218
- ShareaholicUtilities::log(curl_getinfo($curl));
219
- curl_close($curl);
220
-
221
- if (preg_match('/^20*/', $info['http_code'])) {
222
- return ShareaholicUtilities::object_to_array(json_decode($result)) ?
223
- ShareaholicUtilities::object_to_array(json_decode($result)) : $result;
224
- } else {
225
- return false;
226
- }
227
- }
228
-
229
- /**
230
- * Sometimes the response from APIs begins with BOM (byte order mark) which
231
- * makes it difficult to parse JSON responses.
232
- *
233
- * If it exists, remove it and return the cleaned up string
234
- *
235
- * @param {String} $str the string to strip BOM
236
- * @return {String} the stripped out string if BOM exists
237
- */
238
- private static function strip_utf8_bom($str) {
239
- // create binary string for BOM
240
- $bom = pack("CCC", 0xef, 0xbb, 0xbf);
241
-
242
- // binary safe compare the BOM with the string
243
- if (0 === strncmp($str, $bom, 3)) {
244
- return substr($str, 3);
245
- }
246
-
247
- return $str;
248
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  }
250
 
251
- ?>
5
  * @package shareaholic
6
  */
7
 
8
+ require_once SHAREAHOLIC_PATH . 'query_string_builder.php';
9
 
10
  /**
11
  * This class is a library to easily interface with PHP's native
14
  * @package shareaholic
15
  */
16
  class ShareaholicCurl {
17
+ /**
18
+ *
19
+ * Performs a POST request
20
+ *
21
+ * @param string $url the url you are POSTing to
22
+ * @param array $data an associative array of the data you are posting
23
+ * @param string $data_type defaults to nothing, you can pass in 'json'
24
+ * @param bool $ignore_error whether to log a networking error
25
+ *
26
+ * @return array the returned data json decoded
27
+ */
28
+ public static function post( $url, $data = array(), $data_type = '', $ignore_error = false, $timeout = 10 ) {
29
+ return self::send_request_with_wp( $url, $data, $data_type, $ignore_error, 'POST', $timeout );
30
+ }
31
+
32
+ /**
33
+ *
34
+ * Performs a GET request
35
+ *
36
+ * @param string $url the url you are GETing to
37
+ * @param array $data an associative array of the data you are posting
38
+ * @param string $data_type defaults to nothing, you can pass in 'json'
39
+ * @param bool $ignore_error whether to log a networking error
40
+ *
41
+ * @return array the returned data json decoded
42
+ */
43
+ public static function get( $url, $data = array(), $data_type = '', $ignore_error = false, $timeout = 10 ) {
44
+ return self::send_request_with_wp( $url, $data, $data_type, $ignore_error, 'GET', $timeout );
45
+ }
46
+
47
+ /**
48
+ *
49
+ * Performs a request using the methods built into WordPress, which account for
50
+ * various PHP eccenctricities.
51
+ *
52
+ * @param string $url
53
+ * @param array $data an associative array of the data
54
+ * @param string $data_type either an empty string or 'json'
55
+ * @param bool $ignore_error whether to log a networking error
56
+ * @param string $method the HTTP verb to be used
57
+ * @param int $timeout timeout in seconds
58
+ *
59
+ * @return mixed the returned data json decoded or false
60
+ */
61
+ private static function send_request_with_wp( $url, $data, $data_type, $ignore_error, $method, $timeout = 10 ) {
62
+ ShareaholicUtilities::log( $url );
63
+ ShareaholicUtilities::log( $data );
64
+ ShareaholicUtilities::log( $data_type );
65
+ ShareaholicUtilities::log( $method );
66
+ ShareaholicUtilities::log( '-----------------' );
67
+ $useragent = 'WordPress/' . get_bloginfo( 'version' ) . ' (' . 'PHP/' . phpversion() . '; ' . 'SHR_WP/' . Shareaholic::VERSION . '; +' . get_bloginfo( 'url' ) . ')';
68
+ if ( $method == 'GET' ) {
69
+ $request = array();
70
+ if ( WP_Http_Encoding::is_available() ) {
71
+ $request['headers']['Accept-Encoding'] = 'gzip, deflate';
72
+ }
73
+ $response = wp_remote_get(
74
+ $url,
75
+ array(
76
+ 'body' => $data,
77
+ 'sslverify' => false,
78
+ 'user-agent' => $useragent,
79
+ 'timeout' => $timeout,
80
+ 'headers' => $request['headers'],
81
+ )
82
+ );
83
+ } elseif ( $method == 'POST' ) {
84
+ $request = array();
85
+ if ( $data_type == 'json' ) {
86
+ $request['headers'] = array(
87
+ 'Content-Type' => 'application/json',
88
+ );
89
+ $request['body'] = json_encode( $data );
90
+ } else {
91
+ $request['body'] = $data;
92
+ }
93
+ $request['headers']['Accept'] = 'application/json';
94
+ if ( WP_Http_Encoding::is_available() ) {
95
+ $request['headers']['Accept-Encoding'] = 'gzip, deflate';
96
+ }
97
+ $request['headers']['user-agent'] = $useragent;
98
+ $request['sslverify'] = false;
99
+ $request['timeout'] = $timeout;
100
+ $response = wp_remote_post( $url, $request );
101
+ }
102
+
103
+ if ( is_wp_error( $response ) ) {
104
+ $error_message = $response->get_error_message();
105
+ ShareaholicUtilities::log( $error_message );
106
+ if ( ! $ignore_error ) {
107
+ ShareaholicUtilities::log_event(
108
+ 'CurlRequestFailure',
109
+ array(
110
+ 'error_message' => $error_message,
111
+ 'url' => $url,
112
+ )
113
+ );
114
+ }
115
+ return false;
116
+ } else {
117
+ if ( is_array( $response ) && array_key_exists( 'body', $response ) ) {
118
+ $body = $response['body'];
119
+
120
+ // strip out any BOM appended characters
121
+ $body = self::strip_utf8_bom( $body );
122
+
123
+ $response['body'] = ShareaholicUtilities::object_to_array( json_decode( $body ) ) ?
124
+ ShareaholicUtilities::object_to_array( json_decode( $body ) ) : $body;
125
+ return $response;
126
+ }
127
+ }
128
+ }
129
+
130
+ /**
131
+ *
132
+ * Performs a request using cURL
133
+ *
134
+ * @param string $url the url you are GETing to
135
+ * @param array $data an associative array of the data you are posting
136
+ * @param string $data_type either an empty string or 'json'
137
+ * @param string $method the HTTP verb to be used
138
+ *
139
+ * @return array the returned data json decoded
140
+ */
141
+ private static function send_request( $url, $data, $data_type, $method ) {
142
+ $curl = curl_init();
143
+ curl_setopt_array(
144
+ $curl,
145
+ array(
146
+ CURLOPT_URL => $url,
147
+ CURLOPT_RETURNTRANSFER => 1,
148
+ CURLOPT_SSL_VERIFYPEER => false,
149
+ CURLOPT_SSL_VERIFYHOST => false,
150
+ )
151
+ );
152
+
153
+ /*
154
+ * Because many shared hosting providers set `open_basedir` in php.ini
155
+ * that means we can't always set CURLOPT_FOLLOWLOCATION.
156
+ * This next block is an attempt around that by sending head requests
157
+ * to determine if there will be a redirect and then following it.
158
+ * Shamelessly stolen from here:
159
+ * http://us2.php.net/manual/en/function.curl-setopt.php#102121
160
+ */
161
+ $mr = 5;
162
+ if ( ini_get( 'open_basedir' ) == '' && ini_get( 'safe_mode' == 'Off' ) ) {
163
+ curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, $mr > 0 );
164
+ curl_setopt( $curl, CURLOPT_MAXREDIRS, $mr );
165
+ } else {
166
+ curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, false );
167
+ if ( $mr > 0 ) {
168
+ $newurl = curl_getinfo( $curl, CURLINFO_EFFECTIVE_URL );
169
+
170
+ $rch = curl_copy_handle( $curl );
171
+ curl_setopt( $rch, CURLOPT_HEADER, true );
172
+ curl_setopt( $rch, CURLOPT_NOBODY, true );
173
+ curl_setopt( $rch, CURLOPT_FORBID_REUSE, false );
174
+ curl_setopt( $rch, CURLOPT_RETURNTRANSFER, true );
175
+ do {
176
+ curl_setopt( $rch, CURLOPT_URL, $newurl );
177
+ $header = curl_exec( $rch );
178
+ if ( curl_errno( $rch ) ) {
179
+ $code = 0;
180
+ } else {
181
+ $code = curl_getinfo( $rch, CURLINFO_HTTP_CODE );
182
+ if ( $code == 301 || $code == 302 ) {
183
+ preg_match( '/Location:(.*?)\n/', $header, $matches );
184
+ $newurl = trim( array_pop( $matches ) );
185
+ } else {
186
+ $code = 0;
187
+ }
188
+ }
189
+ } while ( $code && --$mr );
190
+ curl_close( $rch );
191
+ if ( ! $mr ) {
192
+ if ( $maxredirect === null ) {
193
+ trigger_error( 'Too many redirects. When following redirects, libcurl hit the maximum amount.', E_USER_WARNING );
194
+ } else {
195
+ $maxredirect = 0;
196
+ }
197
+ return false;
198
+ }
199
+ curl_setopt( $curl, CURLOPT_URL, $newurl );
200
+ }
201
+ }
202
+ /* end stolen code */
203
+
204
+ if ( $method == 'POST' ) {
205
+ curl_setopt_array(
206
+ $curl,
207
+ array(
208
+ CURLOPT_POST => 1,
209
+ CURLOPT_HTTPHEADER => array( 'Accept: application/json,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain' ),
210
+ )
211
+ );
212
+
213
+ if ( $data_type == 'json' ) {
214
+ curl_setopt_array(
215
+ $curl,
216
+ array(
217
+ CURLOPT_POSTFIELDS => json_encode( $data ),
218
+ CURLOPT_HTTPHEADER => array(
219
+ 'Content-Type: application/json',
220
+ 'Content-Length: ' . strlen( json_encode( $data ) ),
221
+ ),
222
+ )
223
+ );
224
+ } else {
225
+ curl_setopt_array(
226
+ $curl,
227
+ array(
228
+ CURLOPT_POSTFIELDS => ShareaholicQueryStringBuilder::build_query_string( $data ),
229
+ )
230
+ );
231
+ }
232
+ }
233
+
234
+ $result = curl_exec( $curl );
235
+ $info = curl_getinfo( $curl );
236
+ ShareaholicUtilities::log( curl_error( $curl ) );
237
+ ShareaholicUtilities::log( curl_getinfo( $curl ) );
238
+ curl_close( $curl );
239
+
240
+ if ( preg_match( '/^20*/', $info['http_code'] ) ) {
241
+ return ShareaholicUtilities::object_to_array( json_decode( $result ) ) ?
242
+ ShareaholicUtilities::object_to_array( json_decode( $result ) ) : $result;
243
+ } else {
244
+ return false;
245
+ }
246
+ }
247
+
248
+ /**
249
+ * Sometimes the response from APIs begins with BOM (byte order mark) which
250
+ * makes it difficult to parse JSON responses.
251
+ *
252
+ * If it exists, remove it and return the cleaned up string
253
+ *
254
+ * @param {String} $str the string to strip BOM
255
+ * @return {String} the stripped out string if BOM exists
256
+ */
257
+ private static function strip_utf8_bom( $str ) {
258
+ // create binary string for BOM
259
+ $bom = pack( 'CCC', 0xef, 0xbb, 0xbf );
260
+
261
+ // binary safe compare the BOM with the string
262
+ if ( 0 === strncmp( $str, $bom, 3 ) ) {
263
+ return substr( $str, 3 );
264
+ }
265
+
266
+ return $str;
267
+ }
268
  }
269
 
270
+
global_functions.php CHANGED
@@ -11,12 +11,12 @@
11
  *
12
  * @deprecated beginning with the release of 7.0.0.0
13
  */
14
-
15
- if (!function_exists('selfserv_shareaholic')) {
16
- function selfserv_shareaholic() {
17
- _deprecated_function( __FUNCTION__, '7.0.0.0' );
18
- return false;
19
- }
20
  }
21
  /**
22
  * Another old 'shortcode' function. Because this accepts a position
@@ -25,10 +25,10 @@
25
  *
26
  * @param string $position either 'Top' or 'Bottom'
27
  */
28
- if (!function_exists('get_shr_like_buttonset')) {
29
- function get_shr_like_buttonset($position) {
30
- _deprecated_function( __FUNCTION__, '7.0.0.0' );
31
- return false;
32
- }
33
- }
34
- ?>
11
  *
12
  * @deprecated beginning with the release of 7.0.0.0
13
  */
14
+
15
+ if ( ! function_exists( 'selfserv_shareaholic' ) ) {
16
+ function selfserv_shareaholic() {
17
+ _deprecated_function( __FUNCTION__, '7.0.0.0' );
18
+ return false;
19
+ }
20
  }
21
  /**
22
  * Another old 'shortcode' function. Because this accepts a position
25
  *
26
  * @param string $position either 'Top' or 'Bottom'
27
  */
28
+ if ( ! function_exists( 'get_shr_like_buttonset' ) ) {
29
+ function get_shr_like_buttonset( $position ) {
30
+ _deprecated_function( __FUNCTION__, '7.0.0.0' );
31
+ return false;
32
+ }
33
+ }
34
+
notifier.php CHANGED
@@ -11,95 +11,96 @@
11
  * @package shareaholic
12
  */
13
  class ShareaholicNotifier {
14
- /**
15
- * The url of the publisher API
16
- */
17
 
18
- const URL = 'https://api.shareaholic.com/publisher/1.0';
19
 
20
- /**
21
- * Handles publishing or updating a post
22
- *
23
- * @param string $post_id the post id
24
- * @return bool whether the request worked
25
- */
26
- public static function post_notify($post_id) {
27
- global $wpdb;
28
- $post = get_post($post_id);
29
- $url = get_permalink($post_id);
30
- $tags = wp_get_post_tags($post_id, array('fields' => 'names'));
31
 
32
- $categories = array_map(array('ShareaholicNotifier', 'post_notify_iterator'), get_the_category($post_id));
33
 
34
- if ($post->post_author) {
35
- $author_data = get_userdata($post->post_author);
36
- $author_name = $author_data->display_name;
37
- }
38
 
39
- $notification = array(
40
- 'url' => $url,
41
- 'api_key' => ShareaholicUtilities::get_option('api_key'),
42
- 'content' => array(
43
- 'title' => $post->post_title,
44
- 'excerpt' => $post->post_excerpt,
45
- 'body' => $post->post_content,
46
- 'featured-image-url' => ShareaholicUtilities::permalink_thumbnail($post_id),
47
- ),
48
- 'metadata' => array(
49
- 'author-id' => $post->post_author,
50
- 'author-name' => $author_name,
51
- 'post-type' => $post->post_type,
52
- 'post-id' => $post_id,
53
- 'post-tags' => $tags,
54
- 'post-categories' => $categories,
55
- 'post-language' => get_bloginfo('language'),
56
- 'published' => $post->post_date_gmt,
57
- 'updated' => get_lastpostmodified('GMT'),
58
- 'visibility' => $post->post_status,
59
- ),
60
- 'diagnostics' => array(
61
- 'platform' => 'wordpress',
62
- 'platform-version' => get_bloginfo('version'),
63
- 'shareaholic-version' => Shareaholic::VERSION,
64
- 'wp-multisite' => is_multisite(),
65
- 'wp-theme' => get_option('template'),
66
- 'wp-posts-total' => $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts where post_type = 'post' AND post_status = 'publish'" ),
67
- 'wp-pages-total' => $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts where post_type = 'page' AND post_status = 'publish'" ),
68
- 'wp-comments-total' => wp_count_comments()->approved,
69
- 'wp-users-total' => $wpdb->get_var("SELECT count(ID) FROM $wpdb->users"),
70
- ));
71
-
72
- return self::send_notification($notification);
73
- }
74
 
75
- /**
76
- * Because PHP < 5.3 doesn't allow anonymous functions, this
77
- * is the mapping function used in the method above.
78
- *
79
- * @param Category $category
80
- * @return string
81
- */
82
- private static function post_notify_iterator($category) {
83
- return $category->name;
84
- }
85
 
86
- /**
87
- * Actually sends the request to the notification API
88
- *
89
- * @param array $notification an associative array of data
90
- * to send to the API
91
- * @return bool
92
- */
93
- private static function send_notification($notification) {
94
- $url = self::URL . '/notify';
95
- $response = ShareaholicCurl::post($url, $notification, 'json');
96
 
97
- if ($response && preg_match('/20*/', $response['response']['code'])) {
98
- return true;
99
- } else {
100
- return false;
101
- }
102
- }
 
 
 
 
 
 
 
 
 
 
 
103
  }
104
 
105
- ?>
11
  * @package shareaholic
12
  */
13
  class ShareaholicNotifier {
14
+ /**
15
+ * The url of the publisher API
16
+ */
17
 
18
+ const URL = 'https://api.shareaholic.com/publisher/1.0';
19
 
20
+ /**
21
+ * Handles publishing or updating a post
22
+ *
23
+ * @param string $post_id the post id
24
+ * @return bool whether the request worked
25
+ */
26
+ public static function post_notify( $post_id ) {
27
+ global $wpdb;
28
+ $post = get_post( $post_id );
29
+ $url = get_permalink( $post_id );
30
+ $tags = wp_get_post_tags( $post_id, array( 'fields' => 'names' ) );
31
 
32
+ $categories = array_map( array( 'ShareaholicNotifier', 'post_notify_iterator' ), get_the_category( $post_id ) );
33
 
34
+ if ( $post->post_author ) {
35
+ $author_data = get_userdata( $post->post_author );
36
+ $author_name = $author_data->display_name;
37
+ }
38
 
39
+ $notification = array(
40
+ 'url' => $url,
41
+ 'api_key' => ShareaholicUtilities::get_option( 'api_key' ),
42
+ 'content' => array(
43
+ 'title' => $post->post_title,
44
+ 'excerpt' => $post->post_excerpt,
45
+ 'body' => $post->post_content,
46
+ 'featured-image-url' => ShareaholicUtilities::permalink_thumbnail( $post_id ),
47
+ ),
48
+ 'metadata' => array(
49
+ 'author-id' => $post->post_author,
50
+ 'author-name' => $author_name,
51
+ 'post-type' => $post->post_type,
52
+ 'post-id' => $post_id,
53
+ 'post-tags' => $tags,
54
+ 'post-categories' => $categories,
55
+ 'post-language' => get_bloginfo( 'language' ),
56
+ 'published' => $post->post_date_gmt,
57
+ 'updated' => get_lastpostmodified( 'GMT' ),
58
+ 'visibility' => $post->post_status,
59
+ ),
60
+ 'diagnostics' => array(
61
+ 'platform' => 'wordpress',
62
+ 'platform-version' => get_bloginfo( 'version' ),
63
+ 'shareaholic-version' => Shareaholic::VERSION,
64
+ 'wp-multisite' => is_multisite(),
65
+ 'wp-theme' => get_option( 'template' ),
66
+ 'wp-posts-total' => $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts where post_type = 'post' AND post_status = 'publish'" ),
67
+ 'wp-pages-total' => $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts where post_type = 'page' AND post_status = 'publish'" ),
68
+ 'wp-comments-total' => wp_count_comments()->approved,
69
+ 'wp-users-total' => $wpdb->get_var( "SELECT count(ID) FROM $wpdb->users" ),
70
+ ),
71
+ );
 
 
72
 
73
+ return self::send_notification( $notification );
74
+ }
 
 
 
 
 
 
 
 
75
 
76
+ /**
77
+ * Because PHP < 5.3 doesn't allow anonymous functions, this
78
+ * is the mapping function used in the method above.
79
+ *
80
+ * @param Category $category
81
+ * @return string
82
+ */
83
+ private static function post_notify_iterator( $category ) {
84
+ return $category->name;
85
+ }
86
 
87
+ /**
88
+ * Actually sends the request to the notification API
89
+ *
90
+ * @param array $notification an associative array of data
91
+ * to send to the API
92
+ * @return bool
93
+ */
94
+ private static function send_notification( $notification ) {
95
+ $url = self::URL . '/notify';
96
+ $response = ShareaholicCurl::post( $url, $notification, 'json' );
97
+
98
+ if ( $response && preg_match( '/20*/', $response['response']['code'] ) ) {
99
+ return true;
100
+ } else {
101
+ return false;
102
+ }
103
+ }
104
  }
105
 
106
+
public.php CHANGED
@@ -6,10 +6,10 @@
6
  */
7
 
8
  // Get the required libraries for the Share Counts API
9
- require_once(SHAREAHOLIC_PATH . 'lib/social-share-counts/wordpress_http.php');
10
- require_once(SHAREAHOLIC_PATH . 'lib/social-share-counts/seq_share_count.php');
11
- require_once(SHAREAHOLIC_PATH . 'lib/social-share-counts/curl_multi_share_count.php');
12
- require_once(SHAREAHOLIC_PATH . 'public_js.php');
13
 
14
  /**
15
  * This class is all about drawing the stuff in publishers'
@@ -19,930 +19,951 @@ require_once(SHAREAHOLIC_PATH . 'public_js.php');
19
  */
20
  class ShareaholicPublic {
21
 
22
- /**
23
- * Loads before all else
24
- */
25
- public static function after_setup_theme() {
26
- // Ensure thumbnail/featured image support
27
- if(!current_theme_supports('post-thumbnails')){
28
- add_theme_support('post-thumbnails');
29
- }
30
-
31
- // Adds support for shortcodes in sidebar text widgets
32
- if (!has_filter('widget_text', 'do_shortcode')){
33
- add_filter('widget_text', 'do_shortcode', 11);
34
- }
35
-
36
- // Our custom image type
37
- add_image_size('shareaholic-thumbnail', 640); // 640 pixels wide (and unlimited height)
38
- }
39
-
40
- /**
41
- * The function called during the wp_head action. The
42
- * rest of the plugin doesn't need to know exactly what happens.
43
- */
44
- public static function wp_head() {
45
- self::script_tag();
46
- self::shareaholic_tags();
47
- self::draw_og_tags();
48
- }
49
-
50
- /**
51
- * Inserts resource hints in </head> to speed up loading
52
- */
53
- public static function shareaholic_resource_hints($hints, $relation_type) {
54
- if ('dns-prefetch' === $relation_type) {
55
- if ($hints) {
56
- array_push($hints,
57
- '//k4z6w9b5.stackpathcdn.com',
58
- '//cdn.shareaholic.net',
59
- '//www.shareaholic.net',
60
- '//analytics.shareaholic.com',
61
- '//recs.shareaholic.com',
62
- '//go.shareaholic.com',
63
- '//partner.shareaholic.com'
64
- );
65
- }
66
- }
67
- return $hints;
68
- }
69
-
70
- /**
71
- * Inserts the script code snippet into the head of the page
72
- */
73
- public static function script_tag() {
74
- if (ShareaholicUtilities::has_accepted_terms_of_service() && ShareaholicUtilities::get_or_create_api_key()) {
75
- ShareaholicUtilities::load_template('script_tag', array(
76
- 'api_key' => ShareaholicUtilities::get_option('api_key'),
77
- 'base_settings' => ShareaholicPublicJS::get_base_settings(),
78
- 'overrides' => ShareaholicPublicJS::get_overrides()
79
- ));
80
- }
81
- }
82
-
83
- /**
84
- * The function that gets called for shortcodes
85
- *
86
- * @param array $attributes this is passed keys: `id`, `app`, `title`, `link`, `summary`
87
- * @param string $content is the enclosed content (if the shortcode is used in its enclosing form)
88
- */
89
- public static function shortcode($attributes, $content = NULL) {
90
- extract(shortcode_atts(array(
91
- "id" => NULL,
92
- "id_name" => NULL,
93
- "app" => 'share_buttons',
94
- "title" => NULL,
95
- "link" => NULL,
96
- "summary" => NULL
97
- ), $attributes, 'shareaholic'));
98
-
99
- if (isset($attributes['id'])) $id = trim($attributes['id']);
100
- if (isset($attributes['id_name'])) $id_name = trim($attributes['id_name']);
101
- if (isset($attributes['app'])) $app = trim($attributes['app']);
102
- if (isset($attributes['title'])) $title = esc_attr(trim($attributes['title']));
103
- if (isset($attributes['link'])) $link = trim($attributes['link']);
104
- if (isset($attributes['summary'])) $summary = esc_attr(trim($attributes['summary']));
105
-
106
- return self::canvas($id, $app, $id_name, $title, $link, $summary);
107
- }
108
-
109
-
110
- /**
111
- * Draws the shareaholic meta tags.
112
- */
113
- private static function shareaholic_tags() {
114
- echo "\n<!-- Shareaholic Content Tags -->\n";
115
- self::draw_site_name_meta_tag();
116
- self::draw_language_meta_tag();
117
- self::draw_url_meta_tag();
118
- self::draw_keywords_meta_tag();
119
- self::draw_article_meta_tag();
120
- self::draw_site_id_meta_tag();
121
- self::draw_plugin_version_meta_tag();
122
- self::draw_image_meta_tag();
123
- echo "\n<!-- Shareaholic Content Tags End -->\n";
124
- }
125
-
126
- /**
127
- * Draws Shareaholic keywords meta tag.
128
- */
129
- private static function draw_keywords_meta_tag() {
130
- if (in_array(ShareaholicUtilities::page_type(), array('page', 'post'))) {
131
-
132
- global $post;
133
- $tags = array();
134
- if (is_attachment() && $post->post_parent){
135
- $id = $post->post_parent;
136
- } else {
137
- $id = $post->ID;
138
- }
139
-
140
- // Get post tags
141
- $tags = preg_replace('/^/', 'tag:', ShareaholicUtilities::permalink_keywords($id));
142
-
143
- // Get post categories
144
- $categories_array = get_the_category($id);
145
- $categories = array();
146
-
147
- if($categories_array) {
148
- foreach($categories_array as $category) {
149
- if ($category->cat_name != "Uncategorized") {
150
- array_push($categories, $category->cat_name);
151
- }
152
- }
153
- $categories = preg_replace('/^/', 'cat:', $categories);
154
- }
155
-
156
- $keywords_array = array();
157
- $keywords = '';
158
-
159
- // Merge + add page type
160
- $keywords_array = array_merge($tags, $categories);
161
- if ($post->post_type) {
162
- array_push($keywords_array, 'type:'.$post->post_type);
163
- }
164
-
165
- // Unique keywords
166
- $keywords_array = array_unique($keywords_array);
167
-
168
- if (!empty($keywords_array[0])){
169
- $keywords = implode(', ' , $keywords_array);
170
-
171
- // Encode, lowercase & trim appropriately
172
- $keywords = ShareaholicUtilities::normalize_keywords($keywords);
173
- }
174
-
175
- if ($keywords != '' && $keywords != "array") {
176
- echo "<meta name='shareaholic:keywords' content='" . $keywords . "' />\n";
177
- }
178
- }
179
- }
180
-
181
- /**
182
- * Draws Shareaholic article meta tags
183
- */
184
- private static function draw_article_meta_tag() {
185
-
186
- if (in_array(ShareaholicUtilities::page_type(), array('index', 'category')) || is_404()) {
187
- echo "<meta name='shareaholic:article_visibility' content='private' />\n";
188
- return;
189
- }
190
-
191
- if (in_array(ShareaholicUtilities::page_type(), array('page', 'post'))) {
192
- global $post;
193
-
194
- // Article Publish and Modified Time
195
- $article_published_time = get_the_date( DATE_W3C );
196
- $article_modified_time = get_the_modified_date( DATE_W3C );
197
-
198
- if (!empty($article_published_time)) {
199
- echo "<meta name='shareaholic:article_published_time' content='" . $article_published_time . "' />\n";
200
- }
201
- if (!empty($article_modified_time)) {
202
- echo "<meta name='shareaholic:article_modified_time' content='" . $article_modified_time . "' />\n";
203
- }
204
-
205
- // Article Visibility
206
- $article_visibility = $post->post_status;
207
- $article_password = $post->post_password;
208
-
209
- if ($article_visibility == 'draft' || $article_visibility == 'auto-draft' || $article_visibility == 'future' || $article_visibility == 'pending'){
210
- echo "<meta name='shareaholic:shareable_page' content='false' />\n";
211
- $article_visibility = 'draft';
212
- } else if ($article_visibility == 'private' || $post->post_password != '') {
213
- echo "<meta name='shareaholic:shareable_page' content='false' />\n";
214
- $article_visibility = 'private';
215
- } else if (is_attachment()) {
216
- // attachments are shareable but not recommendable
217
- echo "<meta name='shareaholic:shareable_page' content='true' />\n";
218
- $article_visibility = 'private';
219
- } else {
220
- echo "<meta name='shareaholic:shareable_page' content='true' />\n";
221
- $article_visibility = NULL;
222
- }
223
-
224
- // Lookup Metabox value
225
- if (get_post_meta($post->ID, 'shareaholic_exclude_recommendations', true)) {
226
- $article_visibility = 'private';
227
- }
228
-
229
- if (!empty($article_visibility)) {
230
- echo "<meta name='shareaholic:article_visibility' content='" . $article_visibility . "' />\n";
231
- }
232
-
233
- // Article Author Name
234
- if ($post->post_author) {
235
- $article_author_data = get_userdata($post->post_author);
236
- if ($article_author_data) {
237
- $article_author_name = $article_author_data->display_name;
238
- }
239
- }
240
- if (!empty($article_author_name)) {
241
- echo "<meta name='shareaholic:article_author_name' content='" . htmlspecialchars($article_author_name, ENT_QUOTES) . "' />\n";
242
- }
243
- }
244
- }
245
-
246
- /**
247
- * Draws Shareaholic language meta tag.
248
- */
249
- private static function draw_language_meta_tag() {
250
- $blog_language = get_bloginfo('language');
251
- if (!empty($blog_language)) {
252
- echo "<meta name='shareaholic:language' content='" . $blog_language . "' />\n";
253
- }
254
- }
255
-
256
- /**
257
- * Draws Shareaholic url meta tag.
258
- */
259
- private static function draw_url_meta_tag() {
260
- if (in_array(ShareaholicUtilities::page_type(), array('page', 'post'))) {
261
- $url_link = get_permalink();
262
- echo "<meta name='shareaholic:url' content='" . $url_link . "' />\n";
263
- }
264
- }
265
-
266
- /**
267
- * Draws Shareaholic version meta tag.
268
- */
269
- private static function draw_plugin_version_meta_tag() {
270
- echo "<meta name='shareaholic:wp_version' content='" . ShareaholicUtilities::get_version() . "' />\n";
271
- }
272
-
273
- /**
274
- * Draws Shareaholic site name meta tag.
275
- */
276
- private static function draw_site_name_meta_tag() {
277
- $blog_name = get_bloginfo();
278
- if (!empty($blog_name)) {
279
- echo "<meta name='shareaholic:site_name' content='" . $blog_name . "' />\n";
280
- }
281
- }
282
-
283
- /**
284
- * Draws Shareaholic site_id meta tag.
285
- */
286
- private static function draw_site_id_meta_tag() {
287
- $site_id = ShareaholicUtilities::get_option('api_key');
288
- if (!empty($site_id)) {
289
- echo "<meta name='shareaholic:site_id' content='" . $site_id . "' />\n";
290
- }
291
- }
292
-
293
- /**
294
- * Draws Shareaholic image meta tag. Will only run on pages or posts.
295
- */
296
- private static function draw_image_meta_tag() {
297
- if (in_array(ShareaholicUtilities::page_type(), array('page', 'post'))) {
298
- global $post;
299
- $thumbnail_src = '';
300
-
301
- if (is_attachment()) {
302
- $thumbnail_src = wp_get_attachment_thumb_url();
303
- }
304
-
305
- $thumbnail_src = ShareaholicUtilities::post_featured_image();
306
-
307
- if ($thumbnail_src == NULL) {
308
- $thumbnail_src = ShareaholicUtilities::post_first_image();
309
- }
310
-
311
- if ($thumbnail_src != NULL) {
312
- echo "<meta name='shareaholic:image' content='" . $thumbnail_src . "' />";
313
- }
314
- }
315
- }
316
-
317
- /**
318
- * Draws an open graph image meta tag if they are enabled and exist. Will only run on pages or posts.
319
- */
320
- private static function draw_og_tags() {
321
- if (in_array(ShareaholicUtilities::page_type(), array('page', 'post'))) {
322
- global $post;
323
- $thumbnail_src = '';
324
- $settings = ShareaholicUtilities::get_settings();
325
-
326
- if (!get_post_meta($post->ID, 'shareaholic_disable_open_graph_tags', true) && (isset($settings['disable_og_tags']) && $settings['disable_og_tags'] == "off")) {
327
- if (is_attachment()) {
328
- $thumbnail_src = wp_get_attachment_thumb_url();
329
- }
330
- if (function_exists('has_post_thumbnail') && has_post_thumbnail($post->ID)) {
331
- $thumbnail = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'large');
332
- $thumbnail_src = esc_attr($thumbnail[0]);
333
- }
334
- if ($thumbnail_src == NULL) {
335
- $thumbnail_src = ShareaholicUtilities::post_first_image();
336
- }
337
- if ($thumbnail_src != NULL) {
338
- echo "\n<!-- Shareaholic Open Graph Tags -->\n";
339
- echo "<meta property='og:image' content='" . $thumbnail_src . "' />";
340
- echo "\n<!-- Shareaholic Open Graph Tags End -->\n";
341
- }
342
- }
343
- }
344
- }
345
-
346
- /**
347
- * This static function inserts the shareaholic canvas in a post
348
- *
349
- * @param string $content the wordpress content
350
- * @return string the content
351
- */
352
- public static function draw_canvases($content) {
353
- global $wp_current_filter;
354
- if (is_main_query()) {
355
- $settings = ShareaholicUtilities::get_settings();
356
- $page_type = ShareaholicUtilities::page_type();
357
-
358
- // Don't allow this function to run more than once for a page load (prevent infinite loops)
359
- $has_run = false;
360
- foreach ( $wp_current_filter as $filter ) {
361
- if ( 'the_content' == $filter ) {
362
- if ( $has_run ) {
363
- // has already run once
364
- return $content;
365
- } else {
366
- // first run, set flag!
367
- $has_run = true;
368
- }
369
- }
370
- }
371
-
372
- foreach (array('share_buttons', 'recommendations') as $app) {
373
- // check Excerpt prefs
374
- if ('the_excerpt' == current_filter() && isset($settings["{$app}_display_on_excerpts"]) && $settings["{$app}_display_on_excerpts"] == 'off') {
375
- return $content;
376
- }
377
-
378
- // check individual post prefs
379
- if (!get_post_meta(get_the_ID(), "shareaholic_disable_{$app}", true)) {
380
- // check if ABOVE location is turned on
381
- if (isset($settings[$app]["{$page_type}_above_content"]) && $settings[$app]["{$page_type}_above_content"] == 'on') {
382
- $id = $settings['location_name_ids'][$app]["{$page_type}_above_content"];
383
- $content = self::canvas($id, $app, "{$page_type}_above_content") . $content;
384
- }
385
- // check if BELOW location is turned on
386
- if (isset($settings[$app]["{$page_type}_below_content"]) && $settings[$app]["{$page_type}_below_content"] == 'on') {
387
- $id = $settings['location_name_ids'][$app]["{$page_type}_below_content"];
388
- $content .= self::canvas($id, $app, "{$page_type}_below_content");
389
- }
390
- }
391
- }
392
- }
393
-
394
- // something that uses the_content hook must return the $content
395
- return $content;
396
- }
397
-
398
- /**
399
- * Draws an individual canvas given a specific location
400
- * id and app. The app isn't strictly necessary, but is
401
- * being kept for now for backwards compatability.
402
- * This method was private, but was made public to be accessed
403
- * by the shortcode static function in global_functions.php.
404
- *
405
- * @param string $id the location id for configuration
406
- * @param string $id_name the location id name for configuration
407
- * @param string $app the type of app
408
- * @param string $title the title of URL
409
- * @param string $link url
410
- * @param string $summary summary text for URL
411
- */
412
- public static function canvas($id = NULL, $app, $id_name = NULL, $title = NULL, $link = NULL, $summary = NULL) {
413
- global $post, $wp_query;
414
- $page_type = ShareaholicUtilities::page_type();
415
- $is_list_page = $page_type == 'index' || $page_type == 'category';
416
- $loop_start = did_action('loop_start');
417
- $loop_end = did_action('loop_end');
418
- $in_loop = $loop_start > $loop_end ? TRUE : FALSE;
419
-
420
- $link = trim($link);
421
-
422
- // Use the $post object to get the title, link, and summary only if the
423
- // title, link or summary is not provided AND one of the following is true:
424
- // - we are on a non list page
425
- // - we are in the wordpress loop
426
- if (trim($title) == NULL && (!$is_list_page || $in_loop)) {
427
- $title = htmlspecialchars($post->post_title, ENT_QUOTES);
428
- }
429
- if (trim($link) == NULL && (!$is_list_page || $in_loop)) {
430
- $link = get_permalink($post->ID);
431
- }
432
- if (trim($summary) == NULL && (!$is_list_page || $in_loop)) {
433
- $summary = htmlspecialchars(strip_tags(strip_shortcodes($post->post_excerpt)), ENT_QUOTES);
434
- $summary = ShareaholicUtilities::truncate_text($summary, 500);
435
- }
436
-
437
- $canvas = "<div class='shareaholic-canvas'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
  data-app='$app'
439
  data-title='$title'
440
  data-link='$link'";
441
-
442
- if ($summary != NULL) {
443
- $canvas .= " data-summary='$summary'";
444
- }
445
-
446
- if ($id != NULL) {
447
- $canvas .= " data-app-id='$id'";
448
- }
449
-
450
- if ($id_name != NULL) {
451
- $canvas .= " data-app-id-name='$id_name'";
452
- }
453
-
454
- $canvas .="></div>";
455
-
456
- return trim(preg_replace('/\s+/', ' ', $canvas));
457
- }
458
-
459
-
460
- /**
461
- * Function to handle the share count API requests
462
- *
463
- */
464
- public static function share_counts_api() {
465
- $debug_mode = isset($_GET['debug']) && $_GET['debug'] === '1';
466
- $url = isset($_GET['url']) ? $_GET['url'] : '';
467
- $services = isset($_GET['services']) ? $_GET['services'] : array();
468
- $services = self::parse_services($services);
469
- $cache_key = 'shr_api_res-' . md5( $url );
470
-
471
- if (empty($url) || empty($services)) {
472
- $result = array();
473
- } else {
474
- $result = get_transient($cache_key);
475
- }
476
-
477
- $has_curl_multi = self::has_curl();
478
-
479
- if (!$result || $debug_mode || !self::has_services_in_result($result, $services)) {
480
- if (isset($result['services']) && !$debug_mode) {
481
- $services = array_keys(array_flip(array_merge($result['services'], $services)));
482
- }
483
-
484
- $result = array();
485
- $options = array();
486
-
487
- if ($debug_mode && isset($_GET['timeout'])) {
488
- $options['timeout'] = intval($_GET['timeout']);
489
- }
490
-
491
- if ($debug_mode) {
492
- $options['show_raw'] = isset($_GET['raw']) ? $_GET['raw'] : '1';
493
- $options['show_response_header'] = isset($_GET['response_headers']) ? $_GET['response_headers'] : '1';
494
- }
495
-
496
- if (ShareaholicUtilities::facebook_auth_check() == "SUCCESS") {
497
- $options['facebook_access_token'] = ShareaholicUtilities::fetch_fb_access_token();
498
- }
499
-
500
- if(is_array($services) && count($services) > 0 && !empty($url)) {
501
- if ($debug_mode && isset($_GET['client'])) {
502
- if ($has_curl_multi && $_GET['client'] !== 'seq') {
503
- $shares = new ShareaholicCurlMultiShareCount($url, $services, $options);
504
- } else {
505
- $shares = new ShareaholicSeqShareCount($url, $services, $options);
506
- }
507
- } else if($has_curl_multi) {
508
- $shares = new ShareaholicCurlMultiShareCount($url, $services, $options);
509
- } else {
510
- $shares = new ShareaholicSeqShareCount($url, $services, $options);
511
- }
512
-
513
- $result = $shares->get_counts();
514
-
515
- if ($debug_mode) {
516
- $result['has_curl_multi'] = $has_curl_multi;
517
- $result['curl_type'] = get_class($shares);
518
- $result['meta'] = $shares->raw_response;
519
- }
520
-
521
- if (isset($result['data']) && !$debug_mode) {
522
- $result['services'] = $services;
523
- set_transient( $cache_key, $result, SHARE_COUNTS_CHECK_CACHE_LENGTH );
524
- }
525
- }
526
- }
527
-
528
- $seconds_to_cache = 900; // 15 minutes
529
- $ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
530
- header('Access-Control-Allow-Origin: *');
531
- header('Content-Type: application/json');
532
- header("Expires: $ts");
533
- header("Cache-Control: max-age=$seconds_to_cache"); // 10 minutes
534
- echo json_encode($result);
535
- exit;
536
- }
537
-
538
- /**
539
- * Helper method to parse the list of social services to get share counts
540
- */
541
- public static function parse_services($services) {
542
- $result = array();
543
-
544
- if (empty($services) || !is_array($services)) {
545
- return $result;
546
- }
547
-
548
- // make the set of services unique
549
- $services = array_unique($services);
550
-
551
- // only get the services we can get share counts for
552
- $social_services = array_keys(ShareaholicSeqShareCount::get_services_config());
553
-
554
- foreach($services as $service) {
555
- if (in_array($service, $social_services)) {
556
- array_push($result, $service);
557
- }
558
- }
559
-
560
- return $result;
561
- }
562
-
563
- /**
564
- * Helper method to check if the result has the requested services
565
- */
566
- public static function has_services_in_result($result, $services) {
567
- if (!isset($result['services'])) {
568
- return false;
569
- }
570
-
571
- $requested_services = $result['services'];
572
- foreach($services as $service) {
573
- if (!in_array($service, $requested_services)) {
574
- return false;
575
- }
576
- }
577
-
578
- return true;
579
- }
580
-
581
- /**
582
- * Function to return relevant plugin debug info
583
- *
584
- * @return debug info in JSON
585
- */
586
- public static function debug_info() {
587
-
588
- if (ShareaholicUtilities::get_option('disable_debug_info') == "on"){
589
- exit;
590
- }
591
-
592
- if (ShareaholicUtilities::has_accepted_terms_of_service() == 1){
593
- $tos_status = "accepted";
594
- } else {
595
- $tos_status = "pending";
596
- }
597
-
598
- if (function_exists('curl_version')){
599
- $curl_version = curl_version();
600
- }
601
-
602
- $info = array(
603
- 'plugin_version' => Shareaholic::VERSION,
604
- 'plugin_version_in_db' => ShareaholicUtilities::get_version(),
605
- 'site_id' => ShareaholicUtilities::get_option('api_key'),
606
- 'domain' => get_bloginfo('url'),
607
- 'language' => get_bloginfo('language'),
608
- 'tos_status' => $tos_status,
609
- 'stats' => ShareaholicUtilities::get_stats(),
610
- 'diagnostics' => array(
611
- 'theme' => get_option('template'),
612
- 'multisite' => is_multisite(),
613
- 'shareaholic_server_reachable' => ShareaholicUtilities::connectivity_check(),
614
- 'server_side_share_count_api_reachable' => ShareaholicUtilities::share_counts_api_connectivity_check(),
615
- 'php_version' => phpversion(),
616
- 'wp_version' => get_bloginfo('version'),
617
- 'curl' => array (
618
- 'status' => ShareaholicPublic::has_curl(),
619
- 'version' => $curl_version,
620
- ),
621
- 'plugins' => array(
622
- 'active' => ShareaholicUtilities::get_active_plugins(),
623
- ),
624
- ),
625
- 'app_locations' => array(
626
- 'share_buttons' => ShareaholicUtilities::get_option('share_buttons'),
627
- 'recommendations' => ShareaholicUtilities::get_option('recommendations'),
628
- ),
629
- 'advanced_settings' => array(
630
- 'server_side_share_count_api' => ShareaholicUtilities::get_internal_share_counts_api_status(),
631
- 'facebook_access_token' => ShareaholicUtilities::fetch_fb_access_token() === false ? 'no' : 'yes',
632
- 'facebook_auth_check' => ShareaholicUtilities::facebook_auth_check(),
633
- 'enable_user_nicename' => ShareaholicUtilities::get_option('enable_user_nicename'),
634
- 'disable_og_tags' => ShareaholicUtilities::get_option('disable_og_tags'),
635
- 'disable_admin_bar_menu' => ShareaholicUtilities::get_option('disable_admin_bar_menu'),
636
- 'recommendations_display_on_excerpts' => ShareaholicUtilities::get_option('recommendations_display_on_excerpts'),
637
- 'share_buttons_display_on_excerpts' => ShareaholicUtilities::get_option('share_buttons_display_on_excerpts'),
638
- ),
639
- );
640
-
641
- header('Content-Type: application/json');
642
- echo json_encode($info);
643
- exit;
644
- }
645
-
646
-
647
- /**
648
- * Function to return list of permalinks
649
- *
650
- * @return list of permalinks in JSON or plain text
651
- */
652
- public static function permalink_list(){
653
- // Input Params
654
- $post_type = isset($_GET['post_type']) ? $_GET['post_type'] : "any";
655
- $n = isset($_GET['n']) ? intval($_GET['n']) : -1;
656
- $format = isset($_GET['format']) ? $_GET['format'] : "json";
657
-
658
- $permalink_list = array();
659
- $permalink_query = "post_type=$post_type&post_status=publish&posts_per_page=$n";
660
- $posts = new WP_Query ($permalink_query);
661
- $posts = $posts->posts;
662
- foreach($posts as $post){
663
- switch ($post->post_type){
664
- case 'revision':
665
- case 'nav_menu_item':
666
- break;
667
- case 'page':
668
- $permalink = get_page_link($post->ID);
669
- array_push($permalink_list, $permalink);
670
- break;
671
- case 'post':
672
- $permalink = get_permalink($post->ID);
673
- array_push($permalink_list, $permalink);
674
- break;
675
- case 'attachment':
676
- break;
677
- default:
678
- $permalink = get_post_permalink($post->ID);
679
- array_push($permalink_list, $permalink);
680
- break;
681
- }
682
- }
683
-
684
- if ($format === "text"){
685
- header('Content-Type: text/plain; charset=utf-8');
686
- foreach($permalink_list as $link) {
687
- echo $link. "\r\n";
688
- }
689
- } elseif ($format === "json"){
690
- header('Content-Type: application/json; charset=utf-8');
691
- echo json_encode($permalink_list);
692
- }
693
- exit;
694
- }
695
-
696
- /**
697
- * Function to return relevant info for the SDK Badge
698
- *
699
- * @return sdk info in JSON
700
- */
701
- public static function sdk_info() {
702
-
703
- if (!current_user_can('activate_plugins')) {
704
- $info = array(
705
- 'sdk_info' => array(
706
- 'message' => "Unauthorized",
707
- ),
708
- );
709
- } else {
710
- $info = array(
711
- 'sdk_info' => array(
712
- 'site_id' => ShareaholicUtilities::get_option('api_key'),
713
- 'verification_key' => ShareaholicUtilities::get_option('verification_key'),
714
- 'wp_user_info' => ShareaholicUtilities::user_info(),
715
- ),
716
- );
717
- }
718
-
719
- header('Content-Type: application/json; charset=utf-8');
720
- echo json_encode($info);
721
- exit;
722
- }
723
-
724
- /**
725
- * Function to return relevant info for a given permalink for the Related Content index
726
- *
727
- * @return page info in JSON
728
- */
729
- public static function permalink_info() {
730
- global $wpdb, $post;
731
-
732
- // Input Params
733
- $permalink = isset($_GET['permalink']) ? $_GET['permalink'] : NULL;
734
- $body_text = isset($_GET['body_text']) ? $_GET['body_text'] : "raw";
735
-
736
- if ($permalink == NULL){
737
- return;
738
- }
739
-
740
- // Get post ID
741
- $post_id = url_to_postid($permalink);
742
-
743
- // for non-default paths - handle both https and http versions of the permalink
744
- if ($post_id == 0){
745
- $parse = parse_url($permalink);
746
- if ($parse['scheme'] == "https"){
747
- $permalink = str_replace("https", "http", $permalink);
748
- $post_id = url_to_postid($permalink);
749
- } else if ($parse['scheme'] == "http"){
750
- $permalink = str_replace("http", "https", $permalink);
751
- $post_id = url_to_postid($permalink);
752
- }
753
- }
754
-
755
- if ($post_id == 0){
756
- return;
757
- }
758
-
759
- // Get post for given ID
760
- $post = get_post($post_id);
761
-
762
- if ($post->post_status != 'publish' || $post->post_password != ''){
763
- return;
764
- }
765
-
766
- // Post tags
767
- $tags = ShareaholicUtilities::permalink_keywords($post_id);
768
-
769
- // Post categories
770
- $categories = array();
771
- $categories_array = get_the_category($post_id);
772
-
773
- if($categories_array) {
774
- foreach($categories_array as $category) {
775
- if ($category->cat_name != "Uncategorized") {
776
- $category_name = ShareaholicUtilities::normalize_keywords($category->cat_name);
777
- array_push($categories, $category_name);
778
- }
779
- }
780
- }
781
-
782
- // Post body
783
- $order = array("&nbsp;", "\r\n", "\n", "\r", " ");
784
- $post_body = str_replace($order, ' ', $post->post_content);
785
-
786
- if ($body_text == "clean"){
787
- $post_body = strip_tags($post_body);
788
- } elseif ($body_text == "raw" || $body_text == NULL) {
789
- $post_body = $post_body;
790
- }
791
-
792
- // Get post author name
793
- if ($post->post_author) {
794
- $author_data = get_userdata($post->post_author);
795
- $author_name = $author_data->display_name;
796
- }
797
-
798
- // Term frequencies
799
- // $term_frequency_title = array_count_values(str_word_count(strtolower(strip_tags($post->post_title)), 1));
800
- $term_frequency_body = array_count_values(str_word_count(strtolower(strip_tags($post_body)), 1));
801
-
802
- $term_frequency = $term_frequency_body;
803
- arsort($term_frequency);
804
-
805
- // Construct array
806
- $info = array(
807
- 'permalink' => $permalink,
808
- 'domain' => get_bloginfo('url'),
809
- 'site_id' => ShareaholicUtilities::get_option('api_key'),
810
- 'content' => array(
811
- 'title' => $post->post_title,
812
- 'excerpt' => $post->post_excerpt,
813
- 'body' => $post_body,
814
- 'thumbnail' => ShareaholicUtilities::permalink_thumbnail($post->ID),
815
- ),
816
- 'post_metadata' => array(
817
- 'author_id' => $post->post_author,
818
- 'author_name' => $author_name,
819
- 'post_type' => $post->post_type,
820
- 'post_id' => $post_id,
821
- 'post_tags' => $tags,
822
- 'post_categories' => $categories,
823
- 'post_language' => get_bloginfo('language'),
824
- 'post_published' => get_the_date( DATE_W3C ),
825
- 'post_updated' => get_the_modified_date( DATE_W3C ),
826
- 'post_visibility' => $post->post_status,
827
- ),
828
- 'post_stats' => array(
829
- 'post_comments_count' => get_comments_number($post_id),
830
- 'post_content_title_character_count' => strlen(trim(html_entity_decode($post->post_title))),
831
- 'post_content_title_word_count' => str_word_count(strip_tags($post->post_title)),
832
- 'post_content_body_character_count' => strlen(trim(html_entity_decode($post_body))),
833
- 'post_content_body_word_count' => str_word_count(strip_tags($post_body)),
834
- 'term_frequency' => $term_frequency,
835
- ),
836
- 'diagnostics' => array(
837
- 'platform' => 'wp',
838
- 'platform_version' => get_bloginfo('version'),
839
- 'plugin_version' => Shareaholic::VERSION,
840
- ),
841
- );
842
-
843
- header('Content-Type: application/json; charset=utf-8');
844
- echo json_encode($info);
845
- exit;
846
- }
847
-
848
- /**
849
- * Function to return related permalinks for a given permalink to bootstrap the Related Posts app until cloud-based processing routines complete
850
- *
851
- * @return list of related permalinks in JSON
852
- */
853
- public static function permalink_related() {
854
- global $post;
855
-
856
- // Input Params
857
- $permalink = isset($_GET['permalink']) ? $_GET['permalink'] : NULL;
858
- $match = isset($_GET['match']) ? $_GET['match'] : "random"; // match method
859
- $n = isset($_GET['n']) ? intval($_GET['n']) : 10; // number of related permalinks to return
860
-
861
- $related_permalink_list = array();
862
-
863
- // Get post ID
864
- if ($permalink == NULL){
865
- // default to random match if no permalink is available
866
- $match = "random";
867
- $post_id = 0;
868
- } else {
869
- $post_id = url_to_postid($permalink);
870
-
871
- // for non-default paths - handle both https and http versions of the permalink
872
- if ($post_id == 0){
873
- $parse = parse_url($permalink);
874
- if ($parse['scheme'] == "https"){
875
- $permalink = str_replace("https", "http", $permalink);
876
- $post_id = url_to_postid($permalink);
877
- } else if ($parse['scheme'] == "http"){
878
- $permalink = str_replace("http", "https", $permalink);
879
- $post_id = url_to_postid($permalink);
880
- }
881
- }
882
- }
883
-
884
- if ($match == "random"){
885
- // Determine which page types to show
886
- $post_types = get_post_types(array('public' => true));
887
- $post_types_exclude = array('page', 'attachment', 'nav_menu_item');
888
- $post_types_filtered = array_diff($post_types, $post_types_exclude);
889
-
890
- // Query
891
- $args = array(
892
- 'post_type' => $post_types_filtered,
893
- 'post__not_in' => array($post_id),
894
- 'posts_per_page' => $n,
895
- 'orderby' => 'rand',
896
- 'post_status' => 'publish'
897
- );
898
-
899
- $rand_posts = get_posts( $args );
900
- foreach ( $rand_posts as $post ){
901
- if ($post->post_title) {
902
- $related_link = array(
903
- 'content_id' => $post->ID,
904
- 'url' => get_permalink($post->ID),
905
- 'title' => $post->post_title,
906
- 'description' => $post->post_excerpt,
907
- 'author' => get_userdata($post->post_author)->display_name,
908
- 'image_url' => preg_replace('#^https?://#', '//', ShareaholicUtilities::permalink_thumbnail($post->ID)),
909
- 'score' => 1,
910
- 'published_date' => get_the_date( DATE_W3C ),
911
- 'modified_date' => get_the_modified_date( DATE_W3C ),
912
- 'channel_id' => 'plugin',
913
- 'display_url' => get_permalink($post->ID),
914
- );
915
- array_push($related_permalink_list, $related_link);
916
- }
917
- }
918
- wp_reset_postdata();
919
- } else {
920
- // other match methods can be added here
921
- }
922
-
923
- // Construct results array
924
- $result = array(
925
- 'request' => array(
926
- 'api_key' => ShareaholicUtilities::get_option('api_key'),
927
- 'url' => $permalink,
928
- ),
929
- 'internal' => $related_permalink_list
930
- );
931
-
932
- header('Content-Type: application/json; charset=utf-8');
933
- header('Cache-Control: max-age=300'); // 5 minutes
934
- echo json_encode($result);
935
- exit;
936
- }
937
-
938
- /**
939
- * Checks to see if curl is installed
940
- *
941
- * @return bool true or false that curl is installed
942
- */
943
- public static function has_curl(){
944
- return function_exists('curl_version') && function_exists('curl_multi_init') && function_exists('curl_multi_add_handle') && function_exists('curl_multi_exec');
945
- }
946
  }
947
 
948
- ?>
6
  */
7
 
8
  // Get the required libraries for the Share Counts API
9
+ require_once SHAREAHOLIC_PATH . 'lib/social-share-counts/wordpress_http.php';
10
+ require_once SHAREAHOLIC_PATH . 'lib/social-share-counts/seq_share_count.php';
11
+ require_once SHAREAHOLIC_PATH . 'lib/social-share-counts/curl_multi_share_count.php';
12
+ require_once SHAREAHOLIC_PATH . 'public_js.php';
13
 
14
  /**
15
  * This class is all about drawing the stuff in publishers'
19
  */
20
  class ShareaholicPublic {
21
 
22
+ /**
23
+ * Loads before all else
24
+ */
25
+ public static function after_setup_theme() {
26
+ // Ensure thumbnail/featured image support
27
+ if ( ! current_theme_supports( 'post-thumbnails' ) ) {
28
+ add_theme_support( 'post-thumbnails' );
29
+ }
30
+
31
+ // Adds support for shortcodes in sidebar text widgets
32
+ if ( ! has_filter( 'widget_text', 'do_shortcode' ) ) {
33
+ add_filter( 'widget_text', 'do_shortcode', 11 );
34
+ }
35
+
36
+ // Our custom image type
37
+ add_image_size( 'shareaholic-thumbnail', 640 ); // 640 pixels wide (and unlimited height)
38
+ }
39
+
40
+ /**
41
+ * The function called during the wp_head action. The
42
+ * rest of the plugin doesn't need to know exactly what happens.
43
+ */
44
+ public static function wp_head() {
45
+ self::script_tag();
46
+ self::shareaholic_tags();
47
+ self::draw_og_tags();
48
+ }
49
+
50
+ /**
51
+ * Inserts resource hints in </head> to speed up loading
52
+ */
53
+ public static function shareaholic_resource_hints( $hints, $relation_type ) {
54
+ if ( 'dns-prefetch' === $relation_type ) {
55
+ if ( $hints ) {
56
+ array_push(
57
+ $hints,
58
+ '//k4z6w9b5.stackpathcdn.com',
59
+ '//cdn.shareaholic.net',
60
+ '//www.shareaholic.net',
61
+ '//analytics.shareaholic.com',
62
+ '//recs.shareaholic.com',
63
+ '//go.shareaholic.com',
64
+ '//partner.shareaholic.com'
65
+ );
66
+ }
67
+ }
68
+ return $hints;
69
+ }
70
+
71
+ /**
72
+ * Inserts the script code snippet into the head of the page
73
+ */
74
+ public static function script_tag() {
75
+ if ( ShareaholicUtilities::has_accepted_terms_of_service() && ShareaholicUtilities::get_or_create_api_key() ) {
76
+ ShareaholicUtilities::load_template(
77
+ 'script_tag',
78
+ array(
79
+ 'api_key' => ShareaholicUtilities::get_option( 'api_key' ),
80
+ 'base_settings' => ShareaholicPublicJS::get_base_settings(),
81
+ 'overrides' => ShareaholicPublicJS::get_overrides(),
82
+ )
83
+ );
84
+ }
85
+ }
86
+
87
+ /**
88
+ * The function that gets called for shortcodes
89
+ *
90
+ * @param array $attributes this is passed keys: `id`, `app`, `title`, `link`, `summary`
91
+ * @param string $content is the enclosed content (if the shortcode is used in its enclosing form)
92
+ */
93
+ public static function shortcode( $attributes, $content = null ) {
94
+ extract(
95
+ shortcode_atts(
96
+ array(
97
+ 'id' => null,
98
+ 'id_name' => null,
99
+ 'app' => 'share_buttons',
100
+ 'title' => null,
101
+ 'link' => null,
102
+ 'summary' => null,
103
+ ),
104
+ $attributes,
105
+ 'shareaholic'
106
+ )
107
+ );
108
+
109
+ if ( isset( $attributes['id'] ) ) {
110
+ $id = trim( $attributes['id'] );
111
+ }
112
+ if ( isset( $attributes['id_name'] ) ) {
113
+ $id_name = trim( $attributes['id_name'] );
114
+ }
115
+ if ( isset( $attributes['app'] ) ) {
116
+ $app = trim( $attributes['app'] );
117
+ }
118
+ if ( isset( $attributes['title'] ) ) {
119
+ $title = esc_attr( trim( $attributes['title'] ) );
120
+ }
121
+ if ( isset( $attributes['link'] ) ) {
122
+ $link = trim( $attributes['link'] );
123
+ }
124
+ if ( isset( $attributes['summary'] ) ) {
125
+ $summary = esc_attr( trim( $attributes['summary'] ) );
126
+ }
127
+
128
+ return self::canvas( $id, $app, $id_name, $title, $link, $summary );
129
+ }
130
+
131
+
132
+ /**
133
+ * Draws the shareaholic meta tags.
134
+ */
135
+ private static function shareaholic_tags() {
136
+ echo "\n<!-- Shareaholic Content Tags -->\n";
137
+ self::draw_site_name_meta_tag();
138
+ self::draw_language_meta_tag();
139
+ self::draw_url_meta_tag();
140
+ self::draw_keywords_meta_tag();
141
+ self::draw_article_meta_tag();
142
+ self::draw_site_id_meta_tag();
143
+ self::draw_plugin_version_meta_tag();
144
+ self::draw_image_meta_tag();
145
+ echo "\n<!-- Shareaholic Content Tags End -->\n";
146
+ }
147
+
148
+ /**
149
+ * Draws Shareaholic keywords meta tag.
150
+ */
151
+ private static function draw_keywords_meta_tag() {
152
+ if ( in_array( ShareaholicUtilities::page_type(), array( 'page', 'post' ) ) ) {
153
+
154
+ global $post;
155
+ $tags = array();
156
+ if ( is_attachment() && $post->post_parent ) {
157
+ $id = $post->post_parent;
158
+ } else {
159
+ $id = $post->ID;
160
+ }
161
+
162
+ // Get post tags
163
+ $tags = preg_replace( '/^/', 'tag:', ShareaholicUtilities::permalink_keywords( $id ) );
164
+
165
+ // Get post categories
166
+ $categories_array = get_the_category( $id );
167
+ $categories = array();
168
+
169
+ if ( $categories_array ) {
170
+ foreach ( $categories_array as $category ) {
171
+ if ( $category->cat_name != 'Uncategorized' ) {
172
+ array_push( $categories, $category->cat_name );
173
+ }
174
+ }
175
+ $categories = preg_replace( '/^/', 'cat:', $categories );
176
+ }
177
+
178
+ $keywords_array = array();
179
+ $keywords = '';
180
+
181
+ // Merge + add page type
182
+ $keywords_array = array_merge( $tags, $categories );
183
+ if ( $post->post_type ) {
184
+ array_push( $keywords_array, 'type:' . $post->post_type );
185
+ }
186
+
187
+ // Unique keywords
188
+ $keywords_array = array_unique( $keywords_array );
189
+
190
+ if ( ! empty( $keywords_array[0] ) ) {
191
+ $keywords = implode( ', ', $keywords_array );
192
+
193
+ // Encode, lowercase & trim appropriately
194
+ $keywords = ShareaholicUtilities::normalize_keywords( $keywords );
195
+ }
196
+
197
+ if ( $keywords != '' && $keywords != 'array' ) {
198
+ echo "<meta name='shareaholic:keywords' content='" . $keywords . "' />\n";
199
+ }
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Draws Shareaholic article meta tags
205
+ */
206
+ private static function draw_article_meta_tag() {
207
+
208
+ if ( in_array( ShareaholicUtilities::page_type(), array( 'index', 'category' ) ) || is_404() ) {
209
+ echo "<meta name='shareaholic:article_visibility' content='private' />\n";
210
+ return;
211
+ }
212
+
213
+ if ( in_array( ShareaholicUtilities::page_type(), array( 'page', 'post' ) ) ) {
214
+ global $post;
215
+
216
+ // Article Publish and Modified Time
217
+ $article_published_time = get_the_date( DATE_W3C );
218
+ $article_modified_time = get_the_modified_date( DATE_W3C );
219
+
220
+ if ( ! empty( $article_published_time ) ) {
221
+ echo "<meta name='shareaholic:article_published_time' content='" . $article_published_time . "' />\n";
222
+ }
223
+ if ( ! empty( $article_modified_time ) ) {
224
+ echo "<meta name='shareaholic:article_modified_time' content='" . $article_modified_time . "' />\n";
225
+ }
226
+
227
+ // Article Visibility
228
+ $article_visibility = $post->post_status;
229
+ $article_password = $post->post_password;
230
+
231
+ if ( $article_visibility == 'draft' || $article_visibility == 'auto-draft' || $article_visibility == 'future' || $article_visibility == 'pending' ) {
232
+ echo "<meta name='shareaholic:shareable_page' content='false' />\n";
233
+ $article_visibility = 'draft';
234
+ } elseif ( $article_visibility == 'private' || $post->post_password != '' ) {
235
+ echo "<meta name='shareaholic:shareable_page' content='false' />\n";
236
+ $article_visibility = 'private';
237
+ } elseif ( is_attachment() ) {
238
+ // attachments are shareable but not recommendable
239
+ echo "<meta name='shareaholic:shareable_page' content='true' />\n";
240
+ $article_visibility = 'private';
241
+ } else {
242
+ echo "<meta name='shareaholic:shareable_page' content='true' />\n";
243
+ $article_visibility = null;
244
+ }
245
+
246
+ // Lookup Metabox value
247
+ if ( get_post_meta( $post->ID, 'shareaholic_exclude_recommendations', true ) ) {
248
+ $article_visibility = 'private';
249
+ }
250
+
251
+ if ( ! empty( $article_visibility ) ) {
252
+ echo "<meta name='shareaholic:article_visibility' content='" . $article_visibility . "' />\n";
253
+ }
254
+
255
+ // Article Author Name
256
+ if ( $post->post_author ) {
257
+ $article_author_data = get_userdata( $post->post_author );
258
+ if ( $article_author_data ) {
259
+ $article_author_name = $article_author_data->display_name;
260
+ }
261
+ }
262
+ if ( ! empty( $article_author_name ) ) {
263
+ echo "<meta name='shareaholic:article_author_name' content='" . htmlspecialchars( $article_author_name, ENT_QUOTES ) . "' />\n";
264
+ }
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Draws Shareaholic language meta tag.
270
+ */
271
+ private static function draw_language_meta_tag() {
272
+ $blog_language = get_bloginfo( 'language' );
273
+ if ( ! empty( $blog_language ) ) {
274
+ echo "<meta name='shareaholic:language' content='" . $blog_language . "' />\n";
275
+ }
276
+ }
277
+
278
+ /**
279
+ * Draws Shareaholic url meta tag.
280
+ */
281
+ private static function draw_url_meta_tag() {
282
+ if ( in_array( ShareaholicUtilities::page_type(), array( 'page', 'post' ) ) ) {
283
+ $url_link = get_permalink();
284
+ echo "<meta name='shareaholic:url' content='" . $url_link . "' />\n";
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Draws Shareaholic version meta tag.
290
+ */
291
+ private static function draw_plugin_version_meta_tag() {
292
+ echo "<meta name='shareaholic:wp_version' content='" . ShareaholicUtilities::get_version() . "' />\n";
293
+ }
294
+
295
+ /**
296
+ * Draws Shareaholic site name meta tag.
297
+ */
298
+ private static function draw_site_name_meta_tag() {
299
+ $blog_name = get_bloginfo();
300
+ if ( ! empty( $blog_name ) ) {
301
+ echo "<meta name='shareaholic:site_name' content='" . $blog_name . "' />\n";
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Draws Shareaholic site_id meta tag.
307
+ */
308
+ private static function draw_site_id_meta_tag() {
309
+ $site_id = ShareaholicUtilities::get_option( 'api_key' );
310
+ if ( ! empty( $site_id ) ) {
311
+ echo "<meta name='shareaholic:site_id' content='" . $site_id . "' />\n";
312
+ }
313
+ }
314
+
315
+ /**
316
+ * Draws Shareaholic image meta tag. Will only run on pages or posts.
317
+ */
318
+ private static function draw_image_meta_tag() {
319
+ if ( in_array( ShareaholicUtilities::page_type(), array( 'page', 'post' ) ) ) {
320
+ global $post;
321
+ $thumbnail_src = '';
322
+
323
+ if ( is_attachment() ) {
324
+ $thumbnail_src = wp_get_attachment_thumb_url();
325
+ }
326
+
327
+ $thumbnail_src = ShareaholicUtilities::post_featured_image();
328
+
329
+ if ( $thumbnail_src == null ) {
330
+ $thumbnail_src = ShareaholicUtilities::post_first_image();
331
+ }
332
+
333
+ if ( $thumbnail_src != null ) {
334
+ echo "<meta name='shareaholic:image' content='" . $thumbnail_src . "' />";
335
+ }
336
+ }
337
+ }
338
+
339
+ /**
340
+ * Draws an open graph image meta tag if they are enabled and exist. Will only run on pages or posts.
341
+ */
342
+ private static function draw_og_tags() {
343
+ if ( in_array( ShareaholicUtilities::page_type(), array( 'page', 'post' ) ) ) {
344
+ global $post;
345
+ $thumbnail_src = '';
346
+ $settings = ShareaholicUtilities::get_settings();
347
+
348
+ if ( ! get_post_meta( $post->ID, 'shareaholic_disable_open_graph_tags', true ) && ( isset( $settings['disable_og_tags'] ) && $settings['disable_og_tags'] == 'off' ) ) {
349
+ if ( is_attachment() ) {
350
+ $thumbnail_src = wp_get_attachment_thumb_url();
351
+ }
352
+ if ( function_exists( 'has_post_thumbnail' ) && has_post_thumbnail( $post->ID ) ) {
353
+ $thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'large' );
354
+ $thumbnail_src = esc_attr( $thumbnail[0] );
355
+ }
356
+ if ( $thumbnail_src == null ) {
357
+ $thumbnail_src = ShareaholicUtilities::post_first_image();
358
+ }
359
+ if ( $thumbnail_src != null ) {
360
+ echo "\n<!-- Shareaholic Open Graph Tags -->\n";
361
+ echo "<meta property='og:image' content='" . $thumbnail_src . "' />";
362
+ echo "\n<!-- Shareaholic Open Graph Tags End -->\n";
363
+ }
364
+ }
365
+ }
366
+ }
367
+
368
+ /**
369
+ * This static function inserts the shareaholic canvas in a post
370
+ *
371
+ * @param string $content the WordPress content
372
+ * @return string the content
373
+ */
374
+ public static function draw_canvases( $content ) {
375
+ global $wp_current_filter;
376
+ if ( is_main_query() ) {
377
+ $settings = ShareaholicUtilities::get_settings();
378
+ $page_type = ShareaholicUtilities::page_type();
379
+
380
+ // Don't allow this function to run more than once for a page load (prevent infinite loops)
381
+ $has_run = false;
382
+ foreach ( $wp_current_filter as $filter ) {
383
+ if ( 'the_content' == $filter ) {
384
+ if ( $has_run ) {
385
+ // has already run once
386
+ return $content;
387
+ } else {
388
+ // first run, set flag!
389
+ $has_run = true;
390
+ }
391
+ }
392
+ }
393
+
394
+ foreach ( array( 'share_buttons', 'recommendations' ) as $app ) {
395
+ // check Excerpt prefs
396
+ if ( 'the_excerpt' == current_filter() && isset( $settings[ "{$app}_display_on_excerpts" ] ) && $settings[ "{$app}_display_on_excerpts" ] == 'off' ) {
397
+ return $content;
398
+ }
399
+
400
+ // check individual post prefs
401
+ if ( ! get_post_meta( get_the_ID(), "shareaholic_disable_{$app}", true ) ) {
402
+ // check if ABOVE location is turned on
403
+ if ( isset( $settings[ $app ][ "{$page_type}_above_content" ] ) && $settings[ $app ][ "{$page_type}_above_content" ] == 'on' ) {
404
+ $id = $settings['location_name_ids'][ $app ][ "{$page_type}_above_content" ];
405
+ $content = self::canvas( $id, $app, "{$page_type}_above_content" ) . $content;
406
+ }
407
+ // check if BELOW location is turned on
408
+ if ( isset( $settings[ $app ][ "{$page_type}_below_content" ] ) && $settings[ $app ][ "{$page_type}_below_content" ] == 'on' ) {
409
+ $id = $settings['location_name_ids'][ $app ][ "{$page_type}_below_content" ];
410
+ $content .= self::canvas( $id, $app, "{$page_type}_below_content" );
411
+ }
412
+ }
413
+ }
414
+ }
415
+
416
+ // something that uses the_content hook must return the $content
417
+ return $content;
418
+ }
419
+
420
+ /**
421
+ * Draws an individual canvas given a specific location
422
+ * id and app. The app isn't strictly necessary, but is
423
+ * being kept for now for backwards compatability.
424
+ * This method was private, but was made public to be accessed
425
+ * by the shortcode static function in global_functions.php.
426
+ *
427
+ * @param string $id the location id for configuration
428
+ * @param string $id_name the location id name for configuration
429
+ * @param string $app the type of app
430
+ * @param string $title the title of URL
431
+ * @param string $link url
432
+ * @param string $summary summary text for URL
433
+ */
434
+ public static function canvas( $id = null, $app, $id_name = null, $title = null, $link = null, $summary = null ) {
435
+ global $post, $wp_query;
436
+ $page_type = ShareaholicUtilities::page_type();
437
+ $is_list_page = $page_type == 'index' || $page_type == 'category';
438
+ $loop_start = did_action( 'loop_start' );
439
+ $loop_end = did_action( 'loop_end' );
440
+ $in_loop = $loop_start > $loop_end ? true : false;
441
+
442
+ $link = trim( $link );
443
+
444
+ // Use the $post object to get the title, link, and summary only if the
445
+ // title, link or summary is not provided AND one of the following is true:
446
+ // - we are on a non list page
447
+ // - we are in the WordPress loop
448
+ if ( trim( $title ) == null && ( ! $is_list_page || $in_loop ) ) {
449
+ $title = htmlspecialchars( $post->post_title, ENT_QUOTES );
450
+ }
451
+ if ( trim( $link ) == null && ( ! $is_list_page || $in_loop ) ) {
452
+ $link = get_permalink( $post->ID );
453
+ }
454
+ if ( trim( $summary ) == null && ( ! $is_list_page || $in_loop ) ) {
455
+ $summary = htmlspecialchars( strip_tags( strip_shortcodes( $post->post_excerpt ) ), ENT_QUOTES );
456
+ $summary = ShareaholicUtilities::truncate_text( $summary, 500 );
457
+ }
458
+
459
+ $canvas = "<div class='shareaholic-canvas'
460
  data-app='$app'
461
  data-title='$title'
462
  data-link='$link'";
463
+
464
+ if ( $summary != null ) {
465
+ $canvas .= " data-summary='$summary'";
466
+ }
467
+
468
+ if ( $id != null ) {
469
+ $canvas .= " data-app-id='$id'";
470
+ }
471
+
472
+ if ( $id_name != null ) {
473
+ $canvas .= " data-app-id-name='$id_name'";
474
+ }
475
+
476
+ $canvas .= '></div>';
477
+
478
+ return trim( preg_replace( '/\s+/', ' ', $canvas ) );
479
+ }
480
+
481
+
482
+ /**
483
+ * Function to handle the share count API requests
484
+ */
485
+ public static function share_counts_api() {
486
+ $debug_mode = isset( $_GET['debug'] ) && $_GET['debug'] === '1';
487
+ $url = isset( $_GET['url'] ) ? $_GET['url'] : '';
488
+ $services = isset( $_GET['services'] ) ? $_GET['services'] : array();
489
+ $services = self::parse_services( $services );
490
+ $cache_key = 'shr_api_res-' . md5( $url );
491
+
492
+ if ( empty( $url ) || empty( $services ) ) {
493
+ $result = array();
494
+ } else {
495
+ $result = get_transient( $cache_key );
496
+ }
497
+
498
+ $has_curl_multi = self::has_curl();
499
+
500
+ if ( ! $result || $debug_mode || ! self::has_services_in_result( $result, $services ) ) {
501
+ if ( isset( $result['services'] ) && ! $debug_mode ) {
502
+ $services = array_keys( array_flip( array_merge( $result['services'], $services ) ) );
503
+ }
504
+
505
+ $result = array();
506
+ $options = array();
507
+
508
+ if ( $debug_mode && isset( $_GET['timeout'] ) ) {
509
+ $options['timeout'] = intval( $_GET['timeout'] );
510
+ }
511
+
512
+ if ( $debug_mode ) {
513
+ $options['show_raw'] = isset( $_GET['raw'] ) ? $_GET['raw'] : '1';
514
+ $options['show_response_header'] = isset( $_GET['response_headers'] ) ? $_GET['response_headers'] : '1';
515
+ }
516
+
517
+ if ( ShareaholicUtilities::facebook_auth_check() == 'SUCCESS' ) {
518
+ $options['facebook_access_token'] = ShareaholicUtilities::fetch_fb_access_token();
519
+ }
520
+
521
+ if ( is_array( $services ) && count( $services ) > 0 && ! empty( $url ) ) {
522
+ if ( $debug_mode && isset( $_GET['client'] ) ) {
523
+ if ( $has_curl_multi && $_GET['client'] !== 'seq' ) {
524
+ $shares = new ShareaholicCurlMultiShareCount( $url, $services, $options );
525
+ } else {
526
+ $shares = new ShareaholicSeqShareCount( $url, $services, $options );
527
+ }
528
+ } elseif ( $has_curl_multi ) {
529
+ $shares = new ShareaholicCurlMultiShareCount( $url, $services, $options );
530
+ } else {
531
+ $shares = new ShareaholicSeqShareCount( $url, $services, $options );
532
+ }
533
+
534
+ $result = $shares->get_counts();
535
+
536
+ if ( $debug_mode ) {
537
+ $result['has_curl_multi'] = $has_curl_multi;
538
+ $result['curl_type'] = get_class( $shares );
539
+ $result['meta'] = $shares->raw_response;
540
+ }
541
+
542
+ if ( isset( $result['data'] ) && ! $debug_mode ) {
543
+ $result['services'] = $services;
544
+ set_transient( $cache_key, $result, SHARE_COUNTS_CHECK_CACHE_LENGTH );
545
+ }
546
+ }
547
+ }
548
+
549
+ $seconds_to_cache = 900; // 15 minutes
550
+ $ts = gmdate( 'D, d M Y H:i:s', time() + $seconds_to_cache ) . ' GMT';
551
+ header( 'Access-Control-Allow-Origin: *' );
552
+ header( 'Content-Type: application/json' );
553
+ header( "Expires: $ts" );
554
+ header( "Cache-Control: max-age=$seconds_to_cache" ); // 10 minutes
555
+ echo json_encode( $result );
556
+ exit;
557
+ }
558
+
559
+ /**
560
+ * Helper method to parse the list of social services to get share counts
561
+ */
562
+ public static function parse_services( $services ) {
563
+ $result = array();
564
+
565
+ if ( empty( $services ) || ! is_array( $services ) ) {
566
+ return $result;
567
+ }
568
+
569
+ // make the set of services unique
570
+ $services = array_unique( $services );
571
+
572
+ // only get the services we can get share counts for
573
+ $social_services = array_keys( ShareaholicSeqShareCount::get_services_config() );
574
+
575
+ foreach ( $services as $service ) {
576
+ if ( in_array( $service, $social_services ) ) {
577
+ array_push( $result, $service );
578
+ }
579
+ }
580
+
581
+ return $result;
582
+ }
583
+
584
+ /**
585
+ * Helper method to check if the result has the requested services
586
+ */
587
+ public static function has_services_in_result( $result, $services ) {
588
+ if ( ! isset( $result['services'] ) ) {
589
+ return false;
590
+ }
591
+
592
+ $requested_services = $result['services'];
593
+ foreach ( $services as $service ) {
594
+ if ( ! in_array( $service, $requested_services ) ) {
595
+ return false;
596
+ }
597
+ }
598
+
599
+ return true;
600
+ }
601
+
602
+ /**
603
+ * Function to return relevant plugin debug info
604
+ *
605
+ * @return debug info in JSON
606
+ */
607
+ public static function debug_info() {
608
+
609
+ if ( ShareaholicUtilities::get_option( 'disable_debug_info' ) == 'on' ) {
610
+ exit;
611
+ }
612
+
613
+ if ( ShareaholicUtilities::has_accepted_terms_of_service() == 1 ) {
614
+ $tos_status = 'accepted';
615
+ } else {
616
+ $tos_status = 'pending';
617
+ }
618
+
619
+ if ( function_exists( 'curl_version' ) ) {
620
+ $curl_version = curl_version();
621
+ }
622
+
623
+ $info = array(
624
+ 'plugin_version' => Shareaholic::VERSION,
625
+ 'plugin_version_in_db' => ShareaholicUtilities::get_version(),
626
+ 'site_id' => ShareaholicUtilities::get_option( 'api_key' ),
627
+ 'domain' => get_bloginfo( 'url' ),
628
+ 'language' => get_bloginfo( 'language' ),
629
+ 'tos_status' => $tos_status,
630
+ 'stats' => ShareaholicUtilities::get_stats(),
631
+ 'diagnostics' => array(
632
+ 'theme' => get_option( 'template' ),
633
+ 'multisite' => is_multisite(),
634
+ 'shareaholic_server_reachable' => ShareaholicUtilities::connectivity_check(),
635
+ 'server_side_share_count_api_reachable' => ShareaholicUtilities::share_counts_api_connectivity_check(),
636
+ 'php_version' => phpversion(),
637
+ 'wp_version' => get_bloginfo( 'version' ),
638
+ 'curl' => array(
639
+ 'status' => self::has_curl(),
640
+ 'version' => $curl_version,
641
+ ),
642
+ 'plugins' => array(
643
+ 'active' => ShareaholicUtilities::get_active_plugins(),
644
+ ),
645
+ ),
646
+ 'app_locations' => array(
647
+ 'share_buttons' => ShareaholicUtilities::get_option( 'share_buttons' ),
648
+ 'recommendations' => ShareaholicUtilities::get_option( 'recommendations' ),
649
+ ),
650
+ 'advanced_settings' => array(
651
+ 'server_side_share_count_api' => ShareaholicUtilities::get_internal_share_counts_api_status(),
652
+ 'facebook_access_token' => ShareaholicUtilities::fetch_fb_access_token() === false ? 'no' : 'yes',
653
+ 'facebook_auth_check' => ShareaholicUtilities::facebook_auth_check(),
654
+ 'enable_user_nicename' => ShareaholicUtilities::get_option( 'enable_user_nicename' ),
655
+ 'disable_og_tags' => ShareaholicUtilities::get_option( 'disable_og_tags' ),
656
+ 'disable_admin_bar_menu' => ShareaholicUtilities::get_option( 'disable_admin_bar_menu' ),
657
+ 'recommendations_display_on_excerpts' => ShareaholicUtilities::get_option( 'recommendations_display_on_excerpts' ),
658
+ 'share_buttons_display_on_excerpts' => ShareaholicUtilities::get_option( 'share_buttons_display_on_excerpts' ),
659
+ ),
660
+ );
661
+
662
+ header( 'Content-Type: application/json' );
663
+ echo json_encode( $info );
664
+ exit;
665
+ }
666
+
667
+
668
+ /**
669
+ * Function to return list of permalinks
670
+ *
671
+ * @return list of permalinks in JSON or plain text
672
+ */
673
+ public static function permalink_list() {
674
+ // Input Params
675
+ $post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : 'any';
676
+ $n = isset( $_GET['n'] ) ? intval( $_GET['n'] ) : -1;
677
+ $format = isset( $_GET['format'] ) ? $_GET['format'] : 'json';
678
+
679
+ $permalink_list = array();
680
+ $permalink_query = "post_type=$post_type&post_status=publish&posts_per_page=$n";
681
+ $posts = new WP_Query( $permalink_query );
682
+ $posts = $posts->posts;
683
+ foreach ( $posts as $post ) {
684
+ switch ( $post->post_type ) {
685
+ case 'revision':
686
+ case 'nav_menu_item':
687
+ break;
688
+ case 'page':
689
+ $permalink = get_page_link( $post->ID );
690
+ array_push( $permalink_list, $permalink );
691
+ break;
692
+ case 'post':
693
+ $permalink = get_permalink( $post->ID );
694
+ array_push( $permalink_list, $permalink );
695
+ break;
696
+ case 'attachment':
697
+ break;
698
+ default:
699
+ $permalink = get_post_permalink( $post->ID );
700
+ array_push( $permalink_list, $permalink );
701
+ break;
702
+ }
703
+ }
704
+
705
+ if ( $format === 'text' ) {
706
+ header( 'Content-Type: text/plain; charset=utf-8' );
707
+ foreach ( $permalink_list as $link ) {
708
+ echo $link . "\r\n";
709
+ }
710
+ } elseif ( $format === 'json' ) {
711
+ header( 'Content-Type: application/json; charset=utf-8' );
712
+ echo json_encode( $permalink_list );
713
+ }
714
+ exit;
715
+ }
716
+
717
+ /**
718
+ * Function to return relevant info for the SDK Badge
719
+ *
720
+ * @return sdk info in JSON
721
+ */
722
+ public static function sdk_info() {
723
+
724
+ if ( ! current_user_can( 'activate_plugins' ) ) {
725
+ $info = array(
726
+ 'sdk_info' => array(
727
+ 'message' => 'Unauthorized',
728
+ ),
729
+ );
730
+ } else {
731
+ $info = array(
732
+ 'sdk_info' => array(
733
+ 'site_id' => ShareaholicUtilities::get_option( 'api_key' ),
734
+ 'verification_key' => ShareaholicUtilities::get_option( 'verification_key' ),
735
+ 'wp_user_info' => ShareaholicUtilities::user_info(),
736
+ ),
737
+ );
738
+ }
739
+
740
+ header( 'Content-Type: application/json; charset=utf-8' );
741
+ echo json_encode( $info );
742
+ exit;
743
+ }
744
+
745
+ /**
746
+ * Function to return relevant info for a given permalink for the Related Content index
747
+ *
748
+ * @return page info in JSON
749
+ */
750
+ public static function permalink_info() {
751
+ global $wpdb, $post;
752
+
753
+ // Input Params
754
+ $permalink = isset( $_GET['permalink'] ) ? $_GET['permalink'] : null;
755
+ $body_text = isset( $_GET['body_text'] ) ? $_GET['body_text'] : 'raw';
756
+
757
+ if ( $permalink == null ) {
758
+ return;
759
+ }
760
+
761
+ // Get post ID
762
+ $post_id = url_to_postid( $permalink );
763
+
764
+ // for non-default paths - handle both https and http versions of the permalink
765
+ if ( $post_id == 0 ) {
766
+ $parse = parse_url( $permalink );
767
+ if ( $parse['scheme'] == 'https' ) {
768
+ $permalink = str_replace( 'https', 'http', $permalink );
769
+ $post_id = url_to_postid( $permalink );
770
+ } elseif ( $parse['scheme'] == 'http' ) {
771
+ $permalink = str_replace( 'http', 'https', $permalink );
772
+ $post_id = url_to_postid( $permalink );
773
+ }
774
+ }
775
+
776
+ if ( $post_id == 0 ) {
777
+ return;
778
+ }
779
+
780
+ // Get post for given ID
781
+ $post = get_post( $post_id );
782
+
783
+ if ( $post->post_status != 'publish' || $post->post_password != '' ) {
784
+ return;
785
+ }
786
+
787
+ // Post tags
788
+ $tags = ShareaholicUtilities::permalink_keywords( $post_id );
789
+
790
+ // Post categories
791
+ $categories = array();
792
+ $categories_array = get_the_category( $post_id );
793
+
794
+ if ( $categories_array ) {
795
+ foreach ( $categories_array as $category ) {
796
+ if ( $category->cat_name != 'Uncategorized' ) {
797
+ $category_name = ShareaholicUtilities::normalize_keywords( $category->cat_name );
798
+ array_push( $categories, $category_name );
799
+ }
800
+ }
801
+ }
802
+
803
+ // Post body
804
+ $order = array( '&nbsp;', "\r\n", "\n", "\r", ' ' );
805
+ $post_body = str_replace( $order, ' ', $post->post_content );
806
+
807
+ if ( $body_text == 'clean' ) {
808
+ $post_body = strip_tags( $post_body );
809
+ } elseif ( $body_text == 'raw' || $body_text == null ) {
810
+ $post_body = $post_body;
811
+ }
812
+
813
+ // Get post author name
814
+ if ( $post->post_author ) {
815
+ $author_data = get_userdata( $post->post_author );
816
+ $author_name = $author_data->display_name;
817
+ }
818
+
819
+ // Term frequencies
820
+ // $term_frequency_title = array_count_values(str_word_count(strtolower(strip_tags($post->post_title)), 1));
821
+ $term_frequency_body = array_count_values( str_word_count( strtolower( strip_tags( $post_body ) ), 1 ) );
822
+
823
+ $term_frequency = $term_frequency_body;
824
+ arsort( $term_frequency );
825
+
826
+ // Construct array
827
+ $info = array(
828
+ 'permalink' => $permalink,
829
+ 'domain' => get_bloginfo( 'url' ),
830
+ 'site_id' => ShareaholicUtilities::get_option( 'api_key' ),
831
+ 'content' => array(
832
+ 'title' => $post->post_title,
833
+ 'excerpt' => $post->post_excerpt,
834
+ 'body' => $post_body,
835
+ 'thumbnail' => ShareaholicUtilities::permalink_thumbnail( $post->ID ),
836
+ ),
837
+ 'post_metadata' => array(
838
+ 'author_id' => $post->post_author,
839
+ 'author_name' => $author_name,
840
+ 'post_type' => $post->post_type,
841
+ 'post_id' => $post_id,
842
+ 'post_tags' => $tags,
843
+ 'post_categories' => $categories,
844
+ 'post_language' => get_bloginfo( 'language' ),
845
+ 'post_published' => get_the_date( DATE_W3C ),
846
+ 'post_updated' => get_the_modified_date( DATE_W3C ),
847
+ 'post_visibility' => $post->post_status,
848
+ ),
849
+ 'post_stats' => array(
850
+ 'post_comments_count' => get_comments_number( $post_id ),
851
+ 'post_content_title_character_count' => strlen( trim( html_entity_decode( $post->post_title ) ) ),
852
+ 'post_content_title_word_count' => str_word_count( strip_tags( $post->post_title ) ),
853
+ 'post_content_body_character_count' => strlen( trim( html_entity_decode( $post_body ) ) ),
854
+ 'post_content_body_word_count' => str_word_count( strip_tags( $post_body ) ),
855
+ 'term_frequency' => $term_frequency,
856
+ ),
857
+ 'diagnostics' => array(
858
+ 'platform' => 'wp',
859
+ 'platform_version' => get_bloginfo( 'version' ),
860
+ 'plugin_version' => Shareaholic::VERSION,
861
+ ),
862
+ );
863
+
864
+ header( 'Content-Type: application/json; charset=utf-8' );
865
+ echo json_encode( $info );
866
+ exit;
867
+ }
868
+
869
+ /**
870
+ * Function to return related permalinks for a given permalink to bootstrap the Related Posts app until cloud-based processing routines complete
871
+ *
872
+ * @return list of related permalinks in JSON
873
+ */
874
+ public static function permalink_related() {
875
+ global $post;
876
+
877
+ // Input Params
878
+ $permalink = isset( $_GET['permalink'] ) ? $_GET['permalink'] : null;
879
+ $match = isset( $_GET['match'] ) ? $_GET['match'] : 'random'; // match method
880
+ $n = isset( $_GET['n'] ) ? intval( $_GET['n'] ) : 10; // number of related permalinks to return
881
+
882
+ $related_permalink_list = array();
883
+
884
+ // Get post ID
885
+ if ( $permalink == null ) {
886
+ // default to random match if no permalink is available
887
+ $match = 'random';
888
+ $post_id = 0;
889
+ } else {
890
+ $post_id = url_to_postid( $permalink );
891
+
892
+ // for non-default paths - handle both https and http versions of the permalink
893
+ if ( $post_id == 0 ) {
894
+ $parse = parse_url( $permalink );
895
+ if ( $parse['scheme'] == 'https' ) {
896
+ $permalink = str_replace( 'https', 'http', $permalink );
897
+ $post_id = url_to_postid( $permalink );
898
+ } elseif ( $parse['scheme'] == 'http' ) {
899
+ $permalink = str_replace( 'http', 'https', $permalink );
900
+ $post_id = url_to_postid( $permalink );
901
+ }
902
+ }
903
+ }
904
+
905
+ if ( $match == 'random' ) {
906
+ // Determine which page types to show
907
+ $post_types = get_post_types( array( 'public' => true ) );
908
+ $post_types_exclude = array( 'page', 'attachment', 'nav_menu_item' );
909
+ $post_types_filtered = array_diff( $post_types, $post_types_exclude );
910
+
911
+ // Query
912
+ $args = array(
913
+ 'post_type' => $post_types_filtered,
914
+ 'post__not_in' => array( $post_id ),
915
+ 'posts_per_page' => $n,
916
+ 'orderby' => 'rand',
917
+ 'post_status' => 'publish',
918
+ );
919
+
920
+ $rand_posts = get_posts( $args );
921
+ foreach ( $rand_posts as $post ) {
922
+ if ( $post->post_title ) {
923
+ $related_link = array(
924
+ 'content_id' => $post->ID,
925
+ 'url' => get_permalink( $post->ID ),
926
+ 'title' => $post->post_title,
927
+ 'description' => $post->post_excerpt,
928
+ 'author' => get_userdata( $post->post_author )->display_name,
929
+ 'image_url' => preg_replace( '#^https?://#', '//', ShareaholicUtilities::permalink_thumbnail( $post->ID ) ),
930
+ 'score' => 1,
931
+ 'published_date' => get_the_date( DATE_W3C ),
932
+ 'modified_date' => get_the_modified_date( DATE_W3C ),
933
+ 'channel_id' => 'plugin',
934
+ 'display_url' => get_permalink( $post->ID ),
935
+ );
936
+ array_push( $related_permalink_list, $related_link );
937
+ }
938
+ }
939
+ wp_reset_postdata();
940
+ } else {
941
+ // other match methods can be added here
942
+ }
943
+
944
+ // Construct results array
945
+ $result = array(
946
+ 'request' => array(
947
+ 'api_key' => ShareaholicUtilities::get_option( 'api_key' ),
948
+ 'url' => $permalink,
949
+ ),
950
+ 'internal' => $related_permalink_list,
951
+ );
952
+
953
+ header( 'Content-Type: application/json; charset=utf-8' );
954
+ header( 'Cache-Control: max-age=300' ); // 5 minutes
955
+ echo json_encode( $result );
956
+ exit;
957
+ }
958
+
959
+ /**
960
+ * Checks to see if curl is installed
961
+ *
962
+ * @return bool true or false that curl is installed
963
+ */
964
+ public static function has_curl() {
965
+ return function_exists( 'curl_version' ) && function_exists( 'curl_multi_init' ) && function_exists( 'curl_multi_add_handle' ) && function_exists( 'curl_multi_exec' );
966
+ }
 
967
  }
968
 
969
+
public_js.php CHANGED
@@ -13,99 +13,103 @@
13
  */
14
  class ShareaholicPublicJS {
15
 
16
- /**
17
- * Return a base set of settings for the Shareaholic JS or Publisher SDK
18
- */
19
- public static function get_base_settings() {
20
- $base_settings = array(
21
- 'endpoints' => array(
22
- 'local_recs_url' => admin_url('admin-ajax.php') . '?action=shareaholic_permalink_related',
23
- 'ajax_url' => admin_url('admin-ajax.php')
24
- )
25
- );
26
-
27
- $site_id = ShareaholicUtilities::get_option('api_key');
28
- if (!empty($site_id)) {
29
- $base_settings['site_id'] = $site_id;
30
- }
31
-
32
- $disable_share_counts_api = ShareaholicUtilities::get_option('disable_internal_share_counts_api');
33
- $share_counts_connect_check = ShareaholicUtilities::get_option('share_counts_connect_check');
34
-
35
- if (isset($disable_share_counts_api)) {
36
- if (isset($share_counts_connect_check) && $share_counts_connect_check == 'SUCCESS' && $disable_share_counts_api != 'on') {
37
- $base_settings['endpoints']['share_counts_url'] = admin_url('admin-ajax.php') . '?action=shareaholic_share_counts_api';
38
- }
39
- }
40
-
41
- // Can publish?
42
- if ( is_user_logged_in() && current_user_can( 'publish_posts' ) ){
43
- $base_settings['user']['capabilities']['publish_posts'] = true;
44
- }
45
-
46
- // Used by Share Count Recovery
47
- if (is_singular()) {
48
- global $post;
49
-
50
- $base_settings['url_components']['year'] = date('Y', strtotime($post->post_date));
51
- $base_settings['url_components']['monthnum'] = date('m', strtotime($post->post_date));
52
- $base_settings['url_components']['day'] = date('d', strtotime($post->post_date));
53
-
54
- $base_settings['url_components']['hour'] = date('H', strtotime($post->post_date));
55
- $base_settings['url_components']['minute'] = date('i', strtotime($post->post_date));
56
- $base_settings['url_components']['second'] = date('s', strtotime($post->post_date));
57
-
58
- $base_settings['url_components']['post_id'] = "$post->ID";
59
- $base_settings['url_components']['postname'] = $post->post_name;
60
-
61
- if (ShareaholicUtilities::get_option('enable_user_nicename') == "on"){
62
- $base_settings['url_components']['author'] = get_the_author_meta('user_nicename', $post->post_author);
63
- }
64
-
65
- // ******** copied from WP core - START ******** //
66
- $category = '';
67
- $cats = get_the_category($post->ID);
68
  if ( $cats ) {
69
- // Sort the terms by ID and get the first category.
70
- if (function_exists('wp_list_sort')) {
71
- $cats = wp_list_sort( $cats, array(
72
- 'term_id' => 'ASC',
73
- ) );
74
- } else {
75
- usort( $cats, '_usort_terms_by_ID' );
76
- }
 
 
 
77
 
78
  $category_object = apply_filters( 'post_link_category', $cats[0], $cats, $post );
79
 
80
  $category_object = get_term( $category_object, 'category' );
81
- $category = $category_object->slug;
82
- if ( $parent = $category_object->parent )
83
- $category = get_category_parents($parent, false, '/', true) . $category;
 
84
  }
85
  // show default category in permalinks, without
86
  // having to assign it explicitly
87
- if ( empty($category) ) {
88
  $default_category = get_term( get_option( 'default_category' ), 'category' );
89
  if ( $default_category && ! is_wp_error( $default_category ) ) {
90
  $category = $default_category->slug;
91
  }
92
  }
93
- // ******** copied from WP core - END ******** //
94
-
95
- $base_settings['url_components']['category'] = $category;
96
- }
97
-
98
- return $base_settings;
99
- }
100
-
101
- public static function get_overrides() {
102
- $output = '';
103
-
104
- if (ShareaholicUtilities::get_env() === 'staging') {
105
- $output = "data-shr-environment='stage' data-shr-assetbase='https://s3.amazonaws.com/cdn-staging-shareaholic/v2/'";
106
- }
107
-
108
- return $output;
109
- }
110
 
111
  }
13
  */
14
  class ShareaholicPublicJS {
15
 
16
+ /**
17
+ * Return a base set of settings for the Shareaholic JS or Publisher SDK
18
+ */
19
+ public static function get_base_settings() {
20
+ $base_settings = array(
21
+ 'endpoints' => array(
22
+ 'local_recs_url' => admin_url( 'admin-ajax.php' ) . '?action=shareaholic_permalink_related',
23
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
24
+ ),
25
+ );
26
+
27
+ $site_id = ShareaholicUtilities::get_option( 'api_key' );
28
+ if ( ! empty( $site_id ) ) {
29
+ $base_settings['site_id'] = $site_id;
30
+ }
31
+
32
+ $disable_share_counts_api = ShareaholicUtilities::get_option( 'disable_internal_share_counts_api' );
33
+ $share_counts_connect_check = ShareaholicUtilities::get_option( 'share_counts_connect_check' );
34
+
35
+ if ( isset( $disable_share_counts_api ) ) {
36
+ if ( isset( $share_counts_connect_check ) && $share_counts_connect_check == 'SUCCESS' && $disable_share_counts_api != 'on' ) {
37
+ $base_settings['endpoints']['share_counts_url'] = admin_url( 'admin-ajax.php' ) . '?action=shareaholic_share_counts_api';
38
+ }
39
+ }
40
+
41
+ // Can publish?
42
+ if ( is_user_logged_in() && current_user_can( 'publish_posts' ) ) {
43
+ $base_settings['user']['capabilities']['publish_posts'] = true;
44
+ }
45
+
46
+ // Used by Share Count Recovery
47
+ if ( is_singular() ) {
48
+ global $post;
49
+
50
+ $base_settings['url_components']['year'] = date( 'Y', strtotime( $post->post_date ) );
51
+ $base_settings['url_components']['monthnum'] = date( 'm', strtotime( $post->post_date ) );
52
+ $base_settings['url_components']['day'] = date( 'd', strtotime( $post->post_date ) );
53
+
54
+ $base_settings['url_components']['hour'] = date( 'H', strtotime( $post->post_date ) );
55
+ $base_settings['url_components']['minute'] = date( 'i', strtotime( $post->post_date ) );
56
+ $base_settings['url_components']['second'] = date( 's', strtotime( $post->post_date ) );
57
+
58
+ $base_settings['url_components']['post_id'] = "$post->ID";
59
+ $base_settings['url_components']['postname'] = $post->post_name;
60
+
61
+ if ( ShareaholicUtilities::get_option( 'enable_user_nicename' ) == 'on' ) {
62
+ $base_settings['url_components']['author'] = get_the_author_meta( 'user_nicename', $post->post_author );
63
+ }
64
+
65
+ // ******** copied from WP core - START ******** //
66
+ $category = '';
67
+ $cats = get_the_category( $post->ID );
68
  if ( $cats ) {
69
+ // Sort the terms by ID and get the first category.
70
+ if ( function_exists( 'wp_list_sort' ) ) {
71
+ $cats = wp_list_sort(
72
+ $cats,
73
+ array(
74
+ 'term_id' => 'ASC',
75
+ )
76
+ );
77
+ } else {
78
+ usort( $cats, '_usort_terms_by_ID' );
79
+ }
80
 
81
  $category_object = apply_filters( 'post_link_category', $cats[0], $cats, $post );
82
 
83
  $category_object = get_term( $category_object, 'category' );
84
+ $category = $category_object->slug;
85
+ if ( $parent = $category_object->parent ) {
86
+ $category = get_category_parents( $parent, false, '/', true ) . $category;
87
+ }
88
  }
89
  // show default category in permalinks, without
90
  // having to assign it explicitly
91
+ if ( empty( $category ) ) {
92
  $default_category = get_term( get_option( 'default_category' ), 'category' );
93
  if ( $default_category && ! is_wp_error( $default_category ) ) {
94
  $category = $default_category->slug;
95
  }
96
  }
97
+ // ******** copied from WP core - END ******** //
98
+
99
+ $base_settings['url_components']['category'] = $category;
100
+ }
101
+
102
+ return $base_settings;
103
+ }
104
+
105
+ public static function get_overrides() {
106
+ $output = '';
107
+
108
+ if ( ShareaholicUtilities::get_env() === 'staging' ) {
109
+ $output = "data-shr-environment='stage' data-shr-assetbase='https://s3.amazonaws.com/cdn-staging-shareaholic/v2/'";
110
+ }
111
+
112
+ return $output;
113
+ }
114
 
115
  }
query_string_builder.php CHANGED
@@ -13,134 +13,138 @@
13
  */
14
  class ShareaholicQueryStringBuilder {
15
 
16
- /**
17
- * Builds the query string
18
- *
19
- * @param array $hash the data to be query stringified
20
- * @param string $key to scop everything under if desired
21
- * @return string
22
- */
23
- public static function build_query_string($hash, $key = '') {
24
- $result = array();
25
- foreach ($hash as $key => $value) {
26
- array_push($result, self::to_param($value, $key));
27
- }
28
- return implode('&', $result);
29
- }
30
 
31
- /**
32
- * An object independent function to parameratize an object
33
- *
34
- * @param string $value the object to be parameratized
35
- * @param string $key the key to scope under
36
- * @return string
37
- */
38
- public static function to_param($value, $key = '') {
39
- if (is_array($value)) {
40
- if (self::is_assoc($value)) {
41
- return self::assoc_array_to_param($value, $key);
42
- } else {
43
- return self::array_to_param($value, $key);
44
- }
45
- } elseif (is_bool($value)) {
46
- return self::bool_to_param($value);
47
- } else {
48
- return ($key ? "$key=" . (string)$value : (string)$value);
49
- }
50
- }
51
 
52
- /**
53
- * Determines whether an array is associative or not
54
- * by checking for the presenve of string keys.
55
- *
56
- * @param array
57
- * @return bool
58
- */
59
- private static function is_assoc($array) {
60
- return (bool)count(array_filter(array_keys($array), 'is_string'));
61
- }
62
 
63
- /**
64
- * Returns a hash like array to a query string under a namespace
65
- *
66
- * <code>
67
- * array('foo' => 'bar') // namspace of baz
68
- * baz[foo]=bar
69
- * </code>
70
- *
71
- * @param array $hash
72
- * @param string $namespace
73
- * @return string
74
- */
75
- private static function assoc_array_to_param($hash, $namespace = '') {
76
- $namespace_array = array_fill(0, count($hash), $namespace);
77
- return implode('&', array_map(
78
- array('self', 'assoc_array_to_param_iterator'),
79
- $hash,
80
- array_keys($hash), $namespace_array
81
- ));
82
- }
 
 
 
 
83
 
84
- /**
85
- * Because PHP < 5.3 doesn't support anonymous functions, this serves
86
- * as the mapping function for the above method.
87
- *
88
- * @param mixed $value
89
- * @param string $key
90
- * @param string $namespace
91
- * @return string
92
- */
93
- private static function assoc_array_to_param_iterator($value, $key, $namespace) {
94
- $new_key = ($namespace ? "{$namespace}[$key]" : $key);
95
- return ShareaholicQueryStringBuilder::to_param($value, $new_key);
96
- }
97
 
98
- /**
99
- * Returns an array paramerterized with a given key
100
- *
101
- * <code>
102
- * array('foo', 'bar', 'baz') // key of hello
103
- * hello[]=foo&hello[]=bar&hello[]=baz
104
- * </code>
105
- *
106
- * This is what is broken in PHP's native `http_build_query`.
107
- * Instead of using empty brackets, it will insert the indices
108
- * of each value instead, which makes it parse as a hash instead
109
- * of an array.
110
- *
111
- * @param array $array
112
- * @param string $key
113
- * @return string
114
- */
115
- private static function array_to_param($array, $key) {
116
- $prefix = "{$key}[]";
117
 
118
- $prefix_array = array_fill(0, count($array), $prefix);
119
- return implode("&", array_map(array('self', 'array_to_param_iterator'), $array, $prefix_array));
120
- }
121
 
122
- /**
123
- * Because PHP < 5.3 doesn't support anonymous functions, this serves
124
- * as the mapping function for the above method.
125
- *
126
- * @param mixed $value
127
- * @param string $prefix
128
- * @return string
129
- */
130
- private static function array_to_param_iterator($value, $prefix) {
131
- return ShareaholicQueryStringBuilder::to_param($value, $prefix);
132
- }
133
 
134
- /**
135
- * There's no official pattern for booleans in URLs,
136
- * I though this made the most sense.
137
- *
138
- * @param bool $bool
139
- * @return string
140
- */
141
- private static function bool_to_param($bool) {
142
- return ($bool ? 'true' : 'false');
143
- }
144
  }
145
 
146
- ?>
13
  */
14
  class ShareaholicQueryStringBuilder {
15
 
16
+ /**
17
+ * Builds the query string
18
+ *
19
+ * @param array $hash the data to be query stringified
20
+ * @param string $key to scop everything under if desired
21
+ * @return string
22
+ */
23
+ public static function build_query_string( $hash, $key = '' ) {
24
+ $result = array();
25
+ foreach ( $hash as $key => $value ) {
26
+ array_push( $result, self::to_param( $value, $key ) );
27
+ }
28
+ return implode( '&', $result );
29
+ }
30
 
31
+ /**
32
+ * An object independent function to parameratize an object
33
+ *
34
+ * @param string $value the object to be parameratized
35
+ * @param string $key the key to scope under
36
+ * @return string
37
+ */
38
+ public static function to_param( $value, $key = '' ) {
39
+ if ( is_array( $value ) ) {
40
+ if ( self::is_assoc( $value ) ) {
41
+ return self::assoc_array_to_param( $value, $key );
42
+ } else {
43
+ return self::array_to_param( $value, $key );
44
+ }
45
+ } elseif ( is_bool( $value ) ) {
46
+ return self::bool_to_param( $value );
47
+ } else {
48
+ return ( $key ? "$key=" . (string) $value : (string) $value );
49
+ }
50
+ }
51
 
52
+ /**
53
+ * Determines whether an array is associative or not
54
+ * by checking for the presenve of string keys.
55
+ *
56
+ * @param array
57
+ * @return bool
58
+ */
59
+ private static function is_assoc( $array ) {
60
+ return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
61
+ }
62
 
63
+ /**
64
+ * Returns a hash like array to a query string under a namespace
65
+ *
66
+ * <code>
67
+ * array('foo' => 'bar') // namspace of baz
68
+ * baz[foo]=bar
69
+ * </code>
70
+ *
71
+ * @param array $hash
72
+ * @param string $namespace
73
+ * @return string
74
+ */
75
+ private static function assoc_array_to_param( $hash, $namespace = '' ) {
76
+ $namespace_array = array_fill( 0, count( $hash ), $namespace );
77
+ return implode(
78
+ '&',
79
+ array_map(
80
+ array( 'self', 'assoc_array_to_param_iterator' ),
81
+ $hash,
82
+ array_keys( $hash ),
83
+ $namespace_array
84
+ )
85
+ );
86
+ }
87
 
88
+ /**
89
+ * Because PHP < 5.3 doesn't support anonymous functions, this serves
90
+ * as the mapping function for the above method.
91
+ *
92
+ * @param mixed $value
93
+ * @param string $key
94
+ * @param string $namespace
95
+ * @return string
96
+ */
97
+ private static function assoc_array_to_param_iterator( $value, $key, $namespace ) {
98
+ $new_key = ( $namespace ? "{$namespace}[$key]" : $key );
99
+ return self::to_param( $value, $new_key );
100
+ }
101
 
102
+ /**
103
+ * Returns an array paramerterized with a given key
104
+ *
105
+ * <code>
106
+ * array('foo', 'bar', 'baz') // key of hello
107
+ * hello[]=foo&hello[]=bar&hello[]=baz
108
+ * </code>
109
+ *
110
+ * This is what is broken in PHP's native `http_build_query`.
111
+ * Instead of using empty brackets, it will insert the indices
112
+ * of each value instead, which makes it parse as a hash instead
113
+ * of an array.
114
+ *
115
+ * @param array $array
116
+ * @param string $key
117
+ * @return string
118
+ */
119
+ private static function array_to_param( $array, $key ) {
120
+ $prefix = "{$key}[]";
121
 
122
+ $prefix_array = array_fill( 0, count( $array ), $prefix );
123
+ return implode( '&', array_map( array( 'self', 'array_to_param_iterator' ), $array, $prefix_array ) );
124
+ }
125
 
126
+ /**
127
+ * Because PHP < 5.3 doesn't support anonymous functions, this serves
128
+ * as the mapping function for the above method.
129
+ *
130
+ * @param mixed $value
131
+ * @param string $prefix
132
+ * @return string
133
+ */
134
+ private static function array_to_param_iterator( $value, $prefix ) {
135
+ return self::to_param( $value, $prefix );
136
+ }
137
 
138
+ /**
139
+ * There's no official pattern for booleans in URLs,
140
+ * I though this made the most sense.
141
+ *
142
+ * @param bool $bool
143
+ * @return string
144
+ */
145
+ private static function bool_to_param( $bool ) {
146
+ return ( $bool ? 'true' : 'false' );
147
+ }
148
  }
149
 
150
+
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: social, social sharing, google analytics, pinterest, twitter, share butto
4
  Requires at least: 3.7
5
  Tested up to: 5.3
6
  Requires PHP: 5.3
7
- Stable tag: 8.13.13
8
 
9
 
10
  Boost Audience Engagement with Award Winning Speed Optimized Social Tools: Share Buttons, Related Posts, Monetization & Google Analytics.
@@ -90,13 +90,13 @@ To take advantage of this privacy feature, enable "Share Count Proxy" under Adva
90
  * [Free] Check whether your campaigns are targeting Verified Human audiences who are actually capable of purchasing your product or service
91
  * Learn more about [Google Analytics integration](https://www.shareaholic.com/website-tools/content-analytics)
92
 
93
- = Follow Buttons =
94
 
95
  * [Free] Grow your social following and page views with our easily customizable social plugin and tools for adding social follow buttons directly to your page.
96
  * [Free] Supported services include: Facebook, Twitter, Instagram, YouTube, LinkedIn ,Spotify ,Google+ ,Pinterest, Etsy, BuzzFeed, iTunes, Tumblr, Vimeo, eBay, 500px, about.me, Baidu, Behance, Better Business Bureau, Bloglovin, Disqus, Dribbble, Feedly, Flickr, Foursquare, Github, Google Classroom, Houzz, LinkedIn Company, LiveJournal, Odnoklassniki, Polyvore, RSS, Skype, SlideShare, SoundCloud, Stack Overflow, StumbleUpon, Tripadvisor, Vine, VK, Yelp, Zillow
97
- * Learn more about [Follow Buttons](https://www.shareaholic.com/website-tools)
98
 
99
- = Cookie Notice =
100
 
101
  * Actively notify your visitors that your site uses cookies through a message bar at the top or bottom of your page
102
  * Target EU and EEA visitors specifically or show to everyone
@@ -310,6 +310,12 @@ The default Shareaholic thumbnail width is 640px with dynamic height and no crop
310
  Each time you change Shareaholic's thumbnail dimensions like this, you will probably want to have WordPress regenerate appropriate sized thumbnails for all of your images. We highly recommend the [Regenerate Thumbnails](https://wordpress.org/plugins/regenerate-thumbnails/) plugin for this purpose.
311
 
312
  == Changelog ==
 
 
 
 
 
 
313
  = 8.13.13 (2020-01-10) =
314
  * Enhancement: A complete rewrite of our JavaScript code resulting in delivering Google PageSpeed scores of 95+ on mobile and 100 on desktop. Yes, 100 out of 100. Shareaholic is now fast and Google agrees.
315
  * Bugfix: Call to undefined function preg_filter() on PHP < v5.3. Use preg_replace instead.
@@ -1015,7 +1021,7 @@ Each time you change Shareaholic's thumbnail dimensions like this, you will prob
1015
  * Show Related Posts data status
1016
 
1017
  == Upgrade Notice ==
1018
- = 8.13.13 =
1019
  We update this plugin regularly so we can make it better for you. Update to the latest version for all of the available features and improvements. Thanks for using Shareaholic!
1020
 
1021
  = 8.12.1 =
4
  Requires at least: 3.7
5
  Tested up to: 5.3
6
  Requires PHP: 5.3
7
+ Stable tag: 8.13.14
8
 
9
 
10
  Boost Audience Engagement with Award Winning Speed Optimized Social Tools: Share Buttons, Related Posts, Monetization & Google Analytics.
90
  * [Free] Check whether your campaigns are targeting Verified Human audiences who are actually capable of purchasing your product or service
91
  * Learn more about [Google Analytics integration](https://www.shareaholic.com/website-tools/content-analytics)
92
 
93
+ = Social Follow Buttons =
94
 
95
  * [Free] Grow your social following and page views with our easily customizable social plugin and tools for adding social follow buttons directly to your page.
96
  * [Free] Supported services include: Facebook, Twitter, Instagram, YouTube, LinkedIn ,Spotify ,Google+ ,Pinterest, Etsy, BuzzFeed, iTunes, Tumblr, Vimeo, eBay, 500px, about.me, Baidu, Behance, Better Business Bureau, Bloglovin, Disqus, Dribbble, Feedly, Flickr, Foursquare, Github, Google Classroom, Houzz, LinkedIn Company, LiveJournal, Odnoklassniki, Polyvore, RSS, Skype, SlideShare, SoundCloud, Stack Overflow, StumbleUpon, Tripadvisor, Vine, VK, Yelp, Zillow
97
+ * Learn more about [Follow Buttons](https://www.shareaholic.com/website-tools/social-follow-buttons)
98
 
99
+ = GDPR Cookie Notice =
100
 
101
  * Actively notify your visitors that your site uses cookies through a message bar at the top or bottom of your page
102
  * Target EU and EEA visitors specifically or show to everyone
310
  Each time you change Shareaholic's thumbnail dimensions like this, you will probably want to have WordPress regenerate appropriate sized thumbnails for all of your images. We highly recommend the [Regenerate Thumbnails](https://wordpress.org/plugins/regenerate-thumbnails/) plugin for this purpose.
311
 
312
  == Changelog ==
313
+
314
+ = 8.13.14 (2020-02-12) =
315
+ * Feature: Check Share Share Counts from Admin Menu
316
+ * Enhancement: Fewer scripts in Admin section
317
+ * Enhancement: Better Admin UX
318
+
319
  = 8.13.13 (2020-01-10) =
320
  * Enhancement: A complete rewrite of our JavaScript code resulting in delivering Google PageSpeed scores of 95+ on mobile and 100 on desktop. Yes, 100 out of 100. Shareaholic is now fast and Google agrees.
321
  * Bugfix: Call to undefined function preg_filter() on PHP < v5.3. Use preg_replace instead.
1021
  * Show Related Posts data status
1022
 
1023
  == Upgrade Notice ==
1024
+ = 8.13.14 =
1025
  We update this plugin regularly so we can make it better for you. Update to the latest version for all of the available features and improvements. Thanks for using Shareaholic!
1026
 
1027
  = 8.12.1 =
sexy-bookmarks.php CHANGED
@@ -1,12 +1,12 @@
1
  <?php
2
 
3
- add_action('admin_init', 'update_primary_shareaholic_plugin_file', 1);
4
 
5
- function update_primary_shareaholic_plugin_file(){
6
- if (is_plugin_active('shareaholic/sexy-bookmarks.php')) {
7
- deactivate_plugins('shareaholic/sexy-bookmarks.php');
8
- activate_plugins('shareaholic/shareaholic.php');
9
- }
10
  }
11
 
12
- ?>
1
  <?php
2
 
3
+ add_action( 'admin_init', 'update_primary_shareaholic_plugin_file', 1 );
4
 
5
+ function update_primary_shareaholic_plugin_file() {
6
+ if ( is_plugin_active( 'shareaholic/sexy-bookmarks.php' ) ) {
7
+ deactivate_plugins( 'shareaholic/sexy-bookmarks.php' );
8
+ activate_plugins( 'shareaholic/shareaholic.php' );
9
+ }
10
  }
11
 
12
+
shareaholic.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Shareaholic - Grow and Engage Your Audience
4
  Plugin URI: https://www.shareaholic.com/website-tools/
5
  Description: Shareaholic’s official WordPress plugin allows you to add Award-Winning Social Share Buttons, Related Posts, Content Analytics, Ad Monetization, and more to your website.
6
- Version: 8.13.13
7
  Author: Shareaholic
8
  Author URI: https://www.shareaholic.com
9
  Text Domain: shareaholic
@@ -14,14 +14,13 @@ Domain Path: /languages
14
  * The main file!
15
  *
16
  * @package shareaholic
17
- * @version 8.13.13
18
  */
19
 
20
  /**
21
  * Make sure we don't expose any info if called directly
22
- *
23
  */
24
- if ( !function_exists( 'add_action' ) ) {
25
  echo 'Hi there! I\'m just a plugin, not much I can do when called directly.';
26
  exit;
27
  }
@@ -31,291 +30,291 @@ Domain Path: /languages
31
  * error_reporting(E_ALL ^ E_NOTICE);
32
  */
33
 
34
- if (!defined('SHAREAHOLIC_FILE')) {
35
- define('SHAREAHOLIC_FILE', __FILE__);
36
  }
37
 
38
- if (!defined('SHAREAHOLIC_PATH')) {
39
- define('SHAREAHOLIC_PATH', plugin_dir_path(SHAREAHOLIC_FILE));
40
  }
41
 
42
- if(!defined('SHAREAHOLIC_ASSET_DIR')) {
43
- define('SHAREAHOLIC_ASSET_DIR', plugins_url( '/assets/' , __FILE__ ));
44
  }
45
 
46
  // Caching
47
- if(!defined('SHARE_COUNTS_CHECK_CACHE_LENGTH')) {
48
- define( 'SHARE_COUNTS_CHECK_CACHE_LENGTH', 900 ); // 900 seconds
49
  }
50
 
51
  // because define can use function returns and const can't
52
- if(!defined('SHAREAHOLIC_DEBUG')) {
53
- define('SHAREAHOLIC_DEBUG', getenv('SHAREAHOLIC_DEBUG'));
54
  }
55
 
56
- require_once(SHAREAHOLIC_PATH . 'utilities.php');
57
- require_once(SHAREAHOLIC_PATH . 'global_functions.php');
58
- require_once(SHAREAHOLIC_PATH . 'admin.php');
59
- require_once(SHAREAHOLIC_PATH . 'public.php');
60
- require_once(SHAREAHOLIC_PATH . 'notifier.php');
61
- require_once(SHAREAHOLIC_PATH . 'cron.php');
62
-
63
- if (!class_exists('Shareaholic')) {
64
- /**
65
- * The main / base class.
66
- *
67
- * @package shareaholic
68
- */
69
- class Shareaholic {
70
-
71
- const URL = 'https://www.shareaholic.com';
72
- const API_URL = 'https://web.shareaholic.com'; // uses static IPs for firewall whitelisting
73
- const CM_API_URL = 'https://cm-web.shareaholic.com'; // uses static IPs for firewall whitelisting
74
-
75
- const VERSION = '8.13.13';
76
-
77
- /**
78
- * Starts off as false so that ::get_instance() returns
79
- * a new instance.
80
- */
81
- private static $instance = false;
82
-
83
- /**
84
- * The constructor registers all the wordpress actions.
85
- */
86
- private function __construct() {
87
- add_action('wp_ajax_shareaholic_accept_terms_of_service', array('ShareaholicUtilities', 'accept_terms_of_service'));
88
-
89
- // Share Counts API
90
- add_action('wp_ajax_nopriv_shareaholic_share_counts_api', array('ShareaholicPublic', 'share_counts_api'));
91
- add_action('wp_ajax_shareaholic_share_counts_api', array('ShareaholicPublic', 'share_counts_api'));
92
-
93
- // Debug info
94
- add_action('wp_ajax_nopriv_shareaholic_debug_info', array('ShareaholicPublic', 'debug_info'));
95
- add_action('wp_ajax_shareaholic_debug_info', array('ShareaholicPublic', 'debug_info'));
96
-
97
- // Permalink list for Related Content index
98
- add_action('wp_ajax_nopriv_shareaholic_permalink_list', array('ShareaholicPublic', 'permalink_list'));
99
- add_action('wp_ajax_shareaholic_permalink_list', array('ShareaholicPublic', 'permalink_list'));
100
-
101
- // SDK Badge
102
- add_action('wp_ajax_nopriv_shareaholic_sdk_info', array('ShareaholicPublic', 'sdk_info'));
103
- add_action('wp_ajax_shareaholic_sdk_info', array('ShareaholicPublic', 'sdk_info'));
104
-
105
- // Permalink info for Related Content index
106
- add_action('wp_ajax_nopriv_shareaholic_permalink_info', array('ShareaholicPublic', 'permalink_info'));
107
- add_action('wp_ajax_shareaholic_permalink_info', array('ShareaholicPublic', 'permalink_info'));
108
-
109
- // Related Permalinks for Related Content app bootup
110
- add_action('wp_ajax_nopriv_shareaholic_permalink_related', array('ShareaholicPublic', 'permalink_related'));
111
- add_action('wp_ajax_shareaholic_permalink_related', array('ShareaholicPublic', 'permalink_related'));
112
-
113
- add_action('after_setup_theme', array('ShareaholicPublic', 'after_setup_theme'));
114
-
115
- add_action('pre_get_posts', array($this, 'shareaholic_draw_canvas'));
116
-
117
- add_action('wp_head', array('ShareaholicPublic', 'wp_head'), 6);
118
- add_filter('wp_resource_hints', array('ShareaholicPublic', 'shareaholic_resource_hints'), 10, 2);
119
- add_shortcode('shareaholic', array('ShareaholicPublic', 'shortcode'));
120
-
121
- add_action('plugins_loaded', array($this, 'shareaholic_init'));
122
-
123
- add_action('admin_init', array('ShareaholicAdmin', 'admin_init'));
124
- add_action('admin_enqueue_scripts', array('ShareaholicAdmin', 'admin_header'));
125
- add_action('wp_ajax_shareaholic_add_location', array('ShareaholicAdmin', 'add_location'));
126
- add_action('add_meta_boxes', array('ShareaholicAdmin', 'add_meta_boxes'));
127
- add_action('save_post', array('ShareaholicAdmin', 'save_post'));
128
- add_action('admin_enqueue_scripts', array('ShareaholicAdmin', 'enqueue_scripts'));
129
- add_action('admin_menu', array('ShareaholicAdmin', 'admin_menu'));
130
-
131
- // add_action('publish_post', array('ShareaholicNotifier', 'post_notify'));
132
- // add_action('publish_page', array('ShareaholicNotifier', 'post_notify'));
133
-
134
- add_action('transition_post_status', array('ShareaholicUtilities', 'post_transitioned'), 10, 3);
135
-
136
- register_activation_hook(__FILE__, array($this, 'after_activation'));
137
- register_deactivation_hook( __FILE__, array($this, 'deactivate'));
138
- register_uninstall_hook(__FILE__, array('Shareaholic', 'uninstall'));
139
-
140
- add_action('wp_before_admin_bar_render', array('ShareaholicUtilities', 'admin_bar_extended'));
141
- add_filter('plugin_action_links_'.plugin_basename(__FILE__), 'ShareaholicUtilities::admin_plugin_action_links', -10);
142
-
143
- // Add custom action to run remove_transients cron job
144
- add_action('shareaholic_remove_transients_hourly', array('ShareaholicCron', 'remove_transients'));
145
-
146
- // Add custom action to run shareaholic_heartbeat cron job
147
- add_action('shareaholic_heartbeat', array('ShareaholicCron', 'heartbeat'));
148
-
149
- // do something before a post is updated
150
- add_action('pre_post_update', array('ShareaholicUtilities', 'before_post_is_updated'));
151
-
152
- // do something before a post is trashed
153
- add_action('pre_trash_post', array('ShareaholicUtilities', 'before_post_is_trashed'));
154
-
155
- // do something before a site's permalink structure changes
156
- add_action('update_option_permalink_structure', array('ShareaholicUtilities', 'notify_content_manager_singledomain'));
157
-
158
- // Show ToS notice
159
- if (!ShareaholicUtilities::has_accepted_terms_of_service()) {
160
- add_action('admin_notices', array('ShareaholicAdmin', 'show_terms_of_service'));
161
- }
162
-
163
- // use the admin notice API
164
- add_action('admin_notices', array('ShareaholicAdmin', 'admin_notices'));
165
-
166
- // Add our custom image type to the Media Library
167
- add_filter('image_size_names_choose', array('ShareaholicAdmin', 'show_custom_sizes'));
168
-
169
- // ShortCode UI plugin specific hooks to prevent duplicate app rendering
170
- // https://wordpress.org/support/topic/custom-post-type-exclude-issue?replies=10#post-3370550
171
- add_action('scui_external_hooks_remove', array($this, 'remove_apps'));
172
- add_action('scui_external_hooks_return', array($this, 'return_apps'));
173
-
174
- // WP Rocket Compatability
175
- add_filter('rocket_minify_excluded_external_js', array('ShareaholicUtilities', 'rocket_exclude_js') );
176
- }
177
-
178
- public static function shareaholic_draw_canvas($query) {
179
- if ( $query->is_main_query() ) {
180
- add_filter('the_content', array('ShareaholicPublic', 'draw_canvases'), 98);
181
- add_filter('the_excerpt', array('ShareaholicPublic', 'draw_canvases'), 98);
182
- }
183
- }
184
-
185
- public static function remove_apps() {
186
- remove_filter('the_content', array('ShareaholicPublic', 'draw_canvases'), 98);
187
- remove_filter('the_excerpt', array('ShareaholicPublic', 'draw_canvases'), 98);
188
- }
189
-
190
- public static function return_apps() {
191
- add_filter('the_content', array('ShareaholicPublic', 'draw_canvases'), 98);
192
- add_filter('the_excerpt', array('ShareaholicPublic', 'draw_canvases'), 98);
193
- }
194
-
195
- /**
196
- * We want this to be a singleton, so return the one instance
197
- * if already instantiated.
198
- *
199
- * @return Shareaholic
200
- */
201
- public static function get_instance() {
202
- if ( ! self::$instance ) {
203
- self::$instance = new self();
204
- }
205
- self::init();
206
- return self::$instance;
207
- }
208
-
209
- /**
210
- * This function initializes the plugin so that everything is scoped
211
- * under the class and no variables leak outside.
212
- */
213
- public static function init() {
214
- self::update();
215
- }
216
-
217
- /**
218
- * This function fires once any activated plugins have been loaded. Is generally used for immediate filter setup, or plugin overrides.
219
- */
220
- public function shareaholic_init() {
221
- ShareaholicUtilities::localize();
222
-
223
- if (ShareaholicUtilities::has_accepted_terms_of_service() &&
224
- isset($_GET['page']) && preg_match('/shareaholic/', $_GET['page'])) {
225
- ShareaholicUtilities::get_or_create_api_key();
226
- }
227
- }
228
-
229
- /**
230
- * Runs update code if the plugin version is different from what is stored in the settings.
231
- */
232
- public static function update() {
233
- if (ShareaholicUtilities::get_version() != Shareaholic::VERSION) {
234
- ShareaholicUtilities::perform_update();
235
- ShareaholicUtilities::set_version(Shareaholic::VERSION);
236
- ShareaholicUtilities::log_event("Upgrade", array ('previous_plugin_version' => ShareaholicUtilities::get_version()));
237
- }
238
- }
239
-
240
- /**
241
- * Checks whether to ask the user to accept the terms of service or not.
242
- */
243
- public function terms_of_service() {
244
- if (!ShareaholicUtilities::has_accepted_terms_of_service()) {
245
- add_action('admin_notices', array('ShareaholicAdmin', 'show_terms_of_service'));
246
- } else {
247
- ShareaholicUtilities::get_or_create_api_key();
248
- }
249
- }
250
-
251
- /**
252
- * This function fires after the plugin has been activated.
253
- */
254
- public function after_activation() {
255
- set_transient('_shr_activation_redirect', true, 120); // for post-activation redirect
256
-
257
- // Cleanup leftover mutex
258
- ShareaholicUtilities::delete_mutex();
259
-
260
- $this->terms_of_service();
261
- ShareaholicUtilities::log_event("Activate");
262
-
263
- // workaround: http://codex.wordpress.org/Function_Reference/register_activation_hook
264
- add_option( 'Activated_Plugin_Shareaholic', 'shareaholic' );
265
- $api_key = ShareaholicUtilities::get_option('api_key');
266
- if (ShareaholicUtilities::has_accepted_terms_of_service() && !empty($api_key)) {
267
- ShareaholicUtilities::notify_content_manager_singledomain();
268
- }
269
-
270
- if (!ShareaholicUtilities::get_version()) {
271
- ShareaholicUtilities::log_event("Install_Fresh");
272
- }
273
-
274
- // Activate the Shareaholic Cron Job for new users
275
- ShareaholicCron::activate();
276
- }
277
-
278
- /**
279
- * This function fires when the plugin is deactivated.
280
- */
281
- public function deactivate() {
282
- ShareaholicUtilities::log_event("Deactivate");
283
- ShareaholicUtilities::clear_cache();
284
- ShareaholicCron::deactivate();
285
- ShareaholicUtilities::delete_mutex();
286
- }
287
-
288
- /**
289
- * This function fires when the plugin is uninstalled.
290
- */
291
- public static function uninstall() {
292
- ShareaholicUtilities::log_event("Uninstall");
293
- delete_option('shareaholic_has_accepted_tos');
294
- delete_option('shareaholic_settings');
295
- delete_option('shareaholic_activate_timestamp');
296
- delete_option('shareaholic_review_dismiss'); // legacy flag for reviews; can remove later
297
- ShareaholicUtilities::delete_api_key();
298
- ShareaholicUtilities::delete_mutex();
299
- }
300
- }
301
-
302
- // the magic
303
- $shareaholic = Shareaholic::get_instance();
304
 
305
  } else {
306
- /* PLUGIN SPECIFIC CODE STARTS HERE */
307
- register_activation_hook(__FILE__, 'shareaholic_update_primary_plugin');
308
  }
309
 
310
  function shareaholic_update_primary_plugin() {
311
- if (is_plugin_active('sexybookmarks/shareaholic.php')) {
312
- add_action('update_option_active_plugins', 'shareaholic_activate_primary_plugin');
313
- }
314
  }
315
 
316
  function shareaholic_activate_primary_plugin() {
317
- deactivate_plugins('sexybookmarks/shareaholic.php');
318
- activate_plugins('shareaholic/shareaholic.php');
319
- add_filter('plugin_action_links_'.plugin_basename(__FILE__), 'ShareaholicUtilities::admin_plugin_action_links', -10);
320
  }
321
- /* PLUGIN SPECIFIC CODE ENDS HERE */
3
  Plugin Name: Shareaholic - Grow and Engage Your Audience
4
  Plugin URI: https://www.shareaholic.com/website-tools/
5
  Description: Shareaholic’s official WordPress plugin allows you to add Award-Winning Social Share Buttons, Related Posts, Content Analytics, Ad Monetization, and more to your website.
6
+ Version: 8.13.14
7
  Author: Shareaholic
8
  Author URI: https://www.shareaholic.com
9
  Text Domain: shareaholic
14
  * The main file!
15
  *
16
  * @package shareaholic
17
+ * @version 8.13.14
18
  */
19
 
20
  /**
21
  * Make sure we don't expose any info if called directly
 
22
  */
23
+ if ( ! function_exists( 'add_action' ) ) {
24
  echo 'Hi there! I\'m just a plugin, not much I can do when called directly.';
25
  exit;
26
  }
30
  * error_reporting(E_ALL ^ E_NOTICE);
31
  */
32
 
33
+ if ( ! defined( 'SHAREAHOLIC_FILE' ) ) {
34
+ define( 'SHAREAHOLIC_FILE', __FILE__ );
35
  }
36
 
37
+ if ( ! defined( 'SHAREAHOLIC_PATH' ) ) {
38
+ define( 'SHAREAHOLIC_PATH', plugin_dir_path( SHAREAHOLIC_FILE ) );
39
  }
40
 
41
+ if ( ! defined( 'SHAREAHOLIC_ASSET_DIR' ) ) {
42
+ define( 'SHAREAHOLIC_ASSET_DIR', plugins_url( '/assets/', __FILE__ ) );
43
  }
44
 
45
  // Caching
46
+ if ( ! defined( 'SHARE_COUNTS_CHECK_CACHE_LENGTH' ) ) {
47
+ define( 'SHARE_COUNTS_CHECK_CACHE_LENGTH', 900 ); // 900 seconds
48
  }
49
 
50
  // because define can use function returns and const can't
51
+ if ( ! defined( 'SHAREAHOLIC_DEBUG' ) ) {
52
+ define( 'SHAREAHOLIC_DEBUG', getenv( 'SHAREAHOLIC_DEBUG' ) );
53
  }
54
 
55
+ require_once SHAREAHOLIC_PATH . 'utilities.php';
56
+ require_once SHAREAHOLIC_PATH . 'global_functions.php';
57
+ require_once SHAREAHOLIC_PATH . 'admin.php';
58
+ require_once SHAREAHOLIC_PATH . 'public.php';
59
+ require_once SHAREAHOLIC_PATH . 'notifier.php';
60
+ require_once SHAREAHOLIC_PATH . 'cron.php';
61
+
62
+ if ( ! class_exists( 'Shareaholic' ) ) {
63
+ /**
64
+ * The main / base class.
65
+ *
66
+ * @package shareaholic
67
+ */
68
+ class Shareaholic {
69
+
70
+ const URL = 'https://www.shareaholic.com';
71
+ const API_URL = 'https://web.shareaholic.com'; // uses static IPs for firewall whitelisting
72
+ const CM_API_URL = 'https://cm-web.shareaholic.com'; // uses static IPs for firewall whitelisting
73
+
74
+ const VERSION = '8.13.14';
75
+
76
+ /**
77
+ * Starts off as false so that ::get_instance() returns
78
+ * a new instance.
79
+ */
80
+ private static $instance = false;
81
+
82
+ /**
83
+ * The constructor registers all the WordPress actions.
84
+ */
85
+ private function __construct() {
86
+ add_action( 'wp_ajax_shareaholic_accept_terms_of_service', array( 'ShareaholicUtilities', 'accept_terms_of_service' ) );
87
+
88
+ // Share Counts API
89
+ add_action( 'wp_ajax_nopriv_shareaholic_share_counts_api', array( 'ShareaholicPublic', 'share_counts_api' ) );
90
+ add_action( 'wp_ajax_shareaholic_share_counts_api', array( 'ShareaholicPublic', 'share_counts_api' ) );
91
+
92
+ // Debug info
93
+ add_action( 'wp_ajax_nopriv_shareaholic_debug_info', array( 'ShareaholicPublic', 'debug_info' ) );
94
+ add_action( 'wp_ajax_shareaholic_debug_info', array( 'ShareaholicPublic', 'debug_info' ) );
95
+
96
+ // Permalink list for Related Content index
97
+ add_action( 'wp_ajax_nopriv_shareaholic_permalink_list', array( 'ShareaholicPublic', 'permalink_list' ) );
98
+ add_action( 'wp_ajax_shareaholic_permalink_list', array( 'ShareaholicPublic', 'permalink_list' ) );
99
+
100
+ // SDK Badge
101
+ add_action( 'wp_ajax_nopriv_shareaholic_sdk_info', array( 'ShareaholicPublic', 'sdk_info' ) );
102
+ add_action( 'wp_ajax_shareaholic_sdk_info', array( 'ShareaholicPublic', 'sdk_info' ) );
103
+
104
+ // Permalink info for Related Content index
105
+ add_action( 'wp_ajax_nopriv_shareaholic_permalink_info', array( 'ShareaholicPublic', 'permalink_info' ) );
106
+ add_action( 'wp_ajax_shareaholic_permalink_info', array( 'ShareaholicPublic', 'permalink_info' ) );
107
+
108
+ // Related Permalinks for Related Content app bootup
109
+ add_action( 'wp_ajax_nopriv_shareaholic_permalink_related', array( 'ShareaholicPublic', 'permalink_related' ) );
110
+ add_action( 'wp_ajax_shareaholic_permalink_related', array( 'ShareaholicPublic', 'permalink_related' ) );
111
+
112
+ add_action( 'after_setup_theme', array( 'ShareaholicPublic', 'after_setup_theme' ) );
113
+
114
+ add_action( 'pre_get_posts', array( $this, 'shareaholic_draw_canvas' ) );
115
+
116
+ add_action( 'wp_head', array( 'ShareaholicPublic', 'wp_head' ), 6 );
117
+ add_filter( 'wp_resource_hints', array( 'ShareaholicPublic', 'shareaholic_resource_hints' ), 10, 2 );
118
+ add_shortcode( 'shareaholic', array( 'ShareaholicPublic', 'shortcode' ) );
119
+
120
+ add_action( 'plugins_loaded', array( $this, 'shareaholic_init' ) );
121
+
122
+ add_action( 'admin_init', array( 'ShareaholicAdmin', 'admin_init' ) );
123
+ add_action( 'admin_enqueue_scripts', array( 'ShareaholicAdmin', 'admin_header' ) );
124
+ add_action( 'wp_ajax_shareaholic_add_location', array( 'ShareaholicAdmin', 'add_location' ) );
125
+ add_action( 'add_meta_boxes', array( 'ShareaholicAdmin', 'add_meta_boxes' ) );
126
+ add_action( 'save_post', array( 'ShareaholicAdmin', 'save_post' ) );
127
+ add_action( 'admin_enqueue_scripts', array( 'ShareaholicAdmin', 'enqueue_scripts' ) );
128
+ add_action( 'admin_menu', array( 'ShareaholicAdmin', 'admin_menu' ) );
129
+
130
+ // add_action('publish_post', array('ShareaholicNotifier', 'post_notify'));
131
+ // add_action('publish_page', array('ShareaholicNotifier', 'post_notify'));
132
+
133
+ add_action( 'transition_post_status', array( 'ShareaholicUtilities', 'post_transitioned' ), 10, 3 );
134
+
135
+ register_activation_hook( __FILE__, array( $this, 'after_activation' ) );
136
+ register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) );
137
+ register_uninstall_hook( __FILE__, array( 'Shareaholic', 'uninstall' ) );
138
+
139
+ add_action( 'wp_before_admin_bar_render', array( 'ShareaholicUtilities', 'admin_bar_extended' ) );
140
+ add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'ShareaholicUtilities::admin_plugin_action_links', -10 );
141
+
142
+ // Add custom action to run remove_transients cron job
143
+ add_action( 'shareaholic_remove_transients_hourly', array( 'ShareaholicCron', 'remove_transients' ) );
144
+
145
+ // Add custom action to run shareaholic_heartbeat cron job
146
+ add_action( 'shareaholic_heartbeat', array( 'ShareaholicCron', 'heartbeat' ) );
147
+
148
+ // do something before a post is updated
149
+ add_action( 'pre_post_update', array( 'ShareaholicUtilities', 'before_post_is_updated' ) );
150
+
151
+ // do something before a post is trashed
152
+ add_action( 'pre_trash_post', array( 'ShareaholicUtilities', 'before_post_is_trashed' ) );
153
+
154
+ // do something before a site's permalink structure changes
155
+ add_action( 'update_option_permalink_structure', array( 'ShareaholicUtilities', 'notify_content_manager_singledomain' ) );
156
+
157
+ // Show ToS notice
158
+ if ( ! ShareaholicUtilities::has_accepted_terms_of_service() ) {
159
+ add_action( 'admin_notices', array( 'ShareaholicAdmin', 'show_terms_of_service' ) );
160
+ }
161
+
162
+ // use the admin notice API
163
+ add_action( 'admin_notices', array( 'ShareaholicAdmin', 'admin_notices' ) );
164
+
165
+ // Add our custom image type to the Media Library
166
+ add_filter( 'image_size_names_choose', array( 'ShareaholicAdmin', 'show_custom_sizes' ) );
167
+
168
+ // ShortCode UI plugin specific hooks to prevent duplicate app rendering
169
+ // https://wordpress.org/support/topic/custom-post-type-exclude-issue?replies=10#post-3370550
170
+ add_action( 'scui_external_hooks_remove', array( $this, 'remove_apps' ) );
171
+ add_action( 'scui_external_hooks_return', array( $this, 'return_apps' ) );
172
+
173
+ // WP Rocket Compatability
174
+ add_filter( 'rocket_minify_excluded_external_js', array( 'ShareaholicUtilities', 'rocket_exclude_js' ) );
175
+ }
176
+
177
+ public static function shareaholic_draw_canvas( $query ) {
178
+ if ( $query->is_main_query() ) {
179
+ add_filter( 'the_content', array( 'ShareaholicPublic', 'draw_canvases' ), 98 );
180
+ add_filter( 'the_excerpt', array( 'ShareaholicPublic', 'draw_canvases' ), 98 );
181
+ }
182
+ }
183
+
184
+ public static function remove_apps() {
185
+ remove_filter( 'the_content', array( 'ShareaholicPublic', 'draw_canvases' ), 98 );
186
+ remove_filter( 'the_excerpt', array( 'ShareaholicPublic', 'draw_canvases' ), 98 );
187
+ }
188
+
189
+ public static function return_apps() {
190
+ add_filter( 'the_content', array( 'ShareaholicPublic', 'draw_canvases' ), 98 );
191
+ add_filter( 'the_excerpt', array( 'ShareaholicPublic', 'draw_canvases' ), 98 );
192
+ }
193
+
194
+ /**
195
+ * We want this to be a singleton, so return the one instance
196
+ * if already instantiated.
197
+ *
198
+ * @return Shareaholic
199
+ */
200
+ public static function get_instance() {
201
+ if ( ! self::$instance ) {
202
+ self::$instance = new self();
203
+ }
204
+ self::init();
205
+ return self::$instance;
206
+ }
207
+
208
+ /**
209
+ * This function initializes the plugin so that everything is scoped
210
+ * under the class and no variables leak outside.
211
+ */
212
+ public static function init() {
213
+ self::update();
214
+ }
215
+
216
+ /**
217
+ * This function fires once any activated plugins have been loaded. Is generally used for immediate filter setup, or plugin overrides.
218
+ */
219
+ public function shareaholic_init() {
220
+ ShareaholicUtilities::localize();
221
+
222
+ if ( ShareaholicUtilities::has_accepted_terms_of_service() &&
223
+ isset( $_GET['page'] ) && preg_match( '/shareaholic/', $_GET['page'] ) ) {
224
+ ShareaholicUtilities::get_or_create_api_key();
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Runs update code if the plugin version is different from what is stored in the settings.
230
+ */
231
+ public static function update() {
232
+ if ( ShareaholicUtilities::get_version() != self::VERSION ) {
233
+ ShareaholicUtilities::perform_update();
234
+ ShareaholicUtilities::set_version( self::VERSION );
235
+ ShareaholicUtilities::log_event( 'Upgrade', array( 'previous_plugin_version' => ShareaholicUtilities::get_version() ) );
236
+ }
237
+ }
238
+
239
+ /**
240
+ * Checks whether to ask the user to accept the terms of service or not.
241
+ */
242
+ public function terms_of_service() {
243
+ if ( ! ShareaholicUtilities::has_accepted_terms_of_service() ) {
244
+ add_action( 'admin_notices', array( 'ShareaholicAdmin', 'show_terms_of_service' ) );
245
+ } else {
246
+ ShareaholicUtilities::get_or_create_api_key();
247
+ }
248
+ }
249
+
250
+ /**
251
+ * This function fires after the plugin has been activated.
252
+ */
253
+ public function after_activation() {
254
+ set_transient( '_shr_activation_redirect', true, 120 ); // for post-activation redirect
255
+
256
+ // Cleanup leftover mutex
257
+ ShareaholicUtilities::delete_mutex();
258
+
259
+ $this->terms_of_service();
260
+ ShareaholicUtilities::log_event( 'Activate' );
261
+
262
+ // workaround: http://codex.wordpress.org/Function_Reference/register_activation_hook
263
+ add_option( 'Activated_Plugin_Shareaholic', 'shareaholic' );
264
+ $api_key = ShareaholicUtilities::get_option( 'api_key' );
265
+ if ( ShareaholicUtilities::has_accepted_terms_of_service() && ! empty( $api_key ) ) {
266
+ ShareaholicUtilities::notify_content_manager_singledomain();
267
+ }
268
+
269
+ if ( ! ShareaholicUtilities::get_version() ) {
270
+ ShareaholicUtilities::log_event( 'Install_Fresh' );
271
+ }
272
+
273
+ // Activate the Shareaholic Cron Job for new users
274
+ ShareaholicCron::activate();
275
+ }
276
+
277
+ /**
278
+ * This function fires when the plugin is deactivated.
279
+ */
280
+ public function deactivate() {
281
+ ShareaholicUtilities::log_event( 'Deactivate' );
282
+ ShareaholicUtilities::clear_cache();
283
+ ShareaholicCron::deactivate();
284
+ ShareaholicUtilities::delete_mutex();
285
+ }
286
+
287
+ /**
288
+ * This function fires when the plugin is uninstalled.
289
+ */
290
+ public static function uninstall() {
291
+ ShareaholicUtilities::log_event( 'Uninstall' );
292
+ delete_option( 'shareaholic_has_accepted_tos' );
293
+ delete_option( 'shareaholic_settings' );
294
+ delete_option( 'shareaholic_activate_timestamp' );
295
+ delete_option( 'shareaholic_review_dismiss' ); // legacy flag for reviews; can remove later
296
+ ShareaholicUtilities::delete_api_key();
297
+ ShareaholicUtilities::delete_mutex();
298
+ }
299
+ }
300
+
301
+ // the magic
302
+ $shareaholic = Shareaholic::get_instance();
303
 
304
  } else {
305
+ /* PLUGIN SPECIFIC CODE STARTS HERE */
306
+ register_activation_hook( __FILE__, 'shareaholic_update_primary_plugin' );
307
  }
308
 
309
  function shareaholic_update_primary_plugin() {
310
+ if ( is_plugin_active( 'sexybookmarks/shareaholic.php' ) ) {
311
+ add_action( 'update_option_active_plugins', 'shareaholic_activate_primary_plugin' );
312
+ }
313
  }
314
 
315
  function shareaholic_activate_primary_plugin() {
316
+ deactivate_plugins( 'sexybookmarks/shareaholic.php' );
317
+ activate_plugins( 'shareaholic/shareaholic.php' );
318
+ add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'ShareaholicUtilities::admin_plugin_action_links', -10 );
319
  }
320
+ /* PLUGIN SPECIFIC CODE ENDS HERE */
six_to_seven.php CHANGED
@@ -7,575 +7,592 @@
7
 
8
  /**
9
  * This class is in charge or extracting the old style of configuration
10
- * from the wordpress database and turning it into a format that we
11
  * can POST back to shareaholic.com to create a new publisher configuration.
12
  *
13
  * @package shareaholic
14
  */
15
  class ShareaholicSixToSeven {
16
- /**
17
- * The updating function. This should create a whole configuration
18
- * object including share buttons and recommendations as well as
19
- * site name and domain to send back to us.
20
- */
21
- public static function update() {
22
- $version = ShareaholicUtilities::get_version();
23
- $sexybookmarks_configuration = get_option('SexyBookmarks');
24
- $classicbookmarks_configuration = get_option('ShareaholicClassicBookmarks');
25
- $recommendations_configuration = get_option('ShareaholicRecommendations');
26
- $top_bar_configuration = get_option('ShareaholicTopBar');
27
-
28
- $new_share_buttons_configuration = self::transform_sexybookmarks_configuration($sexybookmarks_configuration);
29
- $new_classicbookmarks_locations = self::transform_classicbookmarks_locations($classicbookmarks_configuration, $sexybookmarks_configuration);
30
- $new_top_bar_configuration = self::transform_top_bar_configuration($top_bar_configuration);
31
-
32
- $location_names = array_map(array('self', 'grab_location_iterator'), $new_share_buttons_configuration['locations_attributes']);
33
- // if sexybookmarks are off or not on the bottom
34
- if ($sexybookmarks_configuration['sexybookmark'] != '1' ||
35
- !(bool)preg_grep('/below/', $location_names)) {
36
- // then merge in the classic bookmark locations
37
- $new_share_buttons_configuration = array_merge(
38
- $new_share_buttons_configuration,
39
- $new_classicbookmarks_locations
40
- );
41
- } elseif ($sexybookmarks_configuration['sexybookmark'] != '1' ||
42
- !(bool)preg_grep('/above/', $location_names)) {
43
- $new_share_buttons_configuration = array_merge(
44
- $new_share_buttons_configuration,
45
- $new_top_bar_configuration
46
- );
47
- }
48
-
49
- $new_recommendations_configuration = array(
50
- 'locations_attributes' => self::transform_recommendations_configuration($recommendations_configuration)
51
- );
52
-
53
- $new_recommendations_configuration = isset($new_recommendations_configuration) ?
54
- $new_recommendations_configuration :
55
- null;
56
-
57
- $verification_key = md5(mt_rand());
58
-
59
- list($turned_on_share_buttons_location_names, $turned_off_share_buttons_location_names) = self::pad_locations($new_share_buttons_configuration);
60
- list($turned_on_recommendations_location_names, $turned_off_recommendations_location_names) = self::pad_locations($new_recommendations_configuration);
61
-
62
- $new_configuration = array(
63
- 'configuration_publisher' => array(
64
- 'share_buttons_attributes' => $new_share_buttons_configuration,
65
- 'recommendations_attributes' => $new_recommendations_configuration,
66
- 'site_name' => ShareaholicUtilities::site_name(),
67
- 'domain' => ShareaholicUtilities::site_url(),
68
- 'verification_key' => $verification_key,
69
- 'platform_id' => '12',
70
- 'language_id' => ShareaholicUtilities::site_language()
71
- ),
72
- );
73
-
74
- $shortener_configuration = (isset($sexybookmarks_configuration['shorty']) ?
75
- self::transform_shortener_configuration($sexybookmarks_configuration) : array());
76
- $new_configuration['configuration_publisher'] = array_merge($new_configuration['configuration_publisher'], $shortener_configuration);
77
-
78
- $response = ShareaholicCurl::post(Shareaholic::API_URL . '/publisher_tools/anonymous', $new_configuration, 'json');
79
-
80
- if ($response && preg_match('/20*/', $response['response']['code'])) {
81
- ShareaholicUtilities::log_event('6To7ConversionSuccess', array(
82
- 'the_posted_json' => $new_configuration,
83
- 'the_created_api_key' => $response['body']['api_key'],
84
- 'SexyBookmarks' => $sexybookmarks_configuration,
85
- 'ShareaholicClassicBookmarks' => $classicbookmarks_configuration,
86
- 'ShareaholicRecommendations' => $recommendations_configuration
87
- ));
88
-
89
- ShareaholicUtilities::update_options(array(
90
- 'api_key' => $response['body']['api_key'],
91
- 'version' => Shareaholic::VERSION,
92
- 'verification_key' => $verification_key,
93
- 'location_name_ids' => $response['body']['location_name_ids']
94
- ));
95
-
96
- ShareaholicUtilities::turn_on_locations(
97
- array('share_buttons' => array_flip($turned_on_share_buttons_location_names), 'recommendations' => array_flip($turned_on_recommendations_location_names)),
98
- array('share_buttons' => array_flip($turned_off_share_buttons_location_names), 'recommendations' => array_flip($turned_off_recommendations_location_names))
99
- );
100
-
101
- self::transform_wordpress_specific_settings();
102
- self::cleanup_v6_options();
103
- } else {
104
- ShareaholicUtilities::log_event('6To7ConversionFailed', array(
105
- 'the_posted_json' => $new_configuration,
106
- 'SexyBookmarks' => $sexybookmarks_configuration,
107
- 'ShareaholicClassicBookmarks' => $classicbookmarks_configuration,
108
- 'ShareaholicRecommendations' => $recommendations_configuration
109
- ));
110
- }
111
- }
112
-
113
- private static function pad_locations(&$configuration) {
114
- $all_names = array();
115
- foreach (array('post', 'page', 'index', 'category') as $page_type) {
116
- foreach (array('above', 'below') as $location) {
117
- $all_names[] = "{$page_type}_{$location}_content";
118
- }
119
- }
120
-
121
- $already_set_names = array();
122
- foreach($configuration['locations_attributes'] as $attrs) {
123
- $already_set_names[] = $attrs['name'];
124
- }
125
-
126
- $names_to_pad = array_diff($all_names, $already_set_names);
127
- foreach($names_to_pad as $name) {
128
- $configuration['locations_attributes'][] = array('name' => $name);
129
- }
130
-
131
- return array(
132
- $already_set_names,
133
- $names_to_pad
134
- );
135
- }
136
-
137
- private static function grab_location_iterator($location) {
138
- return $location['name'];
139
- }
140
-
141
- /**
142
- * Munge the stored configuration for sexybookmarks
143
- * into the format we expect them on our side.
144
- *
145
- * @param array $share_buttons_configuration the old wordpress configuration
146
- * to be transformed
147
- * @return array
148
- */
149
- private static function transform_sexybookmarks_configuration($share_buttons_configuration) {
150
- $result = array();
151
- $headline_text = self::transform_headline_text_settings($share_buttons_configuration);
152
- $counter = $share_buttons_configuration['showShareCount'] == '1' ? 'badge-counter' : '';
153
- $alignment = $share_buttons_configuration['autocenter'] != '0' ? 'center-align' : '';
154
-
155
- if ($share_buttons_configuration['position'] != 'both') {
156
- $result[$share_buttons_configuration['position']] = array(
157
- 'services' => self::services($share_buttons_configuration['bookmark']),
158
- 'theme' => 'diglett',
159
- 'counter' => $counter,
160
- 'headline_text' => $headline_text,
161
- 'alignment' => $alignment
162
- );
163
- } else {
164
- $result['above'] = array(
165
- 'services' => self::services($share_buttons_configuration['bookmark']),
166
- 'theme' => 'diglett',
167
- 'counter' => $counter,
168
- 'headline_text' => $headline_text,
169
- 'alignment' => $alignment
170
- );
171
- $result['below'] = array(
172
- 'services' => self::services($share_buttons_configuration['bookmark']),
173
- 'theme' => 'diglett',
174
- 'counter' => $counter,
175
- 'headline_text' => $headline_text,
176
- 'alignment' => $alignment
177
- );
178
- }
179
-
180
-
181
- if (!isset($result['above']) && $share_buttons_configuration['likeButtonSetTop']) {
182
- $result['above'] = array(
183
- 'services' => self::like_button_set_services($share_buttons_configuration),
184
- 'size' => 'rectangle',
185
- 'counter' => 'top-counter',
186
- 'headline_text' => ''
187
- );
188
- }
189
-
190
- if (!isset($result['below']) && $share_buttons_configuration['likeButtonSetBottom']) {
191
- $result['below'] = array(
192
- 'services' => self::like_button_set_services($share_buttons_configuration),
193
- // theme candybar
194
- 'size' => 'rectangle',
195
- 'counter' => 'top-counter',
196
- 'headline_text' => ''
197
- );
198
- }
199
-
200
- return array(
201
- 'message_format' => urldecode($share_buttons_configuration['tweetconfig']),
202
- 'locations_attributes' => self::set_page_types($result, $share_buttons_configuration['pageorpost'])
203
- );
204
- }
205
-
206
- /**
207
- * Translates settings for the 'top bar.' If it was not set to be on,
208
- * will return an empty array. Just because something is returned,
209
- * that does not mean it will be used. If the user already has something
210
- * for above content (from either sexy bookmarks or the like button
211
- * sets), this will not be used.
212
- *
213
- * @param array $top_bar_configuration
214
- * @return array either empty or in the style of our new configurations
215
- */
216
- private static function transform_top_bar_configuration($top_bar_configuration) {
217
- $result = array(
218
- 'services' => array()
219
- );
220
-
221
- if (!$top_bar_configuration['topbar']) {
222
- return array();
223
- }
224
-
225
- if ($top_bar_configuration['fbLikeButtonTop'] == '1' ||
226
- $top_bar_configuration['fbSendButtonTop'] == '1') {
227
- array_push($result['services'], 'facebook');
228
- }
229
- if ($top_bar_configuration['tweetButtonTop'] == '1') {
230
- array_push($result['services'], 'twitter');
231
- }
232
- if ($top_bar_configuration['googlePlusOneButtonTop'] == '1') {
233
- array_push($result['services'], 'google_plus');
234
- }
235
-
236
- // do some stuff for the themes!
237
- // there seems to be this thing `likeButtonSizeSetTop`
238
- // which can be one of [0,1,2], and that determines
239
- // the theme. the counters showing up is determined
240
- // by `likeButtonSetCountTop`
241
- switch ($top_bar_configuration['likeButtonSetSizeTop']) {
242
- case 0:
243
- $result['theme'] = '';
244
- $result['size'] = 'rectangle';
245
- $result['orientation'] = '';
246
- $result['counter'] = 'side-counter';
247
- break;
248
- case 1:
249
- $result['theme'] = '';
250
- $result['size'] = 'rectangle';
251
- $result['orientation'] = '';
252
- $result['counter'] = 'side-counter';
253
- break;
254
- case 2:
255
- $result['theme'] = '';
256
- $result['size'] = 'rectangle';
257
- $result['orientation'] = '';
258
- $result['counter'] = 'top-counter';
259
- break;
260
- }
261
-
262
- if (!$top_bar_configuration['likeButtonSetCountTop']) {
263
- $result['counter'] = '';
264
- }
265
-
266
- return self::set_page_types(array('above' => $result), $top_bar_configuration['pageorpost']);
267
- }
268
-
269
- /**
270
- * The old plugin could have a number of different shorteners enabled,
271
- * for which we just want to use shr.lc. Also some use different
272
- * names now.
273
- *
274
- * @param array $share_buttons_configuration
275
- * @return array our new version of the shortener configurations, which
276
- * will contain at least a key of 'shortener', but may also
277
- * include 'shortener_api_key' and 'shortener_login'
278
- */
279
- private static function transform_shortener_configuration($share_buttons_configuration) {
280
- $shortener = isset($share_buttons_configuration['shorty']) ? $share_buttons_configuration['shorty'] : NULL;
281
-
282
- switch ($shortener) {
283
- case 'goog':
284
- case 'google':
285
- return array('shortener' => 'googl');
286
- break;
287
- case 'tiny':
288
- return array('shortener' => 'tinyurl');
289
- break;
290
- case 'shrlc':
291
- case 'shr.lc':
292
- case 'yourls':
293
- case 'tflp':
294
- case 'slly':
295
- case 'snip':
296
- case 'cligs':
297
- case 'tinyarrow':
298
- case 'b2l':
299
- case 'trim':
300
- case 'e7t':
301
- case 'awesm':
302
- case 'supr':
303
- return array('shortener' => 'shrlc');
304
- break;
305
- case '':
306
- return array('shortener' => 'shrlc');
307
- break;
308
- default:
309
- return array(
310
- 'shortener' => $shortener ? $shortener : 'shrlc',
311
- 'shortener_api_key' => (isset($share_buttons_configuration['shortyapi'][$shortener]['key'])
312
- ? $share_buttons_configuration['shortyapi'][$shortener]['key'] : ''),
313
- 'shortener_login' => (isset($share_buttons_configuration['shortyapi'][$shortener]['user'])
314
- ? $share_buttons_configuration['shortyapi'][$shortener]['user'] : ''),
315
- );
316
- }
317
- }
318
-
319
- /**
320
- * The settings mungers only make an 'above' and a 'below' part,
321
- * not broken up by what page it should or not show up on.
322
- * This function checks $page_or_post for whether there should be
323
- * a location configuration for this page type and position.
324
- *
325
- * @param array $hash the configuration
326
- * @param string $page_or_post what types of pages are enabled
327
- * @return array
328
- */
329
- private static function set_page_types($hash, $page_or_post) {
330
- $result = array();
331
- foreach (array('post', 'page', 'index', 'category') as $place) {
332
- foreach (array('above', 'below') as $location) {
333
- if (isset($hash[$location]) && strpos($page_or_post, $place) !== false) {
334
- array_push($result, array_merge($hash[$location], array('name' => "{$place}_{$location}_content")));
335
- }
336
- }
337
- }
338
-
339
- return $result;
340
- }
341
-
342
- /**
343
- * Returns a configuration if the user was using classicbookmarks.
344
- *
345
- * @param array $classicbookmarks_configuration
346
- * @param array $share_buttons_configuration
347
- * @return array
348
- */
349
- private static function transform_classicbookmarks_locations($classicbookmarks_configuration, $share_buttons_configuration) {
350
- $result = array(
351
- 'services' => array('facebook', 'twitter', 'email_this', 'pinterest', 'tumblr', 'google_plus', 'linkedin'),
352
- );
353
-
354
- if ($classicbookmarks_configuration['size'] == '16') {
355
- $result = array_merge($result, array(
356
- 'theme' => '',
357
- 'size' => 'mini',
358
- 'orientation' => '',
359
- 'counter' => '',
360
- ));
361
- } elseif ($classicbookmarks_configuration['size'] == '32') {
362
- $result = array_merge($result, array(
363
- 'theme' => '',
364
- 'size' => '',
365
- 'orientation' => '',
366
- 'counter' => ''
367
- ));
368
- }
369
-
370
- return array(
371
- 'message_format' => urldecode($share_buttons_configuration['tweetconfig']),
372
- 'locations_attributes' => self::set_page_types(array('below' => $result), $classicbookmarks_configuration['pageorpost'])
373
- );
374
- }
375
-
376
- /**
377
- * Munge the stored configuration for recommendations
378
- * into the format we expect them on our side.
379
- *
380
- * @param array $recommendations_configuration
381
- * @return array
382
- */
383
- private static function transform_recommendations_configuration($recommendations_configuration) {
384
- $settings = array(
385
- 'below' => array(
386
- 'headline_text' => 'You may also like:',
387
- // if they requested text, honor that,
388
- // otherwise give them the default style
389
- 'theme' => $recommendations_configuration['style'] == 'text' ? 'text-only' : ''
390
- )
391
- );
392
-
393
- $page_types = 'postpagecategory';
394
-
395
- if ($recommendations_configuration['recommendations'] == '1') {
396
- $page_types = $recommendations_configuration['pageorpost'] . 'postpagecategory';
397
- }
398
-
399
- return self::set_page_types($settings, $page_types);
400
- }
401
-
402
- /**
403
- * Iterates through the bookmark list of services, which is
404
- * a list of class names in the form of `shr-<service>`
405
- *
406
- * @param array $services
407
- * @return array
408
- */
409
- private static function services($services) {
410
- return array_map(array('self', 'services_iterator'), $services);
411
- }
412
-
413
- /**
414
- * Because PHP < 5.3 doesn't support anonymous functions, this serves
415
- * as the mapping function for the above method.
416
- *
417
- * @param string $value
418
- * @return string
419
- */
420
- private static function services_iterator($value) {
421
- if (preg_match('/googleplus/', $value)) {
422
- // it's stored as googleplus in wordpress, but
423
- // now we use google_plus
424
- return 'google_plus';
425
- }
426
- if (preg_match('/googlebookmarks/', $value)) {
427
- // it's stored as googlebookmarks in wordpress, but
428
- // now we use google_bookmarks
429
- return 'google_bookmarks';
430
- }
431
- if (preg_match('/scriptstyle/', $value)) {
432
- return 'script_and_style';
433
- }
434
- if (preg_match('/designfloat/', $value)) {
435
- return 'design_float';
436
- }
437
- if (preg_match('/misterwong/', $value)) {
438
- return 'mister_wong';
439
- }
440
- if (preg_match('/hackernews/', $value)) {
441
- return 'yc_hacker_news';
442
- }
443
- if (preg_match('/designbump/', $value)) {
444
- return 'design_bump';
445
- }
446
- if (preg_match('/globalgrind/', $value)) {
447
- return 'global_grind';
448
- }
449
- if (preg_match('/pingfm/', $value)) {
450
- return 'ping_fm';
451
- }
452
- if (preg_match('/webblend/', $value)) {
453
- return 'web_blend';
454
- }
455
- if (preg_match('/shr-box/', $value)) {
456
- return 'box_net';
457
- }
458
- if (preg_match('/plaxo/', $value)) {
459
- return 'plaxo_pulse';
460
- }
461
- if (preg_match('/gmail/', $value)) {
462
- return 'google_mail';
463
- }
464
- if (preg_match('/yahoomail/', $value)) {
465
- return 'yahoo_mail';
466
- }
467
- if (preg_match('/fastmail/', $value)) {
468
- return 'mail';
469
- }
470
- if (preg_match('/mail/', $value)) {
471
- // it's stored as mail in wordpress, but
472
- // now we use email_this
473
- return 'email_this';
474
- }
475
- // return without the 'shr-'
476
- return str_replace('shr-', '', $value);
477
- }
478
-
479
- /**
480
- * For users who had enabled the 'like button set' thing,
481
- * we will turn them into the candy bar style buttons.
482
- *
483
- * @param array $share_buttons_configuration
484
- * @return array
485
- */
486
- private static function like_button_set_services($share_buttons_configuration) {
487
- if ($share_buttons_configuration['position'] == 'above') {
488
- $position = 'Bottom';
489
- } else {
490
- $position = 'Top';
491
- }
492
-
493
- $result = array();
494
- if ($share_buttons_configuration['fbLikeButton' . $position] == '1' ||
495
- $share_buttons_configuration['fbSendButton' . $position] == '1') {
496
- array_push($result, 'facebook');
497
- }
498
- if ($share_buttons_configuration['tweetButton' . $position] == '1') {
499
- array_push($result, 'twitter');
500
- }
501
- if ($share_buttons_configuration['googlePlusOneButton' . $position] == '1') {
502
- array_push($result, 'google_plus');
503
- }
504
-
505
- return $result;
506
- }
507
-
508
- /**
509
- * This function is for all settings that are specific to wordpress
510
- * and are not stored in a publisher configuration object. So far
511
- * this only inclues disabling the tracking.
512
- */
513
- private static function transform_wordpress_specific_settings() {
514
- $new_shareaholic_settings = array();
515
- $analytics_settings = get_option('ShareaholicAnalytics');
516
- $sexybookmarks_settings = get_option('SexyBookmarks');
517
-
518
- $new_shareaholic_settings['disable_og_tags'] = $sexybookmarks_settings['ogtags'] == '0' ? 'on' : 'off';
519
-
520
- ShareaholicUtilities::update_options($new_shareaholic_settings);
521
- }
522
-
523
- /**
524
- * This function cleans up options created by <= v6 of the plugin
525
- *
526
- */
527
- private static function cleanup_v6_options() {
528
- delete_option('SexyBookmarks');
529
- delete_option('ShareaholicTopbar');
530
- delete_option('ShareaholicAnalytics');
531
- delete_option('ShareaholicRecommendations');
532
- delete_option('ShareaholicClassicBookmarks');
533
- delete_option('shr_reportupgrade');
534
- delete_option('SHRSBvNum');
535
- delete_option('SHRSB_apikey');
536
- delete_option('SEXY_SPONSORS');
537
- delete_option('SHRSB_DefaultSprite');
538
- delete_option('SHRSB_CustomSprite');
539
- delete_option('SexyCustomSprite');
540
- }
541
-
542
- /**
543
- * Transform headline text based on background image
544
- *
545
- */
546
- private static function transform_headline_text_settings($sexybookmarks_configuration) {
547
- $headline_text = '';
548
-
549
- if ($sexybookmarks_configuration['bgimg-yes'] != 'yes') {
550
- return $headline_text;
551
- }
552
-
553
- switch ($sexybookmarks_configuration['bgimg']) {
554
- case 'shr':
555
- $headline_text = 'Sharing is sexy!';
556
- break;
557
- case 'caring':
558
- $headline_text = 'Sharing is caring.';
559
- break;
560
- case 'love':
561
- $headline_text = 'Share the love!';
562
- break;
563
- case 'wealth':
564
- $headline_text = 'Share the wealth!';
565
- break;
566
- case 'enjoy':
567
- $headline_text = 'Share and enjoy!';
568
- break;
569
- case 'knowledge':
570
- $headline_text = 'Share the knowledge!';
571
- break;
572
- case 'german':
573
- case 'care-old':
574
- default:
575
- $headline_text = 'Sharing is caring!';
576
- }
577
- return $headline_text;
578
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
579
  }
580
 
581
- ?>
7
 
8
  /**
9
  * This class is in charge or extracting the old style of configuration
10
+ * from the WordPress database and turning it into a format that we
11
  * can POST back to shareaholic.com to create a new publisher configuration.
12
  *
13
  * @package shareaholic
14
  */
15
  class ShareaholicSixToSeven {
16
+ /**
17
+ * The updating function. This should create a whole configuration
18
+ * object including share buttons and recommendations as well as
19
+ * site name and domain to send back to us.
20
+ */
21
+ public static function update() {
22
+ $version = ShareaholicUtilities::get_version();
23
+ $sexybookmarks_configuration = get_option( 'SexyBookmarks' );
24
+ $classicbookmarks_configuration = get_option( 'ShareaholicClassicBookmarks' );
25
+ $recommendations_configuration = get_option( 'ShareaholicRecommendations' );
26
+ $top_bar_configuration = get_option( 'ShareaholicTopBar' );
27
+
28
+ $new_share_buttons_configuration = self::transform_sexybookmarks_configuration( $sexybookmarks_configuration );
29
+ $new_classicbookmarks_locations = self::transform_classicbookmarks_locations( $classicbookmarks_configuration, $sexybookmarks_configuration );
30
+ $new_top_bar_configuration = self::transform_top_bar_configuration( $top_bar_configuration );
31
+
32
+ $location_names = array_map( array( 'self', 'grab_location_iterator' ), $new_share_buttons_configuration['locations_attributes'] );
33
+ // if sexybookmarks are off or not on the bottom
34
+ if ( $sexybookmarks_configuration['sexybookmark'] != '1' ||
35
+ ! (bool) preg_grep( '/below/', $location_names ) ) {
36
+ // then merge in the classic bookmark locations
37
+ $new_share_buttons_configuration = array_merge(
38
+ $new_share_buttons_configuration,
39
+ $new_classicbookmarks_locations
40
+ );
41
+ } elseif ( $sexybookmarks_configuration['sexybookmark'] != '1' ||
42
+ ! (bool) preg_grep( '/above/', $location_names ) ) {
43
+ $new_share_buttons_configuration = array_merge(
44
+ $new_share_buttons_configuration,
45
+ $new_top_bar_configuration
46
+ );
47
+ }
48
+
49
+ $new_recommendations_configuration = array(
50
+ 'locations_attributes' => self::transform_recommendations_configuration( $recommendations_configuration ),
51
+ );
52
+
53
+ $new_recommendations_configuration = isset( $new_recommendations_configuration ) ?
54
+ $new_recommendations_configuration :
55
+ null;
56
+
57
+ $verification_key = md5( mt_rand() );
58
+
59
+ list($turned_on_share_buttons_location_names, $turned_off_share_buttons_location_names) = self::pad_locations( $new_share_buttons_configuration );
60
+ list($turned_on_recommendations_location_names, $turned_off_recommendations_location_names) = self::pad_locations( $new_recommendations_configuration );
61
+
62
+ $new_configuration = array(
63
+ 'configuration_publisher' => array(
64
+ 'share_buttons_attributes' => $new_share_buttons_configuration,
65
+ 'recommendations_attributes' => $new_recommendations_configuration,
66
+ 'site_name' => ShareaholicUtilities::site_name(),
67
+ 'domain' => ShareaholicUtilities::site_url(),
68
+ 'verification_key' => $verification_key,
69
+ 'platform_id' => '12',
70
+ 'language_id' => ShareaholicUtilities::site_language(),
71
+ ),
72
+ );
73
+
74
+ $shortener_configuration = ( isset( $sexybookmarks_configuration['shorty'] ) ?
75
+ self::transform_shortener_configuration( $sexybookmarks_configuration ) : array() );
76
+ $new_configuration['configuration_publisher'] = array_merge( $new_configuration['configuration_publisher'], $shortener_configuration );
77
+
78
+ $response = ShareaholicCurl::post( Shareaholic::API_URL . '/publisher_tools/anonymous', $new_configuration, 'json' );
79
+
80
+ if ( $response && preg_match( '/20*/', $response['response']['code'] ) ) {
81
+ ShareaholicUtilities::log_event(
82
+ '6To7ConversionSuccess',
83
+ array(
84
+ 'the_posted_json' => $new_configuration,
85
+ 'the_created_api_key' => $response['body']['api_key'],
86
+ 'SexyBookmarks' => $sexybookmarks_configuration,
87
+ 'ShareaholicClassicBookmarks' => $classicbookmarks_configuration,
88
+ 'ShareaholicRecommendations' => $recommendations_configuration,
89
+ )
90
+ );
91
+
92
+ ShareaholicUtilities::update_options(
93
+ array(
94
+ 'api_key' => $response['body']['api_key'],
95
+ 'version' => Shareaholic::VERSION,
96
+ 'verification_key' => $verification_key,
97
+ 'location_name_ids' => $response['body']['location_name_ids'],
98
+ )
99
+ );
100
+
101
+ ShareaholicUtilities::turn_on_locations(
102
+ array(
103
+ 'share_buttons' => array_flip( $turned_on_share_buttons_location_names ),
104
+ 'recommendations' => array_flip( $turned_on_recommendations_location_names ),
105
+ ),
106
+ array(
107
+ 'share_buttons' => array_flip( $turned_off_share_buttons_location_names ),
108
+ 'recommendations' => array_flip( $turned_off_recommendations_location_names ),
109
+ )
110
+ );
111
+
112
+ self::transform_wordpress_specific_settings();
113
+ self::cleanup_v6_options();
114
+ } else {
115
+ ShareaholicUtilities::log_event(
116
+ '6To7ConversionFailed',
117
+ array(
118
+ 'the_posted_json' => $new_configuration,
119
+ 'SexyBookmarks' => $sexybookmarks_configuration,
120
+ 'ShareaholicClassicBookmarks' => $classicbookmarks_configuration,
121
+ 'ShareaholicRecommendations' => $recommendations_configuration,
122
+ )
123
+ );
124
+ }
125
+ }
126
+
127
+ private static function pad_locations( &$configuration ) {
128
+ $all_names = array();
129
+ foreach ( array( 'post', 'page', 'index', 'category' ) as $page_type ) {
130
+ foreach ( array( 'above', 'below' ) as $location ) {
131
+ $all_names[] = "{$page_type}_{$location}_content";
132
+ }
133
+ }
134
+
135
+ $already_set_names = array();
136
+ foreach ( $configuration['locations_attributes'] as $attrs ) {
137
+ $already_set_names[] = $attrs['name'];
138
+ }
139
+
140
+ $names_to_pad = array_diff( $all_names, $already_set_names );
141
+ foreach ( $names_to_pad as $name ) {
142
+ $configuration['locations_attributes'][] = array( 'name' => $name );
143
+ }
144
+
145
+ return array(
146
+ $already_set_names,
147
+ $names_to_pad,
148
+ );
149
+ }
150
+
151
+ private static function grab_location_iterator( $location ) {
152
+ return $location['name'];
153
+ }
154
+
155
+ /**
156
+ * Munge the stored configuration for sexybookmarks
157
+ * into the format we expect them on our side.
158
+ *
159
+ * @param array $share_buttons_configuration the old WordPress configuration
160
+ * to be transformed
161
+ * @return array
162
+ */
163
+ private static function transform_sexybookmarks_configuration( $share_buttons_configuration ) {
164
+ $result = array();
165
+ $headline_text = self::transform_headline_text_settings( $share_buttons_configuration );
166
+ $counter = $share_buttons_configuration['showShareCount'] == '1' ? 'badge-counter' : '';
167
+ $alignment = $share_buttons_configuration['autocenter'] != '0' ? 'center-align' : '';
168
+
169
+ if ( $share_buttons_configuration['position'] != 'both' ) {
170
+ $result[ $share_buttons_configuration['position'] ] = array(
171
+ 'services' => self::services( $share_buttons_configuration['bookmark'] ),
172
+ 'theme' => 'diglett',
173
+ 'counter' => $counter,
174
+ 'headline_text' => $headline_text,
175
+ 'alignment' => $alignment,
176
+ );
177
+ } else {
178
+ $result['above'] = array(
179
+ 'services' => self::services( $share_buttons_configuration['bookmark'] ),
180
+ 'theme' => 'diglett',
181
+ 'counter' => $counter,
182
+ 'headline_text' => $headline_text,
183
+ 'alignment' => $alignment,
184
+ );
185
+ $result['below'] = array(
186
+ 'services' => self::services( $share_buttons_configuration['bookmark'] ),
187
+ 'theme' => 'diglett',
188
+ 'counter' => $counter,
189
+ 'headline_text' => $headline_text,
190
+ 'alignment' => $alignment,
191
+ );
192
+ }
193
+
194
+ if ( ! isset( $result['above'] ) && $share_buttons_configuration['likeButtonSetTop'] ) {
195
+ $result['above'] = array(
196
+ 'services' => self::like_button_set_services( $share_buttons_configuration ),
197
+ 'size' => 'rectangle',
198
+ 'counter' => 'top-counter',
199
+ 'headline_text' => '',
200
+ );
201
+ }
202
+
203
+ if ( ! isset( $result['below'] ) && $share_buttons_configuration['likeButtonSetBottom'] ) {
204
+ $result['below'] = array(
205
+ 'services' => self::like_button_set_services( $share_buttons_configuration ),
206
+ // theme candybar
207
+ 'size' => 'rectangle',
208
+ 'counter' => 'top-counter',
209
+ 'headline_text' => '',
210
+ );
211
+ }
212
+
213
+ return array(
214
+ 'message_format' => urldecode( $share_buttons_configuration['tweetconfig'] ),
215
+ 'locations_attributes' => self::set_page_types( $result, $share_buttons_configuration['pageorpost'] ),
216
+ );
217
+ }
218
+
219
+ /**
220
+ * Translates settings for the 'top bar.' If it was not set to be on,
221
+ * will return an empty array. Just because something is returned,
222
+ * that does not mean it will be used. If the user already has something
223
+ * for above content (from either sexy bookmarks or the like button
224
+ * sets), this will not be used.
225
+ *
226
+ * @param array $top_bar_configuration
227
+ * @return array either empty or in the style of our new configurations
228
+ */
229
+ private static function transform_top_bar_configuration( $top_bar_configuration ) {
230
+ $result = array(
231
+ 'services' => array(),
232
+ );
233
+
234
+ if ( ! $top_bar_configuration['topbar'] ) {
235
+ return array();
236
+ }
237
+
238
+ if ( $top_bar_configuration['fbLikeButtonTop'] == '1' ||
239
+ $top_bar_configuration['fbSendButtonTop'] == '1' ) {
240
+ array_push( $result['services'], 'facebook' );
241
+ }
242
+ if ( $top_bar_configuration['tweetButtonTop'] == '1' ) {
243
+ array_push( $result['services'], 'twitter' );
244
+ }
245
+ if ( $top_bar_configuration['googlePlusOneButtonTop'] == '1' ) {
246
+ array_push( $result['services'], 'google_plus' );
247
+ }
248
+
249
+ // do some stuff for the themes!
250
+ // there seems to be this thing `likeButtonSizeSetTop`
251
+ // which can be one of [0,1,2], and that determines
252
+ // the theme. the counters showing up is determined
253
+ // by `likeButtonSetCountTop`
254
+ switch ( $top_bar_configuration['likeButtonSetSizeTop'] ) {
255
+ case 0:
256
+ $result['theme'] = '';
257
+ $result['size'] = 'rectangle';
258
+ $result['orientation'] = '';
259
+ $result['counter'] = 'side-counter';
260
+ break;
261
+ case 1:
262
+ $result['theme'] = '';
263
+ $result['size'] = 'rectangle';
264
+ $result['orientation'] = '';
265
+ $result['counter'] = 'side-counter';
266
+ break;
267
+ case 2:
268
+ $result['theme'] = '';
269
+ $result['size'] = 'rectangle';
270
+ $result['orientation'] = '';
271
+ $result['counter'] = 'top-counter';
272
+ break;
273
+ }
274
+
275
+ if ( ! $top_bar_configuration['likeButtonSetCountTop'] ) {
276
+ $result['counter'] = '';
277
+ }
278
+
279
+ return self::set_page_types( array( 'above' => $result ), $top_bar_configuration['pageorpost'] );
280
+ }
281
+
282
+ /**
283
+ * The old plugin could have a number of different shorteners enabled,
284
+ * for which we just want to use shr.lc. Also some use different
285
+ * names now.
286
+ *
287
+ * @param array $share_buttons_configuration
288
+ * @return array our new version of the shortener configurations, which
289
+ * will contain at least a key of 'shortener', but may also
290
+ * include 'shortener_api_key' and 'shortener_login'
291
+ */
292
+ private static function transform_shortener_configuration( $share_buttons_configuration ) {
293
+ $shortener = isset( $share_buttons_configuration['shorty'] ) ? $share_buttons_configuration['shorty'] : null;
294
+
295
+ switch ( $shortener ) {
296
+ case 'goog':
297
+ case 'google':
298
+ return array( 'shortener' => 'googl' );
299
+ break;
300
+ case 'tiny':
301
+ return array( 'shortener' => 'tinyurl' );
302
+ break;
303
+ case 'shrlc':
304
+ case 'shr.lc':
305
+ case 'yourls':
306
+ case 'tflp':
307
+ case 'slly':
308
+ case 'snip':
309
+ case 'cligs':
310
+ case 'tinyarrow':
311
+ case 'b2l':
312
+ case 'trim':
313
+ case 'e7t':
314
+ case 'awesm':
315
+ case 'supr':
316
+ return array( 'shortener' => 'shrlc' );
317
+ break;
318
+ case '':
319
+ return array( 'shortener' => 'shrlc' );
320
+ break;
321
+ default:
322
+ return array(
323
+ 'shortener' => $shortener ? $shortener : 'shrlc',
324
+ 'shortener_api_key' => ( isset( $share_buttons_configuration['shortyapi'][ $shortener ]['key'] )
325
+ ? $share_buttons_configuration['shortyapi'][ $shortener ]['key'] : '' ),
326
+ 'shortener_login' => ( isset( $share_buttons_configuration['shortyapi'][ $shortener ]['user'] )
327
+ ? $share_buttons_configuration['shortyapi'][ $shortener ]['user'] : '' ),
328
+ );
329
+ }
330
+ }
331
+
332
+ /**
333
+ * The settings mungers only make an 'above' and a 'below' part,
334
+ * not broken up by what page it should or not show up on.
335
+ * This function checks $page_or_post for whether there should be
336
+ * a location configuration for this page type and position.
337
+ *
338
+ * @param array $hash the configuration
339
+ * @param string $page_or_post what types of pages are enabled
340
+ * @return array
341
+ */
342
+ private static function set_page_types( $hash, $page_or_post ) {
343
+ $result = array();
344
+ foreach ( array( 'post', 'page', 'index', 'category' ) as $place ) {
345
+ foreach ( array( 'above', 'below' ) as $location ) {
346
+ if ( isset( $hash[ $location ] ) && strpos( $page_or_post, $place ) !== false ) {
347
+ array_push( $result, array_merge( $hash[ $location ], array( 'name' => "{$place}_{$location}_content" ) ) );
348
+ }
349
+ }
350
+ }
351
+
352
+ return $result;
353
+ }
354
+
355
+ /**
356
+ * Returns a configuration if the user was using classicbookmarks.
357
+ *
358
+ * @param array $classicbookmarks_configuration
359
+ * @param array $share_buttons_configuration
360
+ * @return array
361
+ */
362
+ private static function transform_classicbookmarks_locations( $classicbookmarks_configuration, $share_buttons_configuration ) {
363
+ $result = array(
364
+ 'services' => array( 'facebook', 'twitter', 'email_this', 'pinterest', 'tumblr', 'google_plus', 'linkedin' ),
365
+ );
366
+
367
+ if ( $classicbookmarks_configuration['size'] == '16' ) {
368
+ $result = array_merge(
369
+ $result,
370
+ array(
371
+ 'theme' => '',
372
+ 'size' => 'mini',
373
+ 'orientation' => '',
374
+ 'counter' => '',
375
+ )
376
+ );
377
+ } elseif ( $classicbookmarks_configuration['size'] == '32' ) {
378
+ $result = array_merge(
379
+ $result,
380
+ array(
381
+ 'theme' => '',
382
+ 'size' => '',
383
+ 'orientation' => '',
384
+ 'counter' => '',
385
+ )
386
+ );
387
+ }
388
+
389
+ return array(
390
+ 'message_format' => urldecode( $share_buttons_configuration['tweetconfig'] ),
391
+ 'locations_attributes' => self::set_page_types( array( 'below' => $result ), $classicbookmarks_configuration['pageorpost'] ),
392
+ );
393
+ }
394
+
395
+ /**
396
+ * Munge the stored configuration for recommendations
397
+ * into the format we expect them on our side.
398
+ *
399
+ * @param array $recommendations_configuration
400
+ * @return array
401
+ */
402
+ private static function transform_recommendations_configuration( $recommendations_configuration ) {
403
+ $settings = array(
404
+ 'below' => array(
405
+ 'headline_text' => 'You may also like:',
406
+ // if they requested text, honor that,
407
+ // otherwise give them the default style
408
+ 'theme' => $recommendations_configuration['style'] == 'text' ? 'text-only' : '',
409
+ ),
410
+ );
411
+
412
+ $page_types = 'postpagecategory';
413
+
414
+ if ( $recommendations_configuration['recommendations'] == '1' ) {
415
+ $page_types = $recommendations_configuration['pageorpost'] . 'postpagecategory';
416
+ }
417
+
418
+ return self::set_page_types( $settings, $page_types );
419
+ }
420
+
421
+ /**
422
+ * Iterates through the bookmark list of services, which is
423
+ * a list of class names in the form of `shr-<service>`
424
+ *
425
+ * @param array $services
426
+ * @return array
427
+ */
428
+ private static function services( $services ) {
429
+ return array_map( array( 'self', 'services_iterator' ), $services );
430
+ }
431
+
432
+ /**
433
+ * Because PHP < 5.3 doesn't support anonymous functions, this serves
434
+ * as the mapping function for the above method.
435
+ *
436
+ * @param string $value
437
+ * @return string
438
+ */
439
+ private static function services_iterator( $value ) {
440
+ if ( preg_match( '/googleplus/', $value ) ) {
441
+ // it's stored as googleplus in WordPress, but
442
+ // now we use google_plus
443
+ return 'google_plus';
444
+ }
445
+ if ( preg_match( '/googlebookmarks/', $value ) ) {
446
+ // it's stored as googlebookmarks in WordPress, but
447
+ // now we use google_bookmarks
448
+ return 'google_bookmarks';
449
+ }
450
+ if ( preg_match( '/scriptstyle/', $value ) ) {
451
+ return 'script_and_style';
452
+ }
453
+ if ( preg_match( '/designfloat/', $value ) ) {
454
+ return 'design_float';
455
+ }
456
+ if ( preg_match( '/misterwong/', $value ) ) {
457
+ return 'mister_wong';
458
+ }
459
+ if ( preg_match( '/hackernews/', $value ) ) {
460
+ return 'yc_hacker_news';
461
+ }
462
+ if ( preg_match( '/designbump/', $value ) ) {
463
+ return 'design_bump';
464
+ }
465
+ if ( preg_match( '/globalgrind/', $value ) ) {
466
+ return 'global_grind';
467
+ }
468
+ if ( preg_match( '/pingfm/', $value ) ) {
469
+ return 'ping_fm';
470
+ }
471
+ if ( preg_match( '/webblend/', $value ) ) {
472
+ return 'web_blend';
473
+ }
474
+ if ( preg_match( '/shr-box/', $value ) ) {
475
+ return 'box_net';
476
+ }
477
+ if ( preg_match( '/plaxo/', $value ) ) {
478
+ return 'plaxo_pulse';
479
+ }
480
+ if ( preg_match( '/gmail/', $value ) ) {
481
+ return 'google_mail';
482
+ }
483
+ if ( preg_match( '/yahoomail/', $value ) ) {
484
+ return 'yahoo_mail';
485
+ }
486
+ if ( preg_match( '/fastmail/', $value ) ) {
487
+ return 'mail';
488
+ }
489
+ if ( preg_match( '/mail/', $value ) ) {
490
+ // it's stored as mail in WordPress, but
491
+ // now we use email_this
492
+ return 'email_this';
493
+ }
494
+ // return without the 'shr-'
495
+ return str_replace( 'shr-', '', $value );
496
+ }
497
+
498
+ /**
499
+ * For users who had enabled the 'like button set' thing,
500
+ * we will turn them into the candy bar style buttons.
501
+ *
502
+ * @param array $share_buttons_configuration
503
+ * @return array
504
+ */
505
+ private static function like_button_set_services( $share_buttons_configuration ) {
506
+ if ( $share_buttons_configuration['position'] == 'above' ) {
507
+ $position = 'Bottom';
508
+ } else {
509
+ $position = 'Top';
510
+ }
511
+
512
+ $result = array();
513
+ if ( $share_buttons_configuration[ 'fbLikeButton' . $position ] == '1' ||
514
+ $share_buttons_configuration[ 'fbSendButton' . $position ] == '1' ) {
515
+ array_push( $result, 'facebook' );
516
+ }
517
+ if ( $share_buttons_configuration[ 'tweetButton' . $position ] == '1' ) {
518
+ array_push( $result, 'twitter' );
519
+ }
520
+ if ( $share_buttons_configuration[ 'googlePlusOneButton' . $position ] == '1' ) {
521
+ array_push( $result, 'google_plus' );
522
+ }
523
+
524
+ return $result;
525
+ }
526
+
527
+ /**
528
+ * This function is for all settings that are specific to WordPress
529
+ * and are not stored in a publisher configuration object. So far
530
+ * this only inclues disabling the tracking.
531
+ */
532
+ private static function transform_wordpress_specific_settings() {
533
+ $new_shareaholic_settings = array();
534
+ $analytics_settings = get_option( 'ShareaholicAnalytics' );
535
+ $sexybookmarks_settings = get_option( 'SexyBookmarks' );
536
+
537
+ $new_shareaholic_settings['disable_og_tags'] = $sexybookmarks_settings['ogtags'] == '0' ? 'on' : 'off';
538
+
539
+ ShareaholicUtilities::update_options( $new_shareaholic_settings );
540
+ }
541
+
542
+ /**
543
+ * This function cleans up options created by <= v6 of the plugin
544
+ */
545
+ private static function cleanup_v6_options() {
546
+ delete_option( 'SexyBookmarks' );
547
+ delete_option( 'ShareaholicTopbar' );
548
+ delete_option( 'ShareaholicAnalytics' );
549
+ delete_option( 'ShareaholicRecommendations' );
550
+ delete_option( 'ShareaholicClassicBookmarks' );
551
+ delete_option( 'shr_reportupgrade' );
552
+ delete_option( 'SHRSBvNum' );
553
+ delete_option( 'SHRSB_apikey' );
554
+ delete_option( 'SEXY_SPONSORS' );
555
+ delete_option( 'SHRSB_DefaultSprite' );
556
+ delete_option( 'SHRSB_CustomSprite' );
557
+ delete_option( 'SexyCustomSprite' );
558
+ }
559
+
560
+ /**
561
+ * Transform headline text based on background image
562
+ */
563
+ private static function transform_headline_text_settings( $sexybookmarks_configuration ) {
564
+ $headline_text = '';
565
+
566
+ if ( $sexybookmarks_configuration['bgimg-yes'] != 'yes' ) {
567
+ return $headline_text;
568
+ }
569
+
570
+ switch ( $sexybookmarks_configuration['bgimg'] ) {
571
+ case 'shr':
572
+ $headline_text = 'Sharing is sexy!';
573
+ break;
574
+ case 'caring':
575
+ $headline_text = 'Sharing is caring.';
576
+ break;
577
+ case 'love':
578
+ $headline_text = 'Share the love!';
579
+ break;
580
+ case 'wealth':
581
+ $headline_text = 'Share the wealth!';
582
+ break;
583
+ case 'enjoy':
584
+ $headline_text = 'Share and enjoy!';
585
+ break;
586
+ case 'knowledge':
587
+ $headline_text = 'Share the knowledge!';
588
+ break;
589
+ case 'german':
590
+ case 'care-old':
591
+ default:
592
+ $headline_text = 'Sharing is caring!';
593
+ }
594
+ return $headline_text;
595
+ }
596
  }
597
 
598
+
templates/admin.php CHANGED
@@ -1,26 +1,26 @@
1
- <?php if ($api_key) { ?>
2
 
3
- <?php ShareaholicAdmin::show_header(); ?>
4
 
5
  <div class='wrap'>
6
- <!-- h2 tag needed for WP to know where to place notices -->
7
- <h2 class="shareaholic-settings-h2"></h2>
8
- <script>
9
- window.ShareaholicConfig = {
10
- apiKey: "<?php echo $api_key ?>",
11
- verificationKey: "<?php echo $jwt ?>",
12
- apiHost: "<?php echo Shareaholic::API_URL ?>",
13
- serviceHost: "<?php echo Shareaholic::URL ?>",
14
- assetHost: "<?php echo ShareaholicUtilities::asset_url_admin() ?>",
15
- assetFolders: true,
16
- origin: "wp_plugin",
17
- language: "<?php echo strtolower(get_bloginfo('language')) ?>"
18
- };
19
- </script>
20
 
21
- <div id="root" class="shr-site-settings"></div>
22
 
23
- <script class="shr-app-loader__site-settings" src="<?php echo ShareaholicUtilities::asset_url_admin('ui-site-settings/loader.js') ?>"></script>
24
  </div>
25
 
26
  <?php } ?>
1
+ <?php if ( $api_key ) { ?>
2
 
3
+ <?php ShareaholicAdmin::show_header(); ?>
4
 
5
  <div class='wrap'>
6
+ <!-- h2 tag needed for WP to know where to place notices -->
7
+ <h2 class="shareaholic-settings-h2"></h2>
8
+ <script>
9
+ window.ShareaholicConfig = {
10
+ apiKey: "<?php echo $api_key; ?>",
11
+ verificationKey: "<?php echo $jwt; ?>",
12
+ apiHost: "<?php echo Shareaholic::API_URL; ?>",
13
+ serviceHost: "<?php echo Shareaholic::URL; ?>",
14
+ assetHost: "<?php echo ShareaholicUtilities::asset_url_admin(); ?>",
15
+ assetFolders: true,
16
+ origin: "wp_plugin",
17
+ language: "<?php echo strtolower( get_bloginfo( 'language' ) ); ?>"
18
+ };
19
+ </script>
20
 
21
+ <div id="root" class="shr-site-settings"></div>
22
 
23
+ <script class="shr-app-loader__site-settings" src="<?php echo ShareaholicUtilities::asset_url_admin( 'ui-site-settings/loader.js' ); ?>"></script>
24
  </div>
25
 
26
  <?php } ?>
templates/advanced_settings.php CHANGED
@@ -2,183 +2,215 @@
2
 
3
  <script>
4
  window.ShareaholicConfig = {
5
- apiHost: "<?php echo Shareaholic::API_URL ?>",
6
- serviceHost: "<?php echo Shareaholic::URL ?>",
7
- assetHost: "<?php echo ShareaholicUtilities::asset_url_admin() ?>",
8
  assetFolders: true,
9
  origin: "wp_plugin",
10
- language: "<?php echo strtolower(get_bloginfo('language')) ?>"
11
  };
12
  </script>
13
 
14
  <div class='wrap'>
15
- <h2><?php _e('Plugin Advanced Settings', 'shareaholic'); ?></h2>
16
  <div style="margin-top:10px;"></div>
17
 
18
  <div class="container-fluid">
19
- <div class="row">
20
- <div class="col-md-12">
21
- <?php _e('After changing any Shareaholic advanced setting, it is good practice to clear any WordPress caching plugins like W3 Total Cache or WP Super Cache.', 'shareaholic'); ?>
22
-
23
- <div class='clear'></div>
24
-
25
- <div class="app">
26
- <h2><?php _e('Shareaholic Site Profile ID', 'shareaholic'); ?></h2>
27
- <div class="app-content">
28
- <?php if (ShareaholicUtilities::get_option('api_key')){
29
- echo '<code style="font-size: 16px;">'.ShareaholicUtilities::get_option('api_key').'</code>';
30
- } else {
31
- _e('Not set.', 'shareaholic');
32
- } ?>
33
- </div>
34
- </div>
35
-
36
- <div class='clear'></div>
37
-
38
- <div class="app">
39
- <h2><?php _e('Server Connectivity', 'shareaholic'); ?></h2>
40
- <div class="app-content">
41
- <?php if (ShareaholicUtilities::connectivity_check() == "SUCCESS") { ?>
42
- <span class="key-status passed"><i class="fa fa-circle green" aria-hidden="true"></i> <?php _e('Shareaholic.com servers are reachable', 'shareaholic'); ?></span>
43
- <p class="key-description"><?php _e('Shareaholic should be working correctly.', 'shareaholic'); ?> <?php _e('All Shareaholic servers are accessible.', 'shareaholic'); ?></p>
44
- <?php } else { // can't connect to any server ?>
45
- <span class="key-status failed"><i class="fa fa-circle red blink" aria-hidden="true"></i> <?php _e('Unable to reach any Shareaholic server', 'shareaholic'); ?></span> <a href="#" onClick="window.location.reload(); this.innerHTML='<?php _e('Checking...', 'shareaholic'); ?>';"><?php _e('Re-check', 'shareaholic'); ?></a>
46
- <p class="key-description"><?php echo sprintf( __('A network problem or firewall is blocking connections from your web server to Shareaholic.com. <strong>Shareaholic cannot work correctly until this is fixed.</strong> Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Shareaholic and firewalls</a>. <a href="#" class="%s">Let us know too</a>, so we can follow up!'), 'https://www.shareaholic.com/blog/shareaholic-hosting-faq/', 'drift-open-chat','</a>'); ?></p>
47
- <?php } ?>
 
 
 
 
 
 
 
 
 
 
48
 
49
- <?php if (ShareaholicUtilities::get_option('disable_internal_share_counts_api') == NULL || ShareaholicUtilities::get_option('disable_internal_share_counts_api') == "off"){ ?>
50
- <?php if (ShareaholicUtilities::share_counts_api_connectivity_check() == 'SUCCESS') { ?>
51
- <span class="key-status passed"><i class="fa fa-circle green" aria-hidden="true"></i> <?php _e('Server-side Share Counts API is reachable', 'shareaholic'); ?></span>
52
- <p class="key-description"><?php _e('The server-side Share Counts API should be working correctly.', 'shareaholic'); ?> <?php _e('All servers and services needed by the API are accessible.', 'shareaholic'); ?></p>
53
- <?php } else { // can't connect to any server ?>
54
- <span class="key-status failed"><i class="fa fa-circle red blink" aria-hidden="true"></i> <?php _e('Unable to reach the server-side Share Count API', 'shareaholic'); ?></span> <a href="#" onClick="window.location.reload(); this.innerHTML='<?php _e('Checking...', 'shareaholic'); ?>';"><?php _e('Re-check', 'shareaholic'); ?></a>
55
- <p class="key-description"><?php echo sprintf( __('A network problem or firewall is blocking connections from your web server to various Share Count APIs. <strong>The API cannot work correctly until this is fixed.</strong> If you continue to face this issue, please <a href="#" class="%s">contact us</a> and we will follow up! In the meantime, if you disable the server-side Share Counts API from the Social Share Counts options, Shareaholic will default to using client-side APIs for share counts successfully -- so nothing to worry about!'), 'drift-open-chat'); ?></p>
56
- <?php } ?>
57
- <?php } ?>
58
- </div>
59
- </div>
60
-
61
- <div class='clear'></div>
62
-
63
- <form name='advanced_settings' method='post' action='<?php echo $action ?>'>
64
- <?php wp_nonce_field($action, 'nonce_field') ?>
65
- <input type='hidden' name='already_submitted' value='Y'>
66
- <div class='clear'>
67
- <div class="app">
68
- <h2><?php _e('Social Share Counts', 'shareaholic'); ?></h2>
69
- <div class="app-content">
70
-
71
- <div class="shr-form-item">
72
- <input type='checkbox' id='user_nicename' name='shareaholic[enable_user_nicename]' class='check'
73
- <?php if (isset($settings['enable_user_nicename'])) { ?>
74
- <?php echo ($settings['enable_user_nicename'] == 'on' ? 'checked' : '') ?>
75
- <?php } ?>>
76
- <label for="user_nicename"> <?php echo sprintf(__('Enable <code>&percnt;author&percnt;</code> permalink tag for Share Count Recovery', 'shareaholic')); ?></label>
77
- </div>
78
-
79
- <div class="shr-form-item">
80
- <input type='checkbox' id='share_counts' name='shareaholic[disable_internal_share_counts_api]' class='check'
81
- <?php if (isset($settings['disable_internal_share_counts_api'])) { ?>
82
- <?php echo ($settings['disable_internal_share_counts_api'] == 'on' ? 'checked' : '') ?>
83
- <?php } ?>>
84
- <label for="share_counts"> <?php echo sprintf(__('Disable Local Share Count Proxy.', 'shareaholic')); ?> <?php echo sprintf(__('When enabled, Share Counts will be fetched and cached locally by your server. This local proxy enhances user privacy and share counts but uses your server resources. Retrieving, caching and serving Share Counts can be a server and database intensive activity which can test even the best of web hosts. You can save on your hosting bill by offloading this heavy lifting to Shareaholic servers instead, <a href="%s" target="_blank">learn more</a>.', 'shareaholic'), 'https://support.shareaholic.com/hc/en-us/articles/360029500132'); ?></label>
85
- </div>
86
-
87
- <?php if (isset($settings['disable_internal_share_counts_api']) && $settings['disable_internal_share_counts_api'] != 'on') { ?>
88
- <fieldset id='facebook-app' <?php echo (ShareaholicUtilities::facebook_auth_check() != 'SUCCESS' ? "class='failed'" : '') ?>>
89
- <legend>
90
- <?php _e('Facebook', 'shareaholic'); ?>
91
-
92
- <?php if (ShareaholicUtilities::facebook_auth_check() == 'SUCCESS') { ?>
93
- <span class="key-status passed"><i class="fa fa-circle green" aria-hidden="true"></i> <?php _e('Live', 'shareaholic'); ?></span>
94
- <?php } else { ?>
95
- <span class="key-status failed"><i class="fa fa-circle red blink" aria-hidden="true"></i> <?php _e('Missing or Invalid Credentials', 'shareaholic'); ?></span></a>
96
- <?php } ?>
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
- </legend>
99
-
100
- <div class="shr-form-item shr-form-text">
101
- <label for="facebook_app_id"><?php _e('Facebook App ID', 'shareaholic'); ?></label><br>
102
- <input class="regular-text" id="facebook_app_id" type="text" name='shareaholic[facebook_app_id]' value="<?php if (isset($settings['facebook_app_id'])) {echo $settings['facebook_app_id'];} ?>">
103
- </div>
104
- <div class="shr-form-item shr-form-text">
105
- <label for="facebook_app_secret"><?php _e('Facebook App Secret', 'shareaholic'); ?></label><br>
106
- <input class="regular-text" id="facebook_app_secret" type="text" name='shareaholic[facebook_app_secret]' value="<?php if (isset($settings['facebook_app_id'])) {echo $settings['facebook_app_secret'];} ?>">
107
- </div>
108
-
109
- <?php echo sprintf(__('Required for better Facebook Share Counts. Please %sfollow documentation%s to get your Facebook App ID and Secret.', 'shareaholic'), '<a href="https://support.shareaholic.com/hc/en-us/articles/360028605231" target="_blank">','</a>'); ?>
110
- </fieldset>
111
- <?php } ?>
112
-
113
- <div class="button-wrapper">
114
- <input type='submit' class="btn btn-primary btn-medium" onclick="this.value='<?php echo sprintf(__('Saving Changes...', 'shareaholic')); ?>';" value='<?php echo sprintf(__('Save Changes', 'shareaholic')); ?>'>
115
- </div>
116
- </div>
117
- </div>
118
- </div>
119
-
120
- <div class='clear'>
121
- <div class="app">
122
- <h2><?php _e('Advanced', 'shareaholic'); ?></h2>
123
- <div class="app-content">
124
- <div class="shr-form-item">
125
- <input type='checkbox' id='og_tags' name='shareaholic[disable_og_tags]' class='check'
126
- <?php if (isset($settings['disable_og_tags'])) { ?>
127
- <?php echo ($settings['disable_og_tags'] == 'on' ? 'checked' : '') ?>
128
- <?php } ?>>
129
- <label for="og_tags"> <?php echo sprintf(__('Disable <code>Open Graph</code> tags', 'shareaholic')); ?> <?php echo sprintf(__('(it is recommended NOT to disable open graph tags)', 'shareaholic')); ?></label>
130
- </div>
131
- <div class="shr-form-item">
132
- <input type='checkbox' id='admin_bar' name='shareaholic[disable_admin_bar_menu]' class='check'
133
- <?php if (isset($settings['disable_admin_bar_menu'])) { ?>
134
- <?php echo ($settings['disable_admin_bar_menu'] == 'on' ? 'checked' : '') ?>
135
- <?php } ?>>
136
- <label for="admin_bar"> <?php echo sprintf(__('Disable Admin Bar Menu (requires page refresh)', 'shareaholic')); ?></label>
137
- </div>
138
- <div class="shr-form-item">
139
- <input type='checkbox' id='review_notice' name='shareaholic[disable_review_notice]' class='check'
140
- <?php if (isset($settings['disable_review_notice'])) { ?>
141
- <?php echo ($settings['disable_review_notice'] == 'on' ? 'checked' : '') ?>
142
- <?php } ?>>
143
- <label for="review_notice"> <?php echo sprintf(__('Disable Review Notice', 'shareaholic')); ?></label>
144
- </div>
145
- <div class="shr-form-item">
146
- <input type='checkbox' id='debugger' name='shareaholic[disable_debug_info]' class='check'
147
- <?php if (isset($settings['disable_debug_info'])) { ?>
148
- <?php echo ($settings['disable_debug_info'] == 'on' ? 'checked' : '') ?>
149
- <?php } ?>>
150
- <label for="debugger"> <?php echo sprintf(__('Disable Debugger (it is recommended NOT to disable the debugger)', 'shareaholic')); ?></label>
151
- </div>
152
- <div class="button-wrapper">
153
- <input type='submit' class="btn btn-primary btn-medium" onclick="this.value='<?php echo sprintf(__('Saving Changes...', 'shareaholic')); ?>';" value='<?php echo sprintf(__('Save Changes', 'shareaholic')); ?>'>
154
- </div>
155
- </div>
156
- </div>
157
- </div>
158
- </form>
159
-
160
- <div class='clear'></div>
161
-
162
- <form name='reset_settings' method='post' action='<?php echo $action ?>'>
163
- <?php wp_nonce_field($action, 'nonce_field') ?>
164
- <input type='hidden' name='reset_settings' value='Y'>
165
- <div class="app">
166
- <h2><?php _e('Reset Plugin', 'shareaholic'); ?></h2>
167
- <div class="app-content">
168
- <?php _e('This will reset all of your settings and start you from scratch. This can not be undone.', 'shareaholic'); ?>
169
- <div class="button-wrapper">
170
- <input class="btn btn-danger btn-medium" type='submit' onclick="this.value='<?php _e('Resetting Plugin...', 'shareaholic'); ?>';" value='<?php _e('Reset Plugin', 'shareaholic'); ?>'>
171
- </div>
172
- </div>
173
- </div>
174
-
175
- <div class='clear' style="padding-bottom:10px;"></div>
176
-
177
- </form>
178
- </div>
179
- </div>
 
 
 
 
 
 
 
 
 
 
180
  </div>
181
  </div>
182
 
183
  <?php ShareaholicAdmin::show_footer(); ?>
184
- <?php ShareaholicAdmin::include_chat(); ?>
2
 
3
  <script>
4
  window.ShareaholicConfig = {
5
+ apiHost: "<?php echo Shareaholic::API_URL; ?>",
6
+ serviceHost: "<?php echo Shareaholic::URL; ?>",
7
+ assetHost: "<?php echo ShareaholicUtilities::asset_url_admin(); ?>",
8
  assetFolders: true,
9
  origin: "wp_plugin",
10
+ language: "<?php echo strtolower( get_bloginfo( 'language' ) ); ?>"
11
  };
12
  </script>
13
 
14
  <div class='wrap'>
15
+ <h2><?php _e( 'Plugin Settings', 'shareaholic' ); ?></h2>
16
  <div style="margin-top:10px;"></div>
17
 
18
  <div class="container-fluid">
19
+ <div class="row">
20
+ <div class="col-md-12">
21
+ <?php _e( 'After changing any Shareaholic plugin setting, it is good practice to clear any WordPress caching plugins like W3 Total Cache or WP Super Cache.', 'shareaholic' ); ?>
22
+
23
+ <div class='clear'></div>
24
+
25
+ <div class="app">
26
+ <h2><?php echo sprintf( __( 'Getting Started' ) ); ?></h2>
27
+ <p><?php echo sprintf( __( '%1$sLearn the basics of how to get started and configure Shareaholic through our popular WordPress plugin.%2$s', 'shareaholic' ), '<a href="https://support.shareaholic.com/hc/en-us/categories/200101476-WordPress-Plugin" target="_blank">', '</a>' ); ?> <?php echo sprintf( __( 'If you are upgrading from an earlier version of Shareaholic for WordPress and need help, have a question or have a bug to report, please %1$slet us know%2$s.', 'shareaholic' ), '<a href="https://www.shareaholic.com/help/message" target="_blank">', '</a>' ); ?>
28
+ </p>
29
+ </div>
30
+
31
+ <div class='clear'></div>
32
+
33
+ <div class="app">
34
+ <h2><?php _e( 'Shareaholic Site Profile ID', 'shareaholic' ); ?></h2>
35
+ <div class="app-content">
36
+ <?php
37
+ if ( ShareaholicUtilities::get_option( 'api_key' ) ) {
38
+ echo '<code style="font-size: 16px;">' . ShareaholicUtilities::get_option( 'api_key' ) . '</code>';
39
+ } else {
40
+ _e( 'Not set.', 'shareaholic' );
41
+ }
42
+ ?>
43
+ </div>
44
+ </div>
45
+
46
+ <div class='clear'></div>
47
+
48
+ <div class="app">
49
+ <h2><?php _e( 'Server Connectivity', 'shareaholic' ); ?></h2>
50
+ <div class="app-content">
51
+ <?php if ( ShareaholicUtilities::connectivity_check() == 'SUCCESS' ) { ?>
52
+ <span class="key-status passed"><i class="fa fa-circle green" aria-hidden="true"></i> <?php _e( 'Shareaholic.com servers are reachable', 'shareaholic' ); ?></span>
53
+ <p class="key-description"><?php _e( 'Shareaholic should be working correctly.', 'shareaholic' ); ?> <?php _e( 'All Shareaholic servers are accessible.', 'shareaholic' ); ?></p>
54
+ <?php } else { // can't connect to any server ?>
55
+ <span class="key-status failed"><i class="fa fa-circle red blink" aria-hidden="true"></i> <?php _e( 'Unable to reach any Shareaholic server', 'shareaholic' ); ?></span> <a href="#" onClick="window.location.reload(); this.innerHTML='<?php _e( 'Checking...', 'shareaholic' ); ?>';"><?php _e( 'Re-check', 'shareaholic' ); ?></a>
56
+ <p class="key-description"><?php echo sprintf( __( 'A network problem or firewall is blocking connections from your web server to Shareaholic.com. <strong>Shareaholic cannot work correctly until this is fixed.</strong> Please contact your web host or firewall administrator and give them <a href="%1$s" target="_blank">this information about Shareaholic and firewalls</a>. <a href="#" class="%2$s">Let us know too</a>, so we can follow up!' ), 'https://www.shareaholic.com/blog/shareaholic-hosting-faq/', 'drift-open-chat', '</a>' ); ?></p>
57
+ <?php } ?>
58
 
59
+ <?php if ( ShareaholicUtilities::get_option( 'disable_internal_share_counts_api' ) == null || ShareaholicUtilities::get_option( 'disable_internal_share_counts_api' ) == 'off' ) { ?>
60
+ <?php if ( ShareaholicUtilities::share_counts_api_connectivity_check() == 'SUCCESS' ) { ?>
61
+ <span class="key-status passed"><i class="fa fa-circle green" aria-hidden="true"></i> <?php _e( 'Server-side Share Counts API is reachable', 'shareaholic' ); ?></span>
62
+ <p class="key-description"><?php _e( 'The server-side Share Counts API should be working correctly.', 'shareaholic' ); ?> <?php _e( 'All servers and services needed by the API are accessible.', 'shareaholic' ); ?></p>
63
+ <?php } else { // can't connect to any server ?>
64
+ <span class="key-status failed"><i class="fa fa-circle red blink" aria-hidden="true"></i> <?php _e( 'Unable to reach the server-side Share Count API', 'shareaholic' ); ?></span> <a href="#" onClick="window.location.reload(); this.innerHTML='<?php _e( 'Checking...', 'shareaholic' ); ?>';"><?php _e( 'Re-check', 'shareaholic' ); ?></a>
65
+ <p class="key-description"><?php echo sprintf( __( 'A network problem or firewall is blocking connections from your web server to various Share Count APIs. <strong>The API cannot work correctly until this is fixed.</strong> If you continue to face this issue, please <a href="#" class="%s">contact us</a> and we will follow up! In the meantime, if you disable the server-side Share Counts API from the Social Share Counts options, Shareaholic will default to using client-side APIs for share counts successfully -- so nothing to worry about!' ), 'drift-open-chat' ); ?></p>
66
+ <?php } ?>
67
+ <?php } ?>
68
+ </div>
69
+ </div>
70
+
71
+ <div class='clear'></div>
72
+
73
+ <div class="app">
74
+ <h2><?php _e( 'Connect Shareaholic Account', 'shareaholic' ); ?></h2>
75
+ <div class="app-content">
76
+ <?php echo sprintf( __( 'Connecting this plugin to a free Shareaholic account is highly recommended. Doing so will unlock additional functionality that requires authentication such as site ownership verification, team features and site integrations like Google Analytics.', 'shareaholic' ) ); ?>
77
+ <div class="button-wrapper">
78
+ <a href="<?php echo esc_url( admin_url( 'admin.php?shareaholic_redirect_url=shareaholic.com/signup/' ) ); ?>" target="_blank" class="btn btn-dark" role="button" style="font-size: 14px;"><?php echo sprintf( __( 'Connect Plugin', 'shareaholic' ) ); ?></a>
79
+ </div>
80
+ </div>
81
+ </div>
82
+
83
+ <div class='clear'></div>
84
+
85
+ <form name='advanced_settings' method='post' action='<?php echo $action; ?>'>
86
+ <?php wp_nonce_field( $action, 'nonce_field' ); ?>
87
+ <input type='hidden' name='already_submitted' value='Y'>
88
+ <div class='clear'>
89
+ <div class="app">
90
+ <h2><?php _e( 'Social Share Counts', 'shareaholic' ); ?></h2>
91
+ <div class="app-content">
92
+
93
+ <div class="shr-form-item">
94
+ <input type='checkbox' id='user_nicename' name='shareaholic[enable_user_nicename]' class='check'
95
+ <?php if ( isset( $settings['enable_user_nicename'] ) ) { ?>
96
+ <?php echo ( $settings['enable_user_nicename'] == 'on' ? 'checked' : '' ); ?>
97
+ <?php } ?>>
98
+ <label for="user_nicename"> <?php echo sprintf( __( 'Enable <code>&percnt;author&percnt;</code> permalink tag for Share Count Recovery', 'shareaholic' ) ); ?></label>
99
+ </div>
100
+
101
+ <div class="shr-form-item">
102
+ <input type='checkbox' id='share_counts' name='shareaholic[disable_internal_share_counts_api]' class='check'
103
+ <?php if ( isset( $settings['disable_internal_share_counts_api'] ) ) { ?>
104
+ <?php echo ( $settings['disable_internal_share_counts_api'] == 'on' ? 'checked' : '' ); ?>
105
+ <?php } ?>>
106
+ <label for="share_counts"> <?php echo sprintf( __( 'Disable Local Share Count Proxy.', 'shareaholic' ) ); ?> <?php echo sprintf( __( 'When enabled, Share Counts will be fetched and cached locally by your server. This local proxy enhances user privacy and share counts but uses your server resources. Retrieving, caching and serving Share Counts can be a server and database intensive activity which can test even the best of web hosts. You can save on your hosting bill by offloading this heavy lifting to Shareaholic servers instead, <a href="%s" target="_blank">learn more</a>.', 'shareaholic' ), 'https://support.shareaholic.com/hc/en-us/articles/360029500132' ); ?></label>
107
+ </div>
108
+
109
+ <?php if ( isset( $settings['disable_internal_share_counts_api'] ) && $settings['disable_internal_share_counts_api'] != 'on' ) { ?>
110
+ <fieldset id='facebook-app' <?php echo ( ShareaholicUtilities::facebook_auth_check() != 'SUCCESS' ? "class='failed'" : '' ); ?>>
111
+ <legend>
112
+ <?php _e( 'Facebook', 'shareaholic' ); ?>
113
+
114
+ <?php if ( ShareaholicUtilities::facebook_auth_check() == 'SUCCESS' ) { ?>
115
+ <span class="key-status passed"><i class="fa fa-circle green" aria-hidden="true"></i> <?php _e( 'Live', 'shareaholic' ); ?></span>
116
+ <?php } else { ?>
117
+ <span class="key-status failed"><i class="fa fa-circle red blink" aria-hidden="true"></i> <?php _e( 'Missing or Invalid Credentials', 'shareaholic' ); ?></span></a>
118
+ <?php } ?>
119
 
120
+ </legend>
121
+
122
+ <div class="shr-form-item shr-form-text">
123
+ <label for="facebook_app_id"><?php _e( 'Facebook App ID', 'shareaholic' ); ?></label><br>
124
+ <input class="regular-text" id="facebook_app_id" type="text" name='shareaholic[facebook_app_id]' value="
125
+ <?php
126
+ if ( isset( $settings['facebook_app_id'] ) ) {
127
+ echo $settings['facebook_app_id'];}
128
+ ?>
129
+ ">
130
+ </div>
131
+ <div class="shr-form-item shr-form-text">
132
+ <label for="facebook_app_secret"><?php _e( 'Facebook App Secret', 'shareaholic' ); ?></label><br>
133
+ <input class="regular-text" id="facebook_app_secret" type="text" name='shareaholic[facebook_app_secret]' value="
134
+ <?php
135
+ if ( isset( $settings['facebook_app_id'] ) ) {
136
+ echo $settings['facebook_app_secret'];}
137
+ ?>
138
+ ">
139
+ </div>
140
+
141
+ <?php echo sprintf( __( 'Required for better Facebook Share Counts. Please %1$sfollow documentation%2$s to get your Facebook App ID and Secret.', 'shareaholic' ), '<a href="https://support.shareaholic.com/hc/en-us/articles/360028605231" target="_blank">', '</a>' ); ?>
142
+ </fieldset>
143
+ <?php } ?>
144
+
145
+ <div class="button-wrapper">
146
+ <input type='submit' class="btn btn-primary btn-medium" onclick="this.value='<?php echo sprintf( __( 'Saving Changes...', 'shareaholic' ) ); ?>';" value='<?php echo sprintf( __( 'Save Changes', 'shareaholic' ) ); ?>'>
147
+ </div>
148
+ </div>
149
+ </div>
150
+ </div>
151
+
152
+ <div class='clear'>
153
+ <div class="app">
154
+ <h2><?php _e( 'Advanced', 'shareaholic' ); ?></h2>
155
+ <div class="app-content">
156
+ <div class="shr-form-item">
157
+ <input type='checkbox' id='og_tags' name='shareaholic[disable_og_tags]' class='check'
158
+ <?php if ( isset( $settings['disable_og_tags'] ) ) { ?>
159
+ <?php echo ( $settings['disable_og_tags'] == 'on' ? 'checked' : '' ); ?>
160
+ <?php } ?>>
161
+ <label for="og_tags"> <?php echo sprintf( __( 'Disable <code>Open Graph</code> tags', 'shareaholic' ) ); ?> <?php echo sprintf( __( '(it is recommended NOT to disable open graph tags)', 'shareaholic' ) ); ?></label>
162
+ </div>
163
+ <div class="shr-form-item">
164
+ <input type='checkbox' id='admin_bar' name='shareaholic[disable_admin_bar_menu]' class='check'
165
+ <?php if ( isset( $settings['disable_admin_bar_menu'] ) ) { ?>
166
+ <?php echo ( $settings['disable_admin_bar_menu'] == 'on' ? 'checked' : '' ); ?>
167
+ <?php } ?>>
168
+ <label for="admin_bar"> <?php echo sprintf( __( 'Disable Admin Bar Menu (requires page refresh)', 'shareaholic' ) ); ?></label>
169
+ </div>
170
+ <div class="shr-form-item">
171
+ <input type='checkbox' id='review_notice' name='shareaholic[disable_review_notice]' class='check'
172
+ <?php if ( isset( $settings['disable_review_notice'] ) ) { ?>
173
+ <?php echo ( $settings['disable_review_notice'] == 'on' ? 'checked' : '' ); ?>
174
+ <?php } ?>>
175
+ <label for="review_notice"> <?php echo sprintf( __( 'Disable Review Notice', 'shareaholic' ) ); ?></label>
176
+ </div>
177
+ <div class="shr-form-item">
178
+ <input type='checkbox' id='debugger' name='shareaholic[disable_debug_info]' class='check'
179
+ <?php if ( isset( $settings['disable_debug_info'] ) ) { ?>
180
+ <?php echo ( $settings['disable_debug_info'] == 'on' ? 'checked' : '' ); ?>
181
+ <?php } ?>>
182
+ <label for="debugger"> <?php echo sprintf( __( 'Disable Debugger (it is recommended NOT to disable the debugger)', 'shareaholic' ) ); ?></label>
183
+ </div>
184
+ <div class="button-wrapper">
185
+ <input type='submit' class="btn btn-primary btn-medium" onclick="this.value='<?php echo sprintf( __( 'Saving Changes...', 'shareaholic' ) ); ?>';" value='<?php echo sprintf( __( 'Save Changes', 'shareaholic' ) ); ?>'>
186
+ </div>
187
+ </div>
188
+ </div>
189
+ </div>
190
+ </form>
191
+
192
+ <div class='clear'></div>
193
+
194
+ <form name='reset_settings' method='post' action='<?php echo $action; ?>'>
195
+ <?php wp_nonce_field( $action, 'nonce_field' ); ?>
196
+ <input type='hidden' name='reset_settings' value='Y'>
197
+ <div class="app">
198
+ <h2><?php _e( 'Reset Plugin', 'shareaholic' ); ?></h2>
199
+ <div class="app-content">
200
+ <?php _e( 'This will reset all of your settings and start you from scratch. This can not be undone.', 'shareaholic' ); ?>
201
+ <div class="button-wrapper">
202
+ <input class="btn btn-danger btn-medium" type='submit' onclick="this.value='<?php _e( 'Resetting Plugin...', 'shareaholic' ); ?>';" value='<?php _e( 'Reset Plugin', 'shareaholic' ); ?>'>
203
+ </div>
204
+ </div>
205
+ </div>
206
+
207
+ <div class='clear' style="padding-bottom:10px;"></div>
208
+
209
+ </form>
210
+ </div>
211
+ </div>
212
  </div>
213
  </div>
214
 
215
  <?php ShareaholicAdmin::show_footer(); ?>
216
+ <?php ShareaholicAdmin::include_chat(); ?>
templates/failed_to_create_api_key.php CHANGED
@@ -1,11 +1,11 @@
1
- <?php if ( current_user_can( 'manage_options' ) ){ ?>
2
  <div class="shareaholic-wrap-container" style="padding: 0 20px 0px 15px; background-color: #45a147; margin: 25px 0px 20px -18px;">
3
- <div style="margin: 0px 8px 0 4px; float: left;"><img src="<?php echo SHAREAHOLIC_ASSET_DIR; ?>img/check.png" width=56 height=50 /></div>
4
- <div class="shareaholic-text-container" style="color: #fff; text-shadow: 0px 1px 1px rgba(0,0,0,0.4); font-size: 14px; display: table-cell;">
5
- <p>
6
- <strong><?php echo sprintf(__('Action required: You\'ve installed Shareaholic for WordPress. We\'re ready when you are. %sGet started now &raquo;%s', 'shareaholic'), '<a href="admin.php?page=shareaholic-settings" class="button-secondary">', '</a>'); ?></strong>
7
- </p>
8
- </div>
9
  </div>
10
  <div style="clear:both;"></div>
11
- <?php } ?>
1
+ <?php if ( current_user_can( 'manage_options' ) ) { ?>
2
  <div class="shareaholic-wrap-container" style="padding: 0 20px 0px 15px; background-color: #45a147; margin: 25px 0px 20px -18px;">
3
+ <div style="margin: 0px 8px 0 4px; float: left;"><img src="<?php echo SHAREAHOLIC_ASSET_DIR; ?>img/check.png" width=56 height=50 /></div>
4
+ <div class="shareaholic-text-container" style="color: #fff; text-shadow: 0px 1px 1px rgba(0,0,0,0.4); font-size: 14px; display: table-cell;">
5
+ <p>
6
+ <strong><?php echo sprintf( __( 'Action required: You\'ve installed Shareaholic for WordPress. We\'re ready when you are. %1$sGet started now &raquo;%2$s', 'shareaholic' ), '<a href="admin.php?page=shareaholic-settings" class="button-secondary">', '</a>' ); ?></strong>
7
+ </p>
8
+ </div>
9
  </div>
10
  <div style="clear:both;"></div>
11
+ <?php } ?>
templates/failed_to_create_api_key_modal.php CHANGED
@@ -1,18 +1,18 @@
1
  <div class='reveal-modal blocking-modal api-key-modal' id='failed_to_create_api_key'>
2
- <h4><?php echo sprintf(__('Setup Shareaholic', 'shareaholic')); ?></h4>
3
  <div class="content pal" style="padding:20px;">
4
- <p style="font-size:14px;">
5
- <?php _e('It appears that we are having some trouble setting up Shareaholic for WordPress right now. This is usually temporary. Please revisit this section after a few minutes or click "retry" now.', 'shareaholic'); ?>
6
- </p>
7
- <a id='get_started' class="btn_main" style="margin-top: 15px;" href=''><?php echo _e('Retry', 'shareaholic'); ?></a>
8
- <br />
9
- <span style="font-size:12px; font-weight:normal;">
10
- <a href='<?php echo admin_url() ?>'><?php _e('or, try again later.', 'shareaholic'); ?></a>
11
- </span>
12
- <br /><br />
13
- <p style="font-size:12px; font-weight:normal;">
14
- <?php echo sprintf(__('If you continue to get this prompt for more than a few minutes, ensure that you have the latest version of the plugin installed. If you still continue to get this prompt, then check "Shareaholic Server Connectivity Status" or reset the plugin. Both are available under %sAdvanced Settings%s.', 'shareaholic'), '<a href="admin.php?page=shareaholic-advanced">', '</a>'); ?> <?php echo sprintf(__('Also, if you have a question or have a bug to report, please %slet us know%s.', 'shareaholic'), '<a href="https://www.shareaholic.com/help/message" target="_blank">','</a>'); ?>
15
- </p>
16
  </div>
17
  </div>
18
 
1
  <div class='reveal-modal blocking-modal api-key-modal' id='failed_to_create_api_key'>
2
+ <h4><?php echo sprintf( __( 'Setup Shareaholic', 'shareaholic' ) ); ?></h4>
3
  <div class="content pal" style="padding:20px;">
4
+ <p style="font-size:14px;">
5
+ <?php _e( 'It appears that we are having some trouble setting up Shareaholic for WordPress right now. This is usually temporary. Please revisit this section after a few minutes or click "retry" now.', 'shareaholic' ); ?>
6
+ </p>
7
+ <a id='get_started' class="btn_main" style="margin-top: 15px;" href=''><?php echo _e( 'Retry', 'shareaholic' ); ?></a>
8
+ <br />
9
+ <span style="font-size:12px; font-weight:normal;">
10
+ <a href='<?php echo admin_url(); ?>'><?php _e( 'or, try again later.', 'shareaholic' ); ?></a>
11
+ </span>
12
+ <br /><br />
13
+ <p style="font-size:12px; font-weight:normal;">
14
+ <?php echo sprintf( __( 'If you continue to get this prompt for more than a few minutes, ensure that you have the latest version of the plugin installed. If you still continue to get this prompt, then check "Shareaholic Server Connectivity Status" or reset the plugin. Both are available under %1$sAdvanced Settings%2$s.', 'shareaholic' ), '<a href="admin.php?page=shareaholic-advanced">', '</a>' ); ?> <?php echo sprintf( __( 'Also, if you have a question or have a bug to report, please %1$slet us know%2$s.', 'shareaholic' ), '<a href="https://www.shareaholic.com/help/message" target="_blank">', '</a>' ); ?>
15
+ </p>
16
  </div>
17
  </div>
18
 
templates/footer.php CHANGED
@@ -1,13 +1,13 @@
1
  <div style="margin-top:45px;"></div>
2
  <div class='clear'>
3
  <p class="text-muted">
4
- <?php echo sprintf(__('%sShareaholic for WordPress v'. ShareaholicUtilities::get_version() .'%s | %sPrivacy Policy%s | %sTerms of Service%s | %sSupport Center%s | %sAPI%s', 'shareaholic'), '<a href="https://www.shareaholic.com/?src=wp_admin" target="_new">', '</a>', '<a href="https://www.shareaholic.com/privacy/?src=wp_admin" target="_new">', '</a>', '<a href="https://www.shareaholic.com/terms/?src=wp_admin" target="_new">', '</a>', '<a href="https://support.shareaholic.com/" target="_new">', '</a>', '<a href="https://www.shareaholic.com/api/?src=wp_admin" target="_new">', '</a>'); ?>
5
  </p>
6
  <p class="text-muted">
7
- <?php echo sprintf(__('If you like our work, please show some love and %sleave a ⭐️⭐️⭐️⭐️⭐️ review%s. It would help us out a lot and we would really appreciate it.', 'shareaholic'), '<a href="https://wordpress.org/support/plugin/shareaholic/reviews/?rate=5#new-post" target="_new">', '</a>'); ?>
8
  <br />
9
  <br />
10
- <iframe src="//www.facebook.com/plugins/like.php?href=https%3A%2F%2Fwww.facebook.com%2Fshareaholic&amp;width&amp;layout=standard&amp;action=like&amp;show_faces=true&amp;share=false&amp;height=80&amp;width=500&amp;appId=207766518608" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:500px; height:80px;" allowTransparency="true"></iframe>
11
  </p>
12
  </div>
13
 
@@ -24,5 +24,5 @@ _hsq.push(["setContentType", "standard-page"]);
24
  </script>
25
  <!-- End of Async HubSpot Analytics Code -->
26
 
27
- <script src="<?php echo ShareaholicUtilities::asset_url_admin('media/js/platforms/wordpress/wordpress-admin.js') ?>"></script>
28
- <script src="<?php echo ShareaholicUtilities::asset_url_admin('assets/pub/loader-reachable.js') ?>" async></script>
1
  <div style="margin-top:45px;"></div>
2
  <div class='clear'>
3
  <p class="text-muted">
4
+ <?php echo sprintf( __( '%sShareaholic for WordPress v' . ShareaholicUtilities::get_version() . '%s | %sPrivacy Policy%s | %sTerms of Service%s | %sSupport Center%s | %sAPI%s', 'shareaholic' ), '<a href="https://www.shareaholic.com/?src=wp_admin" target="_new">', '</a>', '<a href="https://www.shareaholic.com/privacy/?src=wp_admin" target="_new">', '</a>', '<a href="https://www.shareaholic.com/terms/?src=wp_admin" target="_new">', '</a>', '<a href="https://support.shareaholic.com/" target="_new">', '</a>', '<a href="https://www.shareaholic.com/api/?src=wp_admin" target="_new">', '</a>' ); ?>
5
  </p>
6
  <p class="text-muted">
7
+ <?php echo sprintf( __( 'If you like our work, please show some love and %1$sleave a ⭐️⭐️⭐️⭐️⭐️ review%2$s. It would help us out a lot and we would really appreciate it.', 'shareaholic' ), '<a href="https://wordpress.org/support/plugin/shareaholic/reviews/?rate=5#new-post" target="_new">', '</a>' ); ?>
8
  <br />
9
  <br />
10
+ <iframe src="//www.facebook.com/plugins/like.php?href=https%3A%2F%2Fwww.facebook.com%2Fshareaholic&amp;width&amp;layout=standard&amp;action=like&amp;show_faces=true&amp;share=false&amp;height=80&amp;width=500&amp;appId=207766518608" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:500px; height:80px;" allowTransparency="true"></iframe>
11
  </p>
12
  </div>
13
 
24
  </script>
25
  <!-- End of Async HubSpot Analytics Code -->
26
 
27
+ <script src="<?php echo ShareaholicUtilities::asset_url_admin( 'media/js/platforms/wordpress/wordpress-admin.js' ); ?>"></script>
28
+ <script src="<?php echo ShareaholicUtilities::asset_url_admin( 'assets/pub/loader-reachable.js' ); ?>" async></script>
templates/header.php CHANGED
@@ -1,11 +1,11 @@
1
  <!-- Header - start -->
2
  <div id="shr-header-container"></div>
3
- <script class="shr-app-loader shr-app-loader__header" src="<?php echo ShareaholicUtilities::asset_url_admin('ui-header/loader.js') ?>"></script>
4
  <!-- Header - end -->
5
 
6
  <script>
7
- window.first_part_of_url = '<?php echo $settings['base_link']?>';
8
- window.verification_key = '<?php echo $settings['verification_key'] ?>';
9
  window.SHAREAHOLIC_PLUGIN_VERSION = '<?php echo ShareaholicUtilities::get_version(); ?>';
10
- window.shareaholic_add_location_nonce = '<?php echo wp_create_nonce("shareaholic_add_location"); ?>';
11
- </script>
1
  <!-- Header - start -->
2
  <div id="shr-header-container"></div>
3
+ <script class="shr-app-loader shr-app-loader__header" src="<?php echo ShareaholicUtilities::asset_url_admin( 'ui-header/loader.js' ); ?>"></script>
4
  <!-- Header - end -->
5
 
6
  <script>
7
+ window.first_part_of_url = '<?php echo $settings['base_link']; ?>';
8
+ window.verification_key = '<?php echo $settings['verification_key']; ?>';
9
  window.SHAREAHOLIC_PLUGIN_VERSION = '<?php echo ShareaholicUtilities::get_version(); ?>';
10
+ window.shareaholic_add_location_nonce = '<?php echo wp_create_nonce( 'shareaholic_add_location' ); ?>';
11
+ </script>
templates/meta_boxes.php CHANGED
@@ -1,37 +1,37 @@
1
  <label>
2
  <input type='checkbox' name='shareaholic[disable_share_buttons]'
3
- <?php if (get_post_meta($post->ID, 'shareaholic_disable_share_buttons', true)) { ?>
4
- checked
5
  <?php } ?>>
6
- <?php echo sprintf(__('Hide Share Buttons', 'shareaholic')); ?>
7
  </label>
8
 
9
  <br>
10
 
11
  <label>
12
  <input type='checkbox' name='shareaholic[disable_recommendations]'
13
- <?php if (get_post_meta($post->ID, 'shareaholic_disable_recommendations', true)) { ?>
14
- checked
15
  <?php } ?>>
16
- <?php echo sprintf(__('Hide Related Content', 'shareaholic')); ?>
17
  </label>
18
 
19
  <br>
20
 
21
  <label>
22
  <input type='checkbox' name='shareaholic[exclude_recommendations]'
23
- <?php if (get_post_meta($post->ID, 'shareaholic_exclude_recommendations', true)) { ?>
24
- checked
25
  <?php } ?>>
26
- <?php echo sprintf(__('Exclude from Related Content', 'shareaholic')); ?>
27
  </label>
28
 
29
  <br>
30
 
31
  <label>
32
  <input type='checkbox' name='shareaholic[disable_open_graph_tags]'
33
- <?php if (get_post_meta($post->ID, 'shareaholic_disable_open_graph_tags', true)) { ?>
34
- checked
35
  <?php } ?>>
36
- <?php echo sprintf(__('Do not include Open Graph tags', 'shareaholic')); ?>
37
- </label>
1
  <label>
2
  <input type='checkbox' name='shareaholic[disable_share_buttons]'
3
+ <?php if ( get_post_meta( $post->ID, 'shareaholic_disable_share_buttons', true ) ) { ?>
4
+ checked
5
  <?php } ?>>
6
+ <?php echo sprintf( __( 'Hide Share Buttons', 'shareaholic' ) ); ?>
7
  </label>
8
 
9
  <br>
10
 
11
  <label>
12
  <input type='checkbox' name='shareaholic[disable_recommendations]'
13
+ <?php if ( get_post_meta( $post->ID, 'shareaholic_disable_recommendations', true ) ) { ?>
14
+ checked
15
  <?php } ?>>
16
+ <?php echo sprintf( __( 'Hide Related Content', 'shareaholic' ) ); ?>
17
  </label>
18
 
19
  <br>
20
 
21
  <label>
22
  <input type='checkbox' name='shareaholic[exclude_recommendations]'
23
+ <?php if ( get_post_meta( $post->ID, 'shareaholic_exclude_recommendations', true ) ) { ?>
24
+ checked
25
  <?php } ?>>
26
+ <?php echo sprintf( __( 'Exclude from Related Content', 'shareaholic' ) ); ?>
27
  </label>
28
 
29
  <br>
30
 
31
  <label>
32
  <input type='checkbox' name='shareaholic[disable_open_graph_tags]'
33
+ <?php if ( get_post_meta( $post->ID, 'shareaholic_disable_open_graph_tags', true ) ) { ?>
34
+ checked
35
  <?php } ?>>
36
+ <?php echo sprintf( __( 'Do not include Open Graph tags', 'shareaholic' ) ); ?>
37
+ </label>
templates/script_chat.php CHANGED
@@ -1,2 +1,2 @@
1
 
2
- <script src="<?php echo ShareaholicUtilities::asset_url_admin('assets/pub/shareaholic-chat.js') ?>" async></script>
1
 
2
+ <script src="<?php echo ShareaholicUtilities::asset_url_admin( 'assets/pub/shareaholic-chat.js' ); ?>" async></script>
templates/script_tag.php CHANGED
@@ -1,8 +1,8 @@
1
  <!-- Powered by Shareaholic; Grow your Audience faster! - https://www.shareaholic.com -->
2
- <link rel='preload' href='<?php echo ShareaholicUtilities::asset_url('assets/pub/shareaholic.js') ?>' as='script'/>
3
  <script data-no-minify='1' data-cfasync='false'>
4
  //<![CDATA[
5
- _SHR_SETTINGS = <?php echo json_encode($base_settings); ?>;
6
  //]]>
7
  </script>
8
- <script data-no-minify='1' data-cfasync='false' src='<?php echo ShareaholicUtilities::asset_url('assets/pub/shareaholic.js') ?>' data-shr-siteid='<?php echo $api_key; ?>' async <?php echo $overrides ?>></script>
1
  <!-- Powered by Shareaholic; Grow your Audience faster! - https://www.shareaholic.com -->
2
+ <link rel='preload' href='<?php echo ShareaholicUtilities::asset_url( 'assets/pub/shareaholic.js' ); ?>' as='script'/>
3
  <script data-no-minify='1' data-cfasync='false'>
4
  //<![CDATA[
5
+ _SHR_SETTINGS = <?php echo json_encode( $base_settings ); ?>;
6
  //]]>
7
  </script>
8
+ <script data-no-minify='1' data-cfasync='false' src='<?php echo ShareaholicUtilities::asset_url( 'assets/pub/shareaholic.js' ); ?>' data-shr-siteid='<?php echo $api_key; ?>' async <?php echo $overrides; ?>></script>
templates/settings.php CHANGED
@@ -2,17 +2,17 @@
2
 
3
  <script>
4
  window.ShareaholicConfig = {
5
- apiHost: "<?php echo Shareaholic::API_URL ?>",
6
- serviceHost: "<?php echo Shareaholic::URL ?>",
7
- assetHost: "<?php echo ShareaholicUtilities::asset_url_admin() ?>",
8
  assetFolders: true,
9
  origin: "wp_plugin",
10
- language: "<?php echo strtolower(get_bloginfo('language')) ?>"
11
  };
12
  </script>
13
 
14
  <div class='wrap'>
15
- <h2><?php echo sprintf(__('App Manager - Legacy', 'shareaholic')); ?></h2>
16
 
17
  <div class='reveal-modal' id='editing_modal'>
18
  <div id='iframe_container' class='bg-loading-img' allowtransparency='true'></div>
@@ -21,152 +21,115 @@ window.ShareaholicConfig = {
21
 
22
  <div class="container-fluid">
23
  <div class="row">
24
- <div class="col-sm-8">
25
- <form name="settings" method="post" action="<?php echo $action; ?>">
26
- <?php wp_nonce_field($action, 'nonce_field') ?>
27
- <input type="hidden" name="already_submitted" value="Y">
28
 
29
- <div id='app_settings'>
30
 
31
- <div class="app">
32
- <h2><?php echo sprintf(__('Getting Started')); ?></h2>
33
- <p><?php echo sprintf(__('%sLearn the basics of how to get started and configure Shareaholic through our popular WordPress plugin.%s', 'shareaholic'), '<a href="https://support.shareaholic.com/hc/en-us/categories/200101476-WordPress-Plugin" target="_blank">','</a>'); ?> <?php echo sprintf(__('If you are upgrading from an earlier version of Shareaholic for WordPress and need help, have a question or have a bug to report, please %slet us know%s.', 'shareaholic'), '<a href="https://www.shareaholic.com/help/message" target="_blank">','</a>'); ?>
34
- </p>
35
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
- <div class="app">
38
- <p><a href="<?php echo esc_url(admin_url("admin.php?shareaholic_redirect_url=shareaholic.com/signup/")); ?>" target="_blank" class="btn btn-warning btn-block" role="button" style="font-size: 14px;"><?php echo sprintf(__('Open Shareaholic Cloud Dashboard', 'shareaholic')); ?></a>
39
- </p>
40
- <p>
41
- <?php echo sprintf(__('Configure Apps such as Floating Share buttons, Social Share Count Recovery, Follow buttons, Share Buttons for Images, Monetization Dashboard, EU Cookie Consent bar, and more from the dashboard.', 'shareaholic')); ?>
42
- </p>
43
- </div>
44
-
45
- <div class="app">
46
- <h2><i class="icon icon-share_buttons"></i> <?php echo sprintf(__('In-Page Share Buttons', 'shareaholic')); ?></h2>
47
- <p>
48
- <?php echo sprintf(__('Pick where you want your in-page share buttons to be displayed. Click "customize" to customize look & feel, themes, share counters, alignment, and more.', 'shareaholic')); ?>
49
- </p>
50
-
51
- <?php foreach(array('post', 'page', 'index', 'category') as $page_type) { ?>
52
- <fieldset id='sharebuttons'>
53
- <legend><?php echo ucfirst($page_type) ?></legend>
54
- <?php foreach(array('above', 'below') as $position) { ?>
55
- <?php if (isset($settings['location_name_ids']['share_buttons']["{$page_type}_{$position}_content"])) { ?>
56
- <?php $location_id = $settings['location_name_ids']['share_buttons']["{$page_type}_{$position}_content"] ?>
57
- <?php } else { $location_id = ''; } ?>
58
- <div class="location">
59
- <input type="checkbox" id="share_buttons_<?php echo "{$page_type}_{$position}_content" ?>" name="share_buttons[<?php echo "{$page_type}_{$position}_content" ?>]" class="check"
60
- <?php if (isset($share_buttons["{$page_type}_{$position}_content"])) { ?>
61
- <?php echo ($share_buttons["{$page_type}_{$position}_content"] == 'on' ? 'checked' : '') ?>
62
- <?php } ?>>
63
- <label for="share_buttons_<?php echo "{$page_type}_{$position}_content" ?>"><?php echo ucfirst($position) ?> Content</label>
64
- <button data-app='share_buttons'
65
- data-location_id='<?php echo intval($location_id); ?>'
66
- data-href='share_buttons/locations/{{id}}/edit'
67
- class="location_item_cta btn btn-sm btn-success float-right">
68
- <?php _e('Customize', 'shareaholic'); ?></button>
69
- </div>
70
- <?php } ?>
71
- </fieldset>
72
- <?php } ?>
73
-
74
- <div class='fieldset-footer'>
75
- <p>
76
- <input type="checkbox" id="share_buttons_excerpts" name="shareaholic[share_buttons_display_on_excerpts]" class="check"
77
- <?php if (isset($settings["share_buttons_display_on_excerpts"])) { ?>
78
- <?php echo ($settings["share_buttons_display_on_excerpts"] == 'on' ? 'checked' : '') ?>
79
- <?php } ?>>
80
- <label for="share_buttons_excerpts">Display on excerpts</label>
81
- </p>
82
- </div>
83
-
84
- <div class='fieldset-footer'>
85
- <p>
86
- <?php echo sprintf(__('Brand your shares with your @Twitterhandle, pick your favorite URL shortener, share buttons for images, etc.')); ?>
87
- </p>
88
- <p>
89
- <button class='app_wide_settings btn btn-success wide-button' data-href='share_buttons/edit'><?php _e('Edit Settings', 'shareaholic'); ?></button>
90
- </p>
91
- </div>
92
- </div>
93
-
94
- <div class="app">
95
- <h2><i class="icon icon-recommendations"></i> <?php echo sprintf(__('Related Content', 'shareaholic')); ?></h2>
96
- <p>
97
- <?php echo sprintf(__('Pick where you want the app to be displayed. Click "Customize" to customize look & feel, themes, block lists, etc.', 'shareaholic')); ?>
98
- </p>
99
- <?php foreach(array('post', 'page', 'index', 'category') as $page_type) { ?>
100
- <?php foreach(array('below') as $position) { ?>
101
- <?php if (isset($settings['location_name_ids']['recommendations']["{$page_type}_{$position}_content"])) { ?>
102
- <?php $location_id = $settings['location_name_ids']['recommendations']["{$page_type}_{$position}_content"] ?>
103
- <?php } else { $location_id = ''; } ?>
104
- <fieldset id='recommendations'>
105
- <legend><?php echo ucfirst($page_type) ?></legend>
106
- <div class="location">
107
- <input type="checkbox" id="recommendations_<?php echo "{$page_type}_below_content" ?>" name="recommendations[<?php echo "{$page_type}_below_content" ?>]" class="check"
108
- <?php if (isset($recommendations["{$page_type}_below_content"])) { ?>
109
- <?php echo ($recommendations["{$page_type}_below_content"] == 'on' ? 'checked' : '') ?>
110
- <?php } ?>>
111
- <label for="recommendations_<?php echo "{$page_type}_below_content" ?>"><?php echo ucfirst($position) ?> Content</label>
112
- <button data-app='recommendations'
113
- data-location_id='<?php echo intval($location_id); ?>'
114
- data-href="recommendations/locations/{{id}}/edit"
115
- class="location_item_cta btn btn-sm btn-success">
116
- <?php _e('Customize', 'shareaholic'); ?></button>
117
- </div>
118
- <?php } ?>
119
- </fieldset>
120
- <?php } ?>
121
-
122
- <div class='fieldset-footer'>
123
- <p>
124
- <input type="checkbox" id="recommendations_excerpts" name="shareaholic[recommendations_display_on_excerpts]" class="check"
125
- <?php if (isset($settings["recommendations_display_on_excerpts"])) { ?>
126
- <?php echo ($settings["recommendations_display_on_excerpts"] == 'on' ? 'checked' : '') ?>
127
- <?php } ?>>
128
- <label for="recommendations_excerpts">Display on excerpts</label>
129
- </p>
130
- </div>
131
-
132
- <div class='fieldset-footer'>
133
- <p>
134
- <?php echo sprintf(__('Rebuild your Content Index, exclude pages from being recommended, tweak algorithms, and more.', 'shareaholic')); ?>
135
- </p>
136
- <p>
137
- <button class='app_wide_settings btn btn-success wide-button' data-href='recommendations/edit'><?php _e('Edit Settings', 'shareaholic'); ?></button>
138
- </p>
139
- </div>
140
- <div class='fieldset-footer'>
141
- <p>
142
- <?php echo sprintf(__('Note: Shareaholic offloads Related Posts processing to the cloud, so there is no additional load on your server or database, giving you the fastest and most efficient Related Posts solution on the market. The %scloud API%s starts working as soon as your site is live. Until the cloud-based system starts, we use a basic placeholder API powered by the plugin. This API is temporary and does not respect advanced settings such as content exclusion rules.', 'shareaholic'), '<a href="https://shrlc.com/1IzOGiI" target="_blank">','</a>'); ?>
143
- </p>
144
- </div>
145
- </div>
146
-
147
- <div class="app">
148
- <h2>
149
- <i class="icon icon-affiliate"></i> <?php echo sprintf(__('Monetization Settings', 'shareaholic')); ?>
150
- </h2>
151
- <p>
152
- <?php echo sprintf(__('Configure Promoted Content, Affiliate Links, Banner Ads, etc. Check your earnings at any time.', 'shareaholic')); ?>
153
- </p>
154
- <p>
155
- <button class='app_wide_settings btn btn-success wide-button' data-href='monetizations/edit'><?php _e('Edit Settings', 'shareaholic'); ?></button>
156
- </p>
157
- </div>
158
- </div>
159
 
160
- <div class="app">
161
- <input type='submit' class="btn btn-primary btn-lg btn-block" onclick="this.value='<?php echo sprintf(__('Saving Changes...', 'shareaholic')); ?>';" value='<?php echo sprintf(__('Save Changes', 'shareaholic')); ?>'>
162
- </div>
163
- </form>
164
- </div>
165
- <?php ShareaholicUtilities::load_template('why_to_sign_up', array('url' => Shareaholic::URL)) ?>
166
- </div>
167
  </div>
168
  </div>
169
  <?php ShareaholicAdmin::show_footer(); ?>
170
  <?php ShareaholicAdmin::include_chat(); ?>
171
 
172
- <script src="https://dsms0mj1bbhn4.cloudfront.net/assets/pub/loader-reachable.js" async></script>
2
 
3
  <script>
4
  window.ShareaholicConfig = {
5
+ apiHost: "<?php echo Shareaholic::API_URL; ?>",
6
+ serviceHost: "<?php echo Shareaholic::URL; ?>",
7
+ assetHost: "<?php echo ShareaholicUtilities::asset_url_admin(); ?>",
8
  assetFolders: true,
9
  origin: "wp_plugin",
10
+ language: "<?php echo strtolower( get_bloginfo( 'language' ) ); ?>"
11
  };
12
  </script>
13
 
14
  <div class='wrap'>
15
+ <h2><?php echo sprintf( __( 'Dashboard - Legacy', 'shareaholic' ) ); ?></h2>
16
 
17
  <div class='reveal-modal' id='editing_modal'>
18
  <div id='iframe_container' class='bg-loading-img' allowtransparency='true'></div>
21
 
22
  <div class="container-fluid">
23
  <div class="row">
24
+ <div class="col-sm-8">
25
+ <form name="settings" method="post" action="<?php echo $action; ?>">
26
+ <?php wp_nonce_field( $action, 'nonce_field' ); ?>
27
+ <input type="hidden" name="already_submitted" value="Y">
28
 
29
+ <div id='app_settings'>
30
 
31
+ <div class="app">
32
+ <h2><i class="icon icon-share_buttons"></i> <?php echo sprintf( __( 'In-Page Share Buttons', 'shareaholic' ) ); ?></h2>
33
+ <p>
34
+ <?php echo sprintf( __( 'Pick where you want your in-page share buttons to be displayed. Click "customize" to customize look & feel, themes, share counters, alignment, and more.', 'shareaholic' ) ); ?>
35
+ </p>
36
+
37
+ <?php foreach ( array( 'post', 'page', 'index', 'category' ) as $page_type ) { ?>
38
+ <fieldset id='sharebuttons'>
39
+ <legend><?php echo ucfirst( $page_type ); ?></legend>
40
+ <?php foreach ( array( 'above', 'below' ) as $position ) { ?>
41
+ <?php if ( isset( $settings['location_name_ids']['share_buttons'][ "{$page_type}_{$position}_content" ] ) ) { ?>
42
+ <?php $location_id = $settings['location_name_ids']['share_buttons'][ "{$page_type}_{$position}_content" ]; ?>
43
+ <?php
44
+ } else {
45
+ $location_id = ''; }
46
+ ?>
47
+ <div class="location">
48
+ <input type="checkbox" id="share_buttons_<?php echo "{$page_type}_{$position}_content"; ?>" name="share_buttons[<?php echo "{$page_type}_{$position}_content"; ?>]" class="check"
49
+ <?php if ( isset( $share_buttons[ "{$page_type}_{$position}_content" ] ) ) { ?>
50
+ <?php echo ( $share_buttons[ "{$page_type}_{$position}_content" ] == 'on' ? 'checked' : '' ); ?>
51
+ <?php } ?>>
52
+ <label for="share_buttons_<?php echo "{$page_type}_{$position}_content"; ?>"><?php echo ucfirst( $position ); ?> Content</label>
53
+ <button data-app='share_buttons'
54
+ data-location_id='<?php echo intval( $location_id ); ?>'
55
+ data-href='share_buttons/locations/{{id}}/edit'
56
+ class="location_item_cta btn btn-sm btn-success float-right">
57
+ <?php _e( 'Customize', 'shareaholic' ); ?></button>
58
+ </div>
59
+ <?php } ?>
60
+ </fieldset>
61
+ <?php } ?>
62
+
63
+ <div class='fieldset-footer'>
64
+ <p>
65
+ <input type="checkbox" id="share_buttons_excerpts" name="shareaholic[share_buttons_display_on_excerpts]" class="check"
66
+ <?php if ( isset( $settings['share_buttons_display_on_excerpts'] ) ) { ?>
67
+ <?php echo ( $settings['share_buttons_display_on_excerpts'] == 'on' ? 'checked' : '' ); ?>
68
+ <?php } ?>>
69
+ <label for="share_buttons_excerpts">Display on excerpts</label>
70
+ </p>
71
+ </div>
72
+ </div>
73
 
74
+ <div class="app">
75
+ <h2><i class="icon icon-recommendations"></i> <?php echo sprintf( __( 'Related Content', 'shareaholic' ) ); ?></h2>
76
+ <p>
77
+ <?php echo sprintf( __( 'Pick where you want the app to be displayed. Click "Customize" to customize look & feel, themes, block lists, etc.', 'shareaholic' ) ); ?>
78
+ </p>
79
+ <?php foreach ( array( 'post', 'page', 'index', 'category' ) as $page_type ) { ?>
80
+ <?php foreach ( array( 'below' ) as $position ) { ?>
81
+ <?php if ( isset( $settings['location_name_ids']['recommendations'][ "{$page_type}_{$position}_content" ] ) ) { ?>
82
+ <?php $location_id = $settings['location_name_ids']['recommendations'][ "{$page_type}_{$position}_content" ]; ?>
83
+ <?php
84
+ } else {
85
+ $location_id = ''; }
86
+ ?>
87
+ <fieldset id='recommendations'>
88
+ <legend><?php echo ucfirst( $page_type ); ?></legend>
89
+ <div class="location">
90
+ <input type="checkbox" id="recommendations_<?php echo "{$page_type}_below_content"; ?>" name="recommendations[<?php echo "{$page_type}_below_content"; ?>]" class="check"
91
+ <?php if ( isset( $recommendations[ "{$page_type}_below_content" ] ) ) { ?>
92
+ <?php echo ( $recommendations[ "{$page_type}_below_content" ] == 'on' ? 'checked' : '' ); ?>
93
+ <?php } ?>>
94
+ <label for="recommendations_<?php echo "{$page_type}_below_content"; ?>"><?php echo ucfirst( $position ); ?> Content</label>
95
+ <button data-app='recommendations'
96
+ data-location_id='<?php echo intval( $location_id ); ?>'
97
+ data-href="recommendations/locations/{{id}}/edit"
98
+ class="location_item_cta btn btn-sm btn-success">
99
+ <?php _e( 'Customize', 'shareaholic' ); ?></button>
100
+ </div>
101
+ <?php } ?>
102
+ </fieldset>
103
+ <?php } ?>
104
+
105
+ <div class='fieldset-footer'>
106
+ <p>
107
+ <input type="checkbox" id="recommendations_excerpts" name="shareaholic[recommendations_display_on_excerpts]" class="check"
108
+ <?php if ( isset( $settings['recommendations_display_on_excerpts'] ) ) { ?>
109
+ <?php echo ( $settings['recommendations_display_on_excerpts'] == 'on' ? 'checked' : '' ); ?>
110
+ <?php } ?>>
111
+ <label for="recommendations_excerpts">Display on excerpts</label>
112
+ </p>
113
+ </div>
114
+
115
+ <div class='fieldset-footer'>
116
+ <p>
117
+ <?php echo sprintf( __( 'Note: Shareaholic offloads Related Posts processing to the cloud, so there is no additional load on your server or database, giving you the fastest and most efficient Related Posts solution on the market. The %1$scloud API%2$s starts working as soon as your site is live. Until the cloud-based system starts, we use a basic placeholder API powered by the plugin. This API is temporary and does not respect advanced settings such as content exclusion rules.', 'shareaholic' ), '<a href="https://shrlc.com/1IzOGiI" target="_blank">', '</a>' ); ?>
118
+ </p>
119
+ </div>
120
+ </div>
121
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
+ <div class="app">
124
+ <input type='submit' class="btn btn-primary btn-lg btn-block" onclick="this.value='<?php echo sprintf( __( 'Saving Changes...', 'shareaholic' ) ); ?>';" value='<?php echo sprintf( __( 'Save Changes', 'shareaholic' ) ); ?>'>
125
+ </div>
126
+ </form>
127
+ </div>
128
+ <?php ShareaholicUtilities::load_template( 'why_to_sign_up', array( 'url' => Shareaholic::URL ) ); ?>
129
+ </div>
130
  </div>
131
  </div>
132
  <?php ShareaholicAdmin::show_footer(); ?>
133
  <?php ShareaholicAdmin::include_chat(); ?>
134
 
135
+ <script src="https://dsms0mj1bbhn4.cloudfront.net/assets/pub/loader-reachable.js" async></script>
templates/terms_of_service_modal.php CHANGED
@@ -1,50 +1,50 @@
1
  <div class='reveal-modal blocking-modal' id='terms_of_service_modal'>
2
- <h4><?php echo sprintf(__('Welcome to Shareaholic!', 'shareaholic')); ?></h4>
3
  <div class="content pal">
4
- <p style="font-size: 18px; color: #323648; line-height: 1.4em; padding-top: 24px; margin: 0;">
5
- <?php echo sprintf(__('%sA Suite of Essential Tools to Grow Your Website%s', 'shareaholic'), '<strong>', '</strong>'); ?>
6
- </p>
7
- <p style="font-size: 12px; color: #666; line-height: 1.8em; padding-bottom: 0;">
8
- <?php echo sprintf(__('Shareaholic provides you with a comprehensive set of marketing tools to engage with your audience, get found on social, and grow your following. The toolkit includes Award-Winning Social Share Buttons, Related Posts, Analytics, Ad Monetization, and more. Customize what is right for your website from the App Manager.', 'shareaholic')); ?>
9
- </p>
10
-
11
- <div class="shr-people"></div>
12
 
13
- <!--
14
- <div class="plugin-value-section-container">
15
- <section class="plugin-value-section">
16
- <span class="plugin-value-line"></span>
17
- <ul class="plugin-value">
18
- <li class="engage">
19
- <span class="icon fa fa-fire"></span>
20
- <span class="title"><?php _e('Engage', 'shareaholic'); ?></span>
21
- <p><?php _e('Increase traffic, time on site and repeat visits.', 'shareaholic'); ?></p>
22
- </li>
23
- <li class="learn">
24
- <span class="icon fa fa-bar-chart-o"></span>
25
- <span class="title"><?php _e('Discover', 'shareaholic'); ?></span>
26
- <p><?php _e('Understand your audience with our easy-to-use analytics dashboard.', 'shareaholic'); ?></p>
27
- </li>
28
- <li class="monetize">
29
- <span class="icon fa fa-usd"></span>
30
- <span class="title"><?php _e('Earn', 'shareaholic'); ?></span>
31
- <p><?php _e('Generate revenue with personalized, unobtrusive native ads.', 'shareaholic'); ?></p>
32
- </li>
33
- <li class="acquire">
34
- <span class="icon fa fa-bullhorn"></span>
35
- <span class="title"><?php _e('Acquire', 'shareaholic'); ?></span>
36
- <p><?php _e('Reach over 400 million people with native ads and promoted content.', 'shareaholic'); ?></p>
37
- </li>
38
- </ul>
39
- </section>
40
- </div>
41
- -->
42
 
43
- <div class="pvl">
44
- <a id="get_started" class="btn_main" style="margin-top: -20px;"><?php echo sprintf(__('Get Started »', 'shareaholic')); ?></a>
45
- <p><small style="font-size:12px; color: rgb(136, 136, 136);"><?php echo sprintf(__('By clicking "Get Started" you agree to Shareholic\'s %sTerms of Service%s and %sPrivacy Policy%s.', 'shareaholic'), '<a href="https://www.shareaholic.com/terms/?src=wp_admin" target="_new">', '</a>', '<a href="https://www.shareaholic.com/privacy/?src=wp_admin" target="_new">', '</a>'); ?></small>
46
- </p>
47
- </div>
48
 
49
  </div>
50
  </div>
1
  <div class='reveal-modal blocking-modal' id='terms_of_service_modal'>
2
+ <h4><?php echo sprintf( __( 'Welcome to Shareaholic!', 'shareaholic' ) ); ?></h4>
3
  <div class="content pal">
4
+ <p style="font-size: 18px; color: #323648; line-height: 1.4em; padding-top: 24px; margin: 0;">
5
+ <?php echo sprintf( __( '%1$sA Suite of Essential Tools to Grow Your Website%2$s', 'shareaholic' ), '<strong>', '</strong>' ); ?>
6
+ </p>
7
+ <p style="font-size: 12px; color: #666; line-height: 1.8em; padding-bottom: 0;">
8
+ <?php echo sprintf( __( 'Shareaholic provides you with a comprehensive set of marketing tools to engage with your audience, get found on social, and grow your following. The toolkit includes Award-Winning Social Share Buttons, Related Posts, Analytics, Ad Monetization, and more. Customize what is right for your website from the App Manager.', 'shareaholic' ) ); ?>
9
+ </p>
10
+
11
+ <div class="shr-people"></div>
12
 
13
+ <!--
14
+ <div class="plugin-value-section-container">
15
+ <section class="plugin-value-section">
16
+ <span class="plugin-value-line"></span>
17
+ <ul class="plugin-value">
18
+ <li class="engage">
19
+ <span class="icon fa fa-fire"></span>
20
+ <span class="title"><?php _e( 'Engage', 'shareaholic' ); ?></span>
21
+ <p><?php _e( 'Increase traffic, time on site and repeat visits.', 'shareaholic' ); ?></p>
22
+ </li>
23
+ <li class="learn">
24
+ <span class="icon fa fa-bar-chart-o"></span>
25
+ <span class="title"><?php _e( 'Discover', 'shareaholic' ); ?></span>
26
+ <p><?php _e( 'Understand your audience with our easy-to-use analytics dashboard.', 'shareaholic' ); ?></p>
27
+ </li>
28
+ <li class="monetize">
29
+ <span class="icon fa fa-usd"></span>
30
+ <span class="title"><?php _e( 'Earn', 'shareaholic' ); ?></span>
31
+ <p><?php _e( 'Generate revenue with personalized, unobtrusive native ads.', 'shareaholic' ); ?></p>
32
+ </li>
33
+ <li class="acquire">
34
+ <span class="icon fa fa-bullhorn"></span>
35
+ <span class="title"><?php _e( 'Acquire', 'shareaholic' ); ?></span>
36
+ <p><?php _e( 'Reach over 400 million people with native ads and promoted content.', 'shareaholic' ); ?></p>
37
+ </li>
38
+ </ul>
39
+ </section>
40
+ </div>
41
+ -->
42
 
43
+ <div class="pvl">
44
+ <a id="get_started" class="btn_main" style="margin-top: -20px;"><?php echo sprintf( __( 'Get Started »', 'shareaholic' ) ); ?></a>
45
+ <p><small style="font-size:12px; color: rgb(136, 136, 136);"><?php echo sprintf( __( 'By clicking "Get Started" you agree to Shareholic\'s %1$sTerms of Service%2$s and %3$sPrivacy Policy%4$s.', 'shareaholic' ), '<a href="https://www.shareaholic.com/terms/?src=wp_admin" target="_new">', '</a>', '<a href="https://www.shareaholic.com/privacy/?src=wp_admin" target="_new">', '</a>' ); ?></small>
46
+ </p>
47
+ </div>
48
 
49
  </div>
50
  </div>
templates/terms_of_service_notice.php CHANGED
@@ -1,13 +1,13 @@
1
- <?php if ( current_user_can( 'manage_options' ) ){ ?>
2
 
3
  <div class="shareaholic-wrap-container" style="background-color: #009688; margin: 5px 0px 5px -20px;">
4
- <div style="margin: 0px 15px 0 20px; float: left;">
5
- <img src="<?php echo SHAREAHOLIC_ASSET_DIR; ?>img/check.png" width="56" height="50" />
6
- </div>
7
- <div class="shareaholic-text-container" style="color: #fff; text-shadow: 0px 1px 1px rgba(0,0,0,0.2); font-size: 14px; line-height: 1.5em; height: 50px; vertical-align: middle; display: table-cell; line-height: 1.5;">
8
- <?php echo sprintf(__('You\'ve added Shareaholic - Welcome! Action required: %sComplete Installation &raquo;%s', 'shareaholic'), '<a href="admin.php?page=shareaholic-settings" class="button-secondary" style="vertical-align: initial;">', '</a>'); ?>
9
- </div>
10
  </div>
11
  <div style="clear:both;"></div>
12
 
13
- <?php } ?>
1
+ <?php if ( current_user_can( 'manage_options' ) ) { ?>
2
 
3
  <div class="shareaholic-wrap-container" style="background-color: #009688; margin: 5px 0px 5px -20px;">
4
+ <div style="margin: 0px 15px 0 20px; float: left;">
5
+ <img src="<?php echo SHAREAHOLIC_ASSET_DIR; ?>img/check.png" width="56" height="50" />
6
+ </div>
7
+ <div class="shareaholic-text-container" style="color: #fff; text-shadow: 0px 1px 1px rgba(0,0,0,0.2); font-size: 14px; line-height: 1.5em; height: 50px; vertical-align: middle; display: table-cell; line-height: 1.5;">
8
+ <?php echo sprintf( __( 'You\'ve added Shareaholic - Welcome! Action required: %1$sComplete Installation &raquo;%2$s', 'shareaholic' ), '<a href="admin.php?page=shareaholic-settings" class="button-secondary" style="vertical-align: initial;">', '</a>' ); ?>
9
+ </div>
10
  </div>
11
  <div style="clear:both;"></div>
12
 
13
+ <?php } ?>
templates/verify_api_key_js.php CHANGED
@@ -2,17 +2,17 @@
2
  Shareaholic.click_objects['unverified_app_settings'] = {
3
  selector: Shareaholic.click_objects['app_settings'].selector,
4
  url: function(button) {
5
- url = first_part_of_url + 'verify'
6
- + '?verification_key=<?php echo $verification_key ?>'
7
- + '&embedded=true'
8
- + '&redirect_to='
9
- + encodeURIComponent(
10
- Shareaholic.click_objects['app_settings'].url(button)
11
- );
12
- return url;
13
  },
14
  callback: function(button) {
15
- Shareaholic.click_objects['app_settings'].callback(button);
16
  },
17
  close: Shareaholic.click_objects['app_settings'].close
18
  }
@@ -20,16 +20,16 @@ Shareaholic.click_objects['unverified_app_settings'] = {
20
  Shareaholic.click_objects['unverified_general_settings'] = {
21
  selector: Shareaholic.click_objects['general_settings'].selector,
22
  url: function(button) {
23
- url = first_part_of_url + 'verify'
24
- + '?verification_key=<?php echo $verification_key ?>'
25
- + '&redirect_to='
26
- + encodeURIComponent(
27
- Shareaholic.click_objects['general_settings'].url(button)
28
- );
29
- return Shareaholic.click_objects['general_settings'].url(button);
30
  },
31
  callback: function(button) {
32
- Shareaholic.click_objects['general_settings'].callback(button);
33
  },
34
  close: Shareaholic.click_objects['general_settings'].close
35
  }
2
  Shareaholic.click_objects['unverified_app_settings'] = {
3
  selector: Shareaholic.click_objects['app_settings'].selector,
4
  url: function(button) {
5
+ url = first_part_of_url + 'verify'
6
+ + '?verification_key=<?php echo $verification_key; ?>'
7
+ + '&embedded=true'
8
+ + '&redirect_to='
9
+ + encodeURIComponent(
10
+ Shareaholic.click_objects['app_settings'].url(button)
11
+ );
12
+ return url;
13
  },
14
  callback: function(button) {
15
+ Shareaholic.click_objects['app_settings'].callback(button);
16
  },
17
  close: Shareaholic.click_objects['app_settings'].close
18
  }
20
  Shareaholic.click_objects['unverified_general_settings'] = {
21
  selector: Shareaholic.click_objects['general_settings'].selector,
22
  url: function(button) {
23
+ url = first_part_of_url + 'verify'
24
+ + '?verification_key=<?php echo $verification_key; ?>'
25
+ + '&redirect_to='
26
+ + encodeURIComponent(
27
+ Shareaholic.click_objects['general_settings'].url(button)
28
+ );
29
+ return Shareaholic.click_objects['general_settings'].url(button);
30
  },
31
  callback: function(button) {
32
+ Shareaholic.click_objects['general_settings'].callback(button);
33
  },
34
  close: Shareaholic.click_objects['general_settings'].close
35
  }
templates/why_to_sign_up.php CHANGED
@@ -1,37 +1,28 @@
1
  <div class="col-sm-4">
2
  <!--<div class="signuppromo">
3
- <p class="promoh1">
4
- <?php echo sprintf(__('Link to Shareaholic.com to unlock:', 'shareaholic')); ?>
5
- </p>
6
- <ul>
7
- <li><?php echo sprintf(__('Analytics', 'shareaholic')); ?></li>
8
- <li><?php echo sprintf(__('Floating Share buttons', 'shareaholic')); ?></li>
9
- <li><?php echo sprintf(__('Social Share Count Recovery', 'shareaholic')); ?></li>
10
- <li><?php echo sprintf(__('Follow buttons', 'shareaholic')); ?></li>
11
- <li><?php echo sprintf(__('Share Buttons for Images', 'shareaholic')); ?></li>
12
- <li><?php echo sprintf(__('Earnings Dashboard', 'shareaholic')); ?></li>
13
- <li><?php echo sprintf(__('...lots more!', 'shareaholic')); ?></li>
14
- </ul>
15
- <a href="<?php echo esc_url(admin_url("admin.php?shareaholic_redirect_url=shareaholic.com/signup/")); ?>" target="_blank" class="btn btn-info btn-lg" role="button" style="font-size: 16px;"><?php echo sprintf(__('Shareaholic Dashboard', 'shareaholic')); ?></a>
16
- <p class="signuppromo_note">
17
- <?php echo sprintf(__("Already have a Shareaholic account? Click the button above to log in.", 'shareaholic')); ?>
18
- </p>
19
  </div>
20
  -->
21
-
22
- <div class="sidebar_links">
23
- <ul>
24
- <li><a href="https://support.shareaholic.com/" target="_blank"><?php _e('Shareaholic Helpdesk', 'shareaholic'); ?></a></li>
25
- <li><a href="https://translate.wordpress.org/projects/wp-plugins/shareaholic" target="_blank"><?php _e('Submit a new or updated language translation', 'shareaholic'); ?></a></li>
26
- <li><a href="https://www.shareaholic.com/tools/browser/" target="_blank"><?php _e('Get the Shareaholic Browser Extension to share content from anywhere on the web', 'shareaholic'); ?></a></li>
27
- <li><a href="https://support.shareaholic.com/hc/en-us/categories/200185046-Website-Monetization-Apps?utm_source=wp_plugin&utm_medium=appsett&utm_campaign=psa_faq" target="_blank"><?php _e('Monetization Options', 'shareaholic'); ?></a></li>
28
- </ul>
29
- </div>
30
 
31
  <div class="sidebar_links">
32
- <div id="shrsb-updates">
33
- <div id="shrsb-updates-container"></div>
34
- </div>
35
  </div>
36
 
37
  </div>
1
  <div class="col-sm-4">
2
  <!--<div class="signuppromo">
3
+ <p class="promoh1">
4
+ <?php echo sprintf( __( 'Link to Shareaholic.com to unlock:', 'shareaholic' ) ); ?>
5
+ </p>
6
+ <ul>
7
+ <li><?php echo sprintf( __( 'Analytics', 'shareaholic' ) ); ?></li>
8
+ <li><?php echo sprintf( __( 'Floating Share buttons', 'shareaholic' ) ); ?></li>
9
+ <li><?php echo sprintf( __( 'Social Share Count Recovery', 'shareaholic' ) ); ?></li>
10
+ <li><?php echo sprintf( __( 'Follow buttons', 'shareaholic' ) ); ?></li>
11
+ <li><?php echo sprintf( __( 'Share Buttons for Images', 'shareaholic' ) ); ?></li>
12
+ <li><?php echo sprintf( __( 'Earnings Dashboard', 'shareaholic' ) ); ?></li>
13
+ <li><?php echo sprintf( __( '...lots more!', 'shareaholic' ) ); ?></li>
14
+ </ul>
15
+ <a href="<?php echo esc_url( admin_url( 'admin.php?shareaholic_redirect_url=shareaholic.com/signup/' ) ); ?>" target="_blank" class="btn btn-info btn-lg" role="button" style="font-size: 16px;"><?php echo sprintf( __( 'Shareaholic Dashboard', 'shareaholic' ) ); ?></a>
16
+ <p class="signuppromo_note">
17
+ <?php echo sprintf( __( 'Already have a Shareaholic account? Click the button above to log in.', 'shareaholic' ) ); ?>
18
+ </p>
19
  </div>
20
  -->
 
 
 
 
 
 
 
 
 
21
 
22
  <div class="sidebar_links">
23
+ <div id="shrsb-updates">
24
+ <div id="shrsb-updates-container"></div>
25
+ </div>
26
  </div>
27
 
28
  </div>
utilities.php CHANGED
@@ -5,9 +5,9 @@
5
  * @package shareaholic
6
  */
7
 
8
- require_once(SHAREAHOLIC_PATH . 'curl.php');
9
- require_once(SHAREAHOLIC_PATH . 'six_to_seven.php');
10
- require_once(SHAREAHOLIC_PATH . 'lib/social-share-counts/seq_share_count.php');
11
 
12
  /**
13
  * This class is just a holder for general functions that have
@@ -16,1703 +16,1754 @@ require_once(SHAREAHOLIC_PATH . 'lib/social-share-counts/seq_share_count.php');
16
  * @package shareaholic
17
  */
18
  class ShareaholicUtilities {
19
- /**
20
- * Logs to the PHP error log if plugin's url is set to
21
- * spreadaholic or the SHAREAHOLIC_DEBUG constant is true.
22
- *
23
- * @param mixed $thing anything to be logged, it will be passed to `print_r`
24
- */
25
- public static function log($thing) {
26
- if (preg_match('/spreadaholic/', Shareaholic::URL) || SHAREAHOLIC_DEBUG) {
27
- error_log(print_r($thing, true));
28
- }
29
- }
30
-
31
- /**
32
- * Locate and require a template, and extract some variables
33
- * to be used in that template.
34
- *
35
- * @param string $template the name of the template
36
- * @param array $vars any variables to be extracted into the template
37
- */
38
- public static function load_template($template, $vars = array()){
39
- // you cannot let locate_template to load your template
40
- // because WP devs made sure you can't pass
41
- // variables to your template :(
42
-
43
- $template_path = 'templates/' . $template . '.php';
44
-
45
- // load it
46
- extract($vars);
47
- require $template_path;
48
- }
49
-
50
- /**
51
- * Just a wrapper around get_option to
52
- * get the shareaholic settings. If the settings
53
- * have not been set it will return an array of defaults.
54
- *
55
- * @return array
56
- */
57
- public static function get_settings() {
58
- return get_option('shareaholic_settings', self::defaults());
59
- }
60
-
61
- public static function reset_settings() {
62
- $settings = self::get_settings();
63
- $api_key = self::get_option('api_key');
64
-
65
- $response = ShareaholicCurl::post(
66
- Shareaholic::API_URL . '/publisher_tools/' . $api_key . '/reset/',
67
- $settings,
68
- 'json'
69
- );
70
-
71
- // set the location on/off back to their defaults
72
- if (isset($settings['location_name_ids']) && is_array($settings['location_name_ids'])) {
73
- self::set_default_location_settings($settings['location_name_ids']);
74
- }
75
- }
76
-
77
- /**
78
- * Returns the defaults we want because PHP does not allow
79
- * arrays in class constants.
80
- *
81
- * @return array
82
- */
83
- private static function defaults() {
84
- return array(
85
- 'disable_admin_bar_menu' => 'on', // advanced
86
- 'disable_review_notice' => 'off', // advanced
87
- 'disable_debug_info' => 'off', // advanced
88
- 'enable_user_nicename' => 'off', // advanced
89
- 'disable_internal_share_counts_api' => 'on', // advanced
90
- 'disable_og_tags' => 'off', // advanced
91
- 'api_key' => '',
92
- 'verification_key' => '',
93
- 'recommendations_display_on_excerpts' => 'on',
94
- 'share_buttons_display_on_excerpts' => 'on'
95
- );
96
- }
97
-
98
- /**
99
- * Returns links to add to the plugin options admin page
100
- *
101
- * @param array $links
102
- * @return array
103
- */
104
- public static function admin_plugin_action_links($links) {
105
- if (is_array($links)) {
106
- $settings_link = '<a href="'.esc_url(admin_url('admin.php?page=shareaholic-settings')).'">'.__('Settings', 'shareaholic').'</a>';
107
- $premium_link = '<a href="https://www.shareaholic.com/plans" target="_blank" rel="noopener noreferrer">'.__('Upgrade', 'shareaholic').'</a>';
108
- $helpdesk_link = '<a href="https://support.shareaholic.com/" target="_blank" rel="noopener noreferrer">'.__('Support & Documentation', 'shareaholic').'</a>';
109
-
110
- array_unshift($links, $settings_link);
111
- $links[] = $helpdesk_link;
112
- $links[] = $premium_link;
113
- }
114
-
115
- return $links;
116
- }
117
-
118
- /**
119
- * Extend the admin bar
120
- *
121
- */
122
-
123
- public static function admin_bar_extended() {
124
- global $wp_admin_bar;
125
-
126
- if(!current_user_can('update_plugins') || !is_admin_bar_showing() || self::get_option('disable_admin_bar_menu') == "on")
127
- return;
128
-
129
- $wp_admin_bar->add_menu(array(
130
- 'id' => 'wp_shareaholic_adminbar_menu',
131
- 'title' => __('Social', 'shareaholic'),
132
- 'href' => esc_url(admin_url('admin.php?page=shareaholic-settings')),
133
- ));
134
-
135
- /*
136
- $wp_admin_bar->add_menu(array(
137
- 'parent' => 'wp_shareaholic_adminbar_menu',
138
- 'id' => 'wp_shareaholic_adminbar_submenu-analytics',
139
- 'title' => __('Social Analytics', 'shareaholic'),
140
- 'href' => 'https://www.shareaholic.com/publishers/analytics/'. ShareaholicUtilities::get_host(),
141
- 'meta' => Array( 'target' => '_blank' )
142
- ));
143
- */
144
-
145
- $wp_admin_bar->add_menu(array(
146
- 'parent' => 'wp_shareaholic_adminbar_menu',
147
- 'id' => 'wp_shareaholic_adminbar_submenu-settings',
148
- 'title' => __('App Manager', 'shareaholic'),
149
- 'href' => admin_url('admin.php?page=shareaholic-settings'),
150
- ));
151
-
152
- $wp_admin_bar->add_menu(array(
153
- 'parent' => 'wp_shareaholic_adminbar_menu',
154
- 'id' => 'wp_shareaholic_adminbar_submenu-general',
155
- 'title' => __('Dashboard', 'shareaholic'),
156
- 'href' => 'https://www.shareaholic.com/publisher_tools/'.self::get_option('api_key').'/websites/edit/?verification_key='.self::get_option('verification_key'),
157
- 'meta' => Array( 'target' => '_blank' )
158
- ));
159
- $wp_admin_bar->add_menu(array(
160
- 'parent' => 'wp_shareaholic_adminbar_menu',
161
- 'id' => 'wp_shareaholic_adminbar_submenu-help',
162
- 'title' => __('FAQ & Support', 'shareaholic'),
163
- 'href' => 'https://support.shareaholic.com/',
164
- 'meta' => Array( 'target' => '_blank' )
165
- ));
166
- }
167
-
168
- /**
169
- * Returns whether the user has accepted our terms of service.
170
- *
171
- * @return bool
172
- */
173
- public static function has_accepted_terms_of_service() {
174
- return get_option('shareaholic_has_accepted_tos');
175
- }
176
-
177
- /**
178
- * Accepts the terms of service.
179
- */
180
- public static function accept_terms_of_service() {
181
- update_option('shareaholic_has_accepted_tos', true);
182
-
183
- ShareaholicUtilities::log_event("AcceptedToS");
184
-
185
- echo "{}";
186
-
187
- die();
188
- }
189
-
190
- /**
191
- * Wrapper for wordpress's get_option
192
- *
193
- * @param string $option
194
- *
195
- * @return mixed
196
- */
197
- public static function get_option($option) {
198
- $settings = self::get_settings();
199
- return (isset($settings[$option]) ? $settings[$option] : array());
200
- }
201
-
202
- /**
203
- * Wrapper for wordpress's update_option
204
- *
205
- * @param array $array an array of options to update
206
- * @return bool
207
- */
208
- public static function update_options($array) {
209
- $old_settings = self::get_settings();
210
- $new_settings = self::array_merge_recursive_distinct($old_settings, $array);
211
- update_option('shareaholic_settings', $new_settings);
212
- }
213
-
214
- /**
215
- * Return the current version.
216
- *
217
- * @return string that looks like a number
218
- */
219
- public static function get_version() {
220
- return self::get_option('version') ? self::get_option('version') : get_option('SHRSBvNUM');
221
- }
222
-
223
- /**
224
- * Return host domain of WordPress install
225
- *
226
- * @return string
227
- */
228
- public static function get_host() {
229
- $parse = parse_url(get_bloginfo('url'));
230
- return $parse['host'];
231
- }
232
-
233
- /**
234
- * Set the current version, how simple.
235
- *
236
- * @param string $version the version you want to set
237
- */
238
- public static function set_version($version) {
239
- self::update_options(array('version' => $version));
240
- }
241
-
242
- /**
243
- * Determines if the first argument version is less than the second
244
- * argument version. A version can be up four levels, e.g. 1.1.1.1.
245
- * Any versions not supplied will be zeroed.
246
- *
247
- * @param string $version
248
- * @param string $comparer
249
- * @return bool
250
- */
251
- public static function version_less_than($version, $comparer) {
252
- $version_array = explode('.', $version);
253
- $comparer_array = explode('.', $comparer);
254
-
255
- for ($i = 0; $i <= 3; $i++) {
256
- // zero out unset numbers
257
- if (!isset($version_array[$i])) { $version_array[$i] = 0; }
258
- if (!isset($comparer_array[$i])) { $comparer_array[$i] = 0; }
259
-
260
- if ($version_array[$i] < $comparer_array[$i]) {
261
- return true;
262
- }
263
-
264
- }
265
- return false;
266
- }
267
-
268
- /**
269
- * Determines if the first argument version is less than or equal to the second
270
- * argument version. A version can be up four levels, e.g. 1.1.1.1.
271
- * Any versions not supplied will be zeroed.
272
- *
273
- * @param string $version
274
- * @param string $comparer
275
- * @return bool
276
- */
277
- public static function version_less_than_or_equal_to($version, $comparer) {
278
- $version_array = explode('.', $version);
279
- $comparer_array = explode('.', $comparer);
280
-
281
- if ($version == $comparer || self::version_less_than($version, $comparer)) {
282
- return true;
283
- }
284
-
285
- return false;
286
- }
287
-
288
- /**
289
- * Determines if the first argument version is greater than the second
290
- * argument version. A version can be up four levels, e.g. 1.1.1.1.
291
- * Any versions not supplied will be zeroed.
292
- *
293
- * @param string $version
294
- * @param string $comparer
295
- * @return bool
296
- */
297
- public static function version_greater_than($version, $comparer) {
298
- $version_array = explode('.', $version);
299
- $comparer_array = explode('.', $comparer);
300
-
301
- for ($i = 0; $i <= 3; $i++) {
302
- // zero out unset numbers
303
- if (!isset($version_array[$i])) { $version_array[$i] = 0; }
304
- if (!isset($comparer_array[$i])) { $comparer_array[$i] = 0; }
305
-
306
- if ($version_array[$i] > $comparer_array[$i]) {
307
- return true;
308
- } elseif ($version_array[$i] < $comparer_array[$i]) {
309
- return false;
310
- }
311
-
312
- }
313
- return false;
314
- }
315
-
316
- /**
317
- * Determines if the first argument version is greater than or equal to the second
318
- * argument version. A version can be up four levels, e.g. 1.1.1.1.
319
- * Any versions not supplied will be zeroed.
320
- *
321
- * @param string $version
322
- * @param string $comparer
323
- * @return bool
324
- */
325
- public static function version_greater_than_or_equal_to($version, $comparer) {
326
- $version_array = explode('.', $version);
327
- $comparer_array = explode('.', $comparer);
328
-
329
- if ($version == $comparer || self::version_greater_than($version, $comparer)) {
330
- return true;
331
- }
332
-
333
- return false;
334
- }
335
-
336
- /**
337
- * This is the function that will perform the update.
338
- */
339
- public static function perform_update() {
340
-
341
- // Set plugin defaults, if not already set
342
- $settings = ShareaholicUtilities::get_settings();
343
-
344
- if (empty($settings["share_buttons_display_on_excerpts"]) || !isset($settings["share_buttons_display_on_excerpts"])) {
345
- ShareaholicUtilities::update_options(array('share_buttons_display_on_excerpts' => 'on'));
346
- }
347
- if (empty($settings["recommendations_display_on_excerpts"]) || !isset($settings["recommendations_display_on_excerpts"])) {
348
- ShareaholicUtilities::update_options(array('recommendations_display_on_excerpts' => 'on'));
349
- }
350
-
351
- if (!self::is_locked('perform_update')) {
352
- self::set_lock('perform_update');
353
-
354
- // Upgrade v6 users
355
- if (self::get_version() && intval(self::get_version()) <= 6) {
356
- ShareaholicSixToSeven::update();
357
- }
358
-
359
- // Activate Shareaholic Cron job
360
- ShareaholicCron::activate();
361
-
362
- // Clear site cache
363
- ShareaholicUtilities::clear_cache();
364
-
365
- // add other things that need to run on version change here
366
-
367
- self::unlock('perform_update');
368
- }
369
- }
370
-
371
- /**
372
- * Return the type of page we're on as a string
373
- * to use for the location in the JS
374
- *
375
- * @return string
376
- */
377
- public static function page_type() {
378
- if (is_front_page() || is_home()) {
379
- return 'index';
380
- } elseif (is_page()) {
381
- return 'page';
382
- } elseif (is_single()) {
383
- return 'post';
384
- } elseif (is_category() || is_author() || is_tag() || is_date() || is_search()) {
385
- return 'category';
386
- }
387
- }
388
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  /**
390
  * Returns a base64 URL for the svg for use in the menu
391
  *
392
  * @param bool $base64 Whether or not to return base64'd output.
393
  * @return string
394
  */
395
- public static function get_icon_svg ($base64=true) {
396
  $svg = '<svg id="svg2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.51 21.49"><defs><style>.cls-1{fill:#92ce23;}.cls-2{fill:#3c9c6a;}</style></defs><title>logo</title><path id="path14" class="cls-1" d="M18.8,2.68H8.73V12.76H18.8ZM7.27,15.44a1.15,1.15,0,0,1-.86-.37,1.19,1.19,0,0,1-.35-.85v-13A1.21,1.21,0,0,1,7.27,0h13a1.21,1.21,0,0,1,1.21,1.21v13a1.21,1.21,0,0,1-1.21,1.22h-13"/><path id="path16" class="cls-2" d="M12.76,8.72H2.68V18.8H12.76ZM1.21,21.49a1.23,1.23,0,0,1-.86-.35A1.25,1.25,0,0,1,0,20.28v-13A1.21,1.21,0,0,1,1.21,6h13a1.21,1.21,0,0,1,1.21,1.21v13a1.22,1.22,0,0,1-1.21,1.21h-13"/><path id="path18" class="cls-1" d="M18.8,12.76H6.06v1.46a1.19,1.19,0,0,0,.35.85,1.15,1.15,0,0,0,.86.37h13a1.21,1.21,0,0,0,1.21-1.22V12.76H18.8"/></svg>';
397
 
398
- if ($base64) {
399
- return 'data:image/svg+xml;base64,' . base64_encode($svg);
400
  }
401
  return $svg;
402
  }
403
 
404
- /**
405
- * Returns the appropriate asset path for environment
406
- *
407
- * @param string $asset
408
- * @return string
409
- */
410
- public static function asset_url($asset = NULL) {
411
- $env = self::get_env();
412
- if ($env === 'development') {
413
- return "http://spreadaholic.com:8080/" . $asset;
414
- } elseif ($env === 'staging') {
415
- return '//d2062rwknz205x.cloudfront.net/' . $asset;
416
- } else {
417
- return '//cdn.shareaholic.net/' . $asset;
418
- }
419
- }
420
-
421
- public static function get_env() {
422
- if (preg_match('/spreadaholic/', Shareaholic::URL)) {
423
- return 'development';
424
- } elseif (preg_match('/stageaholic/', Shareaholic::URL)) {
425
- return 'staging';
426
- } else {
427
- return 'production';
428
- }
429
- }
430
-
431
- /**
432
- * Returns the appropriate asset path for environment - admin
433
- *
434
- * @param string $asset
435
- * @return string
436
- */
437
- public static function asset_url_admin($asset = NULL) {
438
- if (preg_match('/spreadaholic/', Shareaholic::URL)) {
439
- return "http://spreadaholic.com:8080/" . $asset;
440
- } elseif (preg_match('/stageaholic/', Shareaholic::URL)) {
441
- return 'https://d2062rwknz205x.cloudfront.net/' . $asset;
442
- } else {
443
- return 'https://cdn.shareaholic.net/' . $asset;
444
- }
445
- }
446
-
447
- /**
448
- * Checks whether the api key has been verified
449
- * using the rails endpoint. Once the key has
450
- * been verified, we store that away so that we
451
- * don't have to check again.
452
- *
453
- * @return bool
454
- */
455
- public static function api_key_verified() {
456
- $settings = self::get_settings();
457
- if (isset($settings['api_key_verified']) && $settings['api_key_verified']) {
458
- return true;
459
- }
460
-
461
- $api_key = $settings['api_key'];
462
- if (!$api_key) {
463
- return false;
464
- }
465
-
466
- $response = ShareaholicCurl::get(Shareaholic::API_URL . '/publisher_tools/' . $api_key . '/verified');
467
- $result = $response['body'];
468
-
469
- if ($result == 'true') {
470
- ShareaholicUtilities::update_options(array(
471
- 'api_key_verified' => true
472
- ));
473
- }
474
- }
475
-
476
- /**
477
- * A wrapper function to specificaly update the location name ids
478
- * because this is such a common function
479
- *
480
- * @todo Determine whether needed anymore
481
- *
482
- * @param array $array an array of location names to location ids
483
- * @return bool
484
- */
485
- public static function update_location_name_ids($array) {
486
- $settings = self::get_settings();
487
- $location_name_ids = (isset($settings['location_name_ids']) ? $settings['location_name_ids'] : array());
488
- $merge = array_merge($location_name_ids, $array);
489
- $settings['location_name_ids'] = $merge;
490
-
491
- update_option('shareaholic_settings', $settings);
492
- }
493
-
494
-
495
- /**
496
- *
497
- * Loads the locations names and their respective ids for an api key
498
- * and sets them in the shareaholic settings.'
499
- *
500
- * @param string $api_key
501
- */
502
- public static function get_new_location_name_ids($api_key) {
503
- $response = ShareaholicCurl::get(Shareaholic::API_URL . "/publisher_tools/{$api_key}.json");
504
-
505
- if(is_array($response) && array_key_exists('body', $response)) {
506
- $response_code = wp_remote_retrieve_response_code($response);
507
- if ($response_code == "404"){
508
- delete_option('shareaholic_settings');
509
- ShareaholicUtilities::get_or_create_api_key();
510
- }
511
- }
512
-
513
- $publisher_configuration = $response['body'];
514
- $result = array();
515
-
516
- if ($publisher_configuration && is_array($publisher_configuration)) {
517
- foreach (array('share_buttons', 'recommendations') as $app) {
518
- foreach ($publisher_configuration['apps'][$app]['locations'] as $id => $location) {
519
- $result[$app][$location['name']] = $id;
520
- }
521
- }
522
-
523
- self::update_location_name_ids($result);
524
- } else {
525
- ShareaholicUtilities::load_template('failed_to_create_api_key_modal');
526
- ShareaholicUtilities::log_bad_response('FailedToFetchPubConfig', $response);
527
- }
528
- }
529
-
530
- /**
531
- * A general function to underscore a CamelCased string.
532
- *
533
- * @param string $string
534
- * @return string
535
- */
536
- public static function underscore($string) {
537
- return strtolower(preg_replace('/([a-z])([A-Z])', '$1_$2', $string));
538
- }
539
-
540
- /**
541
- * Passed an array of location names mapped to ids per app.
542
- *
543
- * @param array $array
544
- */
545
- public static function turn_on_locations($array, $turn_off_array = array()) {
546
-
547
- if (is_array($array)) {
548
- foreach($array as $app => $ids) {
549
- if (is_array($ids)) {
550
- foreach($ids as $name => $id) {
551
- self::update_options(array(
552
- $app => array($name => 'on')
553
- ));
554
- }
555
- }
556
- }
557
- }
558
-
559
- if (is_array($turn_off_array)) {
560
- foreach($turn_off_array as $app => $ids) {
561
- if (is_array($ids)) {
562
- foreach($ids as $name => $id) {
563
- self::update_options(array(
564
- $app => array($name => 'off')
565
- ));
566
- }
567
- }
568
- }
569
- }
570
- }
571
-
572
- /**
573
- * Give back only the request keys from an array. The first
574
- * argument is the array to be sliced, and after that it can
575
- * either be a variable-length list of keys or one array of keys.
576
- *
577
- * @param array $array
578
- * @param Mixed ... can be either one array or many keys
579
- * @return array
580
- */
581
- public static function associative_array_slice($array) {
582
- $keys = array_slice(func_get_args(), 1);
583
- if (func_num_args() == 2 && is_array($keys[0])) {
584
- $keys = $keys[0];
585
- }
586
-
587
- $result = array();
588
-
589
- foreach($keys as $key) {
590
- $result[$key] = $array[$key];
591
- }
592
-
593
- return $result;
594
- }
595
-
596
- /**
597
- * Sets a lock (mutex)
598
- *
599
- * @param string $name
600
- */
601
- public static function set_lock($name) {
602
- update_option('shareaholic_' . $name, true);
603
- }
604
-
605
- /**
606
- * Checks if an action is locked.
607
- *
608
- * @param string $name
609
- * @return bool
610
- */
611
- public static function is_locked($name) {
612
- return get_option('shareaholic_' . $name, false);
613
- }
614
-
615
- /**
616
- * Unlocks a mutex
617
- *
618
- * @param string $name
619
- */
620
- public static function unlock($name) {
621
- delete_option('shareaholic_' . $name);
622
- }
623
-
624
- /**
625
- * Clears all mutex
626
- *
627
- */
628
- public static function delete_mutex() {
629
- delete_option('shareaholic_get_or_create_api_key');
630
- delete_option('shareaholic_perform_update');
631
- }
632
-
633
- /**
634
- * Checks whether a plugin is active
635
- *
636
- * @param string $name
637
- */
638
- public static function check_for_other_plugin() {
639
- if (is_plugin_active('shareaholic/shareaholic.php')) {
640
- deactivate_plugins('sexybookmarks/shareaholic.php');
641
- }
642
- if (is_plugin_active('shareaholic/sexy-bookmarks.php')) {
643
- deactivate_plugins('sexybookmarks/sexy-bookmarks.php');
644
- }
645
- }
646
-
647
- /**
648
- * Returns Stats
649
- *
650
- */
651
- public static function get_stats() {
652
- global $wpdb;
653
-
654
- $stats = array(
655
- 'posts_total' => $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts where post_type = 'post' AND post_status = 'publish'" ),
656
- 'pages_total' => $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts where post_type = 'page' AND post_status = 'publish'" ),
657
- 'users_total' => $wpdb->get_var("SELECT count(ID) FROM $wpdb->users"),
658
- );
659
-
660
- return (isset($stats) ? $stats : array());
661
- }
662
-
663
- /**
664
- * Returns Active Plugins
665
- *
666
- */
667
- public static function get_active_plugins() {
668
- $active_plugins = (array) get_option('active_plugins', array());
669
-
670
- if (is_multisite()) {
671
- $network_plugins = (array) get_site_option('active_sitewide_plugins', array());
672
- $active_plugins = array_merge($active_plugins, array_keys($network_plugins));
673
- }
674
-
675
- return (isset($active_plugins) ? array_values(array_unique($active_plugins)) : array());
676
- }
677
-
678
- /**
679
- * Returns Local Share Count Proxy Status
680
- *
681
- */
682
- public static function get_internal_share_counts_api_status() {
683
- if (ShareaholicUtilities::get_option('disable_internal_share_counts_api') == NULL || ShareaholicUtilities::get_option('disable_internal_share_counts_api') == "off"){
684
- $server_side_share_count_status = "on";
685
- } else {
686
- $server_side_share_count_status = "off";
687
- }
688
- return $server_side_share_count_status;
689
- }
690
-
691
- /**
692
- * Returns the api key or creates a new one.
693
- *
694
- * It first checks the database. If the key is not
695
- * found (or is an empty string or empty array or
696
- * anything that evaluates to false) then we will
697
- * attempt to make a new one by POSTing to the
698
- * anonymous configuration endpoint. That action
699
- * is wrapped in a mutex to keep two requests from
700
- * trying to create new api keys at the same time.
701
- *
702
- * Note: this function is called on every pageload.
703
- * So please keep it as fast as possible.
704
- *
705
- * @return string
706
- */
707
- public static function get_or_create_api_key() {
708
- $api_key = self::get_option('api_key');
709
-
710
- // ensure api key set is atleast 30 characters
711
- if ($api_key && (strlen($api_key) > 30)) {
712
- return $api_key;
713
- }
714
-
715
- if (!self::is_locked('get_or_create_api_key')) {
716
- self::set_lock('get_or_create_api_key');
717
-
718
- $old_settings = self::get_settings();
719
-
720
- delete_option('shareaholic_settings');
721
-
722
- // restore any old settings that should be preserved between resets
723
- if (isset($old_settings['share_counts_connect_check'])) {
724
- self::update_options(array(
725
- 'share_counts_connect_check' => $old_settings['share_counts_connect_check'],
726
- ));
727
- }
728
-
729
- $verification_key = md5(mt_rand());
730
-
731
- $turned_on_share_buttons_locations = self::get_default_sb_on_locations();
732
- $turned_off_share_buttons_locations = self::get_default_sb_off_locations();
733
-
734
- $turned_on_recommendations_locations = self::get_default_rec_on_locations();
735
- $turned_off_recommendations_locations = self::get_default_rec_off_locations();
736
-
737
- $share_buttons_attributes = array_merge($turned_on_share_buttons_locations, $turned_off_share_buttons_locations);
738
- $recommendations_attributes = array_merge($turned_on_recommendations_locations, $turned_off_recommendations_locations);
739
- $data = array(
740
- 'configuration_publisher' => array(
741
- 'verification_key' => $verification_key,
742
- 'site_name' => self::site_name(),
743
- 'domain' => self::site_url(),
744
- 'platform_id' => '12',
745
- 'language_id' => self::site_language(),
746
- 'shortener' => 'shrlc',
747
- 'recommendations_attributes' => array(
748
- 'locations_attributes' => $recommendations_attributes
749
- ),
750
- 'share_buttons_attributes' => array(
751
- 'locations_attributes' => $share_buttons_attributes
752
- )
753
- )
754
- );
755
-
756
- $response = ShareaholicCurl::post(
757
- Shareaholic::API_URL . '/publisher_tools/anonymous',
758
- $data,
759
- 'json'
760
- );
761
-
762
- if ($response && preg_match('/20*/', $response['response']['code'])) {
763
- self::update_options(array(
764
- 'api_key' => $response['body']['api_key'],
765
- 'verification_key' => $verification_key,
766
- 'location_name_ids' => $response['body']['location_name_ids']
767
- ));
768
-
769
- if (isset($response['body']['location_name_ids']) && is_array($response['body']['location_name_ids'])) {
770
- self::set_default_location_settings($response['body']['location_name_ids']);
771
-
772
- ShareaholicAdmin::welcome_email();
773
- ShareaholicUtilities::clear_cache();
774
- } else {
775
- ShareaholicUtilities::log_bad_response('FailedToCreateApiKey', $response);
776
- }
777
- } else {
778
- // add_action('admin_notices', array('ShareaholicAdmin', 'failed_to_create_api_key'));
779
- ShareaholicUtilities::log_bad_response('FailedToCreateApiKey', $response);
780
- }
781
-
782
- self::unlock('get_or_create_api_key');
783
- } else {
784
- usleep(100000);
785
- self::get_or_create_api_key();
786
- }
787
- }
788
-
789
-
790
-
791
-
792
- /**
793
- * Get share buttons locations that should be turned on by default
794
- *
795
- * @return {Array}
796
- */
797
- public static function get_default_sb_on_locations() {
798
- return array(
799
- array('name' => 'post_below_content', 'counter' => 'badge-counter'),
800
- array('name' => 'page_below_content', 'counter' => 'badge-counter'),
801
- array('name' => 'index_below_content', 'counter' => 'badge-counter'),
802
- array('name' => 'category_below_content', 'counter' => 'badge-counter')
803
- );
804
- }
805
-
806
- /**
807
- * Get share buttons locations that should be turned off by default
808
- *
809
- * @return {Array}
810
- */
811
- public static function get_default_sb_off_locations() {
812
- return array(
813
- array('name' => 'post_above_content', 'counter' => 'badge-counter'),
814
- array('name' => 'page_above_content', 'counter' => 'badge-counter'),
815
- array('name' => 'index_above_content', 'counter' => 'badge-counter'),
816
- array('name' => 'category_above_content', 'counter' => 'badge-counter')
817
- );
818
- }
819
-
820
- /**
821
- * Get recommendations locations that should be turned on by default
822
- *
823
- * @return {Array}
824
- */
825
- public static function get_default_rec_on_locations() {
826
- return array(
827
- array('name' => 'post_below_content'),
828
- array('name' => 'page_below_content'),
829
- );
830
- }
831
-
832
-
833
- /**
834
- * Get recommendations locations that should be turned off by default
835
- *
836
- * @return {Array}
837
- */
838
- public static function get_default_rec_off_locations() {
839
- return array(
840
- array('name' => 'index_below_content'),
841
- array('name' => 'category_below_content'),
842
- );
843
- }
844
-
845
- /**
846
- * Given an object, set the default on/off locations
847
- * for share buttons and recommendations
848
- *
849
- */
850
- public static function set_default_location_settings($location_name_ids) {
851
- $turned_on_share_buttons_locations = self::get_default_sb_on_locations();
852
- $turned_off_share_buttons_locations = self::get_default_sb_off_locations();
853
-
854
- $turned_on_recommendations_locations = self::get_default_rec_on_locations();
855
- $turned_off_recommendations_locations = self::get_default_rec_off_locations();
856
-
857
- $turned_on_share_buttons_keys = array();
858
- foreach($turned_on_share_buttons_locations as $loc) {
859
- $turned_on_share_buttons_keys[] = $loc['name'];
860
- }
861
-
862
- $turned_on_recommendations_keys = array();
863
- foreach($turned_on_recommendations_locations as $loc) {
864
- $turned_on_recommendations_keys[] = $loc['name'];
865
- }
866
-
867
- $turned_off_share_buttons_keys = array();
868
- foreach($turned_off_share_buttons_locations as $loc) {
869
- $turned_off_share_buttons_keys[] = $loc['name'];
870
- }
871
-
872
- $turned_off_recommendations_keys = array();
873
- foreach($turned_off_recommendations_locations as $loc) {
874
- $turned_off_recommendations_keys[] = $loc['name'];
875
- }
876
-
877
- $turn_on = array(
878
- 'share_buttons' => self::associative_array_slice($location_name_ids['share_buttons'], $turned_on_share_buttons_keys),
879
- 'recommendations' => self::associative_array_slice($location_name_ids['recommendations'], $turned_on_recommendations_keys)
880
- );
881
-
882
- $turn_off = array(
883
- 'share_buttons' => self::associative_array_slice($location_name_ids['share_buttons'], $turned_off_share_buttons_keys),
884
- 'recommendations' => self::associative_array_slice($location_name_ids['recommendations'], $turned_off_recommendations_keys)
885
- );
886
-
887
- ShareaholicUtilities::turn_on_locations($turn_on, $turn_off);
888
- }
889
-
890
- /**
891
- * Log reasons for a failure of a response.
892
- *
893
- * Checks if the code is not a 20*, the response body
894
- * is not an array, and whether the response object
895
- * was false. Sends the appropriate logging message.
896
- *
897
- * @param string $name the name of the event to log
898
- * @param mixed $response the response object
899
- */
900
- public static function log_bad_response($name, $response) {
901
- if ($response && is_array($response) && !preg_match('/20*/',$response['response']['code'])) {
902
- ShareaholicUtilities::log_event($name, array('reason' => 'the response was a ' . $response['response']['code']));
903
- } elseif ($response && !is_array($response)) {
904
- $thing = preg_replace('/\n/', '', var_export($response, true));
905
- ShareaholicUtilities::log_event($name, array('reason' => 'the publisher configuration was not an array, it was this ' . $thing));
906
- }
907
- }
908
-
909
- /**
910
- * Returns the site's url stripped of protocol.
911
- *
912
- * @return string
913
- */
914
- public static function site_url() {
915
- return preg_replace('/https?:\/\//', '', site_url());
916
- }
917
-
918
- /**
919
- * Returns the site's name
920
- *
921
- * @return string
922
- */
923
- public static function site_name() {
924
- return get_bloginfo('name') ? get_bloginfo('name') : site_url();
925
- }
926
-
927
- /**
928
- * Returns the site's primary locale / language
929
- *
930
- * @return string
931
- */
932
- public static function site_language() {
933
- $site_language = strtolower(get_bloginfo('language'));
934
-
935
- if (strpos($site_language, 'en-') !== false) {
936
- $language_id = 9; // English
937
- } elseif (strpos($site_language, 'da-') !== false) {
938
- $language_id = 7; // Danish
939
- } elseif (strpos($site_language, 'de-') !== false) {
940
- $language_id = 13; // German
941
- } elseif (strpos($site_language, 'es-') !== false) {
942
- $language_id = 31; // Spanish
943
- } elseif (strpos($site_language, 'fr-') !== false) {
944
- $language_id = 12; // French
945
- } elseif (strpos($site_language, 'pt-') !== false) {
946
- $language_id = 25; // Portuguese
947
- } elseif (strpos($site_language, 'it-') !== false) {
948
- $language_id = 18; // Italian
949
- } elseif (strpos($site_language, 'zh-cn') !== false) {
950
- $language_id = 3; // Chinese (Simplified)
951
- } elseif (strpos($site_language, 'zh-tw') !== false) {
952
- $language_id = 4; // Chinese (Traditional)
953
- } elseif (strpos($site_language, 'ja-') !== false) {
954
- $language_id = 19; // Japanese
955
- } elseif (strpos($site_language, 'ar-') !== false) {
956
- $language_id = 1; // Arabic
957
- } elseif (strpos($site_language, 'sv-') !== false) {
958
- $language_id = 32; // Swedish
959
- } elseif (strpos($site_language, 'tr-') !== false) {
960
- $language_id = 34; // Turkish
961
- } elseif (strpos($site_language, 'el-') !== false) {
962
- $language_id = 14; // Greek
963
- } elseif (strpos($site_language, 'nl-') !== false) {
964
- $language_id = 8; // Dutch
965
- } elseif (strpos($site_language, 'pl-') !== false) {
966
- $language_id = 24; // Polish
967
- } elseif (strpos($site_language, 'ru-') !== false) {
968
- $language_id = 27; // Russian
969
- } elseif (strpos($site_language, 'cs-') !== false) {
970
- $language_id = 6; // Czech
971
- } else {
972
- $language_id = NULL;
973
- }
974
- return $language_id;
975
- }
976
-
977
- /**
978
- * Shockingly the built in PHP array_merge_recursive function is stupid.
979
- * this is stolen from the PHP docs and will overwrite existing keys instead
980
- * of appending the values.
981
- *
982
- * http://www.php.net/manual/en/function.array-merge-recursive.php#92195
983
- *
984
- * @param array $array1
985
- * @param array $array2
986
- * @return array
987
- */
988
- public static function array_merge_recursive_distinct ( array &$array1, array &$array2 )
989
- {
990
- $merged = $array1;
991
-
992
- foreach ( $array2 as $key => &$value )
993
- {
994
- if ( is_array ( $value ) && isset ( $merged [$key] ) && is_array ( $merged [$key] ) )
995
- {
996
- if (empty($value)) {
997
- $merged[$key] = array();
998
- } else {
999
- $merged [$key] = self::array_merge_recursive_distinct ( $merged [$key], $value );
1000
- }
1001
- }
1002
- else
1003
- {
1004
- $merged [$key] = $value;
1005
- }
1006
- }
1007
-
1008
- return $merged;
1009
- }
1010
-
1011
- /**
1012
- * Array casting an object is not recursive, this makes it recursive
1013
- *
1014
- * @param object $d
1015
- *
1016
- * http://www.if-not-true-then-false.com/2009/php-tip-convert-stdclass-object-to-multidimensional-array-and-convert-multidimensional-array-to-stdclass-object/
1017
- */
1018
- public static function object_to_array($d) {
1019
- if (is_object($d)) {
1020
- // Gets the properties of the given object
1021
- // with get_object_vars function
1022
- $d = get_object_vars($d);
1023
- }
1024
-
1025
- if (is_array($d)) {
1026
- /*
1027
- * Return array converted to object
1028
- */
1029
- return array_map(array('self', 'object_to_array'), $d);
1030
- }
1031
- else {
1032
- // Return array
1033
- return $d;
1034
- }
1035
- }
1036
-
1037
- /**
1038
- * Wrapper for the Shareaholic Content Manager Single Page worker API
1039
- *
1040
- * @param string $post_id
1041
- */
1042
- public static function notify_content_manager_singlepage($post = NULL, $status = NULL) {
1043
-
1044
- if ($post == NULL) {
1045
- return;
1046
- }
1047
-
1048
- $api_key = ShareaholicUtilities::get_option('api_key');
1049
-
1050
- if (ShareaholicUtilities::has_accepted_terms_of_service() && !empty($api_key)) {
1051
-
1052
- if ($status != NULL) {
1053
- $visiblity = $status;
1054
- } else {
1055
- $visiblity = $post->post_status;
1056
- }
1057
-
1058
- if (in_array($post->post_status, array('draft', 'pending'))) {
1059
- // Get the correct permalink for a draft
1060
- $my_post = clone $post;
1061
- $my_post->post_status = 'published';
1062
- $my_post->post_name = sanitize_title($my_post->post_name ? $my_post->post_name : $my_post->post_title, $my_post->ID);
1063
- $post_permalink = get_permalink($my_post);
1064
- } else {
1065
- $post_permalink = get_permalink($post->ID);
1066
- }
1067
-
1068
- if ($post_permalink != NULL
1069
- && (strpos($post_permalink, '__trashed') == false)
1070
- && !in_array($post->post_status, array('auto-draft', 'inherit')) ) {
1071
- $cm_single_page_job_url = Shareaholic::CM_API_URL . '/jobs/uber_single_page';
1072
- $payload = array (
1073
- 'args' => array (
1074
- $post_permalink,
1075
- array (
1076
- 'force' => true
1077
- ),
1078
- ),
1079
- 'api_key' => ShareaholicUtilities::get_option('api_key'),
1080
- 'verification_key' => ShareaholicUtilities::get_option('verification_key'),
1081
- 'admin_ajax_path' => admin_url('admin-ajax.php'),
1082
- 'wp_version' => Shareaholic::VERSION,
1083
- 'post_visibility' => $visiblity
1084
- );
1085
- $response = ShareaholicCurl::post($cm_single_page_job_url, $payload, 'json');
1086
- }
1087
-
1088
- }
1089
- }
1090
-
1091
- /**
1092
- * Wrapper for the Shareaholic Content Manager Single Domain worker API
1093
- *
1094
- */
1095
- public static function notify_content_manager_singledomain() {
1096
- $domain = get_bloginfo('url');
1097
- if ($domain != NULL) {
1098
- $cm_single_domain_job_url = Shareaholic::CM_API_URL . '/jobs/single_domain';
1099
- $payload = array (
1100
- 'args' => array (
1101
- $domain,
1102
- array (
1103
- 'force' => true
1104
- ),
1105
- ),
1106
- 'api_key' => ShareaholicUtilities::get_option('api_key'),
1107
- 'verification_key' => ShareaholicUtilities::get_option('verification_key'),
1108
- 'admin_ajax_path' => admin_url('admin-ajax.php'),
1109
- 'wp_version' => Shareaholic::VERSION
1110
- );
1111
- $response = ShareaholicCurl::post($cm_single_domain_job_url, $payload, 'json');
1112
- }
1113
- }
1114
-
1115
- /**
1116
- * This is a wrapper for the Event API
1117
- *
1118
- * @param string $event_name the name of the event
1119
- * @param array $extra_params any extra data points to be included
1120
- */
1121
- public static function log_event($event_name = 'Default', $extra_params = false) {
1122
- $event_metadata = array(
1123
- 'plugin_version' => Shareaholic::VERSION,
1124
- 'api_key' => self::get_option('api_key'),
1125
- 'domain' => get_bloginfo('url'),
1126
- 'diagnostics' => array (
1127
- 'php_version' => phpversion(),
1128
- 'wp_version' => get_bloginfo('version'),
1129
- 'theme' => get_option('template'),
1130
- 'multisite' => is_multisite(),
1131
- ),
1132
- 'features' => array(
1133
- 'share_buttons' => self::get_option('share_buttons'),
1134
- 'recommendations' => self::get_option('recommendations')
1135
- ),
1136
- );
1137
-
1138
- if ($extra_params) {
1139
- $event_metadata = array_merge($event_metadata, $extra_params);
1140
- }
1141
-
1142
- $event_api_url = Shareaholic::API_URL . '/api/events';
1143
- $event_params = array('name' => "WordPress:".$event_name, 'data' => json_encode($event_metadata) );
1144
- $response = ShareaholicCurl::post($event_api_url, $event_params, '', true, 2);
1145
- }
1146
-
1147
- /**
1148
- * This is a wrapper for the Heartbeat API
1149
- *
1150
- */
1151
- public static function heartbeat() {
1152
- $data = array(
1153
- 'platform' => 'wordpress',
1154
- 'plugin_name' => 'shareaholic',
1155
- 'plugin_version' => Shareaholic::VERSION,
1156
- 'api_key' => self::get_option('api_key'),
1157
- 'verification_key' => self::get_option('verification_key'),
1158
- 'domain' => preg_replace('#^https?://#', '', get_bloginfo('url')),
1159
- 'language' => get_bloginfo('language'),
1160
- 'stats' => ShareaholicUtilities::get_stats(),
1161
- 'diagnostics' => array(
1162
- 'tos_status' => ShareaholicUtilities::has_accepted_terms_of_service(),
1163
- 'shareaholic_server_reachable' => ShareaholicUtilities::connectivity_check(),
1164
- 'server_side_share_count_api_reachable' => ShareaholicUtilities::share_counts_api_connectivity_check(),
1165
- 'php_version' => phpversion(),
1166
- 'wp_version' => get_bloginfo('version'),
1167
- 'theme' => get_option('template'),
1168
- 'multisite' => is_multisite(),
1169
- 'plugins' => array(
1170
- 'active' => ShareaholicUtilities::get_active_plugins(),
1171
- ),
1172
- ),
1173
- 'endpoints' => array(
1174
- 'ajax_url' => admin_url('admin-ajax.php')
1175
- ),
1176
- 'advanced_settings' => array(
1177
- 'server_side_share_count_api' => ShareaholicUtilities::get_internal_share_counts_api_status(),
1178
- 'facebook_access_token' => ShareaholicUtilities::fetch_fb_access_token() === false ? 'no' : 'yes',
1179
- 'facebook_auth_check' => ShareaholicUtilities::facebook_auth_check(),
1180
- 'enable_user_nicename' => ShareaholicUtilities::get_option('enable_user_nicename'),
1181
- 'disable_og_tags' => ShareaholicUtilities::get_option('disable_og_tags'),
1182
- 'disable_admin_bar_menu' => ShareaholicUtilities::get_option('disable_admin_bar_menu'),
1183
- 'recommendations_display_on_excerpts' => ShareaholicUtilities::get_option('recommendations_display_on_excerpts'),
1184
- 'share_buttons_display_on_excerpts' => ShareaholicUtilities::get_option('share_buttons_display_on_excerpts'),
1185
- ),
1186
- );
1187
-
1188
- $heartbeat_api_url = Shareaholic::API_URL . '/api/plugin_heartbeats';
1189
- $response = ShareaholicCurl::post($heartbeat_api_url, $data, 'json', true, 2);
1190
- }
1191
-
1192
- /**
1193
- * Deletes the api key
1194
- *
1195
- */
1196
- public static function delete_api_key () {
1197
- $payload = array(
1198
- 'site_id' => self::get_option('api_key'),
1199
- 'verification_key' => self::get_option('verification_key')
1200
- );
1201
-
1202
- $response = ShareaholicCurl::post(
1203
- Shareaholic::API_URL . '/integrations/plugin/delete',
1204
- $payload,
1205
- 'json',
1206
- true
1207
- );
1208
- }
1209
-
1210
- /**
1211
- * This loads the locales
1212
- *
1213
- */
1214
- public static function localize() {
1215
- load_plugin_textdomain('shareaholic', false, basename(dirname(__FILE__)) . '/languages/');
1216
- }
1217
-
1218
- /**
1219
- * Function to return a list of permalink keywords
1220
- *
1221
- * @return list of keywords for the given permalink in an array
1222
- */
1223
- public static function permalink_keywords($post_id = NULL){
1224
- global $post;
1225
- $keywords = '';
1226
-
1227
- if ($post_id != NULL) {
1228
- $id = $post_id;
1229
- } else {
1230
- $id = $post->ID;
1231
- }
1232
-
1233
- // Get post tags
1234
- $keywords = implode(', ', wp_get_post_tags( $id, array('fields' => 'names') ) );
1235
-
1236
- // Support for "All in One SEO Pack" plugin keywords
1237
- if (get_post_meta($id, '_aioseop_keywords') != NULL){
1238
- $keywords .= ', '.stripslashes(get_post_meta($id, '_aioseop_keywords', true));
1239
- }
1240
-
1241
- // Support for "WordPress SEO by Yoast" plugin keywords
1242
- if (get_post_meta($id, '_yoast_wpseo_focuskw') != NULL){
1243
- $keywords .= ', '.stripslashes(get_post_meta($id, '_yoast_wpseo_focuskw', true));
1244
- }
1245
-
1246
- if (get_post_meta($id, '_yoast_wpseo_metakeywords') != NULL){
1247
- $keywords .= ', '.stripslashes(get_post_meta($id, '_yoast_wpseo_metakeywords', true));
1248
- }
1249
-
1250
- // Support for "Add Meta Tags" plugin keywords
1251
- if (get_post_meta($id, '_amt_keywords') != NULL){
1252
- $keywords .= ', '.stripslashes(get_post_meta($id, '_amt_keywords', true));
1253
- }
1254
-
1255
- if (get_post_meta($id, '_amt_news_keywords') != NULL){
1256
- $keywords .= ', '.stripslashes(get_post_meta($id, '_amt_news_keywords', true));
1257
- }
1258
-
1259
- // Encode, lowercase & trim appropriately
1260
- $keywords = ShareaholicUtilities::normalize_keywords($keywords);
1261
-
1262
- // Unique keywords
1263
- $keywords_array = array();
1264
- $keywords_array = explode(', ', $keywords);
1265
- $keywords_array = array_unique($keywords_array);
1266
-
1267
- if (empty($keywords_array[0])){
1268
- return array();
1269
- } else {
1270
- return $keywords_array;
1271
- }
1272
- }
1273
-
1274
- /**
1275
- * Normalizes and cleans up a list of comma separated keywords ie. encode, lowercase & trim appropriately
1276
- *
1277
- * @param string $keywords
1278
- * @return string
1279
- */
1280
- public static function normalize_keywords($keywords) {
1281
- return trim(trim(strtolower(trim(htmlspecialchars(htmlspecialchars_decode($keywords), ENT_QUOTES))), ","));
1282
- }
1283
-
1284
- /**
1285
- * Function to return a thumbnail for a given permalink
1286
- *
1287
- * @return thumbnail URL
1288
- */
1289
- public static function permalink_thumbnail($post_id = NULL, $size = "shareaholic-thumbnail"){
1290
- $thumbnail_src = '';
1291
-
1292
- // Get Featured Image
1293
- $thumbnail_src = ShareaholicUtilities::post_featured_image($size);
1294
-
1295
- // Get first image included in the post
1296
- if ($thumbnail_src == NULL) {
1297
- $thumbnail_src = ShareaholicUtilities::post_first_image($post_id);
1298
- }
1299
-
1300
- if ($thumbnail_src == NULL){
1301
- return NULL;
1302
- } else {
1303
- return $thumbnail_src;
1304
- }
1305
- }
1306
-
1307
- /**
1308
- * This function returns the URL of the featured image for a given post
1309
- *
1310
- * @return returns `false` or a string of the image src
1311
- */
1312
- public static function post_featured_image($size = "shareaholic-thumbnail") {
1313
- global $post;
1314
- $featured_img = '';
1315
- if ($post == NULL)
1316
- return false;
1317
- else {
1318
- if (function_exists('has_post_thumbnail') && has_post_thumbnail($post->ID)) {
1319
- $thumbnail_shareaholic = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'shareaholic-thumbnail');
1320
- $thumbnail_full = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'full');
1321
-
1322
- if (($size == "shareaholic-thumbnail") && ($thumbnail_shareaholic[0] !== $thumbnail_full[0])) {
1323
- $featured_img = esc_attr($thumbnail_shareaholic[0]);
1324
- } else {
1325
- if ($size == "shareaholic-thumbnail") {
1326
- $thumbnail_large = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'large');
1327
- } else {
1328
- $thumbnail_large = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), $size);
1329
- }
1330
- $featured_img = esc_attr($thumbnail_large[0]);
1331
- }
1332
- } else {
1333
- return false;
1334
- }
1335
- }
1336
- return $featured_img;
1337
- }
1338
-
1339
-
1340
- /**
1341
- * Return Facebook Access Token
1342
- */
1343
- public static function fetch_fb_access_token() {
1344
- if (ShareaholicUtilities::get_option('facebook_app_id') && ShareaholicUtilities::get_option('facebook_app_secret')) {
1345
- return ShareaholicUtilities::get_option('facebook_app_id') . '|' . ShareaholicUtilities::get_option('facebook_app_secret');
1346
- }
1347
- return false;
1348
- }
1349
-
1350
-
1351
- /**
1352
- * This function grabs the URL of the first image in a given post
1353
- *
1354
- * @return returns `false` or a string of the image src
1355
- */
1356
- public static function post_first_image() {
1357
- global $post;
1358
- $first_img = '';
1359
- if ($post == NULL)
1360
- return false;
1361
- else {
1362
- $output = preg_match_all('/<img.*?src=[\'"](.*?)[\'"].*?>/i', $post->post_content, $matches);
1363
- if (isset($matches[1][0])) {
1364
- // Exclude base64 images; meta tags require full URLs
1365
- if (strpos($matches[1][0], 'data:') === false) {
1366
- $first_img = $matches[1][0];
1367
- }
1368
- } else {
1369
- return false;
1370
- }
1371
- return $first_img;
1372
- }
1373
- }
1374
-
1375
- /**
1376
- * WP Rocket Compatability - Excludes Shareaholic scripts from JS minification, etc
1377
- *
1378
- * @param Array $excluded_external An array of JS hosts
1379
- * @return Array the updated array of hosts
1380
- */
1381
- function rocket_exclude_js($excluded_external) {
1382
- if (defined('WP_ROCKET_VERSION')) {
1383
- $excluded_external[] = 'cdn.shareaholic.net';
1384
- $excluded_external[] = 'k4z6w9b5.stackpathcdn.com';
1385
-
1386
- return $excluded_external;
1387
- }
1388
- }
1389
-
1390
- /*
1391
- * Clears cache created by caching plugins like W3 Total Cache
1392
- *
1393
- */
1394
- public static function clear_cache() {
1395
-
1396
- // Default WordPress
1397
- if (function_exists('wp_cache_flush')) {
1398
- wp_cache_flush();
1399
- }
1400
- // W3 Total Cache plugin
1401
- if (function_exists('w3tc_pgcache_flush')) {
1402
- w3tc_pgcache_flush();
1403
- }
1404
- // WP Super Cache
1405
- if (function_exists('wp_cache_clear_cache')) {
1406
- if (is_multisite()) {
1407
- $blog_id = get_current_blog_id();
1408
- wp_cache_clear_cache($blog_id);
1409
- } else {
1410
- wp_cache_clear_cache();
1411
- }
1412
- }
1413
- // Hyper Cache
1414
- if (function_exists('hyper_cache_flush_all')) {
1415
- hyper_cache_flush_all();
1416
- }
1417
- // WP Fastest Cache
1418
- if (class_exists('WpFastestCache')) {
1419
- $WpFastestCache = new WpFastestCache();
1420
- if (method_exists($WpFastestCache, 'deleteCache')) {
1421
- $WpFastestCache->deleteCache();
1422
- }
1423
- }
1424
- // WPEngine
1425
- if (class_exists('WpeCommon')) {
1426
- if (method_exists('WpeCommon', 'purge_memcached')) {
1427
- WpeCommon::purge_memcached();
1428
- }
1429
- if (method_exists('WpeCommon','clear_maxcdn_cache')) {
1430
- WpeCommon::clear_maxcdn_cache();
1431
- }
1432
- if (method_exists('WpeCommon', 'purge_varnish_cache')) {
1433
- WpeCommon::purge_varnish_cache();
1434
- }
1435
- }
1436
- // Cachify Cache
1437
- if (has_action('cachify_flush_cache')) {
1438
- do_action('cachify_flush_cache');
1439
- }
1440
- // Quick Cache
1441
- if (function_exists('auto_clear_cache')) {
1442
- auto_clear_cache();
1443
- }
1444
- // Zencache
1445
- if (class_exists('zencache')) {
1446
- zencache::clear();
1447
- }
1448
- // CometCache
1449
- if (class_exists('comet_cache')) {
1450
- comet_cache::clear();
1451
- }
1452
- }
1453
-
1454
- /**
1455
- * List below is from Jetpack, with a few custom additions:
1456
- * Source: https://github.com/Automattic/jetpack/blob/master/sync/class.jetpack-sync-defaults.php
1457
- **/
1458
- static $blacklisted_post_types = array(
1459
- 'nav_menu_item',
1460
- 'attachment',
1461
- 'ai1ec_event',
1462
- 'bwg_album',
1463
- 'bwg_gallery',
1464
- 'customize_changeset', // WP built-in post type for Customizer changesets
1465
- 'dn_wp_yt_log',
1466
- 'http',
1467
- 'idx_page',
1468
- 'jetpack_migration',
1469
- 'postman_sent_mail',
1470
- 'rssap-feed',
1471
- 'rssmi_feed_item',
1472
- 'secupress_log_action',
1473
- 'sg_optimizer_jobs',
1474
- 'snitch',
1475
- 'wpephpcompat_jobs',
1476
- 'wprss_feed_item',
1477
- 'wp_automatic',
1478
- 'jp_sitemap_master',
1479
- 'jp_sitemap',
1480
- 'jp_sitemap_index',
1481
- 'jp_img_sitemap',
1482
- 'jp_img_sitemap_index',
1483
- 'jp_vid_sitemap',
1484
- 'jp_vid_sitemap_index',
1485
- );
1486
-
1487
- /**
1488
- * A post just transitioned state. Do something.
1489
- *
1490
- */
1491
- public static function post_transitioned($new_status, $old_status, $post) {
1492
- $post_type = get_post_type($post);
1493
-
1494
- // exit if blacklisted post type
1495
- if ($post_type && in_array($post_type, ShareaholicUtilities::$blacklisted_post_types)) {
1496
- return;
1497
- }
1498
-
1499
- if ($new_status == 'publish') {
1500
- // Post was just published
1501
- ShareaholicUtilities::notify_content_manager_singlepage($post);
1502
- }
1503
- if ($old_status == 'publish' && $new_status != 'publish') {
1504
- // Notify CM that the post is no longer public
1505
- ShareaholicUtilities::notify_content_manager_singlepage($post);
1506
- }
1507
- }
1508
-
1509
-
1510
- /**
1511
- * Server Connectivity check
1512
- *
1513
- */
1514
- public static function connectivity_check() {
1515
- $health_check_url = Shareaholic::API_URL . "/haproxy_health_check";
1516
- $response = ShareaholicCurl::get($health_check_url);
1517
- if(is_array($response) && array_key_exists('body', $response)) {
1518
- $response_code = wp_remote_retrieve_response_code($response);
1519
- if ($response_code == "200"){
1520
- return "SUCCESS";
1521
- } else {
1522
- return "FAIL";
1523
- }
1524
- } else {
1525
- return "FAIL";
1526
- }
1527
- }
1528
-
1529
- /**
1530
- * Facebook Auth Token check
1531
- *
1532
- */
1533
- public static function facebook_auth_check() {
1534
- if (ShareaholicUtilities::fetch_fb_access_token() === false) {
1535
- ShareaholicUtilities::update_options(array('facebook_auth_check' => "FAIL"));
1536
- return "FAIL";
1537
- }
1538
-
1539
- $health_check_url = "https://graph.facebook.com/?fields=engagement&id=https://www.google.com/&access_token=" . ShareaholicUtilities::fetch_fb_access_token();
1540
-
1541
- $response = ShareaholicCurl::get($health_check_url);
1542
-
1543
- if(is_array($response) && array_key_exists('body', $response)) {
1544
- $response_code = wp_remote_retrieve_response_code($response);
1545
- if ($response_code == "200"){
1546
- ShareaholicUtilities::update_options(array('facebook_auth_check' => "SUCCESS"));
1547
- return "SUCCESS";
1548
- } else {
1549
- ShareaholicUtilities::update_options(array('facebook_auth_check' => "FAIL"));
1550
- return "FAIL";
1551
- }
1552
- } else {
1553
- return "FAIL";
1554
- }
1555
- }
1556
-
1557
- /**
1558
- * Share Counts API Connectivity check
1559
- *
1560
- */
1561
- public static function share_counts_api_connectivity_check() {
1562
-
1563
- // if we already checked and it is successful, then do not call the API again
1564
- $share_counts_connect_check = self::get_option('share_counts_connect_check');
1565
- if (isset($share_counts_connect_check) && $share_counts_connect_check == 'SUCCESS') {
1566
- return $share_counts_connect_check;
1567
- }
1568
-
1569
- $services_config = ShareaholicSeqShareCount::get_services_config();
1570
- $services = array_keys($services_config);
1571
- $param_string = implode('&services[]=', $services);
1572
- $share_counts_api_url = admin_url('admin-ajax.php') . '?action=shareaholic_share_counts_api&url=https%3A%2F%2Fwww.google.com%2F&services[]=' . $param_string;
1573
- $cache_key = 'share_counts_api_connectivity_check';
1574
-
1575
- $response = get_transient($cache_key);
1576
- if (!$response) {
1577
- $response = ShareaholicCurl::get($share_counts_api_url, array(), '', true);
1578
- }
1579
-
1580
- $response_status = self::get_share_counts_api_status($response);
1581
- // if this was the first time we are doing this and it failed, disable
1582
- // the share counts API
1583
- if (empty($share_counts_connect_check) && $response_status == 'FAIL') {
1584
- self::update_options(array('disable_internal_share_counts_api' => 'on'));
1585
- }
1586
-
1587
- if ($response_status == 'SUCCESS') {
1588
- set_transient( $cache_key, $response, SHARE_COUNTS_CHECK_CACHE_LENGTH );
1589
- }
1590
-
1591
- self::update_options(array('share_counts_connect_check' => $response_status));
1592
- return $response_status;
1593
- }
1594
-
1595
- /**
1596
- * Check the share counts API for empty response or missing services
1597
- */
1598
- public static function get_share_counts_api_status($response) {
1599
- if (!$response || !isset($response['body']) || !is_array($response['body']) || !isset($response['body']['data'])) {
1600
- return 'FAIL';
1601
- }
1602
-
1603
- // Did it return at least 4 services?
1604
- $has_majority_services = count(array_keys($response['body']['data'])) >= 4 ? true : false;
1605
- $has_important_services = true;
1606
- // Does it have counts for linkedin, pinterest?
1607
- foreach (array('facebook', 'pinterest') as $service) {
1608
- if (!isset($response['body']['data'][$service]) || !is_numeric($response['body']['data'][$service])) {
1609
- $has_important_services = false;
1610
- }
1611
- }
1612
-
1613
- if (!$has_majority_services || !$has_important_services) {
1614
- return 'FAIL';
1615
- }
1616
-
1617
- return 'SUCCESS';
1618
- }
1619
-
1620
-
1621
- /**
1622
- * Call the content manager for a post before it is trashed
1623
- *
1624
- * We do this because permalink changes on being trashed
1625
- * and so we tell CM that the old permalink is no longer valid
1626
- *
1627
- */
1628
- public static function before_post_is_trashed($post_id) {
1629
-
1630
- $post_type = get_post_type($post_id);
1631
-
1632
- // exit if blacklisted post type
1633
- if ($post_type && in_array($post_type, ShareaholicUtilities::$blacklisted_post_types)) {
1634
- return;
1635
- }
1636
-
1637
- ShareaholicUtilities::notify_content_manager_singlepage(get_post($post_id), 'trash');
1638
- }
1639
-
1640
-
1641
- /**
1642
- * Call the content manager for a post before it is updated
1643
- *
1644
- * We do this because a user may change their permalink
1645
- * and so we tell CM that the old permalink is no longer valid
1646
- *
1647
- */
1648
- public static function before_post_is_updated($post_id) {
1649
-
1650
- $post_type = get_post_type($post_id);
1651
-
1652
- // exit if blacklisted post type
1653
- if ($post_type && in_array($post_type, ShareaholicUtilities::$blacklisted_post_types)) {
1654
- return;
1655
- }
1656
-
1657
- ShareaholicUtilities::notify_content_manager_singlepage(get_post($post_id));
1658
- }
1659
-
1660
- public static function user_info() {
1661
- $user_info = array();
1662
-
1663
- if (function_exists('wp_get_current_user')) {
1664
-
1665
- $current_user = wp_get_current_user();
1666
-
1667
- if ( !($current_user instanceof WP_User) || !is_user_logged_in()) {
1668
- return array();
1669
- }
1670
-
1671
- $user_caps = $current_user->get_role_caps();
1672
-
1673
- $caps = array('switch_themes', 'edit_themes', 'activate_plugins',
1674
- 'edit_plugins', 'manage_options', 'unfiltered_html', 'edit_dashboard',
1675
- 'update_plugins', 'delete_plugins', 'install_plugins', 'update_themes',
1676
- 'install_themes', 'update_core', 'edit_theme_options', 'delete_themes',
1677
- 'administrator'
1678
- );
1679
-
1680
- $user_info = array(
1681
- 'username' => $current_user->user_login,
1682
- 'email' => $current_user->user_email,
1683
- 'roles' => $current_user->roles,
1684
- 'capabilities' => array(),
1685
- 'is_super_admin' => is_super_admin()
1686
- );
1687
-
1688
- foreach($caps as $cap) {
1689
- $user_info['capabilities'][$cap] = isset($user_caps[$cap]) ? $user_caps[$cap] : '';
1690
- }
1691
- }
1692
-
1693
- return $user_info;
1694
- }
1695
-
1696
- /**
1697
- * Shorten a string to a certain character limit
1698
- * If the limit is reached, then return the truncated text
1699
- *
1700
- * @param {String} $text the text to truncate
1701
- * @param {Number} $char_count the max number of characters
1702
- * @return {String} the truncated text
1703
- */
1704
- public static function truncate_text($text, $char_count) {
1705
- $words = preg_split('/\s+/', $text);
1706
- $truncated_text = '';
1707
-
1708
- foreach($words as $word) {
1709
- if (strlen($word) + strlen($truncated_text) >= $char_count) {
1710
- break;
1711
- }
1712
-
1713
- $truncated_text .= ' ' . $word;
1714
- }
1715
-
1716
- return trim($truncated_text);
1717
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1718
  }
5
  * @package shareaholic
6
  */
7
 
8
+ require_once SHAREAHOLIC_PATH . 'curl.php';
9
+ require_once SHAREAHOLIC_PATH . 'six_to_seven.php';
10
+ require_once SHAREAHOLIC_PATH . 'lib/social-share-counts/seq_share_count.php';
11
 
12
  /**
13
  * This class is just a holder for general functions that have
16
  * @package shareaholic
17
  */
18
  class ShareaholicUtilities {
19
+ /**
20
+ * Logs to the PHP error log if plugin's url is set to
21
+ * spreadaholic or the SHAREAHOLIC_DEBUG constant is true.
22
+ *
23
+ * @param mixed $thing anything to be logged, it will be passed to `print_r`
24
+ */
25
+ public static function log( $thing ) {
26
+ if ( preg_match( '/spreadaholic/', Shareaholic::URL ) || SHAREAHOLIC_DEBUG ) {
27
+ error_log( print_r( $thing, true ) );
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Locate and require a template, and extract some variables
33
+ * to be used in that template.
34
+ *
35
+ * @param string $template the name of the template
36
+ * @param array $vars any variables to be extracted into the template
37
+ */
38
+ public static function load_template( $template, $vars = array() ) {
39
+ // you cannot let locate_template to load your template
40
+ // because WP devs made sure you can't pass
41
+ // variables to your template :(
42
+
43
+ $template_path = 'templates/' . $template . '.php';
44
+
45
+ // load it
46
+ extract( $vars );
47
+ require $template_path;
48
+ }
49
+
50
+ /**
51
+ * Just a wrapper around get_option to
52
+ * get the shareaholic settings. If the settings
53
+ * have not been set it will return an array of defaults.
54
+ *
55
+ * @return array
56
+ */
57
+ public static function get_settings() {
58
+ return get_option( 'shareaholic_settings', self::defaults() );
59
+ }
60
+
61
+ public static function reset_settings() {
62
+ $settings = self::get_settings();
63
+ $api_key = self::get_option( 'api_key' );
64
+
65
+ $response = ShareaholicCurl::post(
66
+ Shareaholic::API_URL . '/publisher_tools/' . $api_key . '/reset/',
67
+ $settings,
68
+ 'json'
69
+ );
70
+
71
+ // set the location on/off back to their defaults
72
+ if ( isset( $settings['location_name_ids'] ) && is_array( $settings['location_name_ids'] ) ) {
73
+ self::set_default_location_settings( $settings['location_name_ids'] );
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Returns the defaults we want because PHP does not allow
79
+ * arrays in class constants.
80
+ *
81
+ * @return array
82
+ */
83
+ private static function defaults() {
84
+ return array(
85
+ 'disable_admin_bar_menu' => 'on', // advanced
86
+ 'disable_review_notice' => 'off', // advanced
87
+ 'disable_debug_info' => 'off', // advanced
88
+ 'enable_user_nicename' => 'off', // advanced
89
+ 'disable_internal_share_counts_api' => 'on', // advanced
90
+ 'disable_og_tags' => 'off', // advanced
91
+ 'api_key' => '',
92
+ 'verification_key' => '',
93
+ 'recommendations_display_on_excerpts' => 'on',
94
+ 'share_buttons_display_on_excerpts' => 'on',
95
+ );
96
+ }
97
+
98
+ /**
99
+ * Returns links to add to the plugin options admin page
100
+ *
101
+ * @param array $links
102
+ * @return array
103
+ */
104
+ public static function admin_plugin_action_links( $links ) {
105
+ if ( is_array( $links ) ) {
106
+ $settings_link = '<a href="' . esc_url( admin_url( 'admin.php?page=shareaholic-settings' ) ) . '">' . __( 'Settings', 'shareaholic' ) . '</a>';
107
+ $premium_link = '<a href="https://www.shareaholic.com/plans" target="_blank" rel="noopener noreferrer">' . __( 'Upgrade', 'shareaholic' ) . '</a>';
108
+ $helpdesk_link = '<a href="https://support.shareaholic.com/" target="_blank" rel="noopener noreferrer">' . __( 'Support & Documentation', 'shareaholic' ) . '</a>';
109
+
110
+ array_unshift( $links, $settings_link );
111
+ $links[] = $helpdesk_link;
112
+ $links[] = $premium_link;
113
+ }
114
+
115
+ return $links;
116
+ }
117
+
118
+
119
+ /**
120
+ * Extend the admin bar
121
+ */
122
+
123
+ public static function admin_bar_extended() {
124
+ global $wp_admin_bar;
125
+
126
+ $title = '<span class="ab-icon dashicons dashicons-share-alt" style="padding-top:6px;">' . '<span class="screen-reader-text">' . __( 'Shareaholic', 'shareaholic' ) . '</span></span>';
127
+
128
+ if ( ! current_user_can( 'update_plugins' ) || ! is_admin_bar_showing() || self::get_option( 'disable_admin_bar_menu' ) == 'on' ) {
129
+ return;
130
+ }
131
+
132
+ $wp_admin_bar->add_menu(
133
+ array(
134
+ 'id' => 'wp_shareaholic_adminbar_menu',
135
+ 'title' => $title,
136
+ 'href' => esc_url( admin_url( 'admin.php?page=shareaholic-settings' ) ),
137
+ )
138
+ );
139
+
140
+ if ( ! is_admin() ) {
141
+
142
+ if ( in_array( self::page_type(), array( 'page', 'post' ) ) ) {
143
+ $url_link = esc_url( get_permalink() );
144
+ } else {
145
+ global $wp;
146
+ $url_link = esc_url( trailingslashit( home_url( $wp->request ) ) );
147
+ }
148
+
149
+ $wp_admin_bar->add_menu(
150
+ array(
151
+ 'parent' => 'wp_shareaholic_adminbar_menu',
152
+ 'id' => 'wp_shareaholic_adminbar_submenu-sharecounts',
153
+ 'title' => __( 'Check Share Counts', 'shareaholic' ),
154
+ 'href' => 'https://www.shareaholic.com/sharecounter?url=' . $url_link,
155
+ 'meta' => array( 'target' => '_blank' ),
156
+ )
157
+ );
158
+ }
159
+
160
+ $wp_admin_bar->add_menu(
161
+ array(
162
+ 'parent' => 'wp_shareaholic_adminbar_menu',
163
+ 'id' => 'wp_shareaholic_adminbar_submenu-settings',
164
+ 'title' => __( 'Dashboard', 'shareaholic' ),
165
+ 'href' => admin_url( 'admin.php?page=shareaholic-settings' ),
166
+ )
167
+ );
168
+
169
+ $wp_admin_bar->add_menu(
170
+ array(
171
+ 'parent' => 'wp_shareaholic_adminbar_menu',
172
+ 'id' => 'wp_shareaholic_adminbar_submenu-general',
173
+ 'title' => __( 'Shareaholic.com', 'shareaholic' ),
174
+ 'href' => 'https://www.shareaholic.com/publisher_tools/' . self::get_option( 'api_key' ) . '/websites/edit/?verification_key=' . self::get_option( 'verification_key' ),
175
+ 'meta' => array( 'target' => '_blank' ),
176
+ )
177
+ );
178
+
179
+ $wp_admin_bar->add_menu(
180
+ array(
181
+ 'parent' => 'wp_shareaholic_adminbar_menu',
182
+ 'id' => 'wp_shareaholic_adminbar_submenu-help',
183
+ 'title' => __( 'Support & FAQ', 'shareaholic' ),
184
+ 'href' => 'https://support.shareaholic.com/',
185
+ 'meta' => array( 'target' => '_blank' ),
186
+ )
187
+ );
188
+ }
189
+
190
+ /**
191
+ * Returns whether the user has accepted our terms of service.
192
+ *
193
+ * @return bool
194
+ */
195
+ public static function has_accepted_terms_of_service() {
196
+ return get_option( 'shareaholic_has_accepted_tos' );
197
+ }
198
+
199
+ /**
200
+ * Accepts the terms of service.
201
+ */
202
+ public static function accept_terms_of_service() {
203
+ update_option( 'shareaholic_has_accepted_tos', true );
204
+
205
+ self::log_event( 'AcceptedToS' );
206
+
207
+ echo '{}';
208
+
209
+ die();
210
+ }
211
+
212
+ /**
213
+ * Wrapper for WordPress's get_option
214
+ *
215
+ * @param string $option
216
+ *
217
+ * @return mixed
218
+ */
219
+ public static function get_option( $option ) {
220
+ $settings = self::get_settings();
221
+ return ( isset( $settings[ $option ] ) ? $settings[ $option ] : array() );
222
+ }
223
+
224
+ /**
225
+ * Wrapper for WordPress's update_option
226
+ *
227
+ * @param array $array an array of options to update
228
+ * @return bool
229
+ */
230
+ public static function update_options( $array ) {
231
+ $old_settings = self::get_settings();
232
+ $new_settings = self::array_merge_recursive_distinct( $old_settings, $array );
233
+ update_option( 'shareaholic_settings', $new_settings );
234
+ }
235
+
236
+ /**
237
+ * Return the current version.
238
+ *
239
+ * @return string that looks like a number
240
+ */
241
+ public static function get_version() {
242
+ return self::get_option( 'version' ) ? self::get_option( 'version' ) : get_option( 'SHRSBvNUM' );
243
+ }
244
+
245
+ /**
246
+ * Return host domain of WordPress install
247
+ *
248
+ * @return string
249
+ */
250
+ public static function get_host() {
251
+ $parse = parse_url( get_bloginfo( 'url' ) );
252
+ return $parse['host'];
253
+ }
254
+
255
+ /**
256
+ * Set the current version, how simple.
257
+ *
258
+ * @param string $version the version you want to set
259
+ */
260
+ public static function set_version( $version ) {
261
+ self::update_options( array( 'version' => $version ) );
262
+ }
263
+
264
+ /**
265
+ * Determines if the first argument version is less than the second
266
+ * argument version. A version can be up four levels, e.g. 1.1.1.1.
267
+ * Any versions not supplied will be zeroed.
268
+ *
269
+ * @param string $version
270
+ * @param string $comparer
271
+ * @return bool
272
+ */
273
+ public static function version_less_than( $version, $comparer ) {
274
+ $version_array = explode( '.', $version );
275
+ $comparer_array = explode( '.', $comparer );
276
+
277
+ for ( $i = 0; $i <= 3; $i++ ) {
278
+ // zero out unset numbers
279
+ if ( ! isset( $version_array[ $i ] ) ) {
280
+ $version_array[ $i ] = 0; }
281
+ if ( ! isset( $comparer_array[ $i ] ) ) {
282
+ $comparer_array[ $i ] = 0; }
283
+
284
+ if ( $version_array[ $i ] < $comparer_array[ $i ] ) {
285
+ return true;
286
+ }
287
+ }
288
+ return false;
289
+ }
290
+
291
+ /**
292
+ * Determines if the first argument version is less than or equal to the second
293
+ * argument version. A version can be up four levels, e.g. 1.1.1.1.
294
+ * Any versions not supplied will be zeroed.
295
+ *
296
+ * @param string $version
297
+ * @param string $comparer
298
+ * @return bool
299
+ */
300
+ public static function version_less_than_or_equal_to( $version, $comparer ) {
301
+ $version_array = explode( '.', $version );
302
+ $comparer_array = explode( '.', $comparer );
303
+
304
+ if ( $version == $comparer || self::version_less_than( $version, $comparer ) ) {
305
+ return true;
306
+ }
307
+
308
+ return false;
309
+ }
310
+
311
+ /**
312
+ * Determines if the first argument version is greater than the second
313
+ * argument version. A version can be up four levels, e.g. 1.1.1.1.
314
+ * Any versions not supplied will be zeroed.
315
+ *
316
+ * @param string $version
317
+ * @param string $comparer
318
+ * @return bool
319
+ */
320
+ public static function version_greater_than( $version, $comparer ) {
321
+ $version_array = explode( '.', $version );
322
+ $comparer_array = explode( '.', $comparer );
323
+
324
+ for ( $i = 0; $i <= 3; $i++ ) {
325
+ // zero out unset numbers
326
+ if ( ! isset( $version_array[ $i ] ) ) {
327
+ $version_array[ $i ] = 0; }
328
+ if ( ! isset( $comparer_array[ $i ] ) ) {
329
+ $comparer_array[ $i ] = 0; }
330
+
331
+ if ( $version_array[ $i ] > $comparer_array[ $i ] ) {
332
+ return true;
333
+ } elseif ( $version_array[ $i ] < $comparer_array[ $i ] ) {
334
+ return false;
335
+ }
336
+ }
337
+ return false;
338
+ }
339
+
340
+ /**
341
+ * Determines if the first argument version is greater than or equal to the second
342
+ * argument version. A version can be up four levels, e.g. 1.1.1.1.
343
+ * Any versions not supplied will be zeroed.
344
+ *
345
+ * @param string $version
346
+ * @param string $comparer
347
+ * @return bool
348
+ */
349
+ public static function version_greater_than_or_equal_to( $version, $comparer ) {
350
+ $version_array = explode( '.', $version );
351
+ $comparer_array = explode( '.', $comparer );
352
+
353
+ if ( $version == $comparer || self::version_greater_than( $version, $comparer ) ) {
354
+ return true;
355
+ }
356
+
357
+ return false;
358
+ }
359
+
360
+ /**
361
+ * This is the function that will perform the update.
362
+ */
363
+ public static function perform_update() {
364
+
365
+ // Set plugin defaults, if not already set
366
+ $settings = self::get_settings();
367
+
368
+ if ( empty( $settings['share_buttons_display_on_excerpts'] ) || ! isset( $settings['share_buttons_display_on_excerpts'] ) ) {
369
+ self::update_options( array( 'share_buttons_display_on_excerpts' => 'on' ) );
370
+ }
371
+ if ( empty( $settings['recommendations_display_on_excerpts'] ) || ! isset( $settings['recommendations_display_on_excerpts'] ) ) {
372
+ self::update_options( array( 'recommendations_display_on_excerpts' => 'on' ) );
373
+ }
374
+
375
+ if ( ! self::is_locked( 'perform_update' ) ) {
376
+ self::set_lock( 'perform_update' );
377
+
378
+ // Upgrade v6 users
379
+ if ( self::get_version() && intval( self::get_version() ) <= 6 ) {
380
+ ShareaholicSixToSeven::update();
381
+ }
382
+
383
+ // Activate Shareaholic Cron job
384
+ ShareaholicCron::activate();
385
+
386
+ // Clear site cache
387
+ self::clear_cache();
388
+
389
+ // add other things that need to run on version change here
390
+
391
+ self::unlock( 'perform_update' );
392
+ }
393
+ }
394
+
395
+ /**
396
+ * Return the type of page we're on as a string
397
+ * to use for the location in the JS
398
+ *
399
+ * @return string
400
+ */
401
+ public static function page_type() {
402
+ if ( is_front_page() || is_home() ) {
403
+ return 'index';
404
+ } elseif ( is_page() ) {
405
+ return 'page';
406
+ } elseif ( is_single() ) {
407
+ return 'post';
408
+ } elseif ( is_category() || is_author() || is_tag() || is_date() || is_search() ) {
409
+ return 'category';
410
+ }
411
+ }
412
+
413
  /**
414
  * Returns a base64 URL for the svg for use in the menu
415
  *
416
  * @param bool $base64 Whether or not to return base64'd output.
417
  * @return string
418
  */
419
+ public static function get_icon_svg( $base64 = true ) {
420
  $svg = '<svg id="svg2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.51 21.49"><defs><style>.cls-1{fill:#92ce23;}.cls-2{fill:#3c9c6a;}</style></defs><title>logo</title><path id="path14" class="cls-1" d="M18.8,2.68H8.73V12.76H18.8ZM7.27,15.44a1.15,1.15,0,0,1-.86-.37,1.19,1.19,0,0,1-.35-.85v-13A1.21,1.21,0,0,1,7.27,0h13a1.21,1.21,0,0,1,1.21,1.21v13a1.21,1.21,0,0,1-1.21,1.22h-13"/><path id="path16" class="cls-2" d="M12.76,8.72H2.68V18.8H12.76ZM1.21,21.49a1.23,1.23,0,0,1-.86-.35A1.25,1.25,0,0,1,0,20.28v-13A1.21,1.21,0,0,1,1.21,6h13a1.21,1.21,0,0,1,1.21,1.21v13a1.22,1.22,0,0,1-1.21,1.21h-13"/><path id="path18" class="cls-1" d="M18.8,12.76H6.06v1.46a1.19,1.19,0,0,0,.35.85,1.15,1.15,0,0,0,.86.37h13a1.21,1.21,0,0,0,1.21-1.22V12.76H18.8"/></svg>';
421
 
422
+ if ( $base64 ) {
423
+ return 'data:image/svg+xml;base64,' . base64_encode( $svg );
424
  }
425
  return $svg;
426
  }
427
 
428
+ /**
429
+ * Returns the appropriate asset path for environment
430
+ *
431
+ * @param string $asset
432
+ * @return string
433
+ */
434
+ public static function asset_url( $asset = null ) {
435
+ $env = self::get_env();
436
+ if ( $env === 'development' ) {
437
+ return 'http://spreadaholic.com:8080/' . $asset;
438
+ } elseif ( $env === 'staging' ) {
439
+ return '//d2062rwknz205x.cloudfront.net/' . $asset;
440
+ } else {
441
+ return '//cdn.shareaholic.net/' . $asset;
442
+ }
443
+ }
444
+
445
+ public static function get_env() {
446
+ if ( preg_match( '/spreadaholic/', Shareaholic::URL ) ) {
447
+ return 'development';
448
+ } elseif ( preg_match( '/stageaholic/', Shareaholic::URL ) ) {
449
+ return 'staging';
450
+ } else {
451
+ return 'production';
452
+ }
453
+ }
454
+
455
+ /**
456
+ * Returns the appropriate asset path for environment - admin
457
+ *
458
+ * @param string $asset
459
+ * @return string
460
+ */
461
+ public static function asset_url_admin( $asset = null ) {
462
+ if ( preg_match( '/spreadaholic/', Shareaholic::URL ) ) {
463
+ return 'http://spreadaholic.com:8080/' . $asset;
464
+ } elseif ( preg_match( '/stageaholic/', Shareaholic::URL ) ) {
465
+ return 'https://d2062rwknz205x.cloudfront.net/' . $asset;
466
+ } else {
467
+ return 'https://cdn.shareaholic.net/' . $asset;
468
+ }
469
+ }
470
+
471
+ /**
472
+ * Checks whether the api key has been verified
473
+ * using the rails endpoint. Once the key has
474
+ * been verified, we store that away so that we
475
+ * don't have to check again.
476
+ *
477
+ * @return bool
478
+ */
479
+ public static function api_key_verified() {
480
+ $settings = self::get_settings();
481
+ if ( isset( $settings['api_key_verified'] ) && $settings['api_key_verified'] ) {
482
+ return true;
483
+ }
484
+
485
+ $api_key = $settings['api_key'];
486
+ if ( ! $api_key ) {
487
+ return false;
488
+ }
489
+
490
+ $response = ShareaholicCurl::get( Shareaholic::API_URL . '/publisher_tools/' . $api_key . '/verified' );
491
+ $result = $response['body'];
492
+
493
+ if ( $result == 'true' ) {
494
+ self::update_options(
495
+ array(
496
+ 'api_key_verified' => true,
497
+ )
498
+ );
499
+ }
500
+ }
501
+
502
+ /**
503
+ * A wrapper function to specificaly update the location name ids
504
+ * because this is such a common function
505
+ *
506
+ * @todo Determine whether needed anymore
507
+ *
508
+ * @param array $array an array of location names to location ids
509
+ * @return bool
510
+ */
511
+ public static function update_location_name_ids( $array ) {
512
+ $settings = self::get_settings();
513
+ $location_name_ids = ( isset( $settings['location_name_ids'] ) ? $settings['location_name_ids'] : array() );
514
+ $merge = array_merge( $location_name_ids, $array );
515
+ $settings['location_name_ids'] = $merge;
516
+
517
+ update_option( 'shareaholic_settings', $settings );
518
+ }
519
+
520
+
521
+ /**
522
+ *
523
+ * Loads the locations names and their respective ids for an api key
524
+ * and sets them in the shareaholic settings.'
525
+ *
526
+ * @param string $api_key
527
+ */
528
+ public static function get_new_location_name_ids( $api_key ) {
529
+ $response = ShareaholicCurl::get( Shareaholic::API_URL . "/publisher_tools/{$api_key}.json" );
530
+
531
+ if ( is_array( $response ) && array_key_exists( 'body', $response ) ) {
532
+ $response_code = wp_remote_retrieve_response_code( $response );
533
+ if ( $response_code == '404' ) {
534
+ delete_option( 'shareaholic_settings' );
535
+ self::get_or_create_api_key();
536
+ }
537
+ }
538
+
539
+ $publisher_configuration = $response['body'];
540
+ $result = array();
541
+
542
+ if ( $publisher_configuration && is_array( $publisher_configuration ) ) {
543
+ foreach ( array( 'share_buttons', 'recommendations' ) as $app ) {
544
+ foreach ( $publisher_configuration['apps'][ $app ]['locations'] as $id => $location ) {
545
+ $result[ $app ][ $location['name'] ] = $id;
546
+ }
547
+ }
548
+
549
+ self::update_location_name_ids( $result );
550
+ } else {
551
+ self::load_template( 'failed_to_create_api_key_modal' );
552
+ self::log_bad_response( 'FailedToFetchPubConfig', $response );
553
+ }
554
+ }
555
+
556
+ /**
557
+ * A general function to underscore a CamelCased string.
558
+ *
559
+ * @param string $string
560
+ * @return string
561
+ */
562
+ public static function underscore( $string ) {
563
+ return strtolower( preg_replace( '/([a-z])([A-Z])', '$1_$2', $string ) );
564
+ }
565
+
566
+ /**
567
+ * Passed an array of location names mapped to ids per app.
568
+ *
569
+ * @param array $array
570
+ */
571
+ public static function turn_on_locations( $array, $turn_off_array = array() ) {
572
+
573
+ if ( is_array( $array ) ) {
574
+ foreach ( $array as $app => $ids ) {
575
+ if ( is_array( $ids ) ) {
576
+ foreach ( $ids as $name => $id ) {
577
+ self::update_options(
578
+ array(
579
+ $app => array( $name => 'on' ),
580
+ )
581
+ );
582
+ }
583
+ }
584
+ }
585
+ }
586
+
587
+ if ( is_array( $turn_off_array ) ) {
588
+ foreach ( $turn_off_array as $app => $ids ) {
589
+ if ( is_array( $ids ) ) {
590
+ foreach ( $ids as $name => $id ) {
591
+ self::update_options(
592
+ array(
593
+ $app => array( $name => 'off' ),
594
+ )
595
+ );
596
+ }
597
+ }
598
+ }
599
+ }
600
+ }
601
+
602
+ /**
603
+ * Give back only the request keys from an array. The first
604
+ * argument is the array to be sliced, and after that it can
605
+ * either be a variable-length list of keys or one array of keys.
606
+ *
607
+ * @param array $array
608
+ * @param Mixed ... can be either one array or many keys
609
+ * @return array
610
+ */
611
+ public static function associative_array_slice( $array ) {
612
+ $keys = array_slice( func_get_args(), 1 );
613
+ if ( func_num_args() == 2 && is_array( $keys[0] ) ) {
614
+ $keys = $keys[0];
615
+ }
616
+
617
+ $result = array();
618
+
619
+ foreach ( $keys as $key ) {
620
+ $result[ $key ] = $array[ $key ];
621
+ }
622
+
623
+ return $result;
624
+ }
625
+
626
+ /**
627
+ * Sets a lock (mutex)
628
+ *
629
+ * @param string $name
630
+ */
631
+ public static function set_lock( $name ) {
632
+ update_option( 'shareaholic_' . $name, true );
633
+ }
634
+
635
+ /**
636
+ * Checks if an action is locked.
637
+ *
638
+ * @param string $name
639
+ * @return bool
640
+ */
641
+ public static function is_locked( $name ) {
642
+ return get_option( 'shareaholic_' . $name, false );
643
+ }
644
+
645
+ /**
646
+ * Unlocks a mutex
647
+ *
648
+ * @param string $name
649
+ */
650
+ public static function unlock( $name ) {
651
+ delete_option( 'shareaholic_' . $name );
652
+ }
653
+
654
+ /**
655
+ * Clears all mutex
656
+ */
657
+ public static function delete_mutex() {
658
+ delete_option( 'shareaholic_get_or_create_api_key' );
659
+ delete_option( 'shareaholic_perform_update' );
660
+ }
661
+
662
+ /**
663
+ * Checks whether a plugin is active
664
+ *
665
+ * @param string $name
666
+ */
667
+ public static function check_for_other_plugin() {
668
+ if ( is_plugin_active( 'shareaholic/shareaholic.php' ) ) {
669
+ deactivate_plugins( 'sexybookmarks/shareaholic.php' );
670
+ }
671
+ if ( is_plugin_active( 'shareaholic/sexy-bookmarks.php' ) ) {
672
+ deactivate_plugins( 'sexybookmarks/sexy-bookmarks.php' );
673
+ }
674
+ }
675
+
676
+ /**
677
+ * Returns Stats
678
+ */
679
+ public static function get_stats() {
680
+ global $wpdb;
681
+
682
+ $stats = array(
683
+ 'posts_total' => $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts where post_type = 'post' AND post_status = 'publish'" ),
684
+ 'pages_total' => $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts where post_type = 'page' AND post_status = 'publish'" ),
685
+ 'users_total' => $wpdb->get_var( "SELECT count(ID) FROM $wpdb->users" ),
686
+ );
687
+
688
+ return ( isset( $stats ) ? $stats : array() );
689
+ }
690
+
691
+ /**
692
+ * Returns Active Plugins
693
+ */
694
+ public static function get_active_plugins() {
695
+ $active_plugins = (array) get_option( 'active_plugins', array() );
696
+
697
+ if ( is_multisite() ) {
698
+ $network_plugins = (array) get_site_option( 'active_sitewide_plugins', array() );
699
+ $active_plugins = array_merge( $active_plugins, array_keys( $network_plugins ) );
700
+ }
701
+
702
+ return ( isset( $active_plugins ) ? array_values( array_unique( $active_plugins ) ) : array() );
703
+ }
704
+
705
+ /**
706
+ * Returns Local Share Count Proxy Status
707
+ */
708
+ public static function get_internal_share_counts_api_status() {
709
+ if ( self::get_option( 'disable_internal_share_counts_api' ) == null || self::get_option( 'disable_internal_share_counts_api' ) == 'off' ) {
710
+ $server_side_share_count_status = 'on';
711
+ } else {
712
+ $server_side_share_count_status = 'off';
713
+ }
714
+ return $server_side_share_count_status;
715
+ }
716
+
717
+ /**
718
+ * Returns the api key or creates a new one.
719
+ *
720
+ * It first checks the database. If the key is not
721
+ * found (or is an empty string or empty array or
722
+ * anything that evaluates to false) then we will
723
+ * attempt to make a new one by POSTing to the
724
+ * anonymous configuration endpoint. That action
725
+ * is wrapped in a mutex to keep two requests from
726
+ * trying to create new api keys at the same time.
727
+ *
728
+ * Note: this function is called on every pageload.
729
+ * So please keep it as fast as possible.
730
+ *
731
+ * @return string
732
+ */
733
+ public static function get_or_create_api_key() {
734
+ $api_key = self::get_option( 'api_key' );
735
+
736
+ // ensure api key set is atleast 30 characters
737
+ if ( $api_key && ( strlen( $api_key ) > 30 ) ) {
738
+ return $api_key;
739
+ }
740
+
741
+ if ( ! self::is_locked( 'get_or_create_api_key' ) ) {
742
+ self::set_lock( 'get_or_create_api_key' );
743
+
744
+ $old_settings = self::get_settings();
745
+
746
+ delete_option( 'shareaholic_settings' );
747
+
748
+ // restore any old settings that should be preserved between resets
749
+ if ( isset( $old_settings['share_counts_connect_check'] ) ) {
750
+ self::update_options(
751
+ array(
752
+ 'share_counts_connect_check' => $old_settings['share_counts_connect_check'],
753
+ )
754
+ );
755
+ }
756
+
757
+ $verification_key = md5( mt_rand() );
758
+
759
+ $turned_on_share_buttons_locations = self::get_default_sb_on_locations();
760
+ $turned_off_share_buttons_locations = self::get_default_sb_off_locations();
761
+
762
+ $turned_on_recommendations_locations = self::get_default_rec_on_locations();
763
+ $turned_off_recommendations_locations = self::get_default_rec_off_locations();
764
+
765
+ $share_buttons_attributes = array_merge( $turned_on_share_buttons_locations, $turned_off_share_buttons_locations );
766
+ $recommendations_attributes = array_merge( $turned_on_recommendations_locations, $turned_off_recommendations_locations );
767
+ $data = array(
768
+ 'configuration_publisher' => array(
769
+ 'verification_key' => $verification_key,
770
+ 'site_name' => self::site_name(),
771
+ 'domain' => self::site_url(),
772
+ 'platform_id' => '12',
773
+ 'language_id' => self::site_language(),
774
+ 'shortener' => 'shrlc',
775
+ 'recommendations_attributes' => array(
776
+ 'locations_attributes' => $recommendations_attributes,
777
+ ),
778
+ 'share_buttons_attributes' => array(
779
+ 'locations_attributes' => $share_buttons_attributes,
780
+ ),
781
+ ),
782
+ );
783
+
784
+ $response = ShareaholicCurl::post(
785
+ Shareaholic::API_URL . '/publisher_tools/anonymous',
786
+ $data,
787
+ 'json'
788
+ );
789
+
790
+ if ( $response && preg_match( '/20*/', $response['response']['code'] ) ) {
791
+ self::update_options(
792
+ array(
793
+ 'api_key' => $response['body']['api_key'],
794
+ 'verification_key' => $verification_key,
795
+ 'location_name_ids' => $response['body']['location_name_ids'],
796
+ )
797
+ );
798
+
799
+ if ( isset( $response['body']['location_name_ids'] ) && is_array( $response['body']['location_name_ids'] ) ) {
800
+ self::set_default_location_settings( $response['body']['location_name_ids'] );
801
+
802
+ ShareaholicAdmin::welcome_email();
803
+ self::clear_cache();
804
+ } else {
805
+ self::log_bad_response( 'FailedToCreateApiKey', $response );
806
+ }
807
+ } else {
808
+ // add_action('admin_notices', array('ShareaholicAdmin', 'failed_to_create_api_key'));
809
+ self::log_bad_response( 'FailedToCreateApiKey', $response );
810
+ }
811
+
812
+ self::unlock( 'get_or_create_api_key' );
813
+ } else {
814
+ usleep( 100000 );
815
+ self::get_or_create_api_key();
816
+ }
817
+ }
818
+
819
+
820
+
821
+
822
+ /**
823
+ * Get share buttons locations that should be turned on by default
824
+ *
825
+ * @return {Array}
826
+ */
827
+ public static function get_default_sb_on_locations() {
828
+ return array(
829
+ array(
830
+ 'name' => 'post_below_content',
831
+ 'counter' => 'badge-counter',
832
+ ),
833
+ array(
834
+ 'name' => 'page_below_content',
835
+ 'counter' => 'badge-counter',
836
+ ),
837
+ array(
838
+ 'name' => 'index_below_content',
839
+ 'counter' => 'badge-counter',
840
+ ),
841
+ array(
842
+ 'name' => 'category_below_content',
843
+ 'counter' => 'badge-counter',
844
+ ),
845
+ );
846
+ }
847
+
848
+ /**
849
+ * Get share buttons locations that should be turned off by default
850
+ *
851
+ * @return {Array}
852
+ */
853
+ public static function get_default_sb_off_locations() {
854
+ return array(
855
+ array(
856
+ 'name' => 'post_above_content',
857
+ 'counter' => 'badge-counter',
858
+ ),
859
+ array(
860
+ 'name' => 'page_above_content',
861
+ 'counter' => 'badge-counter',
862
+ ),
863
+ array(
864
+ 'name' => 'index_above_content',
865
+ 'counter' => 'badge-counter',
866
+ ),
867
+ array(
868
+ 'name' => 'category_above_content',
869
+ 'counter' => 'badge-counter',
870
+ ),
871
+ );
872
+ }
873
+
874
+ /**
875
+ * Get recommendations locations that should be turned on by default
876
+ *
877
+ * @return {Array}
878
+ */
879
+ public static function get_default_rec_on_locations() {
880
+ return array(
881
+ array( 'name' => 'post_below_content' ),
882
+ array( 'name' => 'page_below_content' ),
883
+ );
884
+ }
885
+
886
+
887
+ /**
888
+ * Get recommendations locations that should be turned off by default
889
+ *
890
+ * @return {Array}
891
+ */
892
+ public static function get_default_rec_off_locations() {
893
+ return array(
894
+ array( 'name' => 'index_below_content' ),
895
+ array( 'name' => 'category_below_content' ),
896
+ );
897
+ }
898
+
899
+ /**
900
+ * Given an object, set the default on/off locations
901
+ * for share buttons and recommendations
902
+ */
903
+ public static function set_default_location_settings( $location_name_ids ) {
904
+ $turned_on_share_buttons_locations = self::get_default_sb_on_locations();
905
+ $turned_off_share_buttons_locations = self::get_default_sb_off_locations();
906
+
907
+ $turned_on_recommendations_locations = self::get_default_rec_on_locations();
908
+ $turned_off_recommendations_locations = self::get_default_rec_off_locations();
909
+
910
+ $turned_on_share_buttons_keys = array();
911
+ foreach ( $turned_on_share_buttons_locations as $loc ) {
912
+ $turned_on_share_buttons_keys[] = $loc['name'];
913
+ }
914
+
915
+ $turned_on_recommendations_keys = array();
916
+ foreach ( $turned_on_recommendations_locations as $loc ) {
917
+ $turned_on_recommendations_keys[] = $loc['name'];
918
+ }
919
+
920
+ $turned_off_share_buttons_keys = array();
921
+ foreach ( $turned_off_share_buttons_locations as $loc ) {
922
+ $turned_off_share_buttons_keys[] = $loc['name'];
923
+ }
924
+
925
+ $turned_off_recommendations_keys = array();
926
+ foreach ( $turned_off_recommendations_locations as $loc ) {
927
+ $turned_off_recommendations_keys[] = $loc['name'];
928
+ }
929
+
930
+ $turn_on = array(
931
+ 'share_buttons' => self::associative_array_slice( $location_name_ids['share_buttons'], $turned_on_share_buttons_keys ),
932
+ 'recommendations' => self::associative_array_slice( $location_name_ids['recommendations'], $turned_on_recommendations_keys ),
933
+ );
934
+
935
+ $turn_off = array(
936
+ 'share_buttons' => self::associative_array_slice( $location_name_ids['share_buttons'], $turned_off_share_buttons_keys ),
937
+ 'recommendations' => self::associative_array_slice( $location_name_ids['recommendations'], $turned_off_recommendations_keys ),
938
+ );
939
+
940
+ self::turn_on_locations( $turn_on, $turn_off );
941
+ }
942
+
943
+ /**
944
+ * Log reasons for a failure of a response.
945
+ *
946
+ * Checks if the code is not a 20*, the response body
947
+ * is not an array, and whether the response object
948
+ * was false. Sends the appropriate logging message.
949
+ *
950
+ * @param string $name the name of the event to log
951
+ * @param mixed $response the response object
952
+ */
953
+ public static function log_bad_response( $name, $response ) {
954
+ if ( $response && is_array( $response ) && ! preg_match( '/20*/', $response['response']['code'] ) ) {
955
+ self::log_event( $name, array( 'reason' => 'the response was a ' . $response['response']['code'] ) );
956
+ } elseif ( $response && ! is_array( $response ) ) {
957
+ $thing = preg_replace( '/\n/', '', var_export( $response, true ) );
958
+ self::log_event( $name, array( 'reason' => 'the publisher configuration was not an array, it was this ' . $thing ) );
959
+ }
960
+ }
961
+
962
+ /**
963
+ * Returns the site's url stripped of protocol.
964
+ *
965
+ * @return string
966
+ */
967
+ public static function site_url() {
968
+ return preg_replace( '/https?:\/\//', '', site_url() );
969
+ }
970
+
971
+ /**
972
+ * Returns the site's name
973
+ *
974
+ * @return string
975
+ */
976
+ public static function site_name() {
977
+ return get_bloginfo( 'name' ) ? get_bloginfo( 'name' ) : site_url();
978
+ }
979
+
980
+ /**
981
+ * Returns the site's primary locale / language
982
+ *
983
+ * @return string
984
+ */
985
+ public static function site_language() {
986
+ $site_language = strtolower( get_bloginfo( 'language' ) );
987
+
988
+ if ( strpos( $site_language, 'en-' ) !== false ) {
989
+ $language_id = 9; // English
990
+ } elseif ( strpos( $site_language, 'da-' ) !== false ) {
991
+ $language_id = 7; // Danish
992
+ } elseif ( strpos( $site_language, 'de-' ) !== false ) {
993
+ $language_id = 13; // German
994
+ } elseif ( strpos( $site_language, 'es-' ) !== false ) {
995
+ $language_id = 31; // Spanish
996
+ } elseif ( strpos( $site_language, 'fr-' ) !== false ) {
997
+ $language_id = 12; // French
998
+ } elseif ( strpos( $site_language, 'pt-' ) !== false ) {
999
+ $language_id = 25; // Portuguese
1000
+ } elseif ( strpos( $site_language, 'it-' ) !== false ) {
1001
+ $language_id = 18; // Italian
1002
+ } elseif ( strpos( $site_language, 'zh-cn' ) !== false ) {
1003
+ $language_id = 3; // Chinese (Simplified)
1004
+ } elseif ( strpos( $site_language, 'zh-tw' ) !== false ) {
1005
+ $language_id = 4; // Chinese (Traditional)
1006
+ } elseif ( strpos( $site_language, 'ja-' ) !== false ) {
1007
+ $language_id = 19; // Japanese
1008
+ } elseif ( strpos( $site_language, 'ar-' ) !== false ) {
1009
+ $language_id = 1; // Arabic
1010
+ } elseif ( strpos( $site_language, 'sv-' ) !== false ) {
1011
+ $language_id = 32; // Swedish
1012
+ } elseif ( strpos( $site_language, 'tr-' ) !== false ) {
1013
+ $language_id = 34; // Turkish
1014
+ } elseif ( strpos( $site_language, 'el-' ) !== false ) {
1015
+ $language_id = 14; // Greek
1016
+ } elseif ( strpos( $site_language, 'nl-' ) !== false ) {
1017
+ $language_id = 8; // Dutch
1018
+ } elseif ( strpos( $site_language, 'pl-' ) !== false ) {
1019
+ $language_id = 24; // Polish
1020
+ } elseif ( strpos( $site_language, 'ru-' ) !== false ) {
1021
+ $language_id = 27; // Russian
1022
+ } elseif ( strpos( $site_language, 'cs-' ) !== false ) {
1023
+ $language_id = 6; // Czech
1024
+ } else {
1025
+ $language_id = null;
1026
+ }
1027
+ return $language_id;
1028
+ }
1029
+
1030
+ /**
1031
+ * Shockingly the built in PHP array_merge_recursive function is stupid.
1032
+ * this is stolen from the PHP docs and will overwrite existing keys instead
1033
+ * of appending the values.
1034
+ *
1035
+ * http://www.php.net/manual/en/function.array-merge-recursive.php#92195
1036
+ *
1037
+ * @param array $array1
1038
+ * @param array $array2
1039
+ * @return array
1040
+ */
1041
+ public static function array_merge_recursive_distinct( array &$array1, array &$array2 ) {
1042
+ $merged = $array1;
1043
+
1044
+ foreach ( $array2 as $key => &$value ) {
1045
+ if ( is_array( $value ) && isset( $merged [ $key ] ) && is_array( $merged [ $key ] ) ) {
1046
+ if ( empty( $value ) ) {
1047
+ $merged[ $key ] = array();
1048
+ } else {
1049
+ $merged [ $key ] = self::array_merge_recursive_distinct( $merged [ $key ], $value );
1050
+ }
1051
+ } else {
1052
+ $merged [ $key ] = $value;
1053
+ }
1054
+ }
1055
+
1056
+ return $merged;
1057
+ }
1058
+
1059
+ /**
1060
+ * Array casting an object is not recursive, this makes it recursive
1061
+ *
1062
+ * @param object $d
1063
+ *
1064
+ * http://www.if-not-true-then-false.com/2009/php-tip-convert-stdclass-object-to-multidimensional-array-and-convert-multidimensional-array-to-stdclass-object/
1065
+ */
1066
+ public static function object_to_array( $d ) {
1067
+ if ( is_object( $d ) ) {
1068
+ // Gets the properties of the given object
1069
+ // with get_object_vars function
1070
+ $d = get_object_vars( $d );
1071
+ }
1072
+
1073
+ if ( is_array( $d ) ) {
1074
+ /*
1075
+ * Return array converted to object
1076
+ */
1077
+ return array_map( array( 'self', 'object_to_array' ), $d );
1078
+ } else {
1079
+ // Return array
1080
+ return $d;
1081
+ }
1082
+ }
1083
+
1084
+ /**
1085
+ * Wrapper for the Shareaholic Content Manager Single Page worker API
1086
+ *
1087
+ * @param string $post_id
1088
+ */
1089
+ public static function notify_content_manager_singlepage( $post = null, $status = null ) {
1090
+
1091
+ if ( $post == null ) {
1092
+ return;
1093
+ }
1094
+
1095
+ $api_key = self::get_option( 'api_key' );
1096
+
1097
+ if ( self::has_accepted_terms_of_service() && ! empty( $api_key ) ) {
1098
+
1099
+ if ( $status != null ) {
1100
+ $visiblity = $status;
1101
+ } else {
1102
+ $visiblity = $post->post_status;
1103
+ }
1104
+
1105
+ if ( in_array( $post->post_status, array( 'draft', 'pending' ) ) ) {
1106
+ // Get the correct permalink for a draft
1107
+ $my_post = clone $post;
1108
+ $my_post->post_status = 'published';
1109
+ $my_post->post_name = sanitize_title( $my_post->post_name ? $my_post->post_name : $my_post->post_title, $my_post->ID );
1110
+ $post_permalink = get_permalink( $my_post );
1111
+ } else {
1112
+ $post_permalink = get_permalink( $post->ID );
1113
+ }
1114
+
1115
+ if ( $post_permalink != null
1116
+ && ( strpos( $post_permalink, '__trashed' ) == false )
1117
+ && ! in_array( $post->post_status, array( 'auto-draft', 'inherit' ) ) ) {
1118
+ $cm_single_page_job_url = Shareaholic::CM_API_URL . '/jobs/uber_single_page';
1119
+ $payload = array(
1120
+ 'args' => array(
1121
+ $post_permalink,
1122
+ array(
1123
+ 'force' => true,
1124
+ ),
1125
+ ),
1126
+ 'api_key' => self::get_option( 'api_key' ),
1127
+ 'verification_key' => self::get_option( 'verification_key' ),
1128
+ 'admin_ajax_path' => admin_url( 'admin-ajax.php' ),
1129
+ 'wp_version' => Shareaholic::VERSION,
1130
+ 'post_visibility' => $visiblity,
1131
+ );
1132
+ $response = ShareaholicCurl::post( $cm_single_page_job_url, $payload, 'json' );
1133
+ }
1134
+ }
1135
+ }
1136
+
1137
+ /**
1138
+ * Wrapper for the Shareaholic Content Manager Single Domain worker API
1139
+ */
1140
+ public static function notify_content_manager_singledomain() {
1141
+ $domain = get_bloginfo( 'url' );
1142
+ if ( $domain != null ) {
1143
+ $cm_single_domain_job_url = Shareaholic::CM_API_URL . '/jobs/single_domain';
1144
+ $payload = array(
1145
+ 'args' => array(
1146
+ $domain,
1147
+ array(
1148
+ 'force' => true,
1149
+ ),
1150
+ ),
1151
+ 'api_key' => self::get_option( 'api_key' ),
1152
+ 'verification_key' => self::get_option( 'verification_key' ),
1153
+ 'admin_ajax_path' => admin_url( 'admin-ajax.php' ),
1154
+ 'wp_version' => Shareaholic::VERSION,
1155
+ );
1156
+ $response = ShareaholicCurl::post( $cm_single_domain_job_url, $payload, 'json' );
1157
+ }
1158
+ }
1159
+
1160
+ /**
1161
+ * This is a wrapper for the Event API
1162
+ *
1163
+ * @param string $event_name the name of the event
1164
+ * @param array $extra_params any extra data points to be included
1165
+ */
1166
+ public static function log_event( $event_name = 'Default', $extra_params = false ) {
1167
+ $event_metadata = array(
1168
+ 'plugin_version' => Shareaholic::VERSION,
1169
+ 'api_key' => self::get_option( 'api_key' ),
1170
+ 'domain' => get_bloginfo( 'url' ),
1171
+ 'diagnostics' => array(
1172
+ 'php_version' => phpversion(),
1173
+ 'wp_version' => get_bloginfo( 'version' ),
1174
+ 'theme' => get_option( 'template' ),
1175
+ 'multisite' => is_multisite(),
1176
+ ),
1177
+ 'features' => array(
1178
+ 'share_buttons' => self::get_option( 'share_buttons' ),
1179
+ 'recommendations' => self::get_option( 'recommendations' ),
1180
+ ),
1181
+ );
1182
+
1183
+ if ( $extra_params ) {
1184
+ $event_metadata = array_merge( $event_metadata, $extra_params );
1185
+ }
1186
+
1187
+ $event_api_url = Shareaholic::API_URL . '/api/events';
1188
+ $event_params = array(
1189
+ 'name' => 'WordPress:' . $event_name,
1190
+ 'data' => json_encode( $event_metadata ),
1191
+ );
1192
+ $response = ShareaholicCurl::post( $event_api_url, $event_params, '', true, 2 );
1193
+ }
1194
+
1195
+ /**
1196
+ * This is a wrapper for the Heartbeat API
1197
+ */
1198
+ public static function heartbeat() {
1199
+ $data = array(
1200
+ 'platform' => 'wordpress',
1201
+ 'plugin_name' => 'shareaholic',
1202
+ 'plugin_version' => Shareaholic::VERSION,
1203
+ 'api_key' => self::get_option( 'api_key' ),
1204
+ 'verification_key' => self::get_option( 'verification_key' ),
1205
+ 'domain' => preg_replace( '#^https?://#', '', get_bloginfo( 'url' ) ),
1206
+ 'language' => get_bloginfo( 'language' ),
1207
+ 'stats' => self::get_stats(),
1208
+ 'diagnostics' => array(
1209
+ 'tos_status' => self::has_accepted_terms_of_service(),
1210
+ 'shareaholic_server_reachable' => self::connectivity_check(),
1211
+ 'server_side_share_count_api_reachable' => self::share_counts_api_connectivity_check(),
1212
+ 'php_version' => phpversion(),
1213
+ 'wp_version' => get_bloginfo( 'version' ),
1214
+ 'theme' => get_option( 'template' ),
1215
+ 'multisite' => is_multisite(),
1216
+ 'plugins' => array(
1217
+ 'active' => self::get_active_plugins(),
1218
+ ),
1219
+ ),
1220
+ 'endpoints' => array(
1221
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
1222
+ ),
1223
+ 'advanced_settings' => array(
1224
+ 'server_side_share_count_api' => self::get_internal_share_counts_api_status(),
1225
+ 'facebook_access_token' => self::fetch_fb_access_token() === false ? 'no' : 'yes',
1226
+ 'facebook_auth_check' => self::facebook_auth_check(),
1227
+ 'enable_user_nicename' => self::get_option( 'enable_user_nicename' ),
1228
+ 'disable_og_tags' => self::get_option( 'disable_og_tags' ),
1229
+ 'disable_admin_bar_menu' => self::get_option( 'disable_admin_bar_menu' ),
1230
+ 'recommendations_display_on_excerpts' => self::get_option( 'recommendations_display_on_excerpts' ),
1231
+ 'share_buttons_display_on_excerpts' => self::get_option( 'share_buttons_display_on_excerpts' ),
1232
+ ),
1233
+ );
1234
+
1235
+ $heartbeat_api_url = Shareaholic::API_URL . '/api/plugin_heartbeats';
1236
+ $response = ShareaholicCurl::post( $heartbeat_api_url, $data, 'json', true, 2 );
1237
+ }
1238
+
1239
+ /**
1240
+ * Deletes the api key
1241
+ */
1242
+ public static function delete_api_key() {
1243
+ $payload = array(
1244
+ 'site_id' => self::get_option( 'api_key' ),
1245
+ 'verification_key' => self::get_option( 'verification_key' ),
1246
+ );
1247
+
1248
+ $response = ShareaholicCurl::post(
1249
+ Shareaholic::API_URL . '/integrations/plugin/delete',
1250
+ $payload,
1251
+ 'json',
1252
+ true
1253
+ );
1254
+ }
1255
+
1256
+ /**
1257
+ * This loads the locales
1258
+ */
1259
+ public static function localize() {
1260
+ load_plugin_textdomain( 'shareaholic', false, basename( dirname( __FILE__ ) ) . '/languages/' );
1261
+ }
1262
+
1263
+ /**
1264
+ * Function to return a list of permalink keywords
1265
+ *
1266
+ * @return list of keywords for the given permalink in an array
1267
+ */
1268
+ public static function permalink_keywords( $post_id = null ) {
1269
+ global $post;
1270
+ $keywords = '';
1271
+
1272
+ if ( $post_id != null ) {
1273
+ $id = $post_id;
1274
+ } else {
1275
+ $id = $post->ID;
1276
+ }
1277
+
1278
+ // Get post tags
1279
+ $keywords = implode( ', ', wp_get_post_tags( $id, array( 'fields' => 'names' ) ) );
1280
+
1281
+ // Support for "All in One SEO Pack" plugin keywords
1282
+ if ( get_post_meta( $id, '_aioseop_keywords' ) != null ) {
1283
+ $keywords .= ', ' . stripslashes( get_post_meta( $id, '_aioseop_keywords', true ) );
1284
+ }
1285
+
1286
+ // Support for "WordPress SEO by Yoast" plugin keywords
1287
+ if ( get_post_meta( $id, '_yoast_wpseo_focuskw' ) != null ) {
1288
+ $keywords .= ', ' . stripslashes( get_post_meta( $id, '_yoast_wpseo_focuskw', true ) );
1289
+ }
1290
+
1291
+ if ( get_post_meta( $id, '_yoast_wpseo_metakeywords' ) != null ) {
1292
+ $keywords .= ', ' . stripslashes( get_post_meta( $id, '_yoast_wpseo_metakeywords', true ) );
1293
+ }
1294
+
1295
+ // Support for "Add Meta Tags" plugin keywords
1296
+ if ( get_post_meta( $id, '_amt_keywords' ) != null ) {
1297
+ $keywords .= ', ' . stripslashes( get_post_meta( $id, '_amt_keywords', true ) );
1298
+ }
1299
+
1300
+ if ( get_post_meta( $id, '_amt_news_keywords' ) != null ) {
1301
+ $keywords .= ', ' . stripslashes( get_post_meta( $id, '_amt_news_keywords', true ) );
1302
+ }
1303
+
1304
+ // Encode, lowercase & trim appropriately
1305
+ $keywords = self::normalize_keywords( $keywords );
1306
+
1307
+ // Unique keywords
1308
+ $keywords_array = array();
1309
+ $keywords_array = explode( ', ', $keywords );
1310
+ $keywords_array = array_unique( $keywords_array );
1311
+
1312
+ if ( empty( $keywords_array[0] ) ) {
1313
+ return array();
1314
+ } else {
1315
+ return $keywords_array;
1316
+ }
1317
+ }
1318
+
1319
+ /**
1320
+ * Normalizes and cleans up a list of comma separated keywords ie. encode, lowercase & trim appropriately
1321
+ *
1322
+ * @param string $keywords
1323
+ * @return string
1324
+ */
1325
+ public static function normalize_keywords( $keywords ) {
1326
+ return trim( trim( strtolower( trim( htmlspecialchars( htmlspecialchars_decode( $keywords ), ENT_QUOTES ) ) ), ',' ) );
1327
+ }
1328
+
1329
+ /**
1330
+ * Function to return a thumbnail for a given permalink
1331
+ *
1332
+ * @return thumbnail URL
1333
+ */
1334
+ public static function permalink_thumbnail( $post_id = null, $size = 'shareaholic-thumbnail' ) {
1335
+ $thumbnail_src = '';
1336
+
1337
+ // Get Featured Image
1338
+ $thumbnail_src = self::post_featured_image( $size );
1339
+
1340
+ // Get first image included in the post
1341
+ if ( $thumbnail_src == null ) {
1342
+ $thumbnail_src = self::post_first_image( $post_id );
1343
+ }
1344
+
1345
+ if ( $thumbnail_src == null ) {
1346
+ return null;
1347
+ } else {
1348
+ return $thumbnail_src;
1349
+ }
1350
+ }
1351
+
1352
+ /**
1353
+ * This function returns the URL of the featured image for a given post
1354
+ *
1355
+ * @return returns `false` or a string of the image src
1356
+ */
1357
+ public static function post_featured_image( $size = 'shareaholic-thumbnail' ) {
1358
+ global $post;
1359
+ $featured_img = '';
1360
+ if ( $post == null ) {
1361
+ return false;
1362
+ } else {
1363
+ if ( function_exists( 'has_post_thumbnail' ) && has_post_thumbnail( $post->ID ) ) {
1364
+ $thumbnail_shareaholic = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'shareaholic-thumbnail' );
1365
+ $thumbnail_full = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' );
1366
+
1367
+ if ( ( $size == 'shareaholic-thumbnail' ) && ( $thumbnail_shareaholic[0] !== $thumbnail_full[0] ) ) {
1368
+ $featured_img = esc_attr( $thumbnail_shareaholic[0] );
1369
+ } else {
1370
+ if ( $size == 'shareaholic-thumbnail' ) {
1371
+ $thumbnail_large = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'large' );
1372
+ } else {
1373
+ $thumbnail_large = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), $size );
1374
+ }
1375
+ $featured_img = esc_attr( $thumbnail_large[0] );
1376
+ }
1377
+ } else {
1378
+ return false;
1379
+ }
1380
+ }
1381
+ return $featured_img;
1382
+ }
1383
+
1384
+
1385
+ /**
1386
+ * Return Facebook Access Token
1387
+ */
1388
+ public static function fetch_fb_access_token() {
1389
+ if ( self::get_option( 'facebook_app_id' ) && self::get_option( 'facebook_app_secret' ) ) {
1390
+ return self::get_option( 'facebook_app_id' ) . '|' . self::get_option( 'facebook_app_secret' );
1391
+ }
1392
+ return false;
1393
+ }
1394
+
1395
+
1396
+ /**
1397
+ * This function grabs the URL of the first image in a given post
1398
+ *
1399
+ * @return returns `false` or a string of the image src
1400
+ */
1401
+ public static function post_first_image() {
1402
+ global $post;
1403
+ $first_img = '';
1404
+ if ( $post == null ) {
1405
+ return false;
1406
+ } else {
1407
+ $output = preg_match_all( '/<img.*?src=[\'"](.*?)[\'"].*?>/i', $post->post_content, $matches );
1408
+ if ( isset( $matches[1][0] ) ) {
1409
+ // Exclude base64 images; meta tags require full URLs
1410
+ if ( strpos( $matches[1][0], 'data:' ) === false ) {
1411
+ $first_img = $matches[1][0];
1412
+ }
1413
+ } else {
1414
+ return false;
1415
+ }
1416
+ return $first_img;
1417
+ }
1418
+ }
1419
+
1420
+ /**
1421
+ * WP Rocket Compatability - Excludes Shareaholic scripts from JS minification, etc
1422
+ *
1423
+ * @param Array $excluded_external An array of JS hosts
1424
+ * @return Array the updated array of hosts
1425
+ */
1426
+ function rocket_exclude_js( $excluded_external ) {
1427
+ if ( defined( 'WP_ROCKET_VERSION' ) ) {
1428
+ $excluded_external[] = 'cdn.shareaholic.net';
1429
+ $excluded_external[] = 'k4z6w9b5.stackpathcdn.com';
1430
+
1431
+ return $excluded_external;
1432
+ }
1433
+ }
1434
+
1435
+ /*
1436
+ * Clears cache created by caching plugins like W3 Total Cache
1437
+ *
1438
+ */
1439
+ public static function clear_cache() {
1440
+
1441
+ // Default WordPress
1442
+ if ( function_exists( 'wp_cache_flush' ) ) {
1443
+ wp_cache_flush();
1444
+ }
1445
+ // W3 Total Cache plugin
1446
+ if ( function_exists( 'w3tc_pgcache_flush' ) ) {
1447
+ w3tc_pgcache_flush();
1448
+ }
1449
+ // WP Super Cache
1450
+ if ( function_exists( 'wp_cache_clear_cache' ) ) {
1451
+ if ( is_multisite() ) {
1452
+ $blog_id = get_current_blog_id();
1453
+ wp_cache_clear_cache( $blog_id );
1454
+ } else {
1455
+ wp_cache_clear_cache();
1456
+ }
1457
+ }
1458
+ // Hyper Cache
1459
+ if ( function_exists( 'hyper_cache_flush_all' ) ) {
1460
+ hyper_cache_flush_all();
1461
+ }
1462
+ // WP Fastest Cache
1463
+ if ( class_exists( 'WpFastestCache' ) ) {
1464
+ $WpFastestCache = new WpFastestCache();
1465
+ if ( method_exists( $WpFastestCache, 'deleteCache' ) ) {
1466
+ $WpFastestCache->deleteCache();
1467
+ }
1468
+ }
1469
+ // WPEngine
1470
+ if ( class_exists( 'WpeCommon' ) ) {
1471
+ if ( method_exists( 'WpeCommon', 'purge_memcached' ) ) {
1472
+ WpeCommon::purge_memcached();
1473
+ }
1474
+ if ( method_exists( 'WpeCommon', 'clear_maxcdn_cache' ) ) {
1475
+ WpeCommon::clear_maxcdn_cache();
1476
+ }
1477
+ if ( method_exists( 'WpeCommon', 'purge_varnish_cache' ) ) {
1478
+ WpeCommon::purge_varnish_cache();
1479
+ }
1480
+ }
1481
+ // Cachify Cache
1482
+ if ( has_action( 'cachify_flush_cache' ) ) {
1483
+ do_action( 'cachify_flush_cache' );
1484
+ }
1485
+ // Quick Cache
1486
+ if ( function_exists( 'auto_clear_cache' ) ) {
1487
+ auto_clear_cache();
1488
+ }
1489
+ // Zencache
1490
+ if ( class_exists( 'zencache' ) ) {
1491
+ zencache::clear();
1492
+ }
1493
+ // CometCache
1494
+ if ( class_exists( 'comet_cache' ) ) {
1495
+ comet_cache::clear();
1496
+ }
1497
+ }
1498
+
1499
+ /**
1500
+ * List below is from Jetpack, with a few custom additions:
1501
+ * Source: https://github.com/Automattic/jetpack/blob/master/sync/class.jetpack-sync-defaults.php
1502
+ **/
1503
+ static $blacklisted_post_types = array(
1504
+ 'nav_menu_item',
1505
+ 'attachment',
1506
+ 'ai1ec_event',
1507
+ 'bwg_album',
1508
+ 'bwg_gallery',
1509
+ 'customize_changeset', // WP built-in post type for Customizer changesets
1510
+ 'dn_wp_yt_log',
1511
+ 'http',
1512
+ 'idx_page',
1513
+ 'jetpack_migration',
1514
+ 'postman_sent_mail',
1515
+ 'rssap-feed',
1516
+ 'rssmi_feed_item',
1517
+ 'secupress_log_action',
1518
+ 'sg_optimizer_jobs',
1519
+ 'snitch',
1520
+ 'wpephpcompat_jobs',
1521
+ 'wprss_feed_item',
1522
+ 'wp_automatic',
1523
+ 'jp_sitemap_master',
1524
+ 'jp_sitemap',
1525
+ 'jp_sitemap_index',
1526
+ 'jp_img_sitemap',
1527
+ 'jp_img_sitemap_index',
1528
+ 'jp_vid_sitemap',
1529
+ 'jp_vid_sitemap_index',
1530
+ );
1531
+
1532
+ /**
1533
+ * A post just transitioned state. Do something.
1534
+ */
1535
+ public static function post_transitioned( $new_status, $old_status, $post ) {
1536
+ $post_type = get_post_type( $post );
1537
+
1538
+ // exit if blacklisted post type
1539
+ if ( $post_type && in_array( $post_type, self::$blacklisted_post_types ) ) {
1540
+ return;
1541
+ }
1542
+
1543
+ if ( $new_status == 'publish' ) {
1544
+ // Post was just published
1545
+ self::notify_content_manager_singlepage( $post );
1546
+ }
1547
+ if ( $old_status == 'publish' && $new_status != 'publish' ) {
1548
+ // Notify CM that the post is no longer public
1549
+ self::notify_content_manager_singlepage( $post );
1550
+ }
1551
+ }
1552
+
1553
+
1554
+ /**
1555
+ * Server Connectivity check
1556
+ */
1557
+ public static function connectivity_check() {
1558
+ $health_check_url = Shareaholic::API_URL . '/haproxy_health_check';
1559
+ $response = ShareaholicCurl::get( $health_check_url );
1560
+ if ( is_array( $response ) && array_key_exists( 'body', $response ) ) {
1561
+ $response_code = wp_remote_retrieve_response_code( $response );
1562
+ if ( $response_code == '200' ) {
1563
+ return 'SUCCESS';
1564
+ } else {
1565
+ return 'FAIL';
1566
+ }
1567
+ } else {
1568
+ return 'FAIL';
1569
+ }
1570
+ }
1571
+
1572
+ /**
1573
+ * Facebook Auth Token check
1574
+ */
1575
+ public static function facebook_auth_check() {
1576
+ if ( self::fetch_fb_access_token() === false ) {
1577
+ self::update_options( array( 'facebook_auth_check' => 'FAIL' ) );
1578
+ return 'FAIL';
1579
+ }
1580
+
1581
+ $health_check_url = 'https://graph.facebook.com/?fields=engagement&id=https://www.google.com/&access_token=' . self::fetch_fb_access_token();
1582
+
1583
+ $response = ShareaholicCurl::get( $health_check_url );
1584
+
1585
+ if ( is_array( $response ) && array_key_exists( 'body', $response ) ) {
1586
+ $response_code = wp_remote_retrieve_response_code( $response );
1587
+ if ( $response_code == '200' ) {
1588
+ self::update_options( array( 'facebook_auth_check' => 'SUCCESS' ) );
1589
+ return 'SUCCESS';
1590
+ } else {
1591
+ self::update_options( array( 'facebook_auth_check' => 'FAIL' ) );
1592
+ return 'FAIL';
1593
+ }
1594
+ } else {
1595
+ return 'FAIL';
1596
+ }
1597
+ }
1598
+
1599
+ /**
1600
+ * Share Counts API Connectivity check
1601
+ */
1602
+ public static function share_counts_api_connectivity_check() {
1603
+
1604
+ // if we already checked and it is successful, then do not call the API again
1605
+ $share_counts_connect_check = self::get_option( 'share_counts_connect_check' );
1606
+ if ( isset( $share_counts_connect_check ) && $share_counts_connect_check == 'SUCCESS' ) {
1607
+ return $share_counts_connect_check;
1608
+ }
1609
+
1610
+ $services_config = ShareaholicSeqShareCount::get_services_config();
1611
+ $services = array_keys( $services_config );
1612
+ $param_string = implode( '&services[]=', $services );
1613
+ $share_counts_api_url = admin_url( 'admin-ajax.php' ) . '?action=shareaholic_share_counts_api&url=https%3A%2F%2Fwww.google.com%2F&services[]=' . $param_string;
1614
+ $cache_key = 'share_counts_api_connectivity_check';
1615
+
1616
+ $response = get_transient( $cache_key );
1617
+ if ( ! $response ) {
1618
+ $response = ShareaholicCurl::get( $share_counts_api_url, array(), '', true );
1619
+ }
1620
+
1621
+ $response_status = self::get_share_counts_api_status( $response );
1622
+ // if this was the first time we are doing this and it failed, disable
1623
+ // the share counts API
1624
+ if ( empty( $share_counts_connect_check ) && $response_status == 'FAIL' ) {
1625
+ self::update_options( array( 'disable_internal_share_counts_api' => 'on' ) );
1626
+ }
1627
+
1628
+ if ( $response_status == 'SUCCESS' ) {
1629
+ set_transient( $cache_key, $response, SHARE_COUNTS_CHECK_CACHE_LENGTH );
1630
+ }
1631
+
1632
+ self::update_options( array( 'share_counts_connect_check' => $response_status ) );
1633
+ return $response_status;
1634
+ }
1635
+
1636
+ /**
1637
+ * Check the share counts API for empty response or missing services
1638
+ */
1639
+ public static function get_share_counts_api_status( $response ) {
1640
+ if ( ! $response || ! isset( $response['body'] ) || ! is_array( $response['body'] ) || ! isset( $response['body']['data'] ) ) {
1641
+ return 'FAIL';
1642
+ }
1643
+
1644
+ // Did it return at least 4 services?
1645
+ $has_majority_services = count( array_keys( $response['body']['data'] ) ) >= 4 ? true : false;
1646
+ $has_important_services = true;
1647
+ // Does it have counts for linkedin, pinterest?
1648
+ foreach ( array( 'facebook', 'pinterest' ) as $service ) {
1649
+ if ( ! isset( $response['body']['data'][ $service ] ) || ! is_numeric( $response['body']['data'][ $service ] ) ) {
1650
+ $has_important_services = false;
1651
+ }
1652
+ }
1653
+
1654
+ if ( ! $has_majority_services || ! $has_important_services ) {
1655
+ return 'FAIL';
1656
+ }
1657
+
1658
+ return 'SUCCESS';
1659
+ }
1660
+
1661
+
1662
+ /**
1663
+ * Call the content manager for a post before it is trashed
1664
+ *
1665
+ * We do this because permalink changes on being trashed
1666
+ * and so we tell CM that the old permalink is no longer valid
1667
+ */
1668
+ public static function before_post_is_trashed( $post_id ) {
1669
+
1670
+ $post_type = get_post_type( $post_id );
1671
+
1672
+ // exit if blacklisted post type
1673
+ if ( $post_type && in_array( $post_type, self::$blacklisted_post_types ) ) {
1674
+ return;
1675
+ }
1676
+
1677
+ self::notify_content_manager_singlepage( get_post( $post_id ), 'trash' );
1678
+ }
1679
+
1680
+
1681
+ /**
1682
+ * Call the content manager for a post before it is updated
1683
+ *
1684
+ * We do this because a user may change their permalink
1685
+ * and so we tell CM that the old permalink is no longer valid
1686
+ */
1687
+ public static function before_post_is_updated( $post_id ) {
1688
+
1689
+ $post_type = get_post_type( $post_id );
1690
+
1691
+ // exit if blacklisted post type
1692
+ if ( $post_type && in_array( $post_type, self::$blacklisted_post_types ) ) {
1693
+ return;
1694
+ }
1695
+
1696
+ self::notify_content_manager_singlepage( get_post( $post_id ) );
1697
+ }
1698
+
1699
+ public static function user_info() {
1700
+ $user_info = array();
1701
+
1702
+ if ( function_exists( 'wp_get_current_user' ) ) {
1703
+
1704
+ $current_user = wp_get_current_user();
1705
+
1706
+ if ( ! ( $current_user instanceof WP_User ) || ! is_user_logged_in() ) {
1707
+ return array();
1708
+ }
1709
+
1710
+ $user_caps = $current_user->get_role_caps();
1711
+
1712
+ $caps = array(
1713
+ 'switch_themes',
1714
+ 'edit_themes',
1715
+ 'activate_plugins',
1716
+ 'edit_plugins',
1717
+ 'manage_options',
1718
+ 'unfiltered_html',
1719
+ 'edit_dashboard',
1720
+ 'update_plugins',
1721
+ 'delete_plugins',
1722
+ 'install_plugins',
1723
+ 'update_themes',
1724
+ 'install_themes',
1725
+ 'update_core',
1726
+ 'edit_theme_options',
1727
+ 'delete_themes',
1728
+ 'administrator',
1729
+ );
1730
+
1731
+ $user_info = array(
1732
+ 'username' => $current_user->user_login,
1733
+ 'email' => $current_user->user_email,
1734
+ 'roles' => $current_user->roles,
1735
+ 'capabilities' => array(),
1736
+ 'is_super_admin' => is_super_admin(),
1737
+ );
1738
+
1739
+ foreach ( $caps as $cap ) {
1740
+ $user_info['capabilities'][ $cap ] = isset( $user_caps[ $cap ] ) ? $user_caps[ $cap ] : '';
1741
+ }
1742
+ }
1743
+
1744
+ return $user_info;
1745
+ }
1746
+
1747
+ /**
1748
+ * Shorten a string to a certain character limit
1749
+ * If the limit is reached, then return the truncated text
1750
+ *
1751
+ * @param {String} $text the text to truncate
1752
+ * @param {Number} $char_count the max number of characters
1753
+ * @return {String} the truncated text
1754
+ */
1755
+ public static function truncate_text( $text, $char_count ) {
1756
+ $words = preg_split( '/\s+/', $text );
1757
+ $truncated_text = '';
1758
+
1759
+ foreach ( $words as $word ) {
1760
+ if ( strlen( $word ) + strlen( $truncated_text ) >= $char_count ) {
1761
+ break;
1762
+ }
1763
+
1764
+ $truncated_text .= ' ' . $word;
1765
+ }
1766
+
1767
+ return trim( $truncated_text );
1768
+ }
1769
  }