PluginProbe
codoc / 0.9.7
codoc v0.9.7
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.7, at class-codoc-util.php

291 lines 12.1 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 get_support_entry($params = [] ,$auth_info = ["usercode" => null, "token" => null]) {
81 $this->setAuthInfo($auth_info);
82 return $this->callAPI('GET','/support_entry');
83 }
84 public function sync_entry($params = [
85 "post_title" => null,
86 "post_content" => null,
87 "post_status" => null, # 0, 1
88 "post_permalink" => null,
89 "codoc_entry_code" => null,
90 ],$auth_info = ["usercode" => null, "token" => null]) {
91
92 $this->setAuthInfo($auth_info);
93
94 $post_content = $params['post_content'];
95 preg_match('/wp:codoc\/codoc-block +?({.*})/',$post_content,$matches);
96 // GUTENBERG で指定されたjson(記事�
97 )がない場合
98 if (!$matches) {
99 return;
100 }
101 // GUTENBERG で保存している�
102 容を取得
103 $codoc_info = json_decode($matches[1],true);
104 // codoc タグがない場合はなにもしない
105 //preg_match('/(<span +data-id="codoc-tag"[^>]+>(?:.+|)<\/span>)/',$post_content,$matches);
106 preg_match('/(<(?:span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:span|div)>)/',$post_content,$matches);
107 if (!$matches) {
108 return;
109 }
110 // TODO: split or html parse? HTMLがつながってる場合はおかしくなる
111 // classic(tinymce)版の場合p、もしくはdivにかこまれている
112 $splited = preg_split('/(?:<(?:div|p)(?:[^>]+|)>|)<\!-- +wp:codoc\/codoc-block .*<\!-- +\/wp:codoc\/codoc-block +-->(?:<\/(?:div|p)>|)/s',$post_content);
113 $status = $params['post_status'];
114 # $body_free = '';
115 # $body_paywalled = '';
116 # if (count($splited) >= 2) {
117 #
118 # }
119 $binded_url = $params['post_permalink'];
120 $CODOC_SETTINGS = get_option(CODOC_SETTINGS_OPTION_NAME);
121 if (isset($CODOC_SETTINGS['str_replace_binded_url_from']) and
122 isset($CODOC_SETTINGS['str_replace_binded_url_to']) and
123 $CODOC_SETTINGS['str_replace_binded_url_from']) {
124 $binded_url = str_replace(sanitize_text_field($CODOC_SETTINGS['str_replace_binded_url_from']),
125 sanitize_text_field($CODOC_SETTINGS['str_replace_binded_url_to']),
126 $binded_url);
127 }
128 $api_params = [
129 'title' => $params['post_title'],
130 'body_free' => $splited[0],
131 'body_paywalled' => $splited[1],
132 'status' => $status,
133 'binded_url' => $binded_url,
134 'show_price' => isset($codoc_info['showPrice']) ? ($codoc_info['showPrice'] ? 1 : 0) : 0,
135 'price' => isset($codoc_info['price']) ? $codoc_info['price'] : 100,
136 'limited' => isset($codoc_info['limited']) ? ($codoc_info['limited'] ? 1 : 0) : 0,
137 'limited_count' => isset($codoc_info['limitedCount']) ? $codoc_info['limitedCount'] : 1,
138 'affiliate_mode' => isset($codoc_info['affiliateMode']) ? ($codoc_info['affiliateMode'] ? 1 : 0) : 0,
139 'affiliate_rate' => isset($codoc_info['affiliateRate']) ? $codoc_info['affiliateRate'] : '0.0500',
140 'show_support' => isset($codoc_info['showSupport']) ? ($codoc_info['showSupport'] ? 1 : 0) : 0,
141 'subscriptions' => isset($codoc_info['subscriptions']) ? array_keys($codoc_info['subscriptions']) : [],
142 ];
143 $entryCode = $params['codoc_entry_code'];
144 $res = null;
145 if ($entryCode) {
146 $res = $this->callAPI('PUT','/entries/' . $entryCode ,$api_params);
147 } else {
148 $res = $this->callAPI('POST', '/entries', $api_params);
149 }
150 return $res;
151 }
152
153 function post_thumbnail( $params = [
154 "file_path" => null,
155 "boundary" => null,
156 "codoc_entry_code" => null,
157 ], $auth_info = ["usercode" => null, "token" => null] ) {
158
159 $this->setAuthInfo($auth_info);
160
161 $file_path = $params['file_path'];
162 $boundary = $params['boundary']; # ランダム変数24桁 wp_generate_password(24);
163 $res = null;
164 if (is_readable($file_path)) {
165 $name = 'file';
166
167 $payload = '';
168 $payload .= '--' . $boundary;
169 $payload .= "\r\n";
170 $payload .= 'Content-Disposition: form-data; name="' . $name . '"; filename="' . basename( $file_path ) . '"' . "\r\n";
171 $payload .= "Content-Type: application/octet-stream\r\n";
172 $payload .= "Content-Transfer-Encoding: binary\r\n";
173 $payload .= "\r\n";
174 $payload .= file_get_contents( $file_path );
175 $payload .= "\r\n";
176
177 $payload .= '--' . $boundary . '--';
178
179 $entryCode = $params['codoc_entry_code'];
180 $res = $this->callAPI(
181 'POST',
182 '/entries/' . $entryCode . '/thumbnail',
183 $payload,
184 ['content-type' => 'multipart/form-data; boundary=' . $boundary]
185 );
186 }
187 return $res;
188 }
189
190 function reset_thumbnail( $params = [
191 "codoc_entry_code" => null,
192 ],$auth_info = ["usercode" => null, "token" => null] ) {
193
194 $this->setAuthInfo($auth_info);
195
196 $entryCode = $params['codoc_entry_code'];
197 $res = $this->callAPI(
198 'POST',
199 '/entries/' . $entryCode . '/thumbnail',
200 [ "reset" => 1 ]
201 );
202 return $res;
203 }
204
205 function filter_content( $params = [
206 "post_content" => null,
207 "preview" => null,
208 "codoc_entry_code" => null,
209 "codoc_settings" => null,
210 "is_amp_endpoint" => null,
211 "post_permalink" => null,
212 "codoc_support_entry_code" => null,
213 ]) {
214 $CODOC_SETTINGS = $params['codoc_settings'];
215
216 $has_codoc_tag = '/(<(span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:div|span)>)/';
217 $post_content = $params['post_content'];
218 // codoc タグがあるかどうか (202001:span -> div に変更)
219 preg_match($has_codoc_tag,$post_content,$matches);
220
221 $show_support_message = '';
222 if (isset($CODOC_SETTINGS['show_support_message'])) {
223 $show_support_message = $CODOC_SETTINGS['show_support_message'];
224 }
225 $show_support_categories = '';
226 if (isset($CODOC_SETTINGS['show_support_categories'])) {
227 $show_support_categories = $CODOC_SETTINGS['show_support_categories'];
228 }
229 $show_support_location = 'bottom';
230 if (isset($CODOC_SETTINGS['show_support_location'])) {
231 $show_support_location = $CODOC_SETTINGS['show_support_location'];
232 }
233
234 $show_support_entry = (is_single() && preg_grep("/(?:$show_support_categories)/",array_map( function($c) { return $c->name; },get_the_category(get_post()->ID))));
235 if (!$matches && ($support_entry_code = $params['codoc_support_entry_code']) && $show_support_entry) {
236 $support_tag = sprintf('<div class="codoc-entries" data-without-body="1" data-support-message="%s" id="codoc-entry-%s" ></div>',htmlspecialchars($show_support_message,ENT_QUOTES),$support_entry_code);
237 $post_content = $show_support_location == 'bottom' ?
238 $post_content . $support_tag :
239 $support_tag . $post_content ;
240 }
241
242 // data-wp-plugin-ver が無いタグは分割しない
243 if (!$matches) {
244 return $post_content;
245 }
246
247 // codocタグで分割 (202001: gutenbergで直前のdivタグを削除)
248 $tag_regex = '/(?:<div(?:[^>]+|)>|)<(?:span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:span|div)>(?:<\/div>|)/';
249 if ( $params['preview'] ) {
250 $post_content = preg_replace($tag_regex,'<div class="codoc-continue">ここから上は無料で表示されます</div>',$post_content);
251 return $post_content;
252 }
253 // codoc タグの前後で分ける
254 $splited = preg_split($tag_regex,$post_content);
255 // codoc タグにID属性のentrycodeとdata-without-body(無料分を非表示)をつける
256 $entryCodeFormated = sprintf('"codoc-entry-%s" ',$params['codoc_entry_code']);
257 $codoc_tag = preg_replace('/<((?:span|div)[^>]+)data-id="[^"]+"((?:[^>]+|))>/','<${1} ${2} data-without-body="1" id=' . $entryCodeFormated . ">", $matches[1]);
258 # THE THOR の page-lp.php が " " をけずるための対策
259 # "div class" -> "div class"
260 $codoc_tag = preg_replace('/div +class/','div class',$codoc_tag);
261
262 if ($params['is_amp_endpoint']) {
263 $format = preg_replace_callback('/(<(?:span|div)[^>]+>)((?:[^<>]+|))(<\/(?:span|div)>)/',function($matches) {
264 $format = $matches[1] . '<a href="%%s">%s</a>' . $matches[3];
265 return sprintf($format,($matches[2] ? $matches[2] : '続きを読む'));
266 },$codoc_tag);
267 $codoc_tag = sprintf($format,$params["post_permalink"]);
268 }
269
270 # タグの前後にHTMLを挿�
271
272 if (!isset($CODOC_SETTINGS['str_before_codoc_tag'])) {
273 $CODOC_SETTINGS['str_before_codoc_tag'] = '';
274 }
275 if (!isset($CODOC_SETTINGS['str_after_codoc_tag'])) {
276 $CODOC_SETTINGS['str_after_codoc_tag'] = '';
277 }
278 // 無料部分のみ表示
279 $post_content = $splited[0] . sprintf(
280 '%s<div class="wp-block-codoc-codoc-block">%s</div>%s',
281 $CODOC_SETTINGS['str_before_codoc_tag'],
282 $codoc_tag,
283 $CODOC_SETTINGS['str_after_codoc_tag']
284 );
285 return $post_content;
286 }
287
288
289 }
290
291