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

Version Description

  • Share Buttons App
    • New alignment options - you can now pick whether you want your text to wrap around your buttons
    • Multishare toggle for Twitter
    • New services:
    • VK (the 2nd largest social network service in Europe after Facebook)
    • Fancy (recommended for e-commerce sites)
    • Wanelo (recommended for e-commerce sites)
    • New Share Counts library
  • Floating Share Buttons App (NEW!)
    • To enable, click on "Edit General Settings" -> Sign In -> Click on "Site Tools" -> Turn on the "Floated Share Buttons" App
  • Shareable Images App (NEW!) learn more
    • To enable, click on "Edit General Settings" -> Sign In -> Turn on "Shareable Images"
Download this release

Release Info

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

Code changes from version 7.2.2.0 to 7.3.0.0

assets/css/index.html CHANGED
@@ -1,6 +1,6 @@
1
  <html>
2
  <head>
3
- <meta http-equiv="refresh" content="0; url=http://www.shareaholic.com">
4
  </head>
5
  <body>
6
  Redirecting you now...
1
  <html>
2
  <head>
3
+ <meta http-equiv="refresh" content="0; url=https://shareaholic.com">
4
  </head>
5
  <body>
6
  Redirecting you now...
assets/index.html CHANGED
@@ -1,6 +1,6 @@
1
  <html>
2
  <head>
3
- <meta http-equiv="refresh" content="0; url=http://www.shareaholic.com">
4
  </head>
5
  <body>
6
  Redirecting you now...
1
  <html>
2
  <head>
3
+ <meta http-equiv="refresh" content="0; url=https://shareaholic.com">
4
  </head>
5
  <body>
6
  Redirecting you now...
assets/js/index.html CHANGED
@@ -1,6 +1,6 @@
1
  <html>
2
  <head>
3
- <meta http-equiv="refresh" content="0; url=http://www.shareaholic.com">
4
  </head>
5
  <body>
6
  Redirecting you now...
1
  <html>
2
  <head>
3
+ <meta http-equiv="refresh" content="0; url=https://shareaholic.com">
4
  </head>
5
  <body>
6
  Redirecting you now...
languages/index.html CHANGED
@@ -1,6 +1,6 @@
1
  <html>
2
  <head>
3
- <meta http-equiv="refresh" content="0; url=http://www.shareaholic.com">
4
  </head>
5
  <body>
6
  Redirecting you now...
1
  <html>
2
  <head>
3
+ <meta http-equiv="refresh" content="0; url=https://shareaholic.com">
4
  </head>
5
  <body>
6
  Redirecting you now...
languages/readme.txt CHANGED
@@ -13,7 +13,9 @@ Instructions: https://shareaholic.com/tools/wordpress/translate
13
  * English (en)
14
  * Simplified Chinese (zh_CN) by [Larry Zhang](http://zhxl.me)
15
  * Greek (el) by [Takis Bouyouris](http://www.nevma.gr)
16
- * German (de) by Lothar Schiborr
 
 
17
  * Contribute a translation!
18
 
19
  == Notes ==
13
  * English (en)
14
  * Simplified Chinese (zh_CN) by [Larry Zhang](http://zhxl.me)
15
  * Greek (el) by [Takis Bouyouris](http://www.nevma.gr)
16
+ * German (de) by Oliver Heinrich
17
+ * French (fr) by Rozenn Dagorn
18
+ * Dutch (nl) by Patrick Ruers
19
  * Contribute a translation!
20
 
21
  == Notes ==
languages/shareaholic.pot CHANGED
@@ -1,23 +1,23 @@
1
- # Copyright (C) 2013 Shareaholic | share buttons, analytics, related content
2
  # This file is distributed under the same license as the Shareaholic | share buttons, analytics, related content package.
3
  msgid ""
4
  msgstr ""
5
  "Project-Id-Version: Shareaholic | share buttons, analytics, related content "
6
- "7.0.6.0\n"
7
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/shareaholic\n"
8
- "POT-Creation-Date: 2013-11-11 23:30:28+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "PO-Revision-Date: 2013-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
15
 
16
- #: admin.php:217 admin.php:284
17
  msgid "Settings successfully saved"
18
  msgstr ""
19
 
20
- #: admin.php:278
21
  msgid "Settings successfully reset. Refresh this page to complete the reset."
22
  msgstr ""
23
 
@@ -49,50 +49,54 @@ msgid "(it is recommended NOT to disable analytics)"
49
  msgstr ""
50
 
51
  #: templates/advanced_settings.php:25
52
- msgid "Do not automatically include <code>Open Graph</code> tags"
53
  msgstr ""
54
 
55
  #: templates/advanced_settings.php:25
56
  msgid "(it is recommended NOT to disable open graph tags)"
57
  msgstr ""
58
 
59
- #: templates/advanced_settings.php:28 templates/settings.php:94
 
 
 
 
60
  msgid "Saving Changes..."
61
  msgstr ""
62
 
63
- #: templates/advanced_settings.php:28 templates/settings.php:94
64
  msgid "Save Changes"
65
  msgstr ""
66
 
67
- #: templates/advanced_settings.php:36
68
  msgid "Server Connectivity"
69
  msgstr ""
70
 
71
- #: templates/advanced_settings.php:38
72
  msgid "All Shareaholic servers are reachable"
73
  msgstr ""
74
 
75
- #: templates/advanced_settings.php:39
76
  msgid "Shareaholic should be working correctly."
77
  msgstr ""
78
 
79
- #: templates/advanced_settings.php:39
80
  msgid "All Shareaholic servers are accessible."
81
  msgstr ""
82
 
83
- #: templates/advanced_settings.php:41
84
  msgid "Unable to reach any Shareaholic server"
85
  msgstr ""
86
 
87
- #: templates/advanced_settings.php:41
88
  msgid "Checking..."
89
  msgstr ""
90
 
91
- #: templates/advanced_settings.php:41
92
  msgid "Re-check"
93
  msgstr ""
94
 
95
- #: templates/advanced_settings.php:42
96
  msgid ""
97
  "A network problem or firewall is blocking all connections from your web "
98
  "server to Shareaholic.com. <strong>Shareaholic cannot work correctly until "
@@ -102,21 +106,29 @@ msgid ""
102
  "onclick=\"%s\">know</a> too, so we can follow up!"
103
  msgstr ""
104
 
105
- #: templates/advanced_settings.php:52
 
 
 
 
 
 
 
 
106
  msgid "Reset"
107
  msgstr ""
108
 
109
- #: templates/advanced_settings.php:53
110
  msgid ""
111
  "This will reset all of your settings and start you from scratch. This can "
112
  "not be undone."
113
  msgstr ""
114
 
115
- #: templates/advanced_settings.php:55
116
  msgid "Resetting Plugin..."
117
  msgstr ""
118
 
119
- #: templates/advanced_settings.php:55
120
  msgid "Reset Plugin"
121
  msgstr ""
122
 
@@ -186,7 +198,7 @@ msgid "Do not include Open Graph tags"
186
  msgstr ""
187
 
188
  #: templates/settings.php:3
189
- msgid "Shareaholic: Available Apps"
190
  msgstr ""
191
 
192
  #: templates/settings.php:22
@@ -227,7 +239,7 @@ msgid ""
227
  msgstr ""
228
 
229
  #: templates/settings.php:79
230
- msgid "Data Status:"
231
  msgstr ""
232
 
233
  #: templates/settings.php:83
@@ -272,42 +284,75 @@ msgid ""
272
  "and %sPrivacy Policy%s."
273
  msgstr ""
274
 
275
- #: templates/why_to_sign_up.php:2
276
- msgid "Customize even more with a FREE Shareaholic account."
277
  msgstr ""
278
 
279
- #: templates/why_to_sign_up.php:3
280
- msgid "Such as:"
281
  msgstr ""
282
 
283
  #: templates/why_to_sign_up.php:5
284
- msgid "Customize tweets coming from your website."
285
  msgstr ""
286
 
287
- #: templates/why_to_sign_up.php:6
288
- msgid "Choose your URL Shortener, or use your own."
 
 
 
 
 
 
 
 
289
  msgstr ""
290
 
291
- #: templates/why_to_sign_up.php:7
292
- msgid "Choose from various themes and styles."
 
 
293
  msgstr ""
294
 
295
- #: templates/why_to_sign_up.php:8
296
- msgid "Exclude pages from Recommendations engine."
 
297
  msgstr ""
298
 
299
- #: templates/why_to_sign_up.php:9
300
- msgid "Plus tons of great features and customization options."
301
  msgstr ""
302
 
303
- #: templates/why_to_sign_up.php:11
304
  msgid "Edit General Website Settings"
305
  msgstr ""
306
 
307
- #: utilities.php:92
 
 
 
 
 
 
 
 
308
  msgid "Settings"
309
  msgstr ""
310
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
  #. Plugin Name of the plugin/theme
312
  msgid "Shareaholic | share buttons, analytics, related content"
313
  msgstr ""
@@ -324,10 +369,6 @@ msgid ""
324
  "more settings."
325
  msgstr ""
326
 
327
- #. Author of the plugin/theme
328
- msgid "Shareaholic"
329
- msgstr ""
330
-
331
  #. Author URI of the plugin/theme
332
  msgid "https://shareaholic.com"
333
  msgstr ""
1
+ # Copyright (C) 2014 Shareaholic | share buttons, analytics, related content
2
  # This file is distributed under the same license as the Shareaholic | share buttons, analytics, related content package.
3
  msgid ""
4
  msgstr ""
5
  "Project-Id-Version: Shareaholic | share buttons, analytics, related content "
6
+ "7.2.2.0\n"
7
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/shareaholic\n"
8
+ "POT-Creation-Date: 2014-03-12 20:11:40+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "PO-Revision-Date: 2014-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
15
 
16
+ #: admin.php:217 admin.php:285
17
  msgid "Settings successfully saved"
18
  msgstr ""
19
 
20
+ #: admin.php:279
21
  msgid "Settings successfully reset. Refresh this page to complete the reset."
22
  msgstr ""
23
 
49
  msgstr ""
50
 
51
  #: templates/advanced_settings.php:25
52
+ msgid "Disable <code>Open Graph</code> tags"
53
  msgstr ""
54
 
55
  #: templates/advanced_settings.php:25
56
  msgid "(it is recommended NOT to disable open graph tags)"
57
  msgstr ""
58
 
59
+ #: templates/advanced_settings.php:31
60
+ msgid "Disable Admin Bar Menu"
61
+ msgstr ""
62
+
63
+ #: templates/advanced_settings.php:34 templates/settings.php:94
64
  msgid "Saving Changes..."
65
  msgstr ""
66
 
67
+ #: templates/advanced_settings.php:34 templates/settings.php:94
68
  msgid "Save Changes"
69
  msgstr ""
70
 
71
+ #: templates/advanced_settings.php:42
72
  msgid "Server Connectivity"
73
  msgstr ""
74
 
75
+ #: templates/advanced_settings.php:44
76
  msgid "All Shareaholic servers are reachable"
77
  msgstr ""
78
 
79
+ #: templates/advanced_settings.php:45
80
  msgid "Shareaholic should be working correctly."
81
  msgstr ""
82
 
83
+ #: templates/advanced_settings.php:45
84
  msgid "All Shareaholic servers are accessible."
85
  msgstr ""
86
 
87
+ #: templates/advanced_settings.php:47
88
  msgid "Unable to reach any Shareaholic server"
89
  msgstr ""
90
 
91
+ #: templates/advanced_settings.php:47
92
  msgid "Checking..."
93
  msgstr ""
94
 
95
+ #: templates/advanced_settings.php:47
96
  msgid "Re-check"
97
  msgstr ""
98
 
99
+ #: templates/advanced_settings.php:48
100
  msgid ""
101
  "A network problem or firewall is blocking all connections from your web "
102
  "server to Shareaholic.com. <strong>Shareaholic cannot work correctly until "
106
  "onclick=\"%s\">know</a> too, so we can follow up!"
107
  msgstr ""
108
 
109
+ #: templates/advanced_settings.php:55
110
+ msgid "Your Shareaholic Site ID"
111
+ msgstr ""
112
+
113
+ #: templates/advanced_settings.php:59
114
+ msgid "Not set."
115
+ msgstr ""
116
+
117
+ #: templates/advanced_settings.php:69
118
  msgid "Reset"
119
  msgstr ""
120
 
121
+ #: templates/advanced_settings.php:70
122
  msgid ""
123
  "This will reset all of your settings and start you from scratch. This can "
124
  "not be undone."
125
  msgstr ""
126
 
127
+ #: templates/advanced_settings.php:72
128
  msgid "Resetting Plugin..."
129
  msgstr ""
130
 
131
+ #: templates/advanced_settings.php:72
132
  msgid "Reset Plugin"
133
  msgstr ""
134
 
198
  msgstr ""
199
 
200
  #: templates/settings.php:3
201
+ msgid "Shareaholic: App Manager"
202
  msgstr ""
203
 
204
  #: templates/settings.php:22
239
  msgstr ""
240
 
241
  #: templates/settings.php:79
242
+ msgid "Related Content:"
243
  msgstr ""
244
 
245
  #: templates/settings.php:83
284
  "and %sPrivacy Policy%s."
285
  msgstr ""
286
 
287
+ #: templates/why_to_sign_up.php:3
288
+ msgid "Installation &amp; Usage Guides"
289
  msgstr ""
290
 
291
+ #: templates/why_to_sign_up.php:4
292
+ msgid "Submit a Translation"
293
  msgstr ""
294
 
295
  #: templates/why_to_sign_up.php:5
296
+ msgid "Get the Shareaholic Browser Add-on"
297
  msgstr ""
298
 
299
+ #: templates/why_to_sign_up.php:10
300
+ msgid ""
301
+ "Unlock additional customization options when you connect this plugin to "
302
+ "your FREE Shareaholic account."
303
+ msgstr ""
304
+
305
+ #: templates/why_to_sign_up.php:12
306
+ msgid ""
307
+ "Brand your social shares. For example, you can make all Twitter shares say "
308
+ "\"by @Twitterhandle\""
309
  msgstr ""
310
 
311
+ #: templates/why_to_sign_up.php:13
312
+ msgid ""
313
+ "Pick your favorite URL shortener, including support for branded bitly short "
314
+ "links."
315
  msgstr ""
316
 
317
+ #: templates/why_to_sign_up.php:14
318
+ msgid ""
319
+ "Additional themes for share buttons, related content, etc to match your site."
320
  msgstr ""
321
 
322
+ #: templates/why_to_sign_up.php:15
323
+ msgid "Opportunities to make money with your site, plus lots more!"
324
  msgstr ""
325
 
326
+ #: templates/why_to_sign_up.php:17
327
  msgid "Edit General Website Settings"
328
  msgstr ""
329
 
330
+ #: templates/why_to_sign_up.php:18
331
+ msgid ""
332
+ "Connecting is simple. Simply click the button above and sign in to your "
333
+ "Shareaholic account to connect this plugin to your account. If you don't "
334
+ "have an account already, simply create a new account — it takes just seconds "
335
+ "and it's free!"
336
+ msgstr ""
337
+
338
+ #: utilities.php:93
339
  msgid "Settings"
340
  msgstr ""
341
 
342
+ #. #-#-#-#-# plugin.pot (Shareaholic | share buttons, analytics, related content 7.2.2.0) #-#-#-#-#
343
+ #. Author of the plugin/theme
344
+ #: utilities.php:110
345
+ msgid "Shareaholic"
346
+ msgstr ""
347
+
348
+ #: utilities.php:127
349
+ msgid "App Manager"
350
+ msgstr ""
351
+
352
+ #: utilities.php:134
353
+ msgid "General Settings"
354
+ msgstr ""
355
+
356
  #. Plugin Name of the plugin/theme
357
  msgid "Shareaholic | share buttons, analytics, related content"
358
  msgstr ""
369
  "more settings."
370
  msgstr ""
371
 
 
 
 
 
372
  #. Author URI of the plugin/theme
373
  msgid "https://shareaholic.com"
374
  msgstr ""
lib/index.html ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="refresh" content="0; url=https://shareaholic.com">
4
+ </head>
5
+ <body>
6
+ Redirecting you now...
7
+ </body>
8
+ </html>
lib/social-share-counts/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ LICENSE
2
+
3
+ Copyright (c) 2014 Shareaholic, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
lib/social-share-counts/README.md ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ social-share-counts
2
+ ===================
3
+
4
+ A library to check how many times a URL has been shared on Facebook, Twitter, Pinterest, Google+, etc.
5
+
6
+
7
+ Contributing
8
+ ------------
9
+
10
+ 1. Fork the [official repository](https://github.com/shareaholic/social-share-counts/tree/master).
11
+ 2. Make your changes in a topic branch.
12
+ 3. Send a pull request.
13
+
14
+ Credits
15
+ -------
16
+
17
+ ![Shareaholic](https://blog.shareaholic.com/wp-content/uploads/2013/10/new-shareaholic-logo.png)
18
+
19
+ social-share-counts is maintained and funded by [Shareaholic, Inc](https://shareaholic.com/). The names and logos for Shareaholic are trademarks of Shareaholic, Inc.
20
+
21
+ Thank you to all [the contributors](https://github.com/shareaholic/social-share-counts/contributors)!
22
+
23
+
24
+ License
25
+ -------
26
+
27
+ social-share-counts is Copyright © 2014 Shareaholic Inc. It is free software, and may be redistributed under the terms specified in the [LICENSE](https://github.com/shareaholic/social-share-counts/blob/master/LICENSE) file.
lib/social-share-counts/curl_multi_share_count.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Shareaholic Multi Share Count
4
+ *
5
+ * @package shareaholic
6
+ * @version 1.0.0.0
7
+ */
8
+
9
+ require_once('share_count.php');
10
+
11
+ /**
12
+ * A class that implements ShareaholicShareCounts
13
+ * This class will get the share counts by calling
14
+ * the social services via curl_multi
15
+ *
16
+ * @package shareaholic
17
+ */
18
+
19
+ class ShareaholicCurlMultiShareCount extends ShareaholicShareCount {
20
+
21
+ /**
22
+ * This function should get all the counts for the
23
+ * supported services
24
+ *
25
+ * It should return an associative array with the services as
26
+ * the keys and the counts as the value.
27
+ *
28
+ * Example:
29
+ * array('facebook' => 12, 'google_plus' => 0, 'twitter' => 14, ...);
30
+ *
31
+ * @return Array an associative array of service => counts
32
+ */
33
+ public function get_counts() {
34
+ $services_length = count($this->services);
35
+ $config = $this->get_services_config();
36
+ $response = array();
37
+ $response['status'] = 200;
38
+
39
+ // array of curl handles
40
+ $curl_handles = array();
41
+
42
+ // multi handle
43
+ $multi_handle = curl_multi_init();
44
+
45
+ for($i = 0; $i < $services_length; $i++) {
46
+ $service = $this->services[$i];
47
+
48
+ if(!isset($config[$service])) {
49
+ continue;
50
+ }
51
+
52
+ if(isset($config[$service]['prepare'])) {
53
+ $this->$config[$service]['prepare']($this->url, $config);
54
+ }
55
+
56
+ $endpoint = sprintf($config[$service]['url'], $this->url);
57
+
58
+ // Create the curl handle
59
+ $curl_handles[$service] = curl_init();
60
+
61
+ // set the curl options to make the request
62
+ $this->curl_setopts($curl_handles[$service], $config, $service);
63
+
64
+ // add the handle to curl_multi_handle
65
+ curl_multi_add_handle($multi_handle, $curl_handles[$service]);
66
+ }
67
+
68
+ // Run curl_multi only if there are some actual curl handles
69
+ if(count($curl_handles) > 0) {
70
+ // execute the handles
71
+ $running = NULL;
72
+ do {
73
+ curl_multi_exec($multi_handle, $running);
74
+ } while($running > 0);
75
+
76
+ // handle the responses
77
+ foreach($curl_handles as $service => $handle) {
78
+ if(curl_errno($handle)) {
79
+ $response['status'] = 500;
80
+ }
81
+ $result = array(
82
+ 'body' => curl_multi_getcontent($handle),
83
+ 'response' => array(
84
+ 'code' => curl_getinfo($handle, CURLINFO_HTTP_CODE)
85
+ ),
86
+ );
87
+ $callback = $config[$service]['callback'];
88
+ $response['data'][$service] = $this->$callback($result);
89
+ }
90
+ curl_multi_close($multi_handle);
91
+ }
92
+ return $response;
93
+ }
94
+
95
+ private function curl_setopts($curl_handle, $config, $service) {
96
+ // set the url to make the curl request
97
+ curl_setopt($curl_handle, CURLOPT_URL, sprintf($config[$service]['url'], $this->url));
98
+
99
+ // other necessary settings:
100
+ // CURLOPT_HEADER means include header in output, which we do not want
101
+ // CURLOPT_RETURNTRANSER means return output as string or not
102
+ curl_setopt_array($curl_handle, array(
103
+ CURLOPT_HEADER => 0,
104
+ CURLOPT_RETURNTRANSFER => 1,
105
+ CURLOPT_TIMEOUT => 2,
106
+ CURLOPT_SSL_VERIFYPEER => false,
107
+ CURLOPT_SSL_VERIFYHOST => false,
108
+ CURLOPT_FRESH_CONNECT => true,
109
+ ));
110
+
111
+ // set the http method: default is GET
112
+ if($config[$service]['method'] === 'POST') {
113
+ curl_setopt($curl_handle, CURLOPT_POST, 1);
114
+ }
115
+
116
+ // set the body and headers
117
+ $headers = isset($config[$service]['headers']) ? $config[$service]['headers'] : array();
118
+ $body = isset($config[$service]['body']) ? $config[$service]['body'] : NULL;
119
+
120
+ if(isset($body)) {
121
+ if(isset($headers['Content-Type']) && $headers['Content-Type'] === 'application/json') {
122
+ $data_string = json_encode($body);
123
+
124
+ curl_setopt($curl_handle, CURLOPT_HTTPHEADER, array(
125
+ 'Content-Type: application/json',
126
+ 'Content-Length: ' . strlen($data_string))
127
+ );
128
+
129
+ curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $data_string);
130
+ }
131
+ }
132
+
133
+ // set the useragent
134
+ $useragent = isset($config[$service]['User-Agent']) ? $config[$service]['User-Agent'] : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0';
135
+ curl_setopt($curl_handle, CURLOPT_USERAGENT, $useragent);
136
+ }
137
+
138
+
139
+ }
lib/social-share-counts/curl_multi_share_count_test.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once('curl_multi_share_count.php');
4
+
5
+ class ShareaholicCurlMultiShareCountsTest extends PHPUnit_Framework_TestCase
6
+ {
7
+ public function setUp() {
8
+ $this->url = 'https://blog.shareaholic.com';
9
+ $counts = new ShareaholicCurlMultiShareCount($this->url, array());
10
+ $this->services = array_keys($counts->get_services_config());
11
+
12
+ // all callbacks take a predefined response structure
13
+ $this->response = array(
14
+ 'response' => array(
15
+ 'code' => 200
16
+ ),
17
+ );
18
+ }
19
+
20
+ public function tearDown() {
21
+
22
+ }
23
+
24
+
25
+ public function testGetCount() {
26
+ // test that this function returns the expected API response
27
+ $share_count = new ShareaholicCurlMultiShareCount($this->url, $this->services);
28
+ $response = $share_count->get_counts();
29
+
30
+ $this->assertNotNull($response, 'The response array should not be null');
31
+
32
+ foreach($this->services as $service) {
33
+ $this->assertNotNull($response['data'][$service], 'The ' . $service . ' count should not be null');
34
+ }
35
+ }
36
+
37
+ }
lib/social-share-counts/drupal_http.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file holds the ShareaholicHttp class.
4
+ *
5
+ * @package shareaholic
6
+ */
7
+
8
+ /**
9
+ * The purpose of this class is to provide an interface around any native
10
+ * http function (wp_remote_get, drupal_http_request, curl) so that one
11
+ * use this consistent API for making http request with well defined input
12
+ * and output.
13
+ *
14
+ * @package shareaholic
15
+ */
16
+ class ShareaholicHttp {
17
+
18
+ /**
19
+ * Performs a HTTP request with a url, array of options, and ignore_error flag
20
+ *
21
+ *
22
+ * The options object is an associative array that takes the following options:
23
+ * - method: The http method for the request as a string. Defaults is 'GET'.
24
+ *
25
+ * - headers: The headers to send with the request as an associative array of name/value pairs. Default is empty array.
26
+ *
27
+ * - body: The body to send with the request as an associative array of name/value pairs. Default is NULL.
28
+ * If the body is meant to be parsed as json, specify the content type in the headers option to be 'application/json'.
29
+ *
30
+ * - redirection: The number of redirects to follow for this request as an integer, Default is 5.
31
+ *
32
+ * - timeout: The number of seconds the request should take as an integer. Default is 15 (seconds).
33
+ *
34
+ * - user-agent: The useragent for the request. Default is mozilla browser useragent.
35
+ *
36
+ *
37
+ * This function returns an object on success or false if there were errors.
38
+ * The object is an associative array with the following keys:
39
+ * - headers: the response headers as an array of key/value pairs
40
+ * - body: the response body as a string
41
+ * - response: an array with the following keys:
42
+ * - code: the response code
43
+ * - message: the status message
44
+ *
45
+ *
46
+ * @param string $url The url you are sending the request to
47
+ * @param array $options An array of supported options to pass to the request
48
+ * @param bool $ignore_error A flag indicating to log error or not. Default is false.
49
+ *
50
+ * @return mixed It returns an associative array of name value pairs or false if there was an error.
51
+ */
52
+ public static function send($url, $options = array(), $ignore_error = false) {
53
+ return self::send_with_drupal($url, $options, $ignore_error);
54
+ }
55
+
56
+ private static function send_with_drupal($url, $options, $ignore_error) {
57
+ $request = array();
58
+ $result = array();
59
+ $request['method'] = isset($options['method']) ? $options['method'] : 'GET';
60
+ $request['headers'] = isset($options['headers']) ? $options['headers'] : array();
61
+ $request['max_redirects'] = isset($options['redirection']) ? $options['redirection'] : 5;
62
+ $request['timeout'] = isset($options['timeout']) ? $options['timeout'] : 15;
63
+ $request['headers']['User-Agent'] = isset($options['user-agent']) ? $options['user-agent'] : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0';
64
+
65
+ if(isset($options['body'])) {
66
+ if(isset($request['headers']['Content-Type']) && $request['headers']['Content-Type'] === 'application/json') {
67
+ $request['data'] = json_encode($options['body']);
68
+ } else {
69
+ $request['data'] = http_build_query($options['body']);
70
+ }
71
+ } else {
72
+ $request['body'] = NULL;
73
+ }
74
+
75
+ $response = drupal_http_request($url, $request);
76
+
77
+ if(isset($response->error)) {
78
+ if(!$ignore_error) {
79
+ ShareaholicUtilities::log('ShareaholicHttp Error for ' . $url . ' with error ' . $response->error);
80
+ }
81
+ return false;
82
+ }
83
+
84
+ $result['headers'] = $response->headers;
85
+ $result['body'] = $response->data;
86
+ $result['response'] = array(
87
+ 'code' => $response->code,
88
+ 'message' => $response->status_message,
89
+ );
90
+
91
+ return $result;
92
+ }
93
+ }
lib/social-share-counts/http.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file holds the ShareaholicHttp class.
4
+ *
5
+ * @package shareaholic
6
+ */
7
+
8
+ /**
9
+ * The purpose of this class is to provide an interface around any native
10
+ * http function (wp_remote_get, drupal_http_request, curl) so that one
11
+ * use this consistent API for making http request with well defined input
12
+ * and output.
13
+ *
14
+ * @package shareaholic
15
+ */
16
+ class ShareaholicHttp {
17
+
18
+ /**
19
+ * Performs a HTTP request with a url and array of options
20
+ *
21
+ *
22
+ * The options object is an associative array that takes the following options:
23
+ * - method: The http method for the request as a string. Defaults is 'GET'.
24
+ *
25
+ * - headers: The headers to send with the request as an associative array of name/value pairs. Default is empty array.
26
+ *
27
+ * - body: The body to send with the request as an associative array of name/value pairs. Default is NULL.
28
+ * If the body is meant to be parsed as json, specify the content type in the headers option to be 'application/json'.
29
+ *
30
+ * - redirection: The number of redirects to follow for this request as an integer, Default is 5.
31
+ *
32
+ * - timeout: The number of seconds the request should take as an integer. Default is 15 (seconds).
33
+ *
34
+ * - user-agent: The useragent for the request. Default is mozilla browser useragent.
35
+ *
36
+ *
37
+ * This function returns an object of the response.
38
+ * The object is an associative array with the following keys:
39
+ * - body: the response body as a string
40
+ * - response: an array with the following keys:
41
+ * - code: the response code
42
+ *
43
+ *
44
+ * @param string $url The url you are sending the request to
45
+ * @param array $options An array of supported options to pass to the request
46
+ *
47
+ * @return array It returns an associative array of name value pairs
48
+ */
49
+ public static function send($url, $options = array()) {
50
+ return self::send_with_curl($url, $options);
51
+ }
52
+
53
+ private static function send_with_curl($url, $options) {
54
+ $curl_handle = curl_init($url);
55
+
56
+ curl_setopt($curl_handle, CURLOPT_HEADER, 0);
57
+ curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
58
+
59
+ // set the timeout
60
+ $timeout = isset($options['timeout']) ? $options['timeout'] : 15;
61
+ curl_setopt($curl_handle, CURLOPT_TIMEOUT, $timeout);
62
+
63
+ // set the http method: default is GET
64
+ if($option['method'] === 'POST') {
65
+ curl_setopt($curl_handle, CURLOPT_POST, 1);
66
+ }
67
+
68
+ // set the body and headers
69
+ $headers = isset($options['headers']) ? $options['headers'] : array();
70
+ $body = isset($options['body']) ? $options['body'] : NULL;
71
+
72
+ if(isset($body)) {
73
+ if(isset($headers['Content-Type']) && $headers['Content-Type'] === 'application/json') {
74
+ $data_string = json_encode($body);
75
+
76
+ curl_setopt($curl_handle, CURLOPT_HTTPHEADER, array(
77
+ 'Content-Type: application/json',
78
+ 'Content-Length: ' . strlen($data_string))
79
+ );
80
+
81
+ curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $data_string);
82
+ }
83
+ }
84
+
85
+ // set the useragent
86
+ $useragent = isset($options['user-agent']) ? $options['user-agent'] : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0';
87
+ curl_setopt($curl_handle, CURLOPT_USERAGENT, $useragent);
88
+
89
+ // set the max redirects
90
+ if(isset($options['redirection'])) {
91
+ curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true);
92
+ curl_setopt($curl_handle, CURLOPT_MAXREDIRS, $option['redirection']);
93
+ }
94
+
95
+ $output = curl_exec($curl_handle);
96
+
97
+ $result['body'] = $output;
98
+ $result['response'] = array(
99
+ 'code' => curl_getinfo($curl_handle, CURLINFO_HTTP_CODE),
100
+ );
101
+
102
+ curl_close($curl_handle);
103
+ return $result;
104
+ }
105
+ }
lib/social-share-counts/index.html ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="refresh" content="0; url=https://shareaholic.com">
4
+ </head>
5
+ <body>
6
+ Redirecting you now...
7
+ </body>
8
+ </html>
lib/social-share-counts/seq_share_count.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Shareaholic Sequential Share Count
4
+ *
5
+ * @package shareaholic
6
+ * @version 1.0.0.0
7
+ */
8
+
9
+ require_once('share_count.php');
10
+
11
+ /**
12
+ * A class that implements ShareaholicShareCounts
13
+ * This class will get the share counts by calling
14
+ * the social services sequentially
15
+ *
16
+ * @package shareaholic
17
+ */
18
+
19
+ class ShareaholicSeqShareCount extends ShareaholicShareCount {
20
+
21
+ /**
22
+ * This function should get all the counts for the
23
+ * supported services
24
+ *
25
+ * It should return an associative array with the services as
26
+ * the keys and the counts as the value.
27
+ *
28
+ * Example:
29
+ * array('facebook' => 12, 'google_plus' => 0, 'twitter' => 14, ...);
30
+ *
31
+ * @return Array an associative array of service => counts
32
+ */
33
+ public function get_counts() {
34
+ $services_length = count($this->services);
35
+ $config = $this->get_services_config();
36
+ $response = array();
37
+ $response['status'] = 200;
38
+
39
+ for($i = 0; $i < $services_length; $i++) {
40
+ $service = $this->services[$i];
41
+
42
+ if(!isset($config[$service])) {
43
+ continue;
44
+ }
45
+
46
+ if(isset($config[$service]['prepare'])) {
47
+ $this->$config[$service]['prepare']($this->url, $config);
48
+ }
49
+
50
+ $options = array(
51
+ 'method' => $config[$service]['method'],
52
+ 'timeout' => 1,
53
+ 'headers' => isset($config[$service]['headers']) ? $config[$service]['headers'] : array(),
54
+ 'body' => isset($config[$service]['body']) ? $config[$service]['body'] : NULL,
55
+ );
56
+
57
+ $result = ShareaholicHttp::send(sprintf($config[$service]['url'], $this->url), $options);
58
+ if(!$result) {
59
+ $response['status'] = 500;
60
+ }
61
+ $callback = $config[$service]['callback'];
62
+ $response['data'][$service] = $this->$callback($result);
63
+ }
64
+ return $response;
65
+ }
66
+ }
lib/social-share-counts/seq_share_count_test.php ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once('seq_share_count.php');
4
+ require_once('http.php');
5
+
6
+ class ShareaholicSeqShareCountsTest extends PHPUnit_Framework_TestCase
7
+ {
8
+ public function setUp() {
9
+ $this->url = 'https://blog.shareaholic.com';
10
+ $counts = new ShareaholicSeqShareCount($this->url, array());
11
+ $this->services = array_keys($counts->get_services_config());
12
+
13
+ // all callbacks take a predefined response structure
14
+ $this->response = array(
15
+ 'response' => array(
16
+ 'code' => 200
17
+ ),
18
+ );
19
+ }
20
+
21
+ public function tearDown() {
22
+
23
+ }
24
+
25
+ public function testFacebookCountCallback() {
26
+ // given a typical facebook counts api response, test that
27
+ // it gives back the expected result (the total_count which is 16)
28
+ $json = '[{"url":"https:\/\/blog.shareaholic.com\/","normalized_url":"https:\/\/blog.shareaholic.com\/","share_count":12,"like_count":4,"comment_count":0,"total_count":16,"click_count":0,"comments_fbid":350586041699622,"commentsbox_count":0}]';
29
+ $this->response['body'] = $json;
30
+
31
+ $share_count = new ShareaholicSeqShareCount($this->url, $this->services);
32
+ $facebook_count = $share_count->facebook_count_callback($this->response);
33
+
34
+ $this->assertEquals(16, $facebook_count, 'It should get the correct fb count');
35
+ }
36
+
37
+
38
+ public function testTwitterCountCallback() {
39
+ // given a typical twitter counts api response, test that
40
+ // it gives back the expected result (the count which is 3)
41
+ $json = '{"count":3,"url":"https:\/\/blog.shareaholic.com\/"}';
42
+ $this->response['body'] = $json;
43
+
44
+ $share_count = new ShareaholicSeqShareCount($this->url, $this->services);
45
+ $twitter_count = $share_count->twitter_count_callback($this->response);
46
+
47
+ $this->assertEquals(3, $twitter_count, 'It should get the correct twtr count');
48
+ }
49
+
50
+
51
+ public function testLinkedinCountCallback() {
52
+ // given a typical linkedin counts api response, test that
53
+ // it gives back the expected result (the count which is 8)
54
+ $json = '{"count":8,"fCnt":"8","fCntPlusOne":"9","url":"https:\/\/blog.shareaholic.com\/"}';
55
+ $this->response['body'] = $json;
56
+
57
+ $share_count = new ShareaholicSeqShareCount($this->url, $this->services);
58
+ $linkedin_count = $share_count->linkedin_count_callback($this->response);
59
+
60
+ $this->assertEquals(8, $linkedin_count, 'It should get the correct linkedin count');
61
+ }
62
+
63
+
64
+ public function testGoogleplusCountCallback() {
65
+ // given a typical google+ counts api response, test that
66
+ // it gives back the expected result (the count which is 10)
67
+ $json = '[{"id": "p", "result": {"kind": "pos#plusones", "id": "https://blog.shareaholic.com/", "isSetByViewer": false, "metadata": {"type": "URL", "globalCounts": {"count": 10.0}}}}]';
68
+ $this->response['body'] = $json;
69
+
70
+ $share_count = new ShareaholicSeqShareCount($this->url, $this->services);
71
+ $google_plus_count = $share_count->google_plus_count_callback($this->response);
72
+
73
+ $this->assertEquals(10, $google_plus_count, 'It should get the correct google_plus count');
74
+ }
75
+
76
+
77
+ public function testDeliciousCountCallback() {
78
+ // given a typical delicious counts api response, test that
79
+ // it gives back the expected result (the total_posts which is 5462)
80
+ $json = '[{"url": "http://www.delicious.com/", "total_posts": 5462, "top_tags": {"web2.0": 1, "web": 1, "search": 1, "technology": 1, "bookmarking": 1, "del.icio.us": 1, "delicious": 1, "social": 1, "home": 1, "tools": 1}, "hash": "ea83167936715d3f712f4fb6c78f92d2", "title": "Delicious"}]';
81
+ $this->response['body'] = $json;
82
+
83
+ $share_count = new ShareaholicSeqShareCount('http://www.delicious.com/', $this->services);
84
+ $delicious_count = $share_count->delicious_count_callback($this->response);
85
+
86
+ $this->assertEquals(5462, $delicious_count, 'It should get the correct delicious count');
87
+ }
88
+
89
+
90
+ public function testPinterestCountCallback() {
91
+ // given a typical pinterest counts api response, test that
92
+ // it gives back the expected result (the count which is 1)
93
+ $body = 'f({"count": 1, "url": "https://blog.shareaholic.com"})';
94
+ $this->response['body'] = $body;
95
+
96
+ $share_count = new ShareaholicSeqShareCount($this->url, $this->services);
97
+ $count = $share_count->pinterest_count_callback($this->response);
98
+
99
+ $this->assertEquals(1, $count, 'It should get the correct pinterest count');
100
+ }
101
+
102
+
103
+ public function testBufferCountCallback() {
104
+ // given a typical buffer counts api response, test that
105
+ // it gives back the expected result (the shares which is 3)
106
+ $body = '{"shares":3}';
107
+ $this->response['body'] = $body;
108
+
109
+ $share_count = new ShareaholicSeqShareCount($this->url, $this->services);
110
+ $count = $share_count->buffer_count_callback($this->response);
111
+
112
+ $this->assertEquals(3, $count, 'It should get the correct buffer count');
113
+ }
114
+
115
+ public function testStumbleuponCountCallback() {
116
+ // given a typical stumbleupon counts api response, test that
117
+ // it gives back the expected result (the views which is 1)
118
+ $body = '{"result":{"url":"https:\/\/blog.shareaholic.com\/","in_index":true,"publicid":"1Qat7p","views":1,"title":"Blog \/ Shareaholic (@shareaholic)","thumbnail":"http:\/\/cdn.stumble-upon.com\/mthumb\/672\/157433672.jpg","thumbnail_b":"http:\/\/cdn.stumble-upon.com\/bthumb\/672\/157433672.jpg","submit_link":"http:\/\/www.stumbleupon.com\/submit\/?url=https:\/\/blog.shareaholic.com\/","badge_link":"http:\/\/www.stumbleupon.com\/badge\/?url=https:\/\/blog.shareaholic.com\/","info_link":"http:\/\/www.stumbleupon.com\/url\/https%253A\/\/blog.shareaholic.com\/"},"timestamp":1394771877,"success":true}';
119
+ $this->response['body'] = $body;
120
+
121
+ $share_count = new ShareaholicSeqShareCount($this->url, $this->services);
122
+ $count = $share_count->stumbleupon_count_callback($this->response);
123
+
124
+ $this->assertEquals(1, $count, 'It should get the correct stumbleupon count');
125
+ }
126
+
127
+ public function testRedditCountCallback() {
128
+ // given a typical reddit counts api response, test that
129
+ // it gives back the expected result (the ups which is 1)
130
+ // NOTE: the actual JSON output was too long so some keys were removed
131
+ $body = '{"kind": "Listing", "data": {"modhash": "", "children": [{"kind": "t3", "data": {"domain": "reddit.com", "banned_by": null, "likes": null, "clicked": false, "stickied": false, "score": 1, "downs": 0, "url": "http://reddit.com", "ups": 1, "num_comments": 0, "distinguished": null}}], "after": null, "before": null}}';
132
+ $this->response['body'] = $body;
133
+
134
+ $share_count = new ShareaholicSeqShareCount($this->url, $this->services);
135
+ $count = $share_count->reddit_count_callback($this->response);
136
+
137
+ $this->assertEquals(1, $count, 'It should get the correct reddit count');
138
+ }
139
+
140
+ public function testVkCountCallback() {
141
+ // given a typical vk counts api response, test that
142
+ // it gives back the expected result (3781)
143
+ $body = 'VK.Share.count(0, 3781);';
144
+ $this->response['body'] = $body;
145
+
146
+ $share_count = new ShareaholicSeqShareCount($this->url, $this->services);
147
+ $count = $share_count->vk_count_callback($this->response);
148
+
149
+ $this->assertEquals(3781, $count, 'It should get the correct vk count');
150
+ }
151
+
152
+ public function testOdnoklassnikiCountCallback() {
153
+ // given a typical odnoklassniki counts api response, test that
154
+ // it gives back the expected result (1)
155
+ $body = "ODKL.updateCount('odklcnt0','1');";
156
+ $this->response['body'] = $body;
157
+
158
+ $share_count = new ShareaholicSeqShareCount($this->url, $this->services);
159
+ $count = $share_count->odnoklassniki_count_callback($this->response);
160
+
161
+ $this->assertEquals(1, $count, 'It should get the correct odnoklassniki count');
162
+ }
163
+
164
+ public function testGooglePlusPrepareRequest() {
165
+ $count = new ShareaholicSeqShareCount($this->url, $this->services);
166
+ $config = $count->get_services_config();
167
+
168
+ // check that the function sets the post body in the $config object
169
+ $count->google_plus_prepare_request($this->url, $config);
170
+ $this->assertNotNull($config['google_plus']['body'], 'The post body for google plus should not be null');
171
+
172
+ }
173
+
174
+ public function testGetCount() {
175
+ // test that this function returns the expected API response
176
+ $share_count = new ShareaholicSeqShareCount($this->url, $this->services);
177
+ $response = $share_count->get_counts();
178
+
179
+ $this->assertNotNull($response, 'The response array should not be null');
180
+
181
+ foreach($this->services as $service) {
182
+ $this->assertNotNull($response['data'][$service], 'The ' . $service . ' count should not be null');
183
+ }
184
+ }
185
+
186
+ }
lib/social-share-counts/share_count.php ADDED
@@ -0,0 +1,325 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Shareaholic's Social Share Counts Library
4
+ *
5
+ * https://github.com/shareaholic/social-share-counts
6
+ *
7
+ * @package shareaholic
8
+ * @version 1.0.0.0
9
+ */
10
+
11
+ /**
12
+ * An abstract class Share Counts to be extended
13
+ *
14
+ * @package shareaholic
15
+ */
16
+ abstract class ShareaholicShareCount {
17
+
18
+ protected $url;
19
+ protected $services;
20
+
21
+ public function __construct($url, $services) {
22
+ $this->url = $url;
23
+ $this->services = $services;
24
+ }
25
+
26
+ public function get_services_config() {
27
+ return array(
28
+ 'facebook' => array(
29
+ 'url' => 'https://api.facebook.com/method/links.getStats?format=json&urls=%s',
30
+ 'method' => 'GET',
31
+ 'callback' => 'facebook_count_callback',
32
+ ),
33
+ 'twitter' => array(
34
+ 'url' => 'http://cdn.api.twitter.com/1/urls/count.json?url=%s',
35
+ 'method' => 'GET',
36
+ 'callback' => 'twitter_count_callback',
37
+ ),
38
+ 'linkedin' => array(
39
+ 'url' => 'http://www.linkedin.com/countserv/count/share?format=json&url=%s',
40
+ 'method' => 'GET',
41
+ 'callback' => 'linkedin_count_callback',
42
+ ),
43
+ 'google_plus' => array(
44
+ 'url' => 'https://clients6.google.com/rpc',
45
+ 'method' => 'POST',
46
+ 'headers' => array('Content-Type' => 'application/json'),
47
+ 'body' => NULL,
48
+ 'prepare' => 'google_plus_prepare_request',
49
+ 'callback' => 'google_plus_count_callback',
50
+ ),
51
+ 'delicious' => array(
52
+ 'url' => 'http://feeds.delicious.com/v2/json/urlinfo/data?url=%s',
53
+ 'method' => 'GET',
54
+ 'callback' => 'delicious_count_callback',
55
+ ),
56
+ 'pinterest' => array(
57
+ 'url' => 'http://api.pinterest.com/v1/urls/count.json?url=%s&callback=f',
58
+ 'method' => 'GET',
59
+ 'callback' => 'pinterest_count_callback',
60
+ ),
61
+ 'buffer' => array(
62
+ 'url' => 'https://api.bufferapp.com/1/links/shares.json?url=%s',
63
+ 'method' => 'GET',
64
+ 'callback' => 'buffer_count_callback',
65
+ ),
66
+ 'stumbleupon' => array(
67
+ 'url' => 'http://www.stumbleupon.com/services/1.01/badge.getinfo?url=%s',
68
+ 'method' => 'GET',
69
+ 'callback' => 'stumbleupon_count_callback',
70
+ ),
71
+ 'reddit' => array(
72
+ 'url' => 'http://buttons.reddit.com/button_info.json?url=%s',
73
+ 'method' => 'GET',
74
+ 'callback' => 'reddit_count_callback',
75
+ ),
76
+ 'vk' => array(
77
+ 'url' => 'http://vk.com/share.php?act=count&url=%s',
78
+ 'method' => 'GET',
79
+ 'callback' => 'vk_count_callback',
80
+ ),
81
+ 'odnoklassniki' => array(
82
+ 'url' => 'http://www.odnoklassniki.ru/dk?st.cmd=extLike&uid=odklcnt0&ref=%s',
83
+ 'method' => 'GET',
84
+ 'callback' => 'odnoklassniki_count_callback',
85
+ ),
86
+ );
87
+ }
88
+
89
+
90
+ /**
91
+ * Callback function for facebook count API
92
+ * Gets the facebook counts from response
93
+ *
94
+ * @param Array $response The response from calling the API
95
+ * @return Integer The counts from the API
96
+ */
97
+ public function facebook_count_callback($response) {
98
+ if(!$response || !preg_match('/20*/', $response['response']['code'])) {
99
+ return 0;
100
+ }
101
+ $body = json_decode($response['body'], true);
102
+ return isset($body[0]['total_count']) ? $body[0]['total_count'] : 0;
103
+ }
104
+
105
+
106
+ /**
107
+ * Callback function for twitter count API
108
+ * Gets the twitter counts from response
109
+ *
110
+ * @param Array $response The response from calling the API
111
+ * @return Integer The counts from the API
112
+ */
113
+ public function twitter_count_callback($response) {
114
+ if(!$response || !preg_match('/20*/', $response['response']['code'])) {
115
+ return 0;
116
+ }
117
+ $body = json_decode($response['body'], true);
118
+ return isset($body['count']) ? $body['count'] : 0;
119
+ }
120
+
121
+
122
+ /**
123
+ * Callback function for linkedin count API
124
+ * Gets the linkedin counts from response
125
+ *
126
+ * @param Array $response The response from calling the API
127
+ * @return Integer The counts from the API
128
+ */
129
+ public function linkedin_count_callback($response) {
130
+ if(!$response || !preg_match('/20*/', $response['response']['code'])) {
131
+ return 0;
132
+ }
133
+ $body = json_decode($response['body'], true);
134
+ return isset($body['count']) ? $body['count'] : 0;
135
+ }
136
+
137
+
138
+ /**
139
+ * A preprocess function to be called necessary to prepare
140
+ * the request to the service.
141
+ *
142
+ * One may customize the headers or body to their liking
143
+ * before the request is sent. The customization should
144
+ * update the services config where it will be read by
145
+ * the get_counts() function
146
+ *
147
+ * @param $url The url needed by google_plus to be passed in to the body
148
+ * @param $config The services configuration object to be updated
149
+ */
150
+ public function google_plus_prepare_request($url, &$config) {
151
+ $post_fields = array(
152
+ array(
153
+ 'method' => 'pos.plusones.get',
154
+ 'id' => 'p',
155
+ 'params' => array(
156
+ 'nolog' => true,
157
+ 'id' => $url,
158
+ 'source' => 'widget',
159
+ 'userId' => '@viewer',
160
+ 'groupId' => '@self',
161
+ ),
162
+ 'jsonrpc' => '2.0',
163
+ 'key' => 'p',
164
+ 'apiVersion' => 'v1',
165
+ )
166
+ );
167
+
168
+ $config['google_plus']['body'] = $post_fields;
169
+ }
170
+
171
+
172
+ /**
173
+ * Callback function for google plus count API
174
+ * Gets the google plus counts from response
175
+ *
176
+ * @param Array $response The response from calling the API
177
+ * @return Integer The counts from the API
178
+ */
179
+ public function google_plus_count_callback($response) {
180
+ if(!$response || !preg_match('/20*/', $response['response']['code'])) {
181
+ return 0;
182
+ }
183
+ $body = json_decode($response['body'], true);
184
+ return isset($body[0]['result']['metadata']['globalCounts']['count']) ? intval($body[0]['result']['metadata']['globalCounts']['count']) : 0;
185
+ }
186
+
187
+
188
+ /**
189
+ * Callback function for delicious count API
190
+ * Gets the delicious counts from response
191
+ *
192
+ * @param Array $response The response from calling the API
193
+ * @return Integer The counts from the API
194
+ */
195
+ public function delicious_count_callback($response) {
196
+ if(!$response || !preg_match('/20*/', $response['response']['code'])) {
197
+ return 0;
198
+ }
199
+ $body = json_decode($response['body'], true);
200
+ return isset($body[0]['total_posts']) ? $body[0]['total_posts'] : 0;
201
+ }
202
+
203
+
204
+ /**
205
+ * Callback function for pinterest count API
206
+ * Gets the pinterest counts from response
207
+ *
208
+ * @param Array $response The response from calling the API
209
+ * @return Integer The counts from the API
210
+ */
211
+ public function pinterest_count_callback($response) {
212
+ if(!$response || !preg_match('/20*/', $response['response']['code'])) {
213
+ return 0;
214
+ }
215
+ $response['body'] = substr($response['body'], 2, strlen($response['body']) - 3);
216
+ $body = json_decode($response['body'], true);
217
+ return isset($body['count']) ? $body['count'] : 0;
218
+ }
219
+
220
+
221
+ /**
222
+ * Callback function for buffer count API
223
+ * Gets the buffer share counts from response
224
+ *
225
+ * @param Array $response The response from calling the API
226
+ * @return Integer The counts from the API
227
+ */
228
+ public function buffer_count_callback($response) {
229
+ if(!$response || !preg_match('/20*/', $response['response']['code'])) {
230
+ return 0;
231
+ }
232
+ $body = json_decode($response['body'], true);
233
+ return isset($body['shares']) ? $body['shares'] : 0;
234
+ }
235
+
236
+
237
+ /**
238
+ * Callback function for stumbleupon count API
239
+ * Gets the stumbleupon counts from response
240
+ *
241
+ * @param Array $response The response from calling the API
242
+ * @return Integer The counts from the API
243
+ */
244
+ public function stumbleupon_count_callback($response) {
245
+ if(!$response || !preg_match('/20*/', $response['response']['code'])) {
246
+ return 0;
247
+ }
248
+ $body = json_decode($response['body'], true);
249
+ return isset($body['result']['views']) ? $body['result']['views'] : 0;
250
+ }
251
+
252
+
253
+ /**
254
+ * Callback function for reddit count API
255
+ * Gets the reddit counts from response
256
+ *
257
+ * @param Array $response The response from calling the API
258
+ * @return Integer The counts from the API
259
+ */
260
+ public function reddit_count_callback($response) {
261
+ if(!$response || !preg_match('/20*/', $response['response']['code'])) {
262
+ return 0;
263
+ }
264
+ $body = json_decode($response['body'], true);
265
+ return isset($body['data']['children'][0]['data']['ups']) ? $body['data']['children'][0]['data']['ups'] : 0;
266
+ }
267
+
268
+
269
+ /**
270
+ * Callback function for vk count API
271
+ * Gets the vk counts from response
272
+ *
273
+ * @param Array $response The response from calling the API
274
+ * @return Integer The counts from the API
275
+ */
276
+ public function vk_count_callback($response) {
277
+ if(!$response || !preg_match('/20*/', $response['response']['code'])) {
278
+ return 0;
279
+ }
280
+
281
+ // This API does not return JSON. Just plain text JS. Example:
282
+ // 'VK.Share.count(0, 3779);'
283
+ // From documentation, need to just grab the 2nd param: http://vk.com/developers.php?oid=-17680044&p=Share
284
+ $matches = array();
285
+ preg_match('/^VK\.Share\.count\(\d, (\d+)\);$/i', $response['body'], $matches);
286
+ return isset($matches[1]) ? intval($matches[1]) : 0;
287
+ }
288
+
289
+
290
+ /**
291
+ * Callback function for odnoklassniki count API
292
+ * Gets the odnoklassniki counts from response
293
+ *
294
+ * @param Array $response The response from calling the API
295
+ * @return Integer The counts from the API
296
+ */
297
+ public function odnoklassniki_count_callback($response) {
298
+ if(!$response || !preg_match('/20*/', $response['response']['code'])) {
299
+ return 0;
300
+ }
301
+
302
+ // Another weird API. Similar to vk, extract the 2nd param from the response:
303
+ // 'ODKL.updateCount('odklcnt0','14198');'
304
+ $matches = array();
305
+ preg_match('/^ODKL\.updateCount\(\'odklcnt0\',\'(\d+)\'\);$/i', $response['body'], $matches);
306
+ return isset($matches[1]) ? intval($matches[1]) : 0;
307
+ }
308
+
309
+
310
+ /**
311
+ * The abstract function to be implemented by its children
312
+ * This function should get all the counts for the
313
+ * supported services
314
+ *
315
+ * It should return an associative array with the services as
316
+ * the keys and the counts as the value.
317
+ *
318
+ * Example:
319
+ * array('facebook' => 12, 'google_plus' => 0, 'twitter' => 14, ...);
320
+ *
321
+ * @return Array an associative array of service => counts
322
+ */
323
+ public abstract function get_counts();
324
+
325
+ }
lib/social-share-counts/wordpress_http.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file holds the ShareaholicHttp class.
4
+ *
5
+ * @package shareaholic
6
+ */
7
+
8
+ /**
9
+ * The purpose of this class is to provide an interface around any native
10
+ * http function (wp_remote_get, drupal_http_request, curl) so that one
11
+ * use this consistent API for making http request with well defined input
12
+ * and output.
13
+ *
14
+ * @package shareaholic
15
+ */
16
+ class ShareaholicHttp {
17
+
18
+ /**
19
+ * Performs a HTTP request with a url, array of options, and ignore_error flag
20
+ *
21
+ *
22
+ * The options object is an associative array that takes the following options:
23
+ * - method: The http method for the request as a string. Defaults is 'GET'.
24
+ *
25
+ * - headers: The headers to send with the request as an associative array of name/value pairs. Default is empty array.
26
+ *
27
+ * - body: The body to send with the request as an associative array of name/value pairs. Default is NULL.
28
+ * If the body is meant to be parsed as json, specify the content type in the headers option to be 'application/json'.
29
+ *
30
+ * - redirection: The number of redirects to follow for this request as an integer, Default is 5.
31
+ *
32
+ * - timeout: The number of seconds the request should take as an integer. Default is 15 (seconds).
33
+ *
34
+ * - user-agent: The useragent for the request. Default is mozilla browser useragent.
35
+ *
36
+ *
37
+ * This function returns an object on success or false if there were errors.
38
+ * The object is an associative array with the following keys:
39
+ * - headers: the response headers as an array of key/value pairs
40
+ * - body: the response body as a string
41
+ * - response: an array with the following keys:
42
+ * - code: the response code
43
+ * - message: the status message
44
+ *
45
+ *
46
+ * @param string $url The url you are sending the request to
47
+ * @param array $options An array of supported options to pass to the request
48
+ * @param bool $ignore_error A flag indicating to log error or not. Default is false.
49
+ *
50
+ * @return mixed It returns an associative array of name value pairs or false if there was an error.
51
+ */
52
+ public static function send($url, $options = array(), $ignore_error = false) {
53
+ return self::send_with_wp($url, $options, $ignore_error);
54
+ }
55
+
56
+ private static function send_with_wp($url, $options, $ignore_error) {
57
+ $request = array();
58
+ $result = array();
59
+ $request['method'] = isset($options['method']) ? $options['method'] : 'GET';
60
+ $request['headers'] = isset($options['headers']) ? $options['headers'] : array();
61
+ $request['redirection'] = isset($options['redirection']) ? $options['redirection'] : 5;
62
+ $request['timeout'] = isset($options['timeout']) ? $options['timeout'] : 15;
63
+ $request['user-agent'] = isset($options['user-agent']) ? $options['user-agent'] : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0';
64
+
65
+ if(isset($options['body'])) {
66
+ if(isset($request['headers']['Content-Type']) && $request['headers']['Content-Type'] === 'application/json') {
67
+ $request['body'] = json_encode($options['body']);
68
+ } else {
69
+ $request['body'] = $options['body'];
70
+ }
71
+ } else {
72
+ $request['body'] = NULL;
73
+ }
74
+ $request['sslverify'] = false;
75
+
76
+ $response = wp_remote_request($url, $request);
77
+
78
+ if (is_wp_error($response)) {
79
+ $error_message = $response->get_error_message();
80
+ ShareaholicUtilities::log($error_message);
81
+ if (!$ignore_error) {
82
+ ShareaholicUtilities::log_event('HttpRequestFailure', array('error_message' => $error_message, 'url' => $url));
83
+ }
84
+ return false;
85
+ }
86
+
87
+ return $response;
88
+ }
89
+ }
public.php CHANGED
@@ -5,6 +5,11 @@
5
  * @package shareaholic
6
  */
7
 
 
 
 
 
 
8
  /**
9
  * This class is all about drawing the stuff in publishers'
10
  * templates that visitors can see.
@@ -401,6 +406,39 @@ class ShareaholicPublic {
401
 
402
  return trim(preg_replace('/\s+/', ' ', $canvas));
403
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
  }
405
 
406
  ?>
5
  * @package shareaholic
6
  */
7
 
8
+ // Get the required libraries for the Share Counts API
9
+ require_once(SHAREAHOLIC_DIR . '/lib/social-share-counts/wordpress_http.php');
10
+ require_once(SHAREAHOLIC_DIR . '/lib/social-share-counts/seq_share_count.php');
11
+ require_once(SHAREAHOLIC_DIR . '/lib/social-share-counts/curl_multi_share_count.php');
12
+
13
  /**
14
  * This class is all about drawing the stuff in publishers'
15
  * templates that visitors can see.
406
 
407
  return trim(preg_replace('/\s+/', ' ', $canvas));
408
  }
409
+
410
+
411
+ /**
412
+ * Function to handle the share count API requests
413
+ *
414
+ */
415
+ public static function share_counts_api() {
416
+ $url = isset($_GET['url']) ? $_GET['url'] : NULL;
417
+ $services = isset($_GET['services']) ? $_GET['services'] : NULL;
418
+ $result = array();
419
+
420
+ if(is_array($services) && count($services) > 0 && !empty($url)) {
421
+ if(self::has_curl()) {
422
+ $shares = new ShareaholicCurlMultiShareCount($url, $services);
423
+ } else {
424
+ $shares = new ShareaholicSeqShareCount($url, $services);
425
+ }
426
+ $result = $shares->get_counts();
427
+ }
428
+
429
+ header('Content-Type: application/json');
430
+ echo json_encode($result);
431
+ exit;
432
+ }
433
+
434
+ /**
435
+ * Checks to see if curl is installed
436
+ *
437
+ * @return bool true or false that curl is installed
438
+ */
439
+ public static function has_curl() {
440
+ return function_exists('curl_version') && function_exists('curl_multi_init') && function_exists('curl_multi_add_handle') && function_exists('curl_multi_exec');
441
+ }
442
  }
443
 
444
  ?>
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: shareaholic
3
  Tags: sexybookmarks, shareaholic, shareholic, facebook, twitter, linkedin, URL Shortener, bitly, tinyurl, Goo.gl, Google+1, Google Analytics, Google Plus, Google, Instapaper, Wish List, Digg, Gmail, Google Bookmarks, Translate, Tumblr, AIM, Yahoo Messenger, Delicious, StumbleUpon, mister wong, evernote, add this, addtoany, share this, sharethis, share and follow, share and enjoy, sharing is sexy, sharing is caring, yahoo, reddit, hackernews, tweet button, twitter button, fark, buffer, myspace, orkut, netlog, hubspot, weheartit, printfriendly, yammer, wanelo, pinterest, google translate, bookmarks, social, email button, social share, socialize, sociable, sharebar, bookmark button, share button, social bookmarking, bookmarks menu, bookmarking, share, seo, analytics, stats, sharing, facebook like, facebook recommend, WPMU, mutisite, shortcode, yaarp, yarpp, nrelate, outbrain, linkwithin, related content, related posts, related, popular posts, popular, thumbnails, recommendations
4
  Requires at least: 3.0
5
  Tested up to: 3.8.1
6
- Stable tag: 7.2.2.0
7
 
8
  Adds an attractive social bookmarking menu and related content widget to your posts, pages, index, or any combination of the three.
9
 
@@ -12,6 +12,7 @@ Adds an attractive social bookmarking menu and related content widget to your po
12
  Three powerful apps to amplify your content and create conversations, across the web. Shareaholic has proven time and time again to be an extremely useful and successful tool in getting your readers to actually **discover** and **submit your articles** to numerous social bookmarking sites.
13
 
14
  = Recent Updates =
 
15
  * [Shareable Images](https://blog.shareaholic.com/image-share-buttons/) (share buttons for images)
16
  * Recommendations & Related Content - Increases engagement and time on site by highlighting relevant content that may not otherwise be discovered from across your site.
17
  * Social Analytics - Provides you with important actionable metrics including insights into how your content is performing, who's sharing it, and through which channels.
@@ -152,13 +153,27 @@ Please see here: [Usage & Installation Instructions](https://shareaholic.com/too
152
 
153
  == Changelog ==
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  = 7.2.2.0 =
156
- * Miscellaneous performance enhancements and big fixes
157
  * New / updated translations:
158
- -> French (by Rozenn Dagorn)
159
- -> German (by Oliver Heinrich)
160
- -> Dutch (by Patrick Ruers)
161
- -> Greek (by Takis Bouyouris)
162
 
163
  = 7.2.1.0 =
164
  * Admin Bar is now configurable
@@ -1019,7 +1034,11 @@ Please see here: [Usage & Installation Instructions](https://shareaholic.com/too
1019
 
1020
  == Upgrade Notice ==
1021
 
 
 
 
1022
  = 7.2.2.0 =
 
1023
 
1024
  = 7.2.1.0 =
1025
  The Admin Bar is now configurable and we also fixed the Related Content data processing status indicator. Also includes miscellaneous plugin performance enhancements.
3
  Tags: sexybookmarks, shareaholic, shareholic, facebook, twitter, linkedin, URL Shortener, bitly, tinyurl, Goo.gl, Google+1, Google Analytics, Google Plus, Google, Instapaper, Wish List, Digg, Gmail, Google Bookmarks, Translate, Tumblr, AIM, Yahoo Messenger, Delicious, StumbleUpon, mister wong, evernote, add this, addtoany, share this, sharethis, share and follow, share and enjoy, sharing is sexy, sharing is caring, yahoo, reddit, hackernews, tweet button, twitter button, fark, buffer, myspace, orkut, netlog, hubspot, weheartit, printfriendly, yammer, wanelo, pinterest, google translate, bookmarks, social, email button, social share, socialize, sociable, sharebar, bookmark button, share button, social bookmarking, bookmarks menu, bookmarking, share, seo, analytics, stats, sharing, facebook like, facebook recommend, WPMU, mutisite, shortcode, yaarp, yarpp, nrelate, outbrain, linkwithin, related content, related posts, related, popular posts, popular, thumbnails, recommendations
4
  Requires at least: 3.0
5
  Tested up to: 3.8.1
6
+ Stable tag: 7.3.0.0
7
 
8
  Adds an attractive social bookmarking menu and related content widget to your posts, pages, index, or any combination of the three.
9
 
12
  Three powerful apps to amplify your content and create conversations, across the web. Shareaholic has proven time and time again to be an extremely useful and successful tool in getting your readers to actually **discover** and **submit your articles** to numerous social bookmarking sites.
13
 
14
  = Recent Updates =
15
+ * Floating Share Buttons!
16
  * [Shareable Images](https://blog.shareaholic.com/image-share-buttons/) (share buttons for images)
17
  * Recommendations & Related Content - Increases engagement and time on site by highlighting relevant content that may not otherwise be discovered from across your site.
18
  * Social Analytics - Provides you with important actionable metrics including insights into how your content is performing, who's sharing it, and through which channels.
153
 
154
  == Changelog ==
155
 
156
+ = 7.3.0.0 =
157
+ * Share Buttons App
158
+ * New alignment options - you can now pick whether you want your text to wrap around your buttons
159
+ * Multishare toggle for Twitter
160
+ * New services:
161
+ * VK (the 2nd largest social network service in Europe after Facebook)
162
+ * Fancy (recommended for e-commerce sites)
163
+ * Wanelo (recommended for e-commerce sites)
164
+ * New Share Counts library
165
+ * Floating Share Buttons App (NEW!)
166
+ * To enable, click on "Edit General Settings" -> Sign In -> Click on "Site Tools" -> Turn on the "Floated Share Buttons" App
167
+ * Shareable Images App (NEW!) [learn more](https://blog.shareaholic.com/image-share-buttons/)
168
+ * To enable, click on "Edit General Settings" -> Sign In -> Turn on "Shareable Images"
169
+
170
  = 7.2.2.0 =
171
+ * Miscellaneous performance enhancements and bug fixes
172
  * New / updated translations:
173
+ * French (by Rozenn Dagorn)
174
+ * German (by Oliver Heinrich)
175
+ * Dutch (by Patrick Ruers)
176
+ * Greek (by Takis Bouyouris)
177
 
178
  = 7.2.1.0 =
179
  * Admin Bar is now configurable
1034
 
1035
  == Upgrade Notice ==
1036
 
1037
+ = 7.3.0.0 =
1038
+ Lots of new features - including Floating Share Buttons and Shareable Images!
1039
+
1040
  = 7.2.2.0 =
1041
+ New / updated translations for French (by Rozenn Dagorn), German (by Oliver Heinrich), Dutch (by Patrick Ruers) and Greek (by Takis Bouyouris)
1042
 
1043
  = 7.2.1.0 =
1044
  The Admin Bar is now configurable and we also fixed the Related Content data processing status indicator. Also includes miscellaneous plugin performance enhancements.
shareaholic.php CHANGED
@@ -3,14 +3,14 @@
3
  * The main file!
4
  *
5
  * @package shareaholic
6
- * @version 7.2.2.0
7
  */
8
 
9
  /*
10
  Plugin Name: Shareaholic | share buttons, analytics, related content
11
  Plugin URI: https://shareaholic.com/publishers/
12
  Description: Whether you want to get people sharing, grow your fans, make money, or know who's reading your content, Shareaholic will help you get it done. See <a href="admin.php?page=shareaholic-settings">configuration panel</a> for more settings.
13
- Version: 7.2.2.0
14
  Author: Shareaholic
15
  Author URI: https://shareaholic.com
16
  Text Domain: shareaholic
@@ -57,7 +57,7 @@ class Shareaholic {
57
  const CM_API_URL = 'https://cm-web.shareaholic.com'; // uses static IPs for firewall whitelisting
58
  const REC_API_URL = 'http://recommendations.shareaholic.com';
59
 
60
- const VERSION = '7.2.2.0';
61
 
62
  /**
63
  * Starts off as false so that ::get_instance() returns
@@ -105,6 +105,10 @@ class Shareaholic {
105
 
106
  add_action('wp_before_admin_bar_render', array('ShareaholicUtilities', 'admin_bar_extended'));
107
  add_filter('plugin_action_links_'.plugin_basename(__FILE__), 'ShareaholicUtilities::admin_plugin_action_links', -10);
 
 
 
 
108
  }
109
 
110
  /**
@@ -155,6 +159,9 @@ class Shareaholic {
155
  ShareaholicUtilities::perform_update();
156
  ShareaholicUtilities::set_version(self::VERSION);
157
  ShareaholicUtilities::notify_content_manager_singledomain();
 
 
 
158
  }
159
  }
160
  }
@@ -201,6 +208,13 @@ class Shareaholic {
201
  ShareaholicUtilities::log_event("Uninstall");
202
  delete_option('shareaholic_settings');
203
  }
 
 
 
 
 
 
 
204
  }
205
 
206
  // the magic
3
  * The main file!
4
  *
5
  * @package shareaholic
6
+ * @version 7.3.0.0
7
  */
8
 
9
  /*
10
  Plugin Name: Shareaholic | share buttons, analytics, related content
11
  Plugin URI: https://shareaholic.com/publishers/
12
  Description: Whether you want to get people sharing, grow your fans, make money, or know who's reading your content, Shareaholic will help you get it done. See <a href="admin.php?page=shareaholic-settings">configuration panel</a> for more settings.
13
+ Version: 7.3.0.0
14
  Author: Shareaholic
15
  Author URI: https://shareaholic.com
16
  Text Domain: shareaholic
57
  const CM_API_URL = 'https://cm-web.shareaholic.com'; // uses static IPs for firewall whitelisting
58
  const REC_API_URL = 'http://recommendations.shareaholic.com';
59
 
60
+ const VERSION = '7.3.0.0';
61
 
62
  /**
63
  * Starts off as false so that ::get_instance() returns
105
 
106
  add_action('wp_before_admin_bar_render', array('ShareaholicUtilities', 'admin_bar_extended'));
107
  add_filter('plugin_action_links_'.plugin_basename(__FILE__), 'ShareaholicUtilities::admin_plugin_action_links', -10);
108
+
109
+ // add action for share counts API call
110
+ add_action('wp_ajax_nopriv_shareaholic_share_counts_api', array($this, 'shareaholic_share_counts_api'));
111
+ add_action('wp_ajax_shareaholic_share_counts_api', array($this, 'shareaholic_share_counts_api'));
112
  }
113
 
114
  /**
159
  ShareaholicUtilities::perform_update();
160
  ShareaholicUtilities::set_version(self::VERSION);
161
  ShareaholicUtilities::notify_content_manager_singledomain();
162
+ if(has_action('wp_ajax_nopriv_shareaholic_share_counts_api') && has_action('wp_ajax_shareaholic_share_counts_api')) {
163
+ $result = ShareaholicCurl::get(admin_url('admin-ajax.php') . '?action=shareaholic_share_counts_api&url=http%3A%2F%2Fwww.odnoklassniki.ru%2F&services[]=twitter');
164
+ }
165
  }
166
  }
167
  }
208
  ShareaholicUtilities::log_event("Uninstall");
209
  delete_option('shareaholic_settings');
210
  }
211
+
212
+ /**
213
+ * This function handles the API request to get the share counts
214
+ */
215
+ public function shareaholic_share_counts_api() {
216
+ ShareaholicPublic::share_counts_api();
217
+ }
218
  }
219
 
220
  // the magic
templates/index.html CHANGED
@@ -1,6 +1,6 @@
1
  <html>
2
  <head>
3
- <meta http-equiv="refresh" content="0; url=http://www.shareaholic.com">
4
  </head>
5
  <body>
6
  Redirecting you now...
1
  <html>
2
  <head>
3
+ <meta http-equiv="refresh" content="0; url=https://shareaholic.com">
4
  </head>
5
  <body>
6
  Redirecting you now...