PluginProbe
codoc / 0.8.4
codoc v0.8.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.php

class-codoc.php in codoc 0.8.4, at class-codoc.php

536 lines 19.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 final class Codoc {
4
5 public function __construct() {
6 if (is_admin()) {
7 // setting
8 $this->add_settings();
9 }
10 $auth_info = get_option(CODOC_AUTHINFO_OPTION_NAME);
11 if (!$auth_info) {
12 return $this;
13 }
14
15 // データ同期 (save_postはis_adminで実行されないケースがある)
16 add_action( 'save_post', [$this,'save_post'], 20, 3 );
17 add_action( 'added_post_meta', [$this,'updated_post_meta'], 10, 3 );
18 add_action( 'updated_post_meta',[$this,'updated_post_meta'], 10, 3 );
19 add_action( 'deleted_post_meta',[$this,'deleted_post_meta'], 10, 4 );
20
21 if (is_admin()) {
22 // gutenberg
23 require_once 'src/init.php';
24 // tinymce
25 $this->add_mce();
26 add_action('wp_loaded', function() {
27 wp_localize_script('wordpress-cgb-block-js', 'OPTIONS', array(
28 'codoc_url' => CODOC_URL,
29 'codoc_usercode' => get_option(CODOC_USERCODE_OPTION_NAME),
30 'codoc_plugin_version' => CODOC_PLUGIN_VERSION,
31 'codoc_sdk_path' => CODOC_SDK_PATH,
32 ));
33
34 // tinymce 用
35 //wp_enqueue_script( 'codoc-integration-js', CODOC_URL . '/js/integration.js', true );
36 });
37 return $this;
38 }
39
40 // codocのJS登録
41
42 add_action( 'wp_enqueue_scripts', function() {
43 wp_enqueue_script( 'codoc-injector-js', CODOC_URL . '/js/cms.js' );
44 });
45 // 登録したscriptタグに属性をつける
46 add_filter('script_loader_tag', [$this,'modifier_script_tag'],10,2);
47 // tinymce用のショートコード
48 add_shortcode('codoc', [$this, 'injector_shortcode']);
49
50 // paywall用の本文非表示化とcodocタグへの属性追加
51 add_filter('the_content',[$this,'the_content']);
52 return $this;
53 }
54
55 public function modifier_script_tag($tag,$handle) {
56 if($handle !== 'codoc-injector-js') {
57 return $tag;
58 }
59 $CODOC_SETTINGS = get_option(CODOC_SETTINGS_OPTION_NAME);
60 $data_css = '';
61 if ($css_path = $CODOC_SETTINGS['css_path']) {
62 $data_css = sprintf(' data-css="%s" ',$css_path);
63 }
64 //return str_replace(' src=', $data_css . ' defer src=', $tag);
65 return preg_replace('/(src=[^>]+)/',' ${1} ' . $data_css . ' defer',$tag);
66 }
67 public function injector_shortcode($atts) {
68 global $post;
69 ob_start();
70 require 'views/codoc-injector.php';
71 return ob_get_clean();
72 }
73 public function callAPI($method,$path,$body = [],$headers = []) {
74 $usercode = get_option(CODOC_USERCODE_OPTION_NAME);
75 $token = get_option(CODOC_TOKEN_OPTION_NAME);
76
77 $headers['X-CodocToken'] = $token;
78 $host = CODOC_URL;
79 $sslverify = true;
80
81 if (preg_match('/local/',CODOC_URL)) {
82 $sslverify = false;
83 $host = 'https://host.docker.internal';
84 }
85 $url = sprintf("%s/api/v1/cms/%s%s",$host,$usercode,$path);
86 $http = new WP_Http();
87 try {
88 $response = $http->request(
89 $url,
90 [
91 'sslverify' => $sslverify,
92 'method' => $method,
93 'timeout' => 10,
94 'headers' => $headers,
95 'body' => $body,
96 ]
97 );
98 if ( is_wp_error($response) || $response['response']['code'] != 200 ) {
99 //何もしない
100 //var_dump( $response );
101 }
102 } catch(Exception $e) {
103 }
104
105 if (!is_wp_error($response) and
106 isset($response['body']) and
107 is_string($response['body']) and
108 is_array(json_decode($response['body'], true)) and
109 (json_last_error() == JSON_ERROR_NONE)) {
110 return json_decode($response['body']);
111 } else {
112 return null;
113 }
114 }
115 # settings / 設定関連
116 public function add_settings() {
117 global $CODOC_SETTINGS;
118 add_action( 'admin_menu' ,function(){
119 add_options_page(
120 'codoc の設定', //ページタイトル
121 'codoc', //設定メニューに表示されるメニュータイトル
122 'edit_users', //権限
123 'codoc', //設定ページのURL。options-general.php?page=codoc
124 function() {
125 echo '<div clas="wrap">';
126 echo '<form method="post" action="options.php">';
127 settings_fields( 'codoc_option_group' );
128 do_settings_sections( 'codoc' );
129 submit_button(); // 送信ボタン
130 echo '</div>';
131 }
132 );
133 });
134
135 add_action( "admin_init", function() {
136 // codocからの認証データ処理
137 if (isset($_GET['page']) and $_GET['page'] == 'codoc' and isset($_GET['fetch_token_key'])) {
138 $key = sanitize_text_field($_GET['fetch_token_key']);
139 $usercode = sanitize_text_field($_GET['usercode']);
140 update_option(CODOC_USERCODE_OPTION_NAME,$usercode);
141 $data = $this->callAPI('GET','/token',[ "fetch_token_key" => $key ]);
142 if ($data->status and $token = $data->token) {
143 update_option(CODOC_TOKEN_OPTION_NAME,$token);
144 $data = $this->callAPI('GET','');
145 if ($data->status and $user = $data->user) {
146 update_option(CODOC_AUTHINFO_OPTION_NAME,[
147 'email' => $user->email,
148 'name' => $user->name,
149 ]);
150 }
151 #$current_url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://').$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
152 #$current_url = preg_replace('/(.*)fetch_token_key.*/','${1}&codoc_auth_finished=1',$current_url);
153 //add_settings_error( 'general', 'settings_updated', __( 'OK' ), 'success' );
154 $current_url = admin_url('options-general.php') . '?page=codoc&codoc_auth_finished=1';
155
156 wp_redirect( $current_url);
157 exit;
158 }
159 }
160
161 global $CODOC_USERCODE;
162 global $CODOC_SETTINGS;
163 global $CODOC_TOKEN;
164 global $CODOC_AUTHINFO;
165 $CODOC_USERCODE = get_option(CODOC_USERCODE_OPTION_NAME);
166 $CODOC_SETTINGS = get_option(CODOC_SETTINGS_OPTION_NAME);
167 $CODOC_TOKEN = get_option(CODOC_TOKEN_OPTION_NAME);
168 $CODOC_AUTHINFO = get_option(CODOC_AUTHINFO_OPTION_NAME);
169 if( !$CODOC_SETTINGS ) {
170 //デフォルト値
171 $CODOC_SETTINGS = array(
172 'css_path' => '',
173 );
174 update_option( CODOC_SETTINGS_OPTION_NAME, $CODOC_SETTINGS );
175 }
176 if (!isset($CODOC_SETTINGS['str_replace_binded_url_from'])) {
177 $CODOC_SETTINGS['str_replace_binded_url_from'] = '';
178 }
179 if (!isset($CODOC_SETTINGS['str_replace_binded_url_to'])) {
180 $CODOC_SETTINGS['str_replace_binded_url_to'] = '';
181 }
182
183 add_settings_section(
184 'setting_section_id', // id
185 'codoc 設定ページ', // title
186 function (){}, // callback
187 'codoc' // page
188 );
189 // 認証がある場合
190 if ($CODOC_AUTHINFO) {
191 register_setting(
192 'codoc_option_group', // option group
193 CODOC_SETTINGS_OPTION_NAME // option name(DB)
194 );
195 add_settings_field(
196 'css_path', // id
197 'カスタマイズ用CSSパス', // title
198 function() {
199 global $CODOC_SETTINGS;
200 echo sprintf('<input type="text" name="%s[css_path]" value="%s">',CODOC_SETTINGS_OPTION_NAME,$CODOC_SETTINGS['css_path']);
201 },
202 'codoc', //page
203 'setting_section_id' //Section
204 );
205 add_settings_field(
206 'str_replace_binded_url', // id
207 'codoc側に登録するパーマリンクを置換', // title
208 function() {
209 global $CODOC_SETTINGS;
210 echo sprintf('<input type="text" name="%s[str_replace_binded_url_from]" value="%s">',CODOC_SETTINGS_OPTION_NAME,$CODOC_SETTINGS['str_replace_binded_url_from']);
211 echo ('');
212 echo sprintf('<input type="text" name="%s[str_replace_binded_url_to]" value="%s">',CODOC_SETTINGS_OPTION_NAME,$CODOC_SETTINGS['str_replace_binded_url_to']);
213 echo ('に変換');
214 },
215 'codoc', //page
216 'setting_section_id' //Section
217 );
218
219 register_setting(
220 'codoc_option_group', // option group
221 CODOC_USERCODE_OPTION_NAME
222 );
223 register_setting(
224 'codoc_option_group', // option group
225 CODOC_TOKEN_OPTION_NAME
226 );
227
228 if (isset($_GET['codoc_auth_finished']) and $_GET['codoc_auth_finished']) {
229 add_settings_error( 'general', 'settings_updated', __( 'codocの認証が完了しました' ), 'success' );
230 }
231
232 add_settings_field(
233 'codoc_auth',
234 '認証',
235 function() {
236 global $CODOC_USERCODE;
237 global $CODOC_TOKEN;
238 global $CODOC_AUTHINFO;
239 $script = "javascript:document.getElementById('codoc-usercode').value='';document.getElementById('codoc-token').value=' ';document.getElementById('codoc-auth-message').innerText='解除を完了するには変更を保存してください';document.getElementById('codoc-auth-message').color='red';";
240
241 echo sprintf('<p><font color="green" id="codoc-auth-message"><strong>%s</strong> で認証済</font></p>',$CODOC_AUTHINFO['email']);
242
243 echo sprintf('<input id="codoc-usercode" type="hidden" name="%s" value="%s">',CODOC_USERCODE_OPTION_NAME,$CODOC_USERCODE);
244 echo sprintf('<input id="codoc-token" type="hidden" name="%s" value="%s">',CODOC_TOKEN_OPTION_NAME,$CODOC_TOKEN);
245 echo sprintf('<p>認証を<a href="javascript:void(0);" onClick="' . $script . '">解除する</p>');
246 },
247 'codoc',
248 'setting_section_id'
249 );
250
251 }
252
253 // ない場合
254 if (!$CODOC_AUTHINFO and !isset($_GET['auth_by_myself'])) {
255 add_settings_field(
256 'codoc_auth',
257 '認証',
258 function() {
259
260 //$current_url = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://').$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
261 $current_url = admin_url('options-general.php') . '?page=codoc';
262 $login_url = sprintf("location.href='%s'",CODOC_URL . '/me/token?from=wp&return_url=' . urlencode($current_url));
263 $register_url = sprintf("location.href='%s'",CODOC_URL . '/register?from=wp&return_url=' . urlencode($current_url));
264 // submitを消しておく
265 echo ('<script type="text/javascript">window.onload=function(){document.getElementById(\'submit\').style.display = \'none\'}</script>');
266 echo ('codocをWordPressでご利用いただくには認証が�
267 要です。<br />');
268 echo sprintf('ユーザーコードとAPIトークンを<a href="%s&auth_by_myself=1">直接�
269 �力</a>することでも認証できます。<br /><br />',$current_url);
270 echo sprintf('<input type="button" class="button button-primary" value="ログインして認証" onClick="%s"> <input type="button" class="button button-primary" value="登録して認証" onClick="%s"><br /><br />',$login_url,$register_url);
271
272
273 },
274 'codoc',
275 'setting_section_id'
276 );
277 }
278 // ない場合かつ自分で認証する場合
279 if (!$CODOC_AUTHINFO and (isset($_GET['auth_by_myself']) and $_GET['auth_by_myself'])) {
280 register_setting(
281 'codoc_option_group', // option group
282 CODOC_USERCODE_OPTION_NAME
283 );
284 add_settings_field(
285 'codoc_usercode',
286 'ユーザーコード',
287 function() {
288 global $CODOC_USERCODE;
289 echo sprintf('<input type="text" name="%s" value="%s">',CODOC_USERCODE_OPTION_NAME,$CODOC_USERCODE);
290 },
291 'codoc',
292 'setting_section_id'
293 );
294 register_setting(
295 'codoc_option_group', // option group
296 CODOC_TOKEN_OPTION_NAME
297 );
298 add_settings_field(
299 'codoc_token',
300 'APIトークン',
301 function() {
302 global $CODOC_TOKEN;
303 echo sprintf('<input type="text" name="%s" value="%s">',CODOC_TOKEN_OPTION_NAME,$CODOC_TOKEN);
304 },
305 'codoc',
306 'setting_section_id'
307 );
308 }
309
310 // 認証�
311 報を保存
312 add_action( 'update_option_' . CODOC_USERCODE_OPTION_NAME, function( $old_value, $new_value ) {
313 global $CODOC_RE_AUTHORIZE;
314 $CODOC_RE_AUTHORIZE = 1;
315 },9,2); // $hook, $function_to_add, $priority, $accepted_args
316 add_action( 'update_option_' . CODOC_TOKEN_OPTION_NAME, function( $old_value, $new_value ) {
317 global $CODOC_RE_AUTHORIZE;
318 $CODOC_RE_AUTHORIZE = 1;
319 },10,2);
320 add_action('updated_option',function(){
321 global $CODOC_RE_AUTHORIZE;
322 if ($CODOC_RE_AUTHORIZE) {
323 $data = $this->callAPI('GET','');
324 if ($data->status and $user = $data->user) {
325 update_option(CODOC_AUTHINFO_OPTION_NAME,[
326 'email' => $user->email,
327 'name' => $user->name,
328 ]);
329 } else {
330 update_option(CODOC_AUTHINFO_OPTION_NAME,'');
331 }
332 }
333 });
334
335 });
336 // プラグイン一覧に設定のリンクをいれる
337 add_filter( 'plugin_action_links_' . plugin_basename( plugin_dir_path( __FILE__ ) . 'codoc' . '.php' ),
338 function( $links ) {
339 $setting_link = sprintf( '<a href="%s">%s</a>', esc_url( add_query_arg( 'page', 'codoc', admin_url( 'options-general.php' ) ) ), esc_html( '設定' ) );
340 array_unshift( $links, $setting_link );
341
342 return $links;
343 }
344 );
345
346 }
347 public function add_mce() {
348 // Add Shortcode options in the WordPres visual editors
349 //wp_enqueue_script( 'codoc-editor-script', CODOC_URL . 'codoc/src_mce/codoc-editor.js');
350
351 add_action( 'init', function() {
352 if ( ! current_user_can( 'edit_posts' ) && ! current_user_can( 'edit_pages' ) ) {
353 return;
354 }
355 if ( get_user_option( 'rich_editing' ) == 'true' ) {
356 // プラグイン�
357 で使うCSRF を生成
358 $path = plugins_url( 'codoc/src_mce/codoc-editor-onload.js', __DIR__ );
359 wp_enqueue_script( 'codoc-editor-onload', $path, array('jquery'), '', true );
360 // I just want to insert this global variables but i don't know how i can do it..
361 wp_localize_script(
362 'codoc-editor-onload',
363 'CODOCEDITOR',
364 array(
365 'action' => 'codoc_shortcodes',
366 'nonce' => wp_create_nonce( 'codoc_shortcodes' ),
367
368 'codoc_url' => CODOC_URL,
369 'codoc_usercode' => get_option(CODOC_USERCODE_OPTION_NAME),
370 'codoc_plugin_version' => CODOC_PLUGIN_VERSION,
371 'codoc_sdk_path' => CODOC_SDK_PATH,
372 )
373 );
374
375 // ここでtinymceのプラグイン追加
376 //wp_enqueue_style( 'codoc-admin-style', plugins_url( 'codoc/src_mce/codoc-admin.css', __DIR__ ) );
377 //add_editor_style( plugins_url( 'codoc/src_mce/codoc-admin.css', __DIR__ ) );
378 wp_enqueue_style( 'codoc-admin-style', CODOC_URL . CODOC_SDK_PATH . '.tinymce.css?c=' . date('Ymd') );
379 add_editor_style( CODOC_URL . CODOC_SDK_PATH . '.tinymce.css' );
380
381 add_filter( 'mce_external_plugins', function( $plugin_array ) {
382 //$plugin_array['codoc'] = plugins_url( 'codoc/src_mce/codoc-editor.js', __DIR__ );
383 $plugin_array['codoc'] = CODOC_URL . CODOC_SDK_PATH . '.tinymce.js?c=' . date('Ymd');
384 return $plugin_array;
385 } );
386 add_filter( 'mce_buttons', function( $buttons ) {
387 array_push( $buttons, "|", "codoc" );
388 return $buttons;
389 } );
390
391 }
392 } );
393 }
394 public function save_post($post_ID,$post,$update) {
395 if (preg_match('/^(auto-draft|inherit)$/',$post->post_status)) {
396 return;
397 }
398
399 $post_content = $post->post_content;
400 preg_match('/wp:codoc\/codoc-block +?({.*})/',$post_content,$matches);
401 // GUTENBERG で指定されたjson(記事�
402 )がない場合
403 if (!$matches) {
404 return;
405 }
406 // GUTENBERG で保存している�
407 容を取得
408 $codoc_info = json_decode($matches[1],true);
409 // codoc タグがない場合はなにもしない
410 //preg_match('/(<span +data-id="codoc-tag"[^>]+>(?:.+|)<\/span>)/',$post_content,$matches);
411 preg_match('/(<(?:span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:span|div)>)/',$post_content,$matches);
412 if (!$matches) {
413 return;
414 }
415 // TODO: split or html parse? HTMLがつながってる場合はおかしくなる
416 // classic(tinymce)版の場合p、もしくはdivにかこまれている
417 $splited = preg_split('/(?:<(?:div|p)(?:[^>]+|)>|)<\!-- +wp:codoc\/codoc-block .*<\!-- +\/wp:codoc\/codoc-block +-->(?:<\/(?:div|p)>|)/s',$post_content);
418 $status = $post->post_status == 'publish' ? 1 : 0;
419 # $body_free = '';
420 # $body_paywalled = '';
421 # if (count($splited) >= 2) {
422 #
423 # }
424 $binded_url = get_permalink($post_ID);
425 $CODOC_SETTINGS = get_option(CODOC_SETTINGS_OPTION_NAME);
426 if (isset($CODOC_SETTINGS['str_replace_binded_url_from']) and
427 isset($CODOC_SETTINGS['str_replace_binded_url_to']) and
428 $CODOC_SETTINGS['str_replace_binded_url_from']) {
429 $binded_url = str_replace(sanitize_text_field($CODOC_SETTINGS['str_replace_binded_url_from']),
430 sanitize_text_field($CODOC_SETTINGS['str_replace_binded_url_to']),
431 $binded_url);
432 }
433
434 $params = [
435 'title' => $post->post_title,
436 'body_free' => $splited[0],
437 'body_paywalled' => $splited[1],
438 'status' => $status,
439 'binded_url' => $binded_url,
440 'show_price' => isset($codoc_info['showPrice']) ? ($codoc_info['showPrice'] ? 1 : 0) : 0,
441 'price' => isset($codoc_info['price']) ? $codoc_info['price'] : 100,
442 'limited' => isset($codoc_info['limited']) ? ($codoc_info['limited'] ? 1 : 0) : 0,
443 'limited_count' => isset($codoc_info['limitedCount']) ? $codoc_info['limitedCount'] : 1,
444 'affiliate_mode' => isset($codoc_info['affiliateMode']) ? ($codoc_info['affiliateMode'] ? 1 : 0) : 0,
445 'affiliate_rate' => isset($codoc_info['affiliateRate']) ? $codoc_info['affiliateRate'] : '0.0500',
446 'show_support' => isset($codoc_info['showSupport']) ? ($codoc_info['showSupport'] ? 1 : 0) : 0,
447 'subscriptions' => isset($codoc_info['subscriptions']) ? array_keys($codoc_info['subscriptions']) : [],
448 ];
449 $entryCode = get_post_meta($post_ID,'codoc_entry_code',true);
450 if ($entryCode) {
451 $res = $this->callAPI('PUT','/entries/' . $entryCode ,$params);
452 } else {
453 $res = $this->callAPI('POST', '/entries', $params);
454 if (is_object($res) and $res->status) {
455 update_post_meta($post_ID,'codoc_entry_code',$res->entry->code);
456 }
457 }
458 return true;
459 }
460 function updated_post_meta( $meta_ID, $post_ID, $meta_key ) {
461 if ($meta_key != '_thumbnail_id') {
462 return;
463 }
464 if ( has_post_thumbnail($post_ID) ) {
465 $attachment = wp_get_attachment_metadata( get_post_thumbnail_id($post_ID));
466 $upload_dir = wp_upload_dir();
467 $file_path = sprintf ('%s/%s',$upload_dir['basedir'],$attachment['file']);
468
469 if (is_readable($file_path)) {
470 $name = 'file';
471
472 $boundary = wp_generate_password(24);
473
474 $payload = '';
475 $payload .= '--' . $boundary;
476 $payload .= "\r\n";
477 $payload .= 'Content-Disposition: form-data; name="' . $name . '"; filename="' . basename( $file_path ) . '"' . "\r\n";
478 $payload .= "Content-Type: application/octet-stream\r\n";
479 $payload .= "Content-Transfer-Encoding: binary\r\n";
480 $payload .= "\r\n";
481 $payload .= file_get_contents( $file_path );
482 $payload .= "\r\n";
483
484 $payload .= '--' . $boundary . '--';
485
486
487 $entryCode = get_post_meta($post_ID,'codoc_entry_code',true);
488 $res = $this->callAPI(
489 'POST',
490 '/entries/' . $entryCode . '/thumbnail',
491 $payload,
492 ['content-type' => 'multipart/form-data; boundary=' . $boundary]
493 );
494 }
495 }
496 }
497 function deleted_post_meta( $meta_ids, $post_ID, $meta_key,$meta_value ) {
498 if ($meta_key != '_thumbnail_id') {
499 return;
500 }
501 $entryCode = get_post_meta($post_ID,'codoc_entry_code',true);
502 $res = $this->callAPI(
503 'POST',
504 '/entries/' . $entryCode . '/thumbnail',
505 [ "reset" => 1 ]
506 );
507 }
508 function the_content( $post_content ) {
509 if ( is_single() && in_the_loop() && is_main_query() ) {
510 }
511 // codoc タグがあるかどうか (202001:span -> div に変更)
512 preg_match('/(<(span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:div|span)>)/',$post_content,$matches);
513 // data-wp-plugin-ver が無いタグは分割しない
514 if (!$matches) {
515 return $post_content;
516 }
517 // codocタグで分割 (202001: gutenbergで直前のdivタグを削除)
518 $tag_regex = '/(?:<div(?:[^>]+|)>|)<(?:span|div)[^>]+data-id="codoc-tag"(?:[^>]+|)>(?:.+|)<\/(?:span|div)>(?:<\/div>|)/';
519 if ( is_preview() ) {
520 $post_content = preg_replace($tag_regex,'<div class="codoc-continue">ここから上は無料で表示されます</div>',$post_content);
521 return $post_content;
522 }
523 // codoc タグの前後で分ける
524 $splited = preg_split($tag_regex,$post_content);
525 // codoc タグにID属性のentrycodeとdata-without-body(無料分を非表示)をつける
526 $post = get_post();
527 $entryCode = sprintf('"codoc-entry-%s" ',get_post_meta($post->ID,'codoc_entry_code',true));
528 $codoc_tag = preg_replace('/<((?:span|div)[^>]+)data-id="[^"]+"((?:[^>]+|))>/','<${1} ${2} data-without-body="1" id=' . $entryCode . ">", $matches[1]);
529 // 無料部分のみ表示
530 return $splited[0] . sprintf('<div class="wp-block-codoc-codoc-block">%s</div>',$codoc_tag);
531 }
532
533
534 }
535
536