PluginProbe
codoc / 0.9.15
codoc v0.9.15
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.15, at class-codoc-util.php

334 lines 14.7 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 public $codoc_url = CODOC_URL;
16 public function __construct($params = ['usercode' => null, 'token' => null,'codoc_url' => null]) {
17 $this->setAuthInfo(['usercode' => $params['usercode'], 'token' => $params['token']]);
18 if (isset($params['codoc_url'])) {
19 $this->codoc_url = $params['codoc_url'];
20 }
21 return $this;
22 }
23
24 public function callAPI($method,$path,$body = [],$headers = []) {
25 $usercode = $this->usercode;
26 $token = $this->token;
27
28 $headers['X-CodocToken'] = $token;
29 $host = $this->codoc_url;
30 $sslverify = true;
31
32 if (preg_match('/local/',$this->codoc_url)) {
33 $sslverify = false;
34 $host = 'https://host.docker.internal';
35 }
36 $url = sprintf("%s/api/v1/cms/%s%s",$host,$usercode,$path);
37 $http = new WP_Http();
38 try {
39 $response = $http->request(
40 $url,
41 [
42 'sslverify' => $sslverify,
43 'method' => $method,
44 'timeout' => 10,
45 'headers' => $headers,
46 'body' => $body,
47 ]
48 );
49 if ( is_wp_error($response) || $response['response']['code'] != 200 ) {
50 //何もしない
51 //var_dump( $response );
52 }
53 } catch(Exception $e) {
54
55 }
56 if (!is_wp_error($response) and
57 isset($response['body']) and
58 is_string($response['body']) and
59 is_array(json_decode($response['body'], true)) and
60 (json_last_error() == JSON_ERROR_NONE)) {
61 return json_decode($response['body']);
62 } else {
63 return null;
64 }
65 }
66 public function setAuthInfo($params = [ "usercode" => null, "token" => null ]) {
67 if ($params["usercode"]) {
68 $this->usercode = $params["usercode"];
69 }
70 if ($params["token"]) {
71 $this->token = $params["token"];
72 }
73 return true;
74 }
75 public function get_token($params = ["fetch_token_key" => null],$auth_info = ["usercode" => null, "token" => null]) {
76 $this->setAuthInfo($auth_info);
77 return $this->callAPI('GET','/token',[ "fetch_token_key" => $params["fetch_token_key"] ]);
78 }
79 public function get_user_info($params = [] ,$auth_info = ["usercode" => null, "token" => null]) {
80 $this->setAuthInfo($auth_info);
81 return $this->callAPI('GET','');
82 }
83 public function get_support_entry($params = [] ,$auth_info = ["usercode" => null, "token" => null]) {
84 $this->setAuthInfo($auth_info);
85 return $this->callAPI('GET','/support_entry');
86 }
87 public function sync_entry($params = [
88 "post_title" => null,
89 "post_content" => null,
90 "post_status" => null, # 0, 1
91 "post_permalink" => null,
92 "codoc_entry_code" => null,
93 ],$auth_info = ["usercode" => null, "token" => null]) {
94
95 $this->setAuthInfo($auth_info);
96
97 $post_content = $params['post_content'];
98 preg_match('/wp:codoc\/codoc-block +?({.*})/',$post_content,$matches);
99 // GUTENBERG で指定されたjson(記事�
100 )がない場合
101 if (!$matches) {
102 return;
103 }
104 // GUTENBERG で保存している�
105 容を取得
106 $codoc_info = json_decode($matches[1],true);
107 // codoc タグがない場合はなにもしない
108 //preg_match('/(<span +data-id="codoc-tag"[^>]+>(?:.+|)<\/span>)/',$post_content,$matches);
109 preg_match('/(<(?:span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:span|div)>)/',$post_content,$matches);
110 if (!$matches) {
111 return;
112 }
113 // TODO: split or html parse? HTMLがつながってる場合はおかしくなる
114 // classic(tinymce)版の場合p、もしくはdivにかこまれている
115 $splited = preg_split('/(?:<(?:div|p)(?:[^>]+|)>|)<\!-- +wp:codoc\/codoc-block .*<\!-- +\/wp:codoc\/codoc-block +-->(?:<\/(?:div|p)>|)/s',$post_content);
116 $status = $params['post_status'];
117 # $body_free = '';
118 # $body_paywalled = '';
119 # if (count($splited) >= 2) {
120 #
121 # }
122 $binded_url = $params['post_permalink'];
123 $CODOC_SETTINGS = get_option(CODOC_SETTINGS_OPTION_NAME);
124 if (isset($CODOC_SETTINGS['str_replace_binded_url_from']) and
125 isset($CODOC_SETTINGS['str_replace_binded_url_to']) and
126 $CODOC_SETTINGS['str_replace_binded_url_from']) {
127 $binded_url = str_replace(sanitize_text_field($CODOC_SETTINGS['str_replace_binded_url_from']),
128 sanitize_text_field($CODOC_SETTINGS['str_replace_binded_url_to']),
129 $binded_url);
130 }
131 $api_params = [
132 'title' => $params['post_title'],
133 'body_free' => $splited[0],
134 'body_paywalled' => $splited[1],
135 'status' => $status,
136 'binded_url' => $binded_url,
137 'show_price' => isset($codoc_info['showPrice']) ? ($codoc_info['showPrice'] ? 1 : 0) : 0,
138 'price' => isset($codoc_info['price']) ? $codoc_info['price'] : 100,
139 'limited' => isset($codoc_info['limited']) ? ($codoc_info['limited'] ? 1 : 0) : 0,
140 'limited_count' => isset($codoc_info['limitedCount']) ? $codoc_info['limitedCount'] : 1,
141 'affiliate_mode' => isset($codoc_info['affiliateMode']) ? ($codoc_info['affiliateMode'] ? 1 : 0) : 0,
142 'affiliate_rate' => isset($codoc_info['affiliateRate']) ? $codoc_info['affiliateRate'] : '0.0500',
143 'show_support' => isset($codoc_info['showSupport']) ? ($codoc_info['showSupport'] ? 1 : 0) : 0,
144 'show_paywalled_support' => isset($codoc_info['showPaywalledSupport']) ? ($codoc_info['showPaywalledSupport'] ? 1 : 0) : 0,
145 'subscriptions' => isset($codoc_info['subscriptions']) ? array_keys($codoc_info['subscriptions']) : [],
146 ];
147 $entryCode = $params['codoc_entry_code'];
148 $res = null;
149 if ($entryCode) {
150 $res = $this->callAPI('PUT','/entries/' . $entryCode ,$api_params);
151 } else {
152 $res = $this->callAPI('POST', '/entries', $api_params);
153 }
154 return $res;
155 }
156
157 function post_thumbnail( $params = [
158 "file_path" => null,
159 "boundary" => null,
160 "codoc_entry_code" => null,
161 ], $auth_info = ["usercode" => null, "token" => null] ) {
162
163 $this->setAuthInfo($auth_info);
164
165 $file_path = $params['file_path'];
166 $boundary = $params['boundary']; # ランダム変数24桁 wp_generate_password(24);
167 $res = null;
168 if (is_readable($file_path)) {
169 $name = 'file';
170
171 $payload = '';
172 $payload .= '--' . $boundary;
173 $payload .= "\r\n";
174 $payload .= 'Content-Disposition: form-data; name="' . $name . '"; filename="' . basename( $file_path ) . '"' . "\r\n";
175 $payload .= "Content-Type: application/octet-stream\r\n";
176 $payload .= "Content-Transfer-Encoding: binary\r\n";
177 $payload .= "\r\n";
178 $payload .= file_get_contents( $file_path );
179 $payload .= "\r\n";
180
181 $payload .= '--' . $boundary . '--';
182
183 $entryCode = $params['codoc_entry_code'];
184 $res = $this->callAPI(
185 'POST',
186 '/entries/' . $entryCode . '/thumbnail',
187 $payload,
188 ['content-type' => 'multipart/form-data; boundary=' . $boundary]
189 );
190 }
191 return $res;
192 }
193
194 function reset_thumbnail( $params = [
195 "codoc_entry_code" => null,
196 ],$auth_info = ["usercode" => null, "token" => null] ) {
197
198 $this->setAuthInfo($auth_info);
199
200 $entryCode = $params['codoc_entry_code'];
201 $res = $this->callAPI(
202 'POST',
203 '/entries/' . $entryCode . '/thumbnail',
204 [ "reset" => 1 ]
205 );
206 return $res;
207 }
208
209 function filter_content( $params = [
210 "post_content" => null,
211 "preview" => null,
212 "codoc_entry_code" => null,
213 "codoc_settings" => null,
214 "is_amp_endpoint" => null,
215 "post_permalink" => null,
216 "codoc_support_entry_code" => null,
217 ]) {
218 $CODOC_SETTINGS = $params['codoc_settings'];
219
220 $has_codoc_tag = '/(<(span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:div|span)>)/';
221 $post_content = $params['post_content'];
222 // codoc タグがあるかどうか (202001:span -> div に変更)
223 preg_match($has_codoc_tag,$post_content,$matches);
224
225 $show_support_message = '';
226 if (isset($CODOC_SETTINGS['show_support_message'])) {
227 $show_support_message = $CODOC_SETTINGS['show_support_message'];
228 }
229 $show_support_categories = '';
230 if (isset($CODOC_SETTINGS['show_support_categories'])) {
231 $show_support_categories = $CODOC_SETTINGS['show_support_categories'];
232 }
233 $show_support_location = 'bottom';
234 if (isset($CODOC_SETTINGS['show_support_location'])) {
235 $show_support_location = $CODOC_SETTINGS['show_support_location'];
236 }
237
238 $show_support_entry = (is_single() && preg_grep("/(?:$show_support_categories)/",array_map( function($c) { return $c->name; },get_the_category(get_post()->ID))));
239 if (!$matches && ($support_entry_code = $params['codoc_support_entry_code']) && $show_support_entry) {
240 $support_tag = sprintf(
241 '<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"></div>',
242 htmlspecialchars($show_support_message,ENT_QUOTES),
243 $support_entry_code,
244 $CODOC_SETTINGS['support_button_text'],
245 $CODOC_SETTINGS['show_like'],
246 $CODOC_SETTINGS['show_about_codoc'],
247 $CODOC_SETTINGS['show_powered_by']
248 );
249 $post_content = $show_support_location == 'bottom' ?
250 $post_content . $support_tag :
251 $support_tag . $post_content ;
252 }
253
254 // data-wp-plugin-ver が無いタグは分割しない
255 if (!$matches) {
256 return $post_content;
257 }
258
259 // codocタグで分割 (202001: gutenbergで直前のdivタグを削除)
260 $tag_regex = '/(?:<div(?:[^>]+|)>|)<(?:span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:span|div)>(?:<\/div>|)/';
261 if ( $params['preview'] ) {
262 $post_content = preg_replace($tag_regex,'<div class="codoc-continue">ここから上は無料で表示されます</div>',$post_content);
263 return $post_content;
264 }
265 // codoc タグの前後で分ける
266 $splited = preg_split($tag_regex,$post_content);
267 // codoc タグにID属性のentrycodeとdata-without-body(無料分を非表示)をつける
268 $entryCodeFormated = sprintf('"codoc-entry-%s" ',$params['codoc_entry_code']);
269
270 // 文言系の設定をつける
271 $tagAttributes = '';
272 if (isset($CODOC_SETTINGS['show_like']) and $CODOC_SETTINGS['show_like'] != 1) {
273 $tagAttributes = $tagAttributes . sprintf(' data-show-like="%s"',$CODOC_SETTINGS['show_like']);
274 }
275 if (isset($CODOC_SETTINGS['show_about_codoc']) and $CODOC_SETTINGS['show_about_codoc'] != 1) {
276 $tagAttributes = $tagAttributes . sprintf(' data-show-about-codoc="%s"',$CODOC_SETTINGS['show_about_codoc']);
277 }
278 if (isset($CODOC_SETTINGS['show_powered_by']) and $CODOC_SETTINGS['show_powered_by'] != 1) {
279 $tagAttributes = $tagAttributes . sprintf(' data-show-powered-by="%s"',$CODOC_SETTINGS['show_powered_by']);
280 }
281 if ($CODOC_SETTINGS['entry_button_text']) {
282 $tagAttributes = $tagAttributes . sprintf(' data-entry-button-text="%s"',$CODOC_SETTINGS['entry_button_text']);
283 }
284 if ($CODOC_SETTINGS['subscription_button_text']) {
285 $tagAttributes = $tagAttributes . sprintf(' data-subscription-button-text="%s"',$CODOC_SETTINGS['subscription_button_text']);
286 }
287 if ($CODOC_SETTINGS['support_button_text']) {
288 $tagAttributes = $tagAttributes . sprintf(' data-support-button-text="%s"',$CODOC_SETTINGS['support_button_text']);
289 }
290 if ($CODOC_SETTINGS['subscription_message']) {
291 $tagAttributes = $tagAttributes . sprintf(' data-subscription-message="%s"',$CODOC_SETTINGS['subscription_message']);
292 }
293 if ($CODOC_SETTINGS['support_message']) {
294 $tagAttributes = $tagAttributes . sprintf(' data-support-message="%s"',$CODOC_SETTINGS['support_message']);
295 }
296 if ($CODOC_SETTINGS['codoc_tag_attributes']) {
297 $tagAttributes = $tagAttributes . sprintf(' %s',$CODOC_SETTINGS['codoc_tag_attributes']);
298 }
299
300 $codoc_tag = preg_replace('/<((?:span|div)[^>]+)data-id="[^"]+"((?:[^>]+|))>/','<${1} ${2} data-without-body="1" id=' . $entryCodeFormated . $tagAttributes . ">", $matches[1]);
301 # THE THOR の page-lp.php が " " をけずるための対策
302 # "div class" -> "div class"
303 $codoc_tag = preg_replace('/div +class/','div class',$codoc_tag);
304
305 if ($params['is_amp_endpoint']) {
306 $format = preg_replace_callback('/(<(?:span|div)[^>]+>)((?:[^<>]+|))(<\/(?:span|div)>)/',function($matches) {
307 $format = $matches[1] . '<a href="%%s">%s</a>' . $matches[3];
308 return sprintf($format,($matches[2] ? $matches[2] : '続きを読む'));
309 },$codoc_tag);
310 $codoc_tag = sprintf($format,$params["post_permalink"]);
311 }
312
313 # タグの前後にHTMLを挿�
314
315 if (!isset($CODOC_SETTINGS['str_before_codoc_tag'])) {
316 $CODOC_SETTINGS['str_before_codoc_tag'] = '';
317 }
318 if (!isset($CODOC_SETTINGS['str_after_codoc_tag'])) {
319 $CODOC_SETTINGS['str_after_codoc_tag'] = '';
320 }
321 // 無料部分のみ表示
322 $post_content = $splited[0] . sprintf(
323 '%s<div class="wp-block-codoc-codoc-block">%s</div>%s',
324 $CODOC_SETTINGS['str_before_codoc_tag'],
325 $codoc_tag,
326 $CODOC_SETTINGS['str_after_codoc_tag']
327 );
328 return $post_content;
329 }
330
331
332 }
333
334