get_error_message());
}
}
// プラグインのメインクラス
class AI_Article_Generator {
public function __construct() {
// アクションとフィルターのセットアップ
add_action('admin_menu', array($this, 'add_admin_menu'));
add_action('admin_init', array($this, 'register_settings'));
add_action('wp_ajax_generate_article', array($this, 'generate_article'));
}
// エラーハンドリング
private function handle_error($error) {
if ($error instanceof AI_Article_Generator_Error) {
$error->log();
wp_die(esc_html($error->get_error_message()), 'AI Article Generator Error', array('response' => 500));
}
}
// 管理メニューの追加
public function add_admin_menu() {
$hook_suffix = add_menu_page(
'AI記事生成',
'AI記事生成',
'manage_options',
'ai-article-generator',
array($this, 'display_admin_page'),
'dashicons-edit',
6
);
add_action("admin_print_scripts-{$hook_suffix}", array($this, 'enqueue_admin_scripts'));
}
// 管理画面用スクリプトのエンキュー
public function enqueue_admin_scripts() {
wp_enqueue_script('ai-article-generator-admin', plugins_url('admin.js', __FILE__), array('jquery'), '1.0', true);
wp_localize_script('ai-article-generator-admin', 'aiArticleGenerator', array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('ai_article_generator_nonce')
));
}
// 設定の登録
public function register_settings() {
register_setting('ai_article_generator_options', 'ai_article_api_key', array(
'sanitize_callback' => 'sanitize_text_field'
));
register_setting('ai_article_generator_options', 'ai_article_theme', array(
'sanitize_callback' => 'sanitize_text_field'
));
register_setting('ai_article_generator_options', 'ai_article_prompt', array(
'sanitize_callback' => 'sanitize_textarea_field'
));
register_setting('ai_article_generator_options', 'ai_article_tone', array(
'sanitize_callback' => 'sanitize_text_field'
));
register_setting('ai_article_generator_options', 'ai_article_publish_option', array(
'sanitize_callback' => 'sanitize_text_field'
));
}
// 管理画面の表示
public function display_admin_page() {
if (isset($_GET['error'])) {
$error_message = sanitize_text_field($_GET['error']);
echo '
' . esc_html($error_message) . '
';
}
?>
array(
'Authorization' => 'Bearer ' . $api_key,
'Content-Type' => 'application/json',
),
'body' => json_encode(array(
'model' => 'gpt-4',
'messages' => array(
array('role' => 'system', 'content' => $system_message),
array('role' => 'user', 'content' => $user_message),
),
'temperature' => 0.7,
'max_tokens' => 2000,
)),
'timeout' => 60, // タイムアウトを60秒に設定
));
if (is_wp_error($response)) {
throw new AI_Article_Generator_Error('api_request_failed', 'APIリクエストエラー: ' . $response->get_error_message());
}
$body = json_decode(wp_remote_retrieve_body($response), true);
if (isset($body['error'])) {
throw new AI_Article_Generator_Error('api_error', 'API エラー: ' . $body['error']['message']);
}
if (!isset($body['choices'][0]['message']['content'])) {
throw new AI_Article_Generator_Error('invalid_response', 'APIからの無効なレスポンス');
}
$generated_content = $body['choices'][0]['message']['content'];
// 重複チェック
if ($this->check_duplicate_content($generated_content)) {
throw new AI_Article_Generator_Error('duplicate_content', '類似の記事が既に存在します。手動で調整してください。');
}
// 記事を投稿
$post_id = wp_insert_post(array(
'post_title' => $theme,
'post_content' => $generated_content,
'post_status' => get_option('ai_article_publish_option'),
));
if (!$post_id) {
throw new AI_Article_Generator_Error('post_creation_failed', '記事の作成に失敗しました。');
}
$post_url = get_permalink($post_id);
$status = get_option('ai_article_publish_option') === 'publish' ? '公開' : '下書き保存';
$message = "記事が正常に生成され、{$status}されました。記事を確認する";
wp_send_json_success($message);
} catch (AI_Article_Generator_Error $e) {
wp_send_json_error($e->get_error_message());
} catch (Exception $e) {
wp_send_json_error('予期せぬエラーが発生しました: ' . $e->getMessage());
}
}
// 記事の重複チェック
public function check_duplicate_content($content) {
try {
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
);
$posts = get_posts($args);
if (is_wp_error($posts)) {
throw new AI_Article_Generator_Error('post_retrieval_failed', '既存の投稿の取得に失敗しました。');
}
foreach ($posts as $post) {
$similarity = $this->calculate_similarity($content, $post->post_content);
if ($similarity > 0.7) { // 70%以上の類似度を重複とみなす
return true;
}
}
return false;
} catch (Exception $e) {
$this->handle_error(new AI_Article_Generator_Error('duplicate_check_failed', '重複チェック中にエラーが発生しました: ' . $e->getMessage()));
}
}
private function calculate_similarity($str1, $str2) {
$str1 = strtolower($str1);
$str2 = strtolower($str2);
$distance = levenshtein($str1, $str2);
$maxLength = max(strlen($str1), strlen($str2));
return 1 - ($distance / $maxLength);
}
}
// プラグインのインスタンス化
$ai_article_generator = new AI_Article_Generator();