404 NOT FOUND

お探しのページは見つかりませんでした。
// ===== FANZA BG Helpers (locks, date formatting, diagnostics) ===== if (!function_exists('fanza_acquire_lock')) { function fanza_acquire_lock($ttl_minutes = 10) { if (get_transient('fanza_import_lock')) return false; set_transient('fanza_import_lock', 1, $ttl_minutes * MINUTE_IN_SECONDS); return true; }} if (!function_exists('fanza_release_lock')) { function fanza_release_lock() { delete_transient('fanza_import_lock'); }} if (!function_exists('fanza_format_date_ymd_to_dash')) { function fanza_format_date_ymd_to_dash($ymd) { if (!$ymd) return ''; $d = preg_replace('/[^0-9]/', '', $ymd); if (strlen($d) !== 8) return ''; return substr($d,0,4) . '-' . substr($d,4,2) . '-' . substr($d,6,2); }} if (!function_exists('fanza_redact_api_url')) { function fanza_redact_api_url($url) { $parts = wp_parse_url($url); if (!$parts) return $url; $qs = array(); if (!empty($parts['query'])) { parse_str($parts['query'], $qs); if (isset($qs['api_id'])) $qs['api_id'] = '***'; if (isset($qs['affiliate_id'])) $qs['affiliate_id'] = '***'; $parts['query'] = http_build_query($qs); } $scheme = isset($parts['scheme']) ? $parts['scheme'].'://' : ''; $host = isset($parts['host']) ? $parts['host'] : ''; $path = isset($parts['path']) ? $parts['path'] : ''; $query = (isset($parts['query']) && $parts['query'] !== '') ? '?'.$parts['query'] : ''; return $scheme . $host . $path . $query; }} // ===== FANZA BG fetch (batching with bookmark) ===== if (!function_exists('fanza_fetch_and_insert_posts_bg')) { function fanza_fetch_and_insert_posts_bg($openstt = null, $openend = null, $post_status = 'publish') { if (!fanza_acquire_lock(10)) { fanza_add_import_log('スキップ:ロック中'); return 'locked'; } $bookmark = get_option('fanza_import_bookmark', array()); if (!$openstt && !$openend && !empty($bookmark['openstt']) && !empty($bookmark['openend'])) { $openstt = $bookmark['openstt']; $openend = $bookmark['openend']; $resume_offset = isset($bookmark['offset']) ? (int)$bookmark['offset'] : 1; } else { $resume_offset = isset($bookmark['offset']) ? (int)$bookmark['offset'] : 1; if ($openstt || $openend) { $bm_st = isset($bookmark['openstt']) ? $bookmark['openstt'] : ''; $bm_ed = isset($bookmark['openend']) ? $bookmark['openend'] : ''; if (!empty($bookmark) && ($bm_st !== $openstt || $bm_ed !== $openend)) { $resume_offset = 1; delete_option('fanza_import_bookmark'); } } } // Swap reversed if (!empty($openstt) && !empty($openend)) { $st_i = intval(preg_replace('/[^0-9]/','',$openstt)); $ed_i = intval(preg_replace('/[^0-9]/','',$openend)); if ($st_i > $ed_i) { $tmp = $openstt; $openstt = $openend; $openend = $tmp; fanza_add_import_log('注意: openstt/openend を入れ替えました'); } } $endpoint = 'https://api.dmm.com/affiliate/v3/ItemList'; $hits = 100; $offset = max(1, (int)$resume_offset); $total_fetched = 0; $api_id = get_fanza_option('api_id'); $affiliate_id = get_fanza_option('affiliate_id'); $site = get_fanza_option('site'); if (!$site || !in_array(strtoupper($site), array('FANZA','DMM'))) { $site = 'FANZA'; } $category_filter_enabled = get_option('fanza_category_filter_enabled', 0); $filter_categories = get_option('fanza_filter_categories', array()); $exclude_categories = get_option('fanza_exclude_categories', array()); $start_time = time(); $time_budget = (int) apply_filters('fanza_time_budget', 50); try { while (true) { $params = array( 'api_id' => $api_id, 'affiliate_id' => $affiliate_id, 'site' => $site, 'service' => 'digital', 'floor' => 'videoa', 'output' => 'json', 'hits' => $hits, 'offset' => $offset, 'sort' => 'date', ); if ($openstt) { $st_dash = fanza_format_date_ymd_to_dash($openstt); if ($st_dash) $params['gte_date'] = $st_dash . 'T00:00:00'; } if ($openend) { $ed_dash = fanza_format_date_ymd_to_dash($openend); if ($ed_dash) $params['lte_date'] = $ed_dash . 'T23:59:59'; } $url = $endpoint . '?' . http_build_query($params); update_option('fanza_last_api_url', fanza_redact_api_url($url), false); $response = wp_remote_get($url, array('timeout' => 30)); if (is_wp_error($response)) { fanza_add_import_log('APIリクエスト失敗: '.$response->get_error_message()); break; } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if ($code !== 200 || empty($data) || empty($data['result'])) { $body_snip = is_string($body) ? mb_substr($body,0,200) : ''; $api_msg = isset($data['message']) ? $data['message'] : ''; fanza_add_import_log('APIレスポンス不正: HTTP ' . $code . ($api_msg ? (' message=' . $api_msg) : '') . ($body_snip ? (' body=' . $body_snip) : '')); break; } if (empty($data['result']['items'])) break; // ==== Item processing copied from original fanza_fetch_and_insert_posts ==== foreach ($data['result']['items'] as $item) { // ▼ 1) カテゴリマスタ登録(フィルタ前) fanza_register_item_categories_to_master($item); // ▼ 2) カテゴリフィルタ if ($category_filter_enabled) { if (!fanza_should_include_item_by_category($item, $filter_categories, $exclude_categories)) { fanza_add_import_log("カテゴリフィルタでスキップ: " . (isset($item['title']) ? $item['title'] : '(no title)')); continue; } } // ▼ 3) Dedup:タイトル正規化・比較コード抽出・同一候補検索 $fanza_title_for_compare = (isset($item['title']) ? $item['title'] : ''); $signature = function_exists('product_signature') ? product_signature($fanza_title_for_compare) : substr(sha1($fanza_title_for_compare), 0, 16); $title_normalized = function_exists('normalize_product_title') ? normalize_product_title($fanza_title_for_compare) : mb_strtolower(trim($fanza_title_for_compare), 'UTF-8'); // content_id → comparable_code_normalized(h_1324skmj00636 → SKMJ636 等) $comparable_code_normalized = ''; if (!empty($item['content_id']) && function_exists('normalize_comparable_code')) { $comparable_code_normalized = normalize_comparable_code($item['content_id']); } // FANZA側の基準日 $ref_date = (isset($item['date']) ? $item['date'] : ''); $existing = []; $post_id = 0; // ★ 追加:コード一致+日付±60日で既存候補(DUGA由来も含む)を検索 if ($comparable_code_normalized && $ref_date && function_exists('find_existing_by_code_and_date')) { $post_id = find_existing_by_code_and_date($comparable_code_normalized, $ref_date, 60); } // 既存ヘルパOR検索(ID/シグネチャ/正規化キー含む) if (!$post_id && function_exists('find_existing_product_post')) { $post_id = find_existing_product_post([ 'fanza_content_id' => (isset($item['content_id']) ? $item['content_id'] : ''), 'signature' => $signature, 'title_normalized' => $title_normalized, 'comparable_code_normalized' => $comparable_code_normalized, ]); } if ($post_id) { $existing = [ (object)['ID' => (int)$post_id] ]; } else { // メタ: content_id で最後のフォールバック $existing = get_posts([ 'post_type' => 'post', 'meta_key' => 'content_id', 'meta_value' => (isset($item['content_id']) ? $item['content_id'] : ''), 'posts_per_page' => 1, 'post_status' => 'any', ]); } // ▼ 4) 追加/更新 if (!empty($existing)) { $post_id = (int)$existing[0]->ID; $category_ids = get_or_create_fanza_categories($item); wp_update_post([ 'ID' => $post_id, 'post_title' => $item['title'], 'post_content' => isset($item['comment']) ? $item['comment'] : '', 'post_category' => $category_ids, 'post_status' => $post_status, ]); set_fanza_taxonomies($post_id, $item); $update_count++; } else { $category_ids = get_or_create_fanza_categories($item); $post_id = wp_insert_post([ 'post_title' => $item['title'], 'post_content' => isset($item['comment']) ? $item['comment'] : '', 'post_type' => 'post', 'post_status' => $post_status, 'post_category' => $category_ids, ]); if ($post_id) { set_fanza_taxonomies($post_id, $item); } $add_count++; } if (!empty($post_id)) { update_post_meta($post_id, 'product_signature', $signature); } // ▼ 5) メタ保存(Dedup Coreのプレフィクス保存を優先) if ($post_id) { $meta_fields = [ 'content_id' => (isset($item['content_id']) ? $item['content_id'] : ''), 'product_id' => (isset($item['product_id']) ? $item['product_id'] : ''), 'url' => (isset($item['URL']) ? $item['URL'] : ''), 'affiliateURL' => (isset($item['affiliateURL']) ? $item['affiliateURL'] : ''), 'price' => isset($item['prices']['price']) ? $item['prices']['price'] : '', 'list_price' => isset($item['prices']['list_price']) ? $item['prices']['list_price'] : '', 'maker_name' => isset($item['iteminfo']['maker'][0]['name']) ? $item['iteminfo']['maker'][0]['name'] : '', 'maker_id' => isset($item['iteminfo']['maker'][0]['id']) ? $item['iteminfo']['maker'][0]['id'] : '', 'date' => (isset($item['date']) ? $item['date'] : ''), 'volume' => isset($item['volume']) ? $item['volume'] : '', 'review_count' => isset($item['review']['count']) ? $item['review']['count'] : 0, 'review_average' => isset($item['review']['average']) ? $item['review']['average'] : 0, // 正規化メタ 'title_normalized' => $title_normalized, 'comparable_code_normalized' => $comparable_code_normalized, ]; // fanza_* の“カノニカル”は個別保存で直書き update_post_meta($post_id, 'fanza_title_normalized', $title_normalized); update_post_meta($post_id, 'fanza_code_normalized', $comparable_code_normalized); // maker_product の確実な保存 $meta_fields['maker_product'] = isset($item['maker_product']) ? sanitize_text_field($item['maker_product']) : ''; if (defined('WP_DEBUG') && WP_DEBUG) { error_log('FANZA API - maker_product: ' . ($meta_fields['maker_product'] !== '' ? $meta_fields['maker_product'] : 'NOT SET') . ' / content_id: ' . ((isset($item['content_id']) ? $item['content_id'] : ''))); } // 画像各種 if (!empty($item['imageURL'])) { $meta_fields['imageURL_small'] = (isset($item['imageURL']['small']) ? $item['imageURL']['small'] : ''); $meta_fields['imageURL_large'] = (isset($item['imageURL']['large']) ? $item['imageURL']['large'] : ''); $meta_fields['imageURL_list'] = (isset($item['imageURL']['list']) ? $item['imageURL']['list'] : ''); } // サンプル画像 if (!empty($item['sampleImageURL'])) { if (isset($item['sampleImageURL']['sample_s'])) { $meta_fields['sampleImageURL_s'] = json_encode($item['sampleImageURL']['sample_s'], JSON_UNESCAPED_UNICODE); } if (isset($item['sampleImageURL']['sample_l'])) { $meta_fields['sampleImageURL_l'] = json_encode($item['sampleImageURL']['sample_l'], JSON_UNESCAPED_UNICODE); } } // サンプル動画 if (!empty($item['sampleMovieURL'])) { foreach (['size_476_306'=>'sampleMovieURL_476_306','size_560_360'=>'sampleMovieURL_560_360','size_644_414'=>'sampleMovieURL_644_414','size_720_480'=>'sampleMovieURL_720_480'] as $k => $mk) { if (isset($item['sampleMovieURL'][$k])) $meta_fields[$mk] = $item['sampleMovieURL'][$k]; } } // 出演者 $actress_names = []; $actress_ids = []; if (!empty($item['iteminfo']['actress'])) { foreach ($item['iteminfo']['actress'] as $actress) { if (!empty($actress['name'])) $actress_names[] = sanitize_text_field($actress['name']); if (!empty($actress['id'])) $actress_ids[] = sanitize_text_field($actress['id']); } } $meta_fields['actress_name'] = implode(', ', $actress_names); $meta_fields['actress_id'] = implode(', ', $actress_ids); $meta_fields['actress_name_json'] = json_encode($actress_names, JSON_UNESCAPED_UNICODE); $meta_fields['actress_id_json'] = json_encode($actress_ids, JSON_UNESCAPED_UNICODE); $meta_fields['actress_count'] = count($actress_names); for ($i = 0; $i < min(5, count($actress_names)); $i++) { $meta_fields['actress_name_' . ($i + 1)] = $actress_names[$i]; if (isset($actress_ids[$i])) { $meta_fields['actress_id_' . ($i + 1)] = $actress_ids[$i]; } } // シリーズ(先頭のみ) if (!empty($item['iteminfo']['series'][0])) { $meta_fields['series_name'] = sanitize_text_field((isset($item['iteminfo']['series'][0]['name']) ? $item['iteminfo']['series'][0]['name'] : '')); $meta_fields['series_id'] = sanitize_text_field((isset($item['iteminfo']['series'][0]['id']) ? $item['iteminfo']['series'][0]['id'] : '')); } // レーベル(メーカー) if (!empty($item['iteminfo']['label'][0])) { $meta_fields['label_name'] = (isset($item['iteminfo']['label'][0]['name']) ? $item['iteminfo']['label'][0]['name'] : ''); $meta_fields['label_id'] = (isset($item['iteminfo']['label'][0]['id']) ? $item['iteminfo']['label'][0]['id'] : ''); } // 監督 if (!empty($item['iteminfo']['director'][0])) { $meta_fields['director_name'] = (isset($item['iteminfo']['director'][0]['name']) ? $item['iteminfo']['director'][0]['name'] : ''); $meta_fields['director_id'] = (isset($item['iteminfo']['director'][0]['id']) ? $item['iteminfo']['director'][0]['id'] : ''); } // JAN if (!empty($item['jancode'])) { $meta_fields['jancode'] = $item['jancode']; } // ジャンル $genre_names = []; $genre_ids = []; if (!empty($item['iteminfo']['genre'])) { foreach ($item['iteminfo']['genre'] as $genre) { if (!empty($genre['name'])) $genre_names[] = sanitize_text_field($genre['name']); if (!empty($genre['id'])) $genre_ids[] = sanitize_text_field($genre['id']); } } $meta_fields['genre_name'] = implode(', ', $genre_names); $meta_fields['genre_id'] = implode(', ', $genre_ids); $meta_fields['genre_name_json'] = json_encode($genre_names, JSON_UNESCAPED_UNICODE); $meta_fields['genre_id_json'] = json_encode($genre_ids, JSON_UNESCAPED_UNICODE); if (function_exists('upsert_meta_prefixed')) { upsert_meta_prefixed($post_id, $meta_fields, 'fanza'); } else { foreach ($meta_fields as $key => $value) { update_post_meta($post_id, $key, $value); } } } $total_fetched++; // time budget check if ((time() - $start_time) > $time_budget) { update_option('fanza_import_bookmark', array('openstt'=>$openstt,'openend'=>$openend,'offset'=>$offset), false); fanza_release_lock(); return 'time-sliced'; } } // pagination forward if (isset($data['result']['result_count']) && intval($data['result']['result_count']) < $hits) { delete_option('fanza_import_bookmark'); break; } if (isset($data['result']['total_count']) && ($offset + $hits) > intval($data['result']['total_count'])) { delete_option('fanza_import_bookmark'); break; } $offset += $hits; update_option('fanza_import_bookmark', array('openstt'=>$openstt,'openend'=>$openend,'offset'=>$offset), false); if ((time() - $start_time) > $time_budget) { fanza_release_lock(); return 'time-sliced'; } sleep(1); } } finally { fanza_release_lock(); } return 'done'; }} // ===== BG Runner Hook ===== add_action('fanza_background_runner', function() { fanza_add_import_log('BG: ランナー起動'); $state = get_option('fanza_runner_state', array()); if (empty($state) || empty($state['openstt']) || empty($state['openend'])) return; $result = fanza_fetch_and_insert_posts_bg($state['openstt'], $state['openend'], get_fanza_option('auto_import_status')); $state['last'] = current_time('mysql'); if ($result === 'done') { $state['done'] = 1; delete_option('fanza_import_bookmark'); fanza_add_import_log('BG: 完走しました。'); } update_option('fanza_runner_state', $state, false); $bm = get_option('fanza_import_bookmark', array()); if (!empty($bm['openstt']) && !empty($bm['openend'])) { $delay = (int) apply_filters('fanza_requeue_delay', 5); wp_schedule_single_event(time() + max(1, $delay), 'fanza_background_runner'); $bm_offset = isset($bm['offset']) ? intval($bm['offset']) : 0; fanza_add_import_log('BG: 次バッチをスケジュール(offset=' . $bm_offset . ')'); } }); // ===== Admin submenu for BG Import ===== add_action('admin_menu', function() { add_submenu_page( 'fanza-products', 'FANZA BGインポート(完走)', 'BGインポート(完走)', 'manage_options', 'fanza-bg-import', 'fanza_bg_import_page' ); }); function fanza_bg_import_page() { if (!current_user_can('manage_options')) return; if (isset($_POST['fanza_bg_run_now']) && check_admin_referer('fanza_bg_run')) { $st = sanitize_text_field($_POST['fanza_bg_openstt']); $ed = sanitize_text_field($_POST['fanza_bg_openend']); update_option('fanza_runner_state', array( 'openstt'=>$st,'openend'=>$ed,'offset'=>1,'added'=>0,'updated'=>0,'skipped'=>0,'fetched'=>0,'done'=>0,'last'=>current_time('mysql'), ), false); delete_option('fanza_import_bookmark'); $delay = (int) apply_filters('fanza_requeue_delay', 5); wp_schedule_single_event(time() + max(1, $delay), 'fanza_background_runner'); do_action('fanza_background_runner'); echo '
BG実行を開始しました。
BGを今すぐ1回実行しました。
BG状態をリセットしました。
次回BG実行: ' . esc_html($next_bg_text) . '
'; if (!empty($last_url)) { echo '直近API URL(マスク済): '. esc_html($last_url) .'
'. esc_html(print_r($state, true)) .''; } else { echo '
まだ進捗情報はありません。
'; } echo 'まだログがありません。
'; } echo '