SNS Count Cache - Version 0.1.0

Version Description

  • Initial working version.

=

Download this release

Release Info

Developer marubon
Plugin Icon SNS Count Cache
Version 0.1.0
Comparing to
See all releases

Version 0.1.0

admin.php ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ admin.php
4
+
5
+ Description: Option page implementation
6
+ Version: 0.1.0
7
+ Author: Daisuke Maruyama
8
+ Author URI: http://marubon.info/
9
+ License: GPL2 or later
10
+ License URI: http://www.gnu.org/licenses/gpl-2.0.txt
11
+ */
12
+
13
+ /*
14
+
15
+ Copyright (C) 2014 Daisuke Maruyama
16
+
17
+ This program is free software; you can redistribute it and/or
18
+ modify it under the terms of the GNU General Public License
19
+ as published by the Free Software Foundation; either version 2
20
+ of the License, or (at your option) any later version.
21
+
22
+ This program is distributed in the hope that it will be useful,
23
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
24
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
+ GNU General Public License for more details.
26
+
27
+ You should have received a copy of the GNU General Public License
28
+ along with this program; if not, write to the Free Software
29
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30
+
31
+ */
32
+
33
+ $count = 1;
34
+ $query_args = array(
35
+ 'post_type' => 'post',
36
+ 'post_status' => 'publish',
37
+ 'nopaging' => true,
38
+ 'update_post_term_cache' => false,
39
+ 'update_post_meta_cache' => false
40
+ );
41
+
42
+ $posts_query = new WP_Query($query_args);
43
+ ?>
44
+ <div class="wrap">
45
+ <h2>SNS Count Cache</h2>
46
+ <div class="sns-cnt-cache">
47
+ <ul class="tab">
48
+ <li class="select"><?php _e('Cache Status', self::DOMAIN) ?></li>
49
+ <li><?php _e('Help', self::DOMAIN) ?></li>
50
+ </ul>
51
+ <ul class="content">
52
+ <li>
53
+ <table>
54
+ <thead>
55
+ <tr>
56
+ <th>No.</th>
57
+ <th><?php _e('Post', self::DOMAIN) ?></th>
58
+ <th><?php _e('Cache Status', self::DOMAIN) ?></th>
59
+ </tr>
60
+ </thead>
61
+ <tbody>
62
+
63
+ <?php
64
+ if($posts_query->have_posts()) {
65
+ while($posts_query->have_posts()){
66
+ $posts_query->the_post();
67
+ ?>
68
+ <tr>
69
+ <td><?php echo $count; ?></td>
70
+ <td><?php echo get_permalink(get_the_ID()); ?></td>
71
+ <?php
72
+ $transient_id = self::TRANSIENT_PREFIX . get_the_ID();
73
+ if (false === ($sns_counts = get_transient($transient_id))) {
74
+ echo '<td class="not-cached">';
75
+ _e('not cached', self::DOMAIN);
76
+ echo '</td>';
77
+ } else {
78
+ echo '<td class="cached">';
79
+ _e('cached', self::DOMAIN);
80
+ echo '</td>';
81
+ }
82
+
83
+ ?>
84
+ </tr>
85
+
86
+ <?php
87
+ $count++;
88
+
89
+ }
90
+ }
91
+ wp_reset_postdata();
92
+ ?>
93
+ </tbody>
94
+ </table>
95
+ </li>
96
+ <li class="hide">
97
+ <div>
98
+ <h3>What is SNS Cout Cache?</h3>
99
+ <p>SNS Count Cache gets share count for Twitter and Facebook, Google Plus, Hatena Bookmark and caches these count in the background. This plugin may help you to shorten page loading time because the share count can be retrieved not through network but through the cache using given functions.</p>
100
+ <h3>How often does this plugin get and cache share count?</h3>
101
+ <p>This plugin gets share count of 20 posts at a time every 10 minutes.</p>
102
+ <h3>How can I know whether share cout of each post is cached or not?</h3>
103
+ <p>Cache status is described in the "Cache Status" tab in the setting page.</p>
104
+ <h3>How can I get share count from the cache?</h3>
105
+ <p>The share cout is retrieved from the cache using the following functions in the WordPress loop such as query_posts(), get_posts() and WP_Query().</p>
106
+ <table>
107
+ <thead>
108
+ <tr>
109
+ <th><?php _e('Function', self::DOMAIN) ?></th>
110
+ <th><?php _e('Description', self::DOMAIN) ?></th>
111
+ </tr>
112
+ </thead>
113
+ <tbody>
114
+ <tr><td>get_scc_twitter()</td><td><?php _e('Twitter share count is returned from cache.', self::DOMAIN) ?></td></tr>
115
+ <tr><td>get_scc_facebook()</td><td><?php _e('Facebook share count is returned from cache.', self::DOMAIN) ?></td></tr>
116
+ <tr><td>get_scc_gplus()</td><td><?php _e('Google Plus share count is returned from cache.', self::DOMAIN) ?></td></tr>
117
+ <tr><td>get_scc_hatebu()</td><td><?php _e('Hatena Bookmark share count is returned from cache.', self::DOMAIN) ?></td></tr>
118
+ </tbody>
119
+ </table>
120
+ <h3>Example Code</h3>
121
+ The code below describes a simple example which displays share count of Twitter, Facebook, Google Plus for each post.
122
+ <pre class="prettyprint">&lt;?php
123
+ $query_args = array(
124
+ &#039;post_type&#039; =&gt; &#039;post&#039;,
125
+ &#039;post_status&#039; =&gt; &#039;publish&#039;,
126
+ &#039;posts_per_page&#039; =&gt; 5
127
+ );
128
+
129
+ $posts_query = new WP_Query($query_args);
130
+
131
+ if($posts_query-&gt;have_posts()) {
132
+ while($posts_query-&gt;have_posts()){
133
+ $posts_query-&gt;the_post();
134
+ ?&gt;
135
+
136
+ &lt;!--
137
+ In WordPress loop, you can use the given function
138
+ in order to get share count for current post.
139
+ --&gt;
140
+ &lt;p&gt;Twitter: &lt;?php echo get_scc_twitter(); ?&gt;&lt;/p&gt;
141
+ &lt;p&gt;Facebook: &lt;?php echo get_scc_facebook(); ?&gt;&lt;/p&gt;
142
+ &lt;p&gt;Google Plus: &lt;?php echo get_scc_gplus(); ?&gt;&lt;/p&gt;
143
+
144
+ &lt;?php
145
+ }
146
+ }
147
+ wp_reset_postdata();
148
+ ?&gt;</pre>
149
+ </div>
150
+ </li>
151
+ </ul>
152
+ </div>
153
+ </div>
css/prettify.css ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .com { color: #93a1a1; }
2
+ .lit { color: #195f91; }
3
+ .pun, .opn, .clo { color: #93a1a1; }
4
+ .fun { color: #dc322f; }
5
+ .str, .atv { color: #D14; }
6
+ .kwd, .prettyprint .tag { color: #1e347b; }
7
+ .typ, .atn, .dec, .var { color: teal; }
8
+ .pln { color: #48484c; }
9
+
10
+ .prettyprint {
11
+ padding: 8px;
12
+ background-color: #f9f9f9;
13
+ border: 1px solid #e1e1e8;
14
+ }
15
+ .prettyprint.linenums {
16
+ -webkit-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
17
+ -moz-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
18
+ box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
19
+ }
20
+
21
+ /* Specify class=linenums on a pre to get line numbering */
22
+ ol.linenums {
23
+ margin: 0 0 0 33px; /* IE indents via margin-left */
24
+ }
25
+ ol.linenums li {
26
+ padding-left: 12px;
27
+ color: #bebec5;
28
+ line-height: 20px;
29
+ text-shadow: 0 1px 0 #fff;
30
+ }
css/sns-count-cache.css ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .sns-cnt-cache table {
2
+ border: 1px solid #000;
3
+ margin: 20px 0 0 0;
4
+ margin: 0px;
5
+ padding: 0px;
6
+ width: 100%;
7
+ border-collapse: collapse;
8
+ border-spacing: 0;
9
+ }
10
+
11
+ .sns-cnt-cache tr:nth-child(odd) {
12
+ background-color: #ffffff;
13
+ }
14
+
15
+ .sns-cnt-cache tr:nth-child(even) {
16
+ background-color: #f9f9f9;
17
+ }
18
+
19
+ .sns-cnt-cache th {
20
+ vertical-align: middle;
21
+ padding: 3px;
22
+ text-align: left;
23
+ background-color: #4c4c4c;
24
+ color: #fff;
25
+ }
26
+
27
+ .sns-cnt-cache td {
28
+ vertical-align: middle;
29
+ padding: 4px;
30
+ text-align: left;
31
+ }
32
+
33
+ .sns-cnt-cache .cached {
34
+ color: #468847;
35
+ /* background-color: #dff0d8 */;
36
+ }
37
+
38
+ .sns-cnt-cache .not-cached {
39
+ color: #ccc;
40
+ }
41
+
42
+ .sns-cnt-cache .tab {
43
+ overflow: hidden;
44
+ padding: 0;
45
+ margin: 30px 0 0 0;
46
+ }
47
+
48
+ .sns-cnt-cache .tab li {
49
+ float: left;
50
+ margin: 0;
51
+ padding: 0 20px;
52
+ height: 31px;
53
+ line-height: 31px;
54
+ border: 1px solid #DFDFDF;
55
+ margin-bottom: -1px;
56
+ overflow: hidden;
57
+ position: relative;
58
+ background: #F5F5F5;
59
+ background-image: -webkit-gradient(linear,left top,left bottom,from(#fff),to(#F5F5F5));
60
+ background-image: -webkit-linear-gradient(center top,#fff,#F5F5F5);
61
+ background-image: -moz-linear-gradient(center top,#fff,#F5F5F5);
62
+ background-image: -ms-linear-gradient(center top,#fff,#F5F5F5);
63
+ background-image: -o-linear-gradient(center top,#fff,#F5F5F5);
64
+ background-image: linear-gradient(center top,#fff,#F5F5F5);
65
+ }
66
+
67
+ .sns-cnt-cache .tab li.select {
68
+ background: #fff;
69
+ text-decoration: none;
70
+ color: #000;
71
+ display: block;
72
+ padding: 0 20px;
73
+ outline: none;
74
+ }
75
+
76
+ .sns-cnt-cache ul.content {
77
+ padding: 10px;
78
+ background: #fff;
79
+ border: 1px solid #DFDFDF;
80
+ border-top: none;
81
+ overflow: hidden;
82
+ background: #fff;
83
+ margin: 0;
84
+ }
85
+
86
+ .sns-cnt-cache .content li {
87
+ padding: 0;
88
+ margin: 0;
89
+ }
90
+
91
+ .sns-cnt-cache .hide {
92
+ display: none;
93
+ }
94
+
js/jquery.sns-count-cache.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function($) {
2
+ //クリックしたときのファンクションをまとめて指定
3
+ $('.tab li').click(function() {
4
+
5
+ //.index()を使いクリックされたタブが何番目かを調べ、
6
+ //indexという変数に代入します。
7
+ var index = $('.tab li').index(this);
8
+
9
+ //コンテンツを一度すべて非表示にし、
10
+ $('.content li').css('display','none');
11
+
12
+ //クリックされたタブと同じ順番のコンテンツを表示します。
13
+ $('.content li').eq(index).css('display','block');
14
+
15
+ //一度タブについているクラスselectを消し、
16
+ $('.tab li').removeClass('select');
17
+
18
+ //クリックされたタブのみにクラスselectをつけます。
19
+ $(this).addClass('select')
20
+ });
21
+ return this;
22
+ });
js/prettify.js ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
2
+ (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
3
+ [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
4
+ f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
5
+ (j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
6
+ {b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
7
+ t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
8
+ "string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
9
+ l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
10
+ q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
11
+ q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
12
+ "");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
13
+ a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
14
+ for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
15
+ m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
16
+ a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
17
+ j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
18
+ "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
19
+ H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
20
+ J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
21
+ I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
22
+ ["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
23
+ /^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
24
+ ["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
25
+ hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
26
+ !k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
27
+ 250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
28
+ PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
module/data-cache-engine.php ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ data-cache-engine.php
4
+
5
+ Description: This class is a data cache engine whitch get and cache data using wp-cron at regular intervals
6
+ Version: 0.1.0
7
+ Author: Daisuke Maruyama
8
+ Author URI: http://marubon.info/
9
+ License: GPL2 or later
10
+ License URI: http://www.gnu.org/licenses/gpl-2.0.txt
11
+ */
12
+
13
+ /*
14
+
15
+ Copyright (C) 2014 Daisuke Maruyama
16
+
17
+ This program is free software; you can redistribute it and/or
18
+ modify it under the terms of the GNU General Public License
19
+ as published by the Free Software Foundation; either version 2
20
+ of the License, or (at your option) any later version.
21
+
22
+ This program is distributed in the hope that it will be useful,
23
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
24
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
+ GNU General Public License for more details.
26
+
27
+ You should have received a copy of the GNU General Public License
28
+ along with this program; if not, write to the Free Software
29
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30
+
31
+ */
32
+
33
+ class DataCacheEngine {
34
+
35
+ /**
36
+ * Instance of crawler to get data
37
+ */
38
+ private $crawler = NULL;
39
+
40
+ /**
41
+ * Interval cheking and caching target data
42
+ */
43
+ private $check_interval = 600;
44
+
45
+ /**
46
+ * Number of posts to check at a time
47
+ */
48
+ private $posts_per_check = 20;
49
+
50
+ /**
51
+ * Prefix of cache ID
52
+ */
53
+ private $transient_prefix = 'data_cache';
54
+
55
+ /**
56
+ * Cron name to schedule cache processing
57
+ */
58
+ private $cron_cache_prime = 'data_cache_prime';
59
+
60
+ /**
61
+ * Cron name to execute cache processing
62
+ */
63
+ private $cron_cache_execute = 'data_cache_exec';
64
+
65
+ /**
66
+ * Schedule name for cache processing
67
+ */
68
+ private $event_schedule = 'cache_event';
69
+
70
+ /**
71
+ * Schedule description for cache processing
72
+ */
73
+ private $event_description = 'cache event';
74
+
75
+ /**
76
+ * Class constarctor
77
+ * Hook onto all of the actions and filters needed by the plugin.
78
+ *
79
+ */
80
+ function __construct($crawler, $options=array()) {
81
+
82
+ $this->crawler = $crawler;
83
+
84
+ if(isset($options['check_interval'])) $this->check_interval = $options['check_interval'];
85
+ if(isset($options['posts_per_check'])) $this->posts_per_check = $options['posts_per_check'];
86
+ if(isset($options['transient_prefix'])) $this->transient_prefix = $options['transient_prefix'];
87
+ if(isset($options['cron_cache_prime'])) $this->cron_cache_prime = $options['cron_cache_prime'];
88
+ if(isset($options['cron_cache_execute'])) $this->cron_cache_execute = $options['cron_cache_execute'];
89
+ if(isset($options['event_schedule'])) $this->event_schedule = $options['event_schedule'];
90
+ if(isset($options['event_description'])) $this->event_description = $options['event_description'];
91
+
92
+ add_filter('cron_schedules', array($this, 'schedule_check_interval'));
93
+ add_action($this->cron_cache_prime, array($this, 'prime_data_cache'));
94
+ add_action($this->cron_cache_execute, array($this, 'execute_data_cache'),10,1);
95
+
96
+ }
97
+
98
+ /**
99
+ * Register base schedule for this engine
100
+ *
101
+ */
102
+ public function register_base_schedule(){
103
+
104
+ if (!wp_next_scheduled($this->cron_cache_prime)) {
105
+ wp_schedule_event( time(), $this->event_schedule, $this->cron_cache_prime);
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Unregister base schedule for this engine
111
+ *
112
+ */
113
+ public function unregister_base_schedule(){
114
+ wp_clear_scheduled_hook($this->cron_cache_prime);
115
+ }
116
+
117
+ /**
118
+ * Register event schedule for this engine
119
+ *
120
+ */
121
+ public function schedule_check_interval($schedules) {
122
+
123
+ $schedules[$this->event_schedule] = array(
124
+ 'interval' => $this->check_interval,
125
+ 'display' => $this->event_description
126
+ );
127
+ return $schedules;
128
+ }
129
+
130
+ /**
131
+ * Schedule data retrieval and cache processing
132
+ *
133
+ */
134
+ public function prime_data_cache(){
135
+
136
+ $next_exec_time = time() + $this->check_interval;
137
+ $posts_total = $this->get_posts_total();
138
+
139
+ $this->log('[prime_data_cache] check_interval: ' . $this->check_interval);
140
+ $this->log('[prime_data_cache] next_exec_time: ' . $next_exec_time);
141
+ $this->log('[prime_data_cache] posts_total: ' . $posts_total);
142
+
143
+ $transient_id = $this->transient_prefix . 'offset';
144
+
145
+ if (false === ($posts_offset = get_transient($transient_id))) {
146
+ $posts_offset = 0;
147
+ }
148
+
149
+ $this->log('[prime_data_cache] posts_offset: ' . $posts_offset);
150
+
151
+ wp_schedule_single_event($next_exec_time, $this->cron_cache_execute, array($posts_offset));
152
+
153
+ $this->log('[prime_data_cache] posts_per_check: ' . $this->posts_per_check);
154
+
155
+ $posts_offset = $posts_offset + $this->posts_per_check;
156
+
157
+ if($posts_offset > $posts_total){
158
+ $posts_offset = 0;
159
+ }
160
+
161
+ delete_transient($transient_id);
162
+ set_transient($transient_id, $posts_offset, $this->check_interval + $this->check_interval);
163
+
164
+ }
165
+
166
+ /**
167
+ * Get and cache data of each published post
168
+ *
169
+ */
170
+ public function execute_data_cache($posts_offset){
171
+
172
+ $this->log('[execute_data_cache] posts_offset: ' . $posts_offset);
173
+ $this->log('[execute_data_cache] posts_per_check: ' . $this->posts_per_check);
174
+ $this->log('[execute_data_cache] check_interval: ' . $this->check_interval);
175
+
176
+ $posts_total = $this->get_posts_total();
177
+ $cache_expiration = (ceil($posts_total / $this->posts_per_check) * $this->check_interval) + 2 * $this->check_interval;
178
+
179
+ $this->log('[execute_data_cache] cache_expiration: ' . $cache_expiration);
180
+ $this->log('[execute_data_cache] posts_total: ' . $posts_total);
181
+
182
+ $query_args = array(
183
+ 'post_type' => 'post',
184
+ 'post_status' => 'publish',
185
+ 'offset' => $posts_offset,
186
+ 'posts_per_page' => $this->posts_per_check,
187
+ 'no_found_rows' => true,
188
+ 'update_post_term_cache' => false,
189
+ 'update_post_meta_cache' => false
190
+ );
191
+
192
+ $posts_query = new WP_Query($query_args);
193
+
194
+ if($posts_query->have_posts()) {
195
+ while($posts_query->have_posts()){
196
+ $posts_query->the_post();
197
+
198
+ $this->log('[execute_data_cache] post_id: ' . get_the_ID());
199
+
200
+ $transient_id = $this->transient_prefix . get_the_ID();
201
+
202
+ $url = get_permalink(get_the_ID());
203
+
204
+ $this->crawler->set_url($url);
205
+
206
+ $data = $this->crawler->get_data();
207
+
208
+ $this->log($data);
209
+
210
+ delete_transient($transient_id);
211
+ set_transient($transient_id, $data, $cache_expiration);
212
+
213
+ }
214
+ }
215
+ wp_reset_postdata();
216
+ }
217
+
218
+ /**
219
+ * Get total count of current published posts
220
+ *
221
+ */
222
+ private function get_posts_total(){
223
+
224
+ $query_args = array(
225
+ 'post_type' => 'post',
226
+ 'post_status' => 'publish',
227
+ 'nopaging' => true,
228
+ 'update_post_term_cache' => false,
229
+ 'update_post_meta_cache' => false
230
+ );
231
+
232
+ $posts_query = new WP_Query($query_args);
233
+
234
+ return $posts_query->found_posts;
235
+ }
236
+
237
+ /**
238
+ * Output log message according to WP_DEBUG setting
239
+ *
240
+ */
241
+ private function log($message) {
242
+ if (WP_DEBUG === true) {
243
+ if (is_array($message) || is_object($message)) {
244
+ error_log(print_r($message, true));
245
+ } else {
246
+ error_log($message);
247
+ }
248
+ }
249
+ }
250
+ }
251
+
252
+ ?>
module/data-crawler.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ data-crawler.php
4
+
5
+ Description: This class is abstract class of a data crawler
6
+ Version: 0.1.0
7
+ Author: Daisuke Maruyama
8
+ Author URI: http://marubon.info/
9
+ License: GPL2 or later
10
+ License URI: http://www.gnu.org/licenses/gpl-2.0.txt
11
+ */
12
+
13
+ /*
14
+
15
+ Copyright (C) 2014 Daisuke Maruyama
16
+
17
+ This program is free software; you can redistribute it and/or
18
+ modify it under the terms of the GNU General Public License
19
+ as published by the Free Software Foundation; either version 2
20
+ of the License, or (at your option) any later version.
21
+
22
+ This program is distributed in the hope that it will be useful,
23
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
24
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
+ GNU General Public License for more details.
26
+
27
+ You should have received a copy of the GNU General Public License
28
+ along with this program; if not, write to the Free Software
29
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30
+
31
+ */
32
+
33
+ abstract class DataCrawler{
34
+
35
+ /**
36
+ * URL for data crawling
37
+ */
38
+ protected $url = '';
39
+
40
+ /**
41
+ * Set URL for data crawling
42
+ */
43
+ public function set_url($url){
44
+ $this->url = rawurlencode($url);
45
+ }
46
+
47
+ /**
48
+ * Abstract method for data crawling
49
+ *
50
+ */
51
+ abstract public function get_data();
52
+ }
53
+
54
+ ?>
module/sns-count-crawler.php ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ sns-count-crawler.php
4
+
5
+ Description: This class is a data crawler whitch get share count using given API and cURL
6
+ Version: 0.1.0
7
+ Author: Daisuke Maruyama
8
+ Author URI: http://marubon.info/
9
+ License: GPL2 or later
10
+ License URI: http://www.gnu.org/licenses/gpl-2.0.txt
11
+ */
12
+
13
+ /*
14
+
15
+ Copyright (C) 2014 Daisuke Maruyama
16
+
17
+ This program is free software; you can redistribute it and/or
18
+ modify it under the terms of the GNU General Public License
19
+ as published by the Free Software Foundation; either version 2
20
+ of the License, or (at your option) any later version.
21
+
22
+ This program is distributed in the hope that it will be useful,
23
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
24
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
+ GNU General Public License for more details.
26
+
27
+ You should have received a copy of the GNU General Public License
28
+ along with this program; if not, write to the Free Software
29
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30
+
31
+ */
32
+
33
+ class SNSCountCrawler extends DataCrawler{
34
+
35
+ /**
36
+ * Timeout for cURL data retrieval
37
+ */
38
+ private $timeout = 10;
39
+
40
+ function __construct($url='',$timeout=10) {
41
+ $this->url=rawurlencode($url);
42
+ $this->timeout=$timeout;
43
+ }
44
+
45
+ function set_timeout($timeout){
46
+ $this->timeout = $timeout;
47
+ }
48
+
49
+ /**
50
+ * Implementation of abstract method. this method gets each share count
51
+ *
52
+ */
53
+ public function get_data(){
54
+ $sns_counts = array();
55
+
56
+ $sns_counts[SNSCountCache::REF_HATEBU] = $this->get_hatebu_count();
57
+ $sns_counts[SNSCountCache::REF_TWITTER] = $this->get_twitter_count();
58
+ $sns_counts[SNSCountCache::REF_FACEBOOK] = $this->get_facebook_count();
59
+ $sns_counts[SNSCountCache::REF_GPLUS] = $this->get_gplus_count();
60
+
61
+ return $sns_counts;
62
+ }
63
+
64
+ /**
65
+ * Get share count for Hatena Bookmark
66
+ *
67
+ */
68
+ public function get_hatebu_count() {
69
+ $query = 'http://api.b.st-hatena.com/entry.count?url=' . $this->url;
70
+
71
+ $hatebu = $this->file_get_contents($query);
72
+
73
+ return isset($hatebu) ? intval($hatebu) : 0;
74
+ }
75
+
76
+ /**
77
+ * Get share count for Twitter
78
+ *
79
+ */
80
+ public function get_twitter_count() {
81
+ $query = 'http://urls.api.twitter.com/1/urls/count.json?url=' . $this->url;
82
+
83
+ $json = $this->file_get_contents($query);
84
+
85
+ $twitter = json_decode($json, true);
86
+
87
+ return isset($twitter['count']) ? intval($twitter['count']) : 0;
88
+ }
89
+
90
+ /**
91
+ * Get share count for Facebook
92
+ *
93
+ */
94
+ public function get_facebook_count() {
95
+ $query = 'http://graph.facebook.com/' . $this->url;
96
+
97
+ $json = $this->file_get_contents($query);
98
+
99
+ $facebook = json_decode($json, true);
100
+
101
+ return isset($facebook['shares']) ? intval($facebook['shares']) : 0;
102
+ }
103
+
104
+ /**
105
+ * Get share count for Google Plus
106
+ *
107
+ */
108
+ public function get_gplus_count() {
109
+ $curl = curl_init();
110
+
111
+ curl_setopt($curl, CURLOPT_URL, "https://clients6.google.com/rpc");
112
+ curl_setopt($curl, CURLOPT_POST, true);
113
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
114
+ curl_setopt($curl, CURLOPT_POSTFIELDS, '[{"method":"pos.plusones.get","id":"p","params":{"nolog":true,"id":"' . rawurldecode($this->url) . '","source":"widget","userId":"@viewer","groupId":"@self"},"jsonrpc":"2.0","key":"p","apiVersion":"v1"}]');
115
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
116
+ curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
117
+
118
+ $curl_results = curl_exec ($curl);
119
+
120
+ if(curl_error($curl)) {
121
+ die(curl_error($curl));
122
+ }
123
+
124
+ curl_close ($curl);
125
+
126
+ $json = json_decode($curl_results, true);
127
+
128
+ return isset($json[0]['result']['metadata']['globalCounts']['count']) ? intval( $json[0]['result']['metadata']['globalCounts']['count'] ) : 0;
129
+ }
130
+
131
+ /**
132
+ * Get content from given URL using cURL
133
+ *
134
+ */
135
+ private function file_get_contents($url){
136
+ $curl = curl_init();
137
+
138
+ curl_setopt($curl, CURLOPT_URL, $url);
139
+ curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
140
+ curl_setopt($curl, CURLOPT_FAILONERROR, true);
141
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
142
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
143
+ curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout);
144
+
145
+ $curl_results = curl_exec($curl);
146
+
147
+ if(curl_error($curl)) {
148
+ die(curl_error($curl));
149
+ }
150
+
151
+ curl_close ($curl);
152
+
153
+ return $curl_results;
154
+ }
155
+
156
+ /**
157
+ * Output log message according to WP_DEBUG setting
158
+ *
159
+ */
160
+ private function log($message) {
161
+ if (WP_DEBUG === true) {
162
+ if (is_array($message) || is_object($message)) {
163
+ error_log(print_r($message, true));
164
+ } else {
165
+ error_log($message);
166
+ }
167
+ }
168
+ }
169
+
170
+ }
171
+
172
+ ?>
readme.txt ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === SNS Count Cache ===
2
+ Contributors: marubon
3
+ Donate link:
4
+ Tags: performance, SNS, social, cache
5
+ Requires at least: 3.2
6
+ Tested up to: 3.9.1
7
+ Stable tag: 0.1.0
8
+ License: GPLv2 or later
9
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+ This plugin gets and caches SNS share count in the background, and provides functions to access the cache.
12
+
13
+
14
+ == Description ==
15
+
16
+ SNS Count Cache gets share count for Twitter and Facebook, Google Plus, Hatena Bookmark and caches these count in the background.
17
+ This plugin may help you to shorten page loading time because the share count can be retrieved not through network but through the cache using given functions.
18
+
19
+ The following shows functions to get share count from the cache:
20
+
21
+ * get_scc_twitter()
22
+ * get_scc_facebook()
23
+ * get_scc_gplus()
24
+ * get_scc_hatebu()
25
+
26
+ == Installation ==
27
+
28
+ 1. Download zip archive file from this repository.
29
+
30
+ 2. Login as an administrator to your WordPress admin page.
31
+ Using the "Add New" menu option under the "Plugins" section of the navigation,
32
+ Click the "Upload" link, find the .zip file you download and then click "Install Now".
33
+ You can also unzip and upload the plugin to your plugins directory (i.e. wp-content/plugins/) through FTP/SFTP.
34
+
35
+ 3. Finally, activate the plugin on the "Plugins" page.
36
+
37
+ == Frequently Asked Questions ==
38
+ There are no questions.
39
+
40
+ == Screenshots ==
41
+ 1. Cache status is described in setting page
42
+ 2. Help page shows available functions to access the cache
43
+
44
+ == Changelog ==
45
+
46
+ = 0.1.0 =
47
+ * Initial working version.
48
+
49
+ == Upgrade Notice ==
50
+ There is no upgrade notice.
51
+
52
+ == Arbitrary section ==
53
+
54
+
screenshot-1.png ADDED
Binary file
screenshot-2.png ADDED
Binary file
sns-count-cache.php ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: SNS Count Cache
4
+ Description: SNS Count Cache gets share count for Twitter and Facebook, Google Plus, Hatena Bookmark and caches these count in the background. This plugin may help you to shorten page loading time because the share count can be retrieved not through network but through the cache using given functions.
5
+ Version: 0.1.0
6
+ Author: Daisuke Maruyama
7
+ Author URI: http://marubon.info/
8
+ License: GPL2 or later
9
+ License URI: http://www.gnu.org/licenses/gpl-2.0.txt
10
+ */
11
+
12
+ /*
13
+
14
+ Copyright (C) 2014 Daisuke Maruyama
15
+
16
+ This program is free software; you can redistribute it and/or
17
+ modify it under the terms of the GNU General Public License
18
+ as published by the Free Software Foundation; either version 2
19
+ of the License, or (at your option) any later version.
20
+
21
+ This program is distributed in the hope that it will be useful,
22
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
+ GNU General Public License for more details.
25
+
26
+ You should have received a copy of the GNU General Public License
27
+ along with this program; if not, write to the Free Software
28
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29
+
30
+ */
31
+
32
+ if (!class_exists('SNSCountCache')){
33
+
34
+ class SNSCountCache {
35
+
36
+ /**
37
+ * Plugin version, used for cache-busting of style and script file references.
38
+ */
39
+ private $version = '0.1.0';
40
+
41
+ /**
42
+ * Instance of module class of schedule and cache processing
43
+ */
44
+ private $cache_engine = NULL;
45
+
46
+ /**
47
+ * Slug of the plugin screen
48
+ */
49
+ private $plugin_screen_hook_suffix = NULL;
50
+
51
+ /**
52
+ * Prefix of cache ID
53
+ */
54
+ const TRANSIENT_PREFIX = 'sns_count_cache_';
55
+
56
+ /**
57
+ * Slug of the plugin
58
+ */
59
+ const DOMAIN = 'sns-count-cache';
60
+
61
+ /**
62
+ * ID of share count (Twitter)
63
+ */
64
+ const REF_TWITTER = 'twitter';
65
+
66
+ /**
67
+ * ID of share count (Facebook)
68
+ */
69
+ const REF_FACEBOOK = 'facebook';
70
+
71
+ /**
72
+ * ID of share count (Google Plus)
73
+ */
74
+ const REF_GPLUS = 'gplus';
75
+
76
+ /**
77
+ * ID of share count (Hatena Bookmark)
78
+ */
79
+ const REF_HATEBU = 'hatebu';
80
+
81
+ /**
82
+ * Class constarctor
83
+ * Hook onto all of the actions and filters needed by the plugin.
84
+ */
85
+ function __construct() {
86
+
87
+ //load_plugin_textdomain(self::DOMAIN, false, basename(dirname( __FILE__ )) . '/languages');
88
+
89
+ require_once (dirname(__FILE__) . '/module/data-cache-engine.php');
90
+ require_once (dirname(__FILE__) . '/module/data-crawler.php');
91
+ require_once (dirname(__FILE__) . '/module/sns-count-crawler.php');
92
+
93
+ $crawler = new SNSCountCrawler();
94
+
95
+ $options = array(
96
+ 'check_interval' => 600,
97
+ 'posts_per_check' => 20,
98
+ 'transient_prefix' => self::TRANSIENT_PREFIX,
99
+ 'cron_cache_prime' => 'scc_cntcache_prime',
100
+ 'cron_cache_execute' => 'scc_cntcache_exec',
101
+ 'event_schedule' => 'cache_event',
102
+ 'event_description' => '[SCC] Share Count Cache Interval'
103
+ );
104
+
105
+ $this->cache_engine = new DataCacheEngine($crawler, $options);
106
+
107
+ add_action('admin_menu', array($this, 'action_admin_menu'));
108
+
109
+ add_action('admin_print_styles', array($this, 'register_admin_styles'));
110
+ add_action('admin_enqueue_scripts', array($this, 'register_admin_scripts'));
111
+
112
+ register_activation_hook( __FILE__, array($this, 'activate_plugin'));
113
+ register_deactivation_hook(__FILE__, array($this, 'deactivate_plugin'));
114
+
115
+ }
116
+
117
+ /**
118
+ * Registers and enqueues admin-specific styles.
119
+ *
120
+ */
121
+ public function register_admin_styles() {
122
+ if (!isset($this->plugin_screen_hook_suffix)) {
123
+ return;
124
+ }
125
+
126
+ $screen = get_current_screen();
127
+ if ($screen->id == $this->plugin_screen_hook_suffix) {
128
+ wp_enqueue_style(self::DOMAIN .'-admin-style-1' , plugins_url(ltrim('/css/sns-count-cache.css', '/'), __FILE__));
129
+ wp_enqueue_style(self::DOMAIN .'-admin-style-2' , plugins_url(ltrim('/css/prettify.css', '/'), __FILE__));
130
+ }
131
+
132
+ }
133
+
134
+ /**
135
+ * Registers and enqueues admin-specific JavaScript.
136
+ *
137
+ */
138
+ public function register_admin_scripts() {
139
+
140
+ if (!isset( $this->plugin_screen_hook_suffix)) {
141
+ return;
142
+ }
143
+
144
+ $screen = get_current_screen();
145
+ if ($screen->id == $this->plugin_screen_hook_suffix) {
146
+ wp_enqueue_script(self::DOMAIN . '-admin-script-1' ,plugins_url(ltrim('/js/jquery.sns-count-cache.js', '/') , __FILE__ ),array( 'jquery' ));
147
+ wp_enqueue_script(self::DOMAIN . '-admin-script-2' ,plugins_url(ltrim('/js/prettify.js', '/') , __FILE__ ),array( 'jquery' ));
148
+ }
149
+
150
+ }
151
+
152
+ /**
153
+ * Activate base schedule cron
154
+ *
155
+ */
156
+ function activate_plugin(){
157
+ $this->cache_engine->register_base_schedule();
158
+ }
159
+
160
+ /**
161
+ * Deactivate base schedule cron
162
+ *
163
+ */
164
+ function deactivate_plugin(){
165
+ $this->cache_engine->unregister_base_schedule();
166
+ }
167
+
168
+ /**
169
+ * Adds options & management pages to the admin menu.
170
+ *
171
+ * Run using the 'admin_menu' action.
172
+ */
173
+ public function action_admin_menu() {
174
+ $this->plugin_screen_hook_suffix = add_options_page('SNS Count Cache', 'SNS Count Cache', 8, 'sns_count_cache_options_page',array($this, 'option_page'));
175
+ }
176
+
177
+ /**
178
+ * Option page implementation
179
+ *
180
+ */
181
+ public function option_page(){
182
+ include_once(dirname(__FILE__) . '/admin.php');
183
+ }
184
+
185
+ public static function init() {
186
+
187
+ static $instance = null;
188
+
189
+ if ( !$instance )
190
+ $instance = new SNSCountCache;
191
+
192
+ return $instance;
193
+
194
+ }
195
+ }
196
+
197
+ SNSCountCache::init();
198
+
199
+ /**
200
+ * Get share count from cache (Hatena Bookmark).
201
+ *
202
+ */
203
+ function get_scc_hatebu($post_ID='') {
204
+ $transient_id ='';
205
+
206
+ if(!empty($post_ID)){
207
+ $transient_id = SNSCountCache::TRANSIENT_PREFIX . $post_ID;
208
+ }else{
209
+ $transient_id = SNSCountCache::TRANSIENT_PREFIX . get_the_ID();
210
+ }
211
+
212
+ $sns_counts = get_transient($transient_id);
213
+
214
+ return $sns_counts[SNSCountCache::REF_HATEBU];
215
+ }
216
+
217
+ /**
218
+ * Get share count from cache (Twitter)
219
+ *
220
+ */
221
+ function get_scc_twitter($post_ID='') {
222
+ $transient_id ='';
223
+
224
+ if(!empty($post_ID)){
225
+ $transient_id = SNSCountCache::TRANSIENT_PREFIX . $post_ID;
226
+ }else{
227
+ $transient_id = SNSCountCache::TRANSIENT_PREFIX . get_the_ID();
228
+ }
229
+
230
+ $sns_counts = get_transient($transient_id);
231
+
232
+ return $sns_counts[SNSCountCache::REF_TWITTER];
233
+ }
234
+
235
+ /**
236
+ * Get share count from cache (Facebook)
237
+ *
238
+ */
239
+ function get_scc_facebook($post_ID='') {
240
+ $transient_id ='';
241
+
242
+ if(!empty($post_ID)){
243
+ $transient_id = SNSCountCache::TRANSIENT_PREFIX . $post_ID;
244
+ }else{
245
+ $transient_id = SNSCountCache::TRANSIENT_PREFIX . get_the_ID();
246
+ }
247
+
248
+ $sns_counts = get_transient($transient_id);
249
+
250
+ return $sns_counts[SNSCountCache::REF_FACEBOOK];
251
+ }
252
+
253
+ /**
254
+ * Get share count from cache (Google Plus)
255
+ *
256
+ */
257
+ function get_scc_gplus($post_ID='') {
258
+ $transient_id ='';
259
+
260
+ if(!empty($post_ID)){
261
+ $transient_id = SNSCountCache::TRANSIENT_PREFIX . $post_ID;
262
+ }else{
263
+ $transient_id = SNSCountCache::TRANSIENT_PREFIX . get_the_ID();
264
+ }
265
+
266
+ $sns_counts = get_transient($transient_id);
267
+
268
+ return $sns_counts[SNSCountCache::REF_GPLUS];
269
+ }
270
+
271
+ /**
272
+ * Get share count from cache
273
+ *
274
+ */
275
+ function get_scc($post_ID='') {
276
+ $transient_id ='';
277
+
278
+ if(!empty($post_ID)){
279
+ $transient_id = SNSCountCache::TRANSIENT_PREFIX . $post_ID;
280
+ }else{
281
+ $transient_id = SNSCountCache::TRANSIENT_PREFIX . get_the_ID();
282
+ }
283
+
284
+ $sns_counts = get_transient($transient_id);
285
+
286
+ return $sns_counts;
287
+ }
288
+
289
+ }
290
+
291
+ ?>