PluginProbe
codoc / 0.9.4
codoc v0.9.4
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
codoc / class-codoc-util.php

class-codoc-util.php in codoc 0.9.4, at class-codoc-util.php

261 lines 10.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('WPINC')) {
4 define( 'WPINC', 'wp-includes' );
5 }
6
7 if (!defined('CODOC_URL')) {
8 define( 'CODOC_URL', 'https://codoc.jp' );
9 }
10
11 require_once( ABSPATH . WPINC . '/class-http.php');
12 require_once( ABSPATH . WPINC . '/class-wp-error.php');
13
14 final class CodocUtil {
15
16 public function __construct($params = ['usercode' => null, 'token' => null]) {
17 $this->setAuthInfo($params);
18 return $this;
19 }
20
21 public function callAPI($method,$path,$body = [],$headers = []) {
22 $usercode = $this->usercode;
23 $token = $this->token;
24
25 $headers['X-CodocToken'] = $token;
26 $host = CODOC_URL;
27 $sslverify = true;
28
29 if (preg_match('/local/',CODOC_URL)) {
30 $sslverify = false;
31 $host = 'https://host.docker.internal';
32 }
33 $url = sprintf("%s/api/v1/cms/%s%s",$host,$usercode,$path);
34 $http = new WP_Http();
35 try {
36 $response = $http->request(
37 $url,
38 [
39 'sslverify' => $sslverify,
40 'method' => $method,
41 'timeout' => 10,
42 'headers' => $headers,
43 'body' => $body,
44 ]
45 );
46 if ( is_wp_error($response) || $response['response']['code'] != 200 ) {
47 //何もしない
48 //var_dump( $response );
49 }
50 } catch(Exception $e) {
51
52 }
53 if (!is_wp_error($response) and
54 isset($response['body']) and
55 is_string($response['body']) and
56 is_array(json_decode($response['body'], true)) and
57 (json_last_error() == JSON_ERROR_NONE)) {
58 return json_decode($response['body']);
59 } else {
60 return null;
61 }
62 }
63 public function setAuthInfo($params = [ "usercode" => null, "token" => null ]) {
64 if ($params["usercode"]) {
65 $this->usercode = $params["usercode"];
66 }
67 if ($params["token"]) {
68 $this->token = $params["token"];
69 }
70 return true;
71 }
72 public function get_token($params = ["fetch_token_key" => null],$auth_info = ["usercode" => null, "token" => null]) {
73 $this->setAuthInfo($auth_info);
74 return $this->callAPI('GET','/token',[ "fetch_token_key" => $params["fetch_token_key"] ]);
75 }
76 public function get_user_info($params = [] ,$auth_info = ["usercode" => null, "token" => null]) {
77 $this->setAuthInfo($auth_info);
78 return $this->callAPI('GET','');
79 }
80 public function sync_entry($params = [
81 "post_title" => null,
82 "post_content" => null,
83 "post_status" => null, # 0, 1
84 "post_permalink" => null,
85 "codoc_entry_code" => null,
86 ],$auth_info = ["usercode" => null, "token" => null]) {
87
88 $this->setAuthInfo($auth_info);
89
90 $post_content = $params['post_content'];
91 preg_match('/wp:codoc\/codoc-block +?({.*})/',$post_content,$matches);
92 // GUTENBERG で指定されたjson(記事�
93 )がない場合
94 if (!$matches) {
95 return;
96 }
97 // GUTENBERG で保存している�
98 容を取得
99 $codoc_info = json_decode($matches[1],true);
100 // codoc タグがない場合はなにもしない
101 //preg_match('/(<span +data-id="codoc-tag"[^>]+>(?:.+|)<\/span>)/',$post_content,$matches);
102 preg_match('/(<(?:span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:span|div)>)/',$post_content,$matches);
103 if (!$matches) {
104 return;
105 }
106 // TODO: split or html parse? HTMLがつながってる場合はおかしくなる
107 // classic(tinymce)版の場合p、もしくはdivにかこまれている
108 $splited = preg_split('/(?:<(?:div|p)(?:[^>]+|)>|)<\!-- +wp:codoc\/codoc-block .*<\!-- +\/wp:codoc\/codoc-block +-->(?:<\/(?:div|p)>|)/s',$post_content);
109 $status = $params['post_status'];
110 # $body_free = '';
111 # $body_paywalled = '';
112 # if (count($splited) >= 2) {
113 #
114 # }
115 $binded_url = $params['post_permalink'];
116 $CODOC_SETTINGS = get_option(CODOC_SETTINGS_OPTION_NAME);
117 if (isset($CODOC_SETTINGS['str_replace_binded_url_from']) and
118 isset($CODOC_SETTINGS['str_replace_binded_url_to']) and
119 $CODOC_SETTINGS['str_replace_binded_url_from']) {
120 $binded_url = str_replace(sanitize_text_field($CODOC_SETTINGS['str_replace_binded_url_from']),
121 sanitize_text_field($CODOC_SETTINGS['str_replace_binded_url_to']),
122 $binded_url);
123 }
124 $api_params = [
125 'title' => $params['post_title'],
126 'body_free' => $splited[0],
127 'body_paywalled' => $splited[1],
128 'status' => $status,
129 'binded_url' => $binded_url,
130 'show_price' => isset($codoc_info['showPrice']) ? ($codoc_info['showPrice'] ? 1 : 0) : 0,
131 'price' => isset($codoc_info['price']) ? $codoc_info['price'] : 100,
132 'limited' => isset($codoc_info['limited']) ? ($codoc_info['limited'] ? 1 : 0) : 0,
133 'limited_count' => isset($codoc_info['limitedCount']) ? $codoc_info['limitedCount'] : 1,
134 'affiliate_mode' => isset($codoc_info['affiliateMode']) ? ($codoc_info['affiliateMode'] ? 1 : 0) : 0,
135 'affiliate_rate' => isset($codoc_info['affiliateRate']) ? $codoc_info['affiliateRate'] : '0.0500',
136 'show_support' => isset($codoc_info['showSupport']) ? ($codoc_info['showSupport'] ? 1 : 0) : 0,
137 'subscriptions' => isset($codoc_info['subscriptions']) ? array_keys($codoc_info['subscriptions']) : [],
138 ];
139 $entryCode = $params['codoc_entry_code'];
140 $res = null;
141 if ($entryCode) {
142 $res = $this->callAPI('PUT','/entries/' . $entryCode ,$api_params);
143 } else {
144 $res = $this->callAPI('POST', '/entries', $api_params);
145 }
146 return $res;
147 }
148
149 function post_thumbnail( $params = [
150 "file_path" => null,
151 "boundary" => null,
152 "codoc_entry_code" => null,
153 ], $auth_info = ["usercode" => null, "token" => null] ) {
154
155 $this->setAuthInfo($auth_info);
156
157 $file_path = $params['file_path'];
158 $boundary = $params['boundary']; # ランダム変数24桁 wp_generate_password(24);
159 $res = null;
160 if (is_readable($file_path)) {
161 $name = 'file';
162
163 $payload = '';
164 $payload .= '--' . $boundary;
165 $payload .= "\r\n";
166 $payload .= 'Content-Disposition: form-data; name="' . $name . '"; filename="' . basename( $file_path ) . '"' . "\r\n";
167 $payload .= "Content-Type: application/octet-stream\r\n";
168 $payload .= "Content-Transfer-Encoding: binary\r\n";
169 $payload .= "\r\n";
170 $payload .= file_get_contents( $file_path );
171 $payload .= "\r\n";
172
173 $payload .= '--' . $boundary . '--';
174
175 $entryCode = $params['codoc_entry_code'];
176 $res = $this->callAPI(
177 'POST',
178 '/entries/' . $entryCode . '/thumbnail',
179 $payload,
180 ['content-type' => 'multipart/form-data; boundary=' . $boundary]
181 );
182 }
183 return $res;
184 }
185
186 function reset_thumbnail( $params = [
187 "codoc_entry_code" => null,
188 ],$auth_info = ["usercode" => null, "token" => null] ) {
189
190 $this->setAuthInfo($auth_info);
191
192 $entryCode = $params['codoc_entry_code'];
193 $res = $this->callAPI(
194 'POST',
195 '/entries/' . $entryCode . '/thumbnail',
196 [ "reset" => 1 ]
197 );
198 return $res;
199 }
200
201 function filter_content( $params = [
202 "post_content" => null,
203 "preview" => null,
204 "codoc_entry_code" => null,
205 "codoc_settings" => null,
206 "is_amp_endpoint" => null,
207 "post_permalink" => null,
208 ]) {
209 $post_content = $params['post_content'];
210 // codoc タグがあるかどうか (202001:span -> div に変更)
211 preg_match('/(<(span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:div|span)>)/',$post_content,$matches);
212 // data-wp-plugin-ver が無いタグは分割しない
213 if (!$matches) {
214 return $post_content;
215 }
216 // codocタグで分割 (202001: gutenbergで直前のdivタグを削除)
217 $tag_regex = '/(?:<div(?:[^>]+|)>|)<(?:span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:span|div)>(?:<\/div>|)/';
218 if ( $params['preview'] ) {
219 $post_content = preg_replace($tag_regex,'<div class="codoc-continue">ここから上は無料で表示されます</div>',$post_content);
220 return $post_content;
221 }
222 // codoc タグの前後で分ける
223 $splited = preg_split($tag_regex,$post_content);
224 // codoc タグにID属性のentrycodeとdata-without-body(無料分を非表示)をつける
225 $entryCodeFormated = sprintf('"codoc-entry-%s" ',$params['codoc_entry_code']);
226 $codoc_tag = preg_replace('/<((?:span|div)[^>]+)data-id="[^"]+"((?:[^>]+|))>/','<${1} ${2} data-without-body="1" id=' . $entryCodeFormated . ">", $matches[1]);
227 # THE THOR の page-lp.php が " " をけずるための対策
228 # "div class" -> "div class"
229 $codoc_tag = preg_replace('/div +class/','div class',$codoc_tag);
230
231 if ($params['is_amp_endpoint']) {
232 $format = preg_replace_callback('/(<(?:span|div)[^>]+>)((?:[^<>]+|))(<\/(?:span|div)>)/',function($matches) {
233 $format = $matches[1] . '<a href="%%s">%s</a>' . $matches[3];
234 return sprintf($format,($matches[2] ? $matches[2] : '続きを読む'));
235 },$codoc_tag);
236 $codoc_tag = sprintf($format,$params["post_permalink"]);
237 }
238
239 # タグの前後にHTMLを挿�
240
241 $CODOC_SETTINGS = $params['codoc_settings'];
242 if (!isset($CODOC_SETTINGS['str_before_codoc_tag'])) {
243 $CODOC_SETTINGS['str_before_codoc_tag'] = '';
244 }
245 if (!isset($CODOC_SETTINGS['str_after_codoc_tag'])) {
246 $CODOC_SETTINGS['str_after_codoc_tag'] = '';
247 }
248 // 無料部分のみ表示
249 $post_content = $splited[0] . sprintf(
250 '%s<div class="wp-block-codoc-codoc-block">%s</div>%s',
251 $CODOC_SETTINGS['str_before_codoc_tag'],
252 $codoc_tag,
253 $CODOC_SETTINGS['str_after_codoc_tag']
254 );
255 return $post_content;
256 }
257
258
259 }
260
261