PluginProbe
codoc / 0.9.51
codoc v0.9.51
0.9.8.8 0.9.8.9 0.9.9 0.9.9.1 trunk 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.8.1 0.8.2 0.8.3 0.8.4 0.8.6 0.8.7 0.8.8 0.8.9 0.9 0.9.1 0.9.10 0.9.11 All 114 releases
← All changes | class-codoc-util.php +305 -25 0.90.9.51 View file →
@@ -3,28 +3,39 @@
3 3 if (!defined('WPINC')) {
4 4 define( 'WPINC', 'wp-includes' );
5 5 }
6 6
7 -require_once( ABSPATH . WPINC . '/class-http.php');
7 +if (!defined('CODOC_URL')) {
8 + define( 'CODOC_URL', 'https://codoc.jp' );
9 +}
10 +global $wp_version;
11 +if (version_compare( $wp_version,'5.9') >= 0 ) {
12 + require_once( ABSPATH . WPINC . '/class-wp-http.php');
13 +} else {
14 + require_once( ABSPATH . WPINC . '/class-http.php');
15 +}
16 +
8 17 require_once( ABSPATH . WPINC . '/class-wp-error.php');
9 18
10 19 final class CodocUtil {
11 -
12 - public function __construct($params = ['usercode' => null, 'token' => null]) {
13 - $this->usercode = $params['usercode'] or die('no usercode');
14 - $this->token = $params['token'] or die('no token');
20 + public $codoc_url = CODOC_URL;
21 + public function __construct($params = ['usercode' => null, 'token' => null,'codoc_url' => null]) {
22 + $this->setAuthInfo(['usercode' => $params['usercode'], 'token' => $params['token']]);
23 + if (isset($params['codoc_url'])) {
24 + $this->codoc_url = $params['codoc_url'];
25 + }
15 26 return $this;
16 27 }
17 -
28 +
18 29 public function callAPI($method,$path,$body = [],$headers = []) {
19 30 $usercode = $this->usercode;
20 31 $token = $this->token;
21 32
22 33 $headers['X-CodocToken'] = $token;
23 - $host = CODOC_URL;
34 + $host = $this->codoc_url;
24 35 $sslverify = true;
25 36
26 - if (preg_match('/local/',CODOC_URL)) {
37 + if (preg_match('/local/',$this->codoc_url)) {
27 38 $sslverify = false;
28 39 $host = 'https://host.docker.internal';
29 40 }
30 41 $url = sprintf("%s/api/v1/cms/%s%s",$host,$usercode,$path);
@@ -56,9 +67,70 @@
56 67 } else {
57 68 return null;
58 69 }
59 70 }
71 + public function callPaywallAPI($method,$path,$body = [],$headers = []) {
72 + $site_usercode = get_option(CODOC_USERCODE_OPTION_NAME);
73 + $paywall_token = $this->get_paywall_token_code();
60 74
75 + $host = $this->codoc_url;
76 + $sslverify = true;
77 +
78 + if (preg_match('/local/',$this->codoc_url)) {
79 + $sslverify = false;
80 + $host = 'https://host.docker.internal';
81 + }
82 + $url = sprintf("%s/api/v1/paywall/%s%s",$host,$site_usercode,$path);
83 + $http = new WP_Http();
84 + try {
85 + $response = $http->request(
86 + $url,
87 + [
88 + 'sslverify' => $sslverify,
89 + 'method' => $method,
90 + 'timeout' => 10,
91 + 'headers' => $headers,
92 + 'body' => $body,
93 + ]
94 + );
95 + if ( is_wp_error($response) || $response['response']['code'] != 200 ) {
96 + //何もしない
97 + //var_dump( $response );
98 + }
99 + } catch(Exception $e) {
100 +
101 + }
102 + if (!is_wp_error($response) and
103 + isset($response['body']) and
104 + is_string($response['body']) and
105 + is_array(json_decode($response['body'], true)) and
106 + (json_last_error() == JSON_ERROR_NONE)) {
107 + return json_decode($response['body']);
108 + } else {
109 + return null;
110 + }
111 + }
112 + public function setAuthInfo($params = [ "usercode" => null, "token" => null ]) {
113 + if ($params["usercode"]) {
114 + $this->usercode = $params["usercode"];
115 + }
116 + if ($params["token"]) {
117 + $this->token = $params["token"];
118 + }
119 + return true;
120 + }
121 + public function get_token($params = ["fetch_token_key" => null],$auth_info = ["usercode" => null, "token" => null]) {
122 + $this->setAuthInfo($auth_info);
123 + return $this->callAPI('GET','/token',[ "fetch_token_key" => $params["fetch_token_key"] ]);
124 + }
125 + public function get_user_info($params = [] ,$auth_info = ["usercode" => null, "token" => null]) {
126 + $this->setAuthInfo($auth_info);
127 + return $this->callAPI('GET','');
128 + }
129 + public function get_support_entry($params = [] ,$auth_info = ["usercode" => null, "token" => null]) {
130 + $this->setAuthInfo($auth_info);
131 + return $this->callAPI('GET','/support_entry');
132 + }
61 133 public function sync_entry($params = [
62 134 "post_title" => null,
63 135 "post_content" => null,
64 136 "post_status" => null, # 0, 1
@@ -63,9 +135,12 @@
63 135 "post_content" => null,
64 136 "post_status" => null, # 0, 1
65 137 "post_permalink" => null,
66 138 "codoc_entry_code" => null,
67 - ]) {
139 + ],$auth_info = ["usercode" => null, "token" => null]) {
140 +
141 + $this->setAuthInfo($auth_info);
142 +
68 143 $post_content = $params['post_content'];
69 144 preg_match('/wp:codoc\/codoc-block +?({.*})/',$post_content,$matches);
70 145 // GUTENBERG で指定されたjson(記事情報)がない場合
71 146 if (!$matches) {
@@ -80,10 +155,17 @@
80 155 return;
81 156 }
82 157 // TODO: split or html parse? HTMLがつながってる場合はおかしくなる
83 158 // classic(tinymce)版の場合p、もしくはdivにかこまれている
159 + $end_tag_regex = '/<(?:div|p)>::CODOC_WP_END_PAYWALL::<\/(?:div|p)>/';
160 + $before_splited = preg_split($end_tag_regex,$post_content);
161 + $post_content = $before_splited[0];
84 162 $splited = preg_split('/(?:<(?:div|p)(?:[^>]+|)>|)<\!-- +wp:codoc\/codoc-block .*<\!-- +\/wp:codoc\/codoc-block +-->(?:<\/(?:div|p)>|)/s',$post_content);
85 - $status = $params['post_status'];
163 + $status = $params['post_status']; # 0: 非公開 1: 公開 2:限定公開(パスワードの場合は限定公開で同期する)
164 + // codoc設定で限定公開を有効で、公開の場合は 限定公開にする
165 + if ($status == 1 and isset($codoc_info['statusLimited']) and $codoc_info['statusLimited']) {
166 + $status = 2;
167 + }
86 168 # $body_free = '';
87 169 # $body_paywalled = '';
88 170 # if (count($splited) >= 2) {
89 171 #
@@ -109,8 +191,9 @@
109 191 'limited_count' => isset($codoc_info['limitedCount']) ? $codoc_info['limitedCount'] : 1,
110 192 'affiliate_mode' => isset($codoc_info['affiliateMode']) ? ($codoc_info['affiliateMode'] ? 1 : 0) : 0,
111 193 'affiliate_rate' => isset($codoc_info['affiliateRate']) ? $codoc_info['affiliateRate'] : '0.0500',
112 194 'show_support' => isset($codoc_info['showSupport']) ? ($codoc_info['showSupport'] ? 1 : 0) : 0,
195 + 'show_paywalled_support' => isset($codoc_info['showPaywalledSupport']) ? ($codoc_info['showPaywalledSupport'] ? 1 : 0) : 0,
113 196 'subscriptions' => isset($codoc_info['subscriptions']) ? array_keys($codoc_info['subscriptions']) : [],
114 197 ];
115 198 $entryCode = $params['codoc_entry_code'];
116 199 $res = null;
@@ -125,9 +208,12 @@
125 208 function post_thumbnail( $params = [
126 209 "file_path" => null,
127 210 "boundary" => null,
128 211 "codoc_entry_code" => null,
129 - ] ) {
212 + ], $auth_info = ["usercode" => null, "token" => null] ) {
213 +
214 + $this->setAuthInfo($auth_info);
215 +
130 216 $file_path = $params['file_path'];
131 217 $boundary = $params['boundary']; # ランダム変数24桁 wp_generate_password(24);
132 218 $res = null;
133 219 if (is_readable($file_path)) {
@@ -157,9 +243,12 @@
157 243 }
158 244
159 245 function reset_thumbnail( $params = [
160 246 "codoc_entry_code" => null,
161 - ]) {
247 + ],$auth_info = ["usercode" => null, "token" => null] ) {
248 +
249 + $this->setAuthInfo($auth_info);
250 +
162 251 $entryCode = $params['codoc_entry_code'];
163 252 $res = $this->callAPI(
164 253 'POST',
165 254 '/entries/' . $entryCode . '/thumbnail',
@@ -171,35 +260,138 @@
171 260 function filter_content( $params = [
172 261 "post_content" => null,
173 262 "preview" => null,
174 263 "codoc_entry_code" => null,
264 + "codoc_settings" => null,
265 + "is_amp_endpoint" => null,
266 + "post_permalink" => null,
267 + "codoc_support_entry_code" => null,
175 268 ]) {
269 + $CODOC_SETTINGS = $params['codoc_settings'];
270 +
271 + $has_codoc_tag = '/(<(span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:div|span)>)/';
176 272 $post_content = $params['post_content'];
177 273 // codoc タグがあるかどうか (202001:span -> div に変更)
178 - preg_match('/(<(span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:div|span)>)/',$post_content,$matches);
274 + preg_match($has_codoc_tag,$post_content,$matches);
275 +
276 + $show_support_message = '';
277 + if (isset($CODOC_SETTINGS['show_support_message'])) {
278 + $show_support_message = $CODOC_SETTINGS['show_support_message'];
279 + }
280 + $show_support_categories = '';
281 + if (isset($CODOC_SETTINGS['show_support_categories'])) {
282 + $show_support_categories = $CODOC_SETTINGS['show_support_categories'];
283 + }
284 + $show_support_location = 'bottom';
285 + if (isset($CODOC_SETTINGS['show_support_location'])) {
286 + $show_support_location = $CODOC_SETTINGS['show_support_location'];
287 + }
288 + // デフォルト値をうめておく
289 + if (!isset($CODOC_SETTINGS['support_button_text'])) {
290 + $CODOC_SETTINGS['support_button_text'] = 'サポートする';
291 + }
292 + if (!isset($CODOC_SETTINGS['show_like'])) {
293 + $CODOC_SETTINGS['show_like'] = 1;
294 + }
295 + if (!isset($CODOC_SETTINGS['show_about_codoc'])) {
296 + $CODOC_SETTINGS['show_about_codoc'] = 1;
297 + }
298 + if (!isset($CODOC_SETTINGS['show_powered_by'])) {
299 + $CODOC_SETTINGS['show_powered_by'] = 1;
300 + }
301 + if (!isset($CODOC_SETTINGS['show_created_by'])) {
302 + $CODOC_SETTINGS['show_created_by'] = 1;
303 + }
304 + if (!isset($CODOC_SETTINGS['show_copyright'])) {
305 + $CODOC_SETTINGS['show_copyright'] = 1;
306 + }
307 + $show_support_entry = (is_single() && preg_grep("/(?:$show_support_categories)/",array_map( function($c) { return $c->name; },get_the_category(get_post()->ID))));
308 + if (!$matches && ($support_entry_code = $params['codoc_support_entry_code']) && $show_support_entry) {
309 + $support_tag = sprintf(
310 + '<div class="codoc-entries" data-without-body="1" data-support-message="%s" id="codoc-entry-%s" data-support-button-text="%s" data-show-like="%s" data-show-about-codoc="%s" data-show-powered-by="%s" data-show-created-by="%s" data-show-copyright="%s"></div>',
311 + htmlspecialchars($show_support_message,ENT_QUOTES),
312 + $support_entry_code,
313 + $CODOC_SETTINGS['support_button_text'],
314 + $CODOC_SETTINGS['show_like'],
315 + $CODOC_SETTINGS['show_about_codoc'],
316 + $CODOC_SETTINGS['show_powered_by'],
317 + $CODOC_SETTINGS['show_created_by'],
318 + $CODOC_SETTINGS['show_copyright']
319 + );
320 + $post_content = $show_support_location == 'bottom' ?
321 + $post_content . $support_tag :
322 + $support_tag . $post_content ;
323 + }
324 +
179 325 // data-wp-plugin-ver が無いタグは分割しない
180 326 if (!$matches) {
181 327 return $post_content;
182 328 }
329 +
183 330 // codocタグで分割 (202001: gutenbergで直前のdivタグを削除)
184 331 $tag_regex = '/(?:<div(?:[^>]+|)>|)<(?:span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:span|div)>(?:<\/div>|)/';
332 + $end_tag_regex = '/<(?:div|p)>::CODOC_WP_END_PAYWALL::<\/(?:div|p)>/';
185 333 if ( $params['preview'] ) {
186 334 $post_content = preg_replace($tag_regex,'<div class="codoc-continue">ここから上は無料で表示されます</div>',$post_content);
335 + $post_content = preg_replace($end_tag_regex,'<div class="codoc-continue">ここから下は無料で表示されます</div>',$post_content);
187 336 return $post_content;
188 337 }
189 338 // codoc タグの前後で分ける
190 - $splited = preg_split($tag_regex,$post_content);
339 + $before_splited = preg_split($end_tag_regex,$post_content);
340 + $splited = preg_split($tag_regex,$before_splited[0]);
191 341 // codoc タグにID属性のentrycodeとdata-without-body(無料分を非表示)をつける
192 - $entryCode = $params['codoc_entry_code'];
193 - $codoc_tag = preg_replace('/<((?:span|div)[^>]+)data-id="[^"]+"((?:[^>]+|))>/','<${1} ${2} data-without-body="1" id=' . $entryCode . ">", $matches[1]);
342 + $entryCodeFormated = sprintf('"codoc-entry-%s" ',$params['codoc_entry_code']);
343 +
344 + // 文言系の設定をつける
345 + $tagAttributes = '';
346 + if (isset($CODOC_SETTINGS['show_like']) and $CODOC_SETTINGS['show_like'] != 1) {
347 + $tagAttributes = $tagAttributes . sprintf(' data-show-like="%s"',$CODOC_SETTINGS['show_like']);
348 + }
349 + if (isset($CODOC_SETTINGS['show_about_codoc']) and $CODOC_SETTINGS['show_about_codoc'] != 1) {
350 + $tagAttributes = $tagAttributes . sprintf(' data-show-about-codoc="%s"',$CODOC_SETTINGS['show_about_codoc']);
351 + }
352 + if (isset($CODOC_SETTINGS['show_powered_by']) and $CODOC_SETTINGS['show_powered_by'] != 1) {
353 + $tagAttributes = $tagAttributes . sprintf(' data-show-powered-by="%s"',$CODOC_SETTINGS['show_powered_by']);
354 + }
355 + if (isset($CODOC_SETTINGS['show_created_by']) and $CODOC_SETTINGS['show_created_by'] != 1) {
356 + $tagAttributes = $tagAttributes . sprintf(' data-show-created-by="%s"',$CODOC_SETTINGS['show_created_by']);
357 + }
358 + if (isset($CODOC_SETTINGS['show_copyright']) and $CODOC_SETTINGS['show_copyright'] != 1) {
359 + $tagAttributes = $tagAttributes . sprintf(' data-show-copyright="%s"',$CODOC_SETTINGS['show_copyright']);
360 + }
361 + if (isset($CODOC_SETTINGS['entry_button_text']) and $CODOC_SETTINGS['entry_button_text'] != '') {
362 + $tagAttributes = $tagAttributes . sprintf(' data-entry-button-text="%s"',$CODOC_SETTINGS['entry_button_text']);
363 + }
364 + if (isset($CODOC_SETTINGS['subscription_button_text']) and $CODOC_SETTINGS['subscription_button_text'] != '') {
365 + $tagAttributes = $tagAttributes . sprintf(' data-subscription-button-text="%s"',$CODOC_SETTINGS['subscription_button_text']);
366 + }
367 + if (isset($CODOC_SETTINGS['support_button_text']) and $CODOC_SETTINGS['support_button_text'] != '') {
368 + $tagAttributes = $tagAttributes . sprintf(' data-support-button-text="%s"',$CODOC_SETTINGS['support_button_text']);
369 + }
370 + if (isset($CODOC_SETTINGS['subscription_message']) and $CODOC_SETTINGS['subscription_message'] != '') {
371 + $tagAttributes = $tagAttributes . sprintf(' data-subscription-message="%s"',$CODOC_SETTINGS['subscription_message']);
372 + }
373 + if (isset($CODOC_SETTINGS['support_message']) and $CODOC_SETTINGS['support_message'] != '') {
374 + $tagAttributes = $tagAttributes . sprintf(' data-support-message="%s"',$CODOC_SETTINGS['support_message']);
375 + }
376 + if (isset($CODOC_SETTINGS['codoc_tag_attributes']) and $CODOC_SETTINGS['codoc_tag_attributes'] != '') {
377 + $tagAttributes = $tagAttributes . sprintf(' %s',$CODOC_SETTINGS['codoc_tag_attributes']);
378 + }
379 +
380 + $codoc_tag = preg_replace('/<((?:span|div)[^>]+)data-id="[^"]+"((?:[^>]+|))>/','<${1} ${2} data-without-body="1" id=' . $entryCodeFormated . $tagAttributes . ">", $matches[1]);
194 381 # THE THOR の page-lp.php が " " をけずるための対策
195 382 # "div class" -> "div class"
196 383 $codoc_tag = preg_replace('/div +class/','div class',$codoc_tag);
197 -
384 +
385 + if ($params['is_amp_endpoint']) {
386 + $format = preg_replace_callback('/(<(?:span|div)[^>]+>)((?:[^<>]+|))(<\/(?:span|div)>)/',function($matches) {
387 + $format = $matches[1] . '<a href="%%s">%s</a>' . $matches[3];
388 + return sprintf($format,($matches[2] ? $matches[2] : '続きを読む'));
389 + },$codoc_tag);
390 + $codoc_tag = sprintf($format,$params["post_permalink"]);
391 + }
392 +
198 393 # タグの前後にHTMLを挿入
199 - $CODOC_SETTINGS = $params['codoc_settings'];
200 - $before = '';
201 - $after = '';
202 394 if (!isset($CODOC_SETTINGS['str_before_codoc_tag'])) {
203 395 $CODOC_SETTINGS['str_before_codoc_tag'] = '';
204 396 }
205 397 if (!isset($CODOC_SETTINGS['str_after_codoc_tag'])) {
@@ -204,14 +396,102 @@
204 396 }
205 397 if (!isset($CODOC_SETTINGS['str_after_codoc_tag'])) {
206 398 $CODOC_SETTINGS['str_after_codoc_tag'] = '';
207 399 }
208 - $before = $CODOC_SETTINGS['str_before_codoc_tag'] or "";
209 - $after = $CODOC_SETTINGS['str_after_codoc_tag'] or "";
210 -
211 400 // 無料部分のみ表示
212 - return $splited[0] . sprintf('%s<div class="wp-block-codoc-codoc-block">%s</div>%s',$before,$codoc_tag,$after);
401 + $post_content = $splited[0] . sprintf(
402 + '%s<div class="wp-block-codoc-codoc-block">%s</div>%s',
403 + $CODOC_SETTINGS['str_before_codoc_tag'],
404 + $codoc_tag,
405 + $CODOC_SETTINGS['str_after_codoc_tag']
406 + );
407 + // ::CODOC_WP_END_PAYWALL:: の後を足す
408 + if (isset($before_splited[1]) and $before_splited[1]) {
409 + $post_content .= $before_splited[1];
410 + }
411 + return $post_content;
213 412 }
413 + /*
214 414
215 -
415 + // Cookieの中のトークンを取得
416 + $_CODOC->util->get_paywall_token_code();
417 +
418 + */
419 + function get_paywall_token_code() {
420 + if (isset($_COOKIE['codocTokenCode']) and $codocTokenCode = $_COOKIE['codocTokenCode']) {
421 + return $codocTokenCode;
422 + }
423 + return null;
424 + }
425 + /*
426 +
427 + $_CODOC->util->check_login($mode); // cookie / strict
428 +
429 + */
430 + function check_login($mode = 'cookie') {
431 + if ($codocTokenCode = $this->get_paywall_token_code()) {
432 + if ($mode == 'cookie') {
433 + // cookieの中にtokenがあればOK
434 + return true;
435 + }
436 + if ($mode == 'strict') {
437 + // ログイン状態を問い合わせ
438 + $res = $this->callPaywallAPI('GET','/users',["paywall_token_code" => $codocTokenCode ]);
439 + if ($res->status) {
440 + return true;
441 + } else {
442 + return false;
443 + }
444 + }
445 + }
446 + return false;
447 + }
448 + /*
449 +
450 + $_CODOC->util->check_owned($entry_code);
451 +
452 + */
453 + function check_owned($entry_code = null) {
454 + if (!$entry_code) {
455 + return false;
456 + }
457 + $res = $this->callPaywallAPI('GET','/entries/' . $entry_code, ["paywall_token_code" => $this->get_paywall_token_code(), "check_owned" => 1 ]);
458 + if ($res->status) {
459 + return true;
460 + }
461 + return false;
462 + }
463 +
464 + /*
465 + $_CODOC->util->health_check();
466 + */
467 + function health_check() {
468 + $sslverify = true;
469 + $host = $this->codoc_url;
470 + if (preg_match('/local/',$this->codoc_url)) {
471 + $sslverify = false;
472 + $host = 'https://host.docker.internal';
473 + }
474 + $url = sprintf("%s/codoc_health_check",$host);
475 + $http = new WP_Http();
476 + try {
477 + $response = $http->request(
478 + $url,
479 + [
480 + 'sslverify' => $sslverify,
481 + 'method' => 'GET',
482 + 'timeout' => 10,
483 + 'headers' => [],
484 + 'body' => [],
485 + ]
486 + );
487 + } catch(Exception $e) {
488 +
489 + }
490 + if ($response and $response['response']['code'] == '200') {
491 + return true;
492 + } else {
493 + return null;
494 + }
495 + }
216 496 }
217 497