[$this, 'sanitize_settings'], 'default' => [ 'max_games_per_day' => 5, 'max_games_per_hour' => 5, 'post_intervals' => 5, 'post_author' => get_current_user_id(), 'post_category' => 0, 'ai_content_prompt' => "You are a passionate football blogger writing for fans who love deep match insights. Your goal is to create an engaging, narrative-driven preview that feels like a conversation with a knowledgeable friend at a sports bar. Writing Instructions: 1. Write in a conversational, passionate tone as if discussing the match with a close friend 2. Provide context beyond raw statistics - discuss team dynamics and potential match narratives 3. Include a balanced, nuanced prediction that considers both statistical likelihood and the unpredictable nature of football 4. Use engaging storytelling techniques to make the preview compelling 5. Incorporate the betting odds context subtly, focusing on match analysis rather than pure gambling perspective 6. Aim for 500-700 words 7. End with a provocative question or intriguing prediction to spark reader engagement Special Requests: - Avoid generic sports clichés - Use vivid, descriptive language - Highlight potential match-defining moments - Create a sense of anticipation and excitement", 'featured_image_url' => '', 'dalle_image_generation' => 0, 'dalle_image_size' => '1024x1024', 'dalle_image_quality' => 'standard', 'openai_model' => 'gpt-3.5-turbo', ], ] ); // Post Configuration Section add_settings_section( 'post_settings', '', [$this, 'render_post_settings_section'], 'ai-sports-writer-post' ); add_settings_field( 'max_games_per_day', 'Maximum Games Per Day', [$this, 'render_max_games_per_day_field'], 'ai-sports-writer-post', 'post_settings' ); add_settings_field( 'max_games_per_hour', 'Maximum Games Per Hour', [$this, 'render_max_games_per_hour_field'], 'ai-sports-writer-post', 'post_settings' ); add_settings_field( 'post_intervals', 'Post Intervals (minutes)', [$this, 'render_post_intervals_field'], 'ai-sports-writer-post', 'post_settings' ); add_settings_field( 'post_author', 'Default Post Author', [$this, 'render_post_author_field'], 'ai-sports-writer-post', 'post_settings' ); add_settings_field( 'post_category', 'Default Post Category', [$this, 'render_post_category_field'], 'ai-sports-writer-post', 'post_settings' ); // Prompt Configuration Section add_settings_section( 'prompt_settings', 'AI Prompt Configuration', [$this, 'render_prompt_settings_section'], 'ai-sports-writer-post' ); add_settings_field( 'ai_content_prompt', 'AI Content Generation Prompt', [$this, 'render_ai_content_prompt_field'], 'ai-sports-writer-post', 'prompt_settings' ); // Featured Image Section add_settings_section( 'image_settings', 'Featured Image Settings', [$this, 'render_image_settings_section'], 'ai-sports-writer-post' ); add_settings_field( 'featured_image_upload', 'Featured Image', [$this, 'render_featured_image_upload_field'], 'ai-sports-writer-post', 'image_settings' ); add_settings_field( 'dalle_image_generation', 'DALL-E Image Generation', [$this, 'render_dalle_image_generation_field'], 'ai-sports-writer-post', 'image_settings' ); add_settings_field( 'dalle_image_size', 'DALL-E Image Size', [$this, 'render_dalle_image_size_field'], 'ai-sports-writer-post', 'image_settings' ); add_settings_field( 'dalle_image_quality', 'DALL-E Image Quality', [$this, 'render_dalle_image_quality_field'], 'ai-sports-writer-post', 'image_settings' ); } // Render callback for post settings public function render_post_settings_section(): void { echo '
' . esc_html__('Configure post generation settings such as the maximum number of posts per day/hour.', 'ai-sports-writer') . '
'; } // Render field for maximum games per day public function render_max_games_per_day_field(): void { $options = get_option('aisprtsw_post_settings'); $value = $options['max_games_per_day'] ?? 5; echo ''; } // Render field for maximum games per hour public function render_max_games_per_hour_field(): void { $options = get_option('aisprtsw_post_settings'); $value = $options['max_games_per_hour'] ?? 5; echo ''; } // Render field for post intervals (in minutes) public function render_post_intervals_field(): void { $options = get_option('aisprtsw_post_settings'); $value = $options['post_intervals'] ?? 5; echo ''; echo 'Interval in minutes between scheduled posts (1-30 minutes).
'; } // Render field for default post author public function render_post_author_field(): void { $options = get_option('aisprtsw_post_settings'); $selected = $options['post_author'] ?? get_current_user_id(); $users = get_users([ 'capability' => 'publish_posts', 'fields' => ['ID', 'display_name'], ]); echo ''; echo 'Select the default author for automatically generated posts.
'; } // Render field for default post category public function render_post_category_field(): void { $options = get_option('aisprtsw_post_settings'); $selected = $options['post_category'] ?? 0; $categories = get_categories(['hide_empty' => false]); echo ''; echo 'Select the default category for automatically generated posts.
'; } public function render_prompt_settings_section(): void {} //Render field for AI content generation prompt public function render_ai_content_prompt_field(): void { $options = get_option('aisprtsw_post_settings'); $value = $options['ai_content_prompt'] ?? ''; echo ''; echo 'Customize the prompt sent to OpenAI for content generation.
'; } // Render callback for image settings public function render_image_settings_section(): void { echo 'Set the configuration for featured images in posts.
'; } // Render field for uploading featured image public function render_featured_image_upload_field(): void { $options = get_option('aisprtsw_post_settings'); $value = $options['featured_image_url'] ?? ''; echo ''; echo ''; $attachment_id = attachment_url_to_postid($value); if ($attachment_id) { // Display the image using wp_get_attachment_image echo 'When checked, the plugin will attempt to generate a featured image using DALL-E for each post.
'; } // Render dropdown for DALL-E image size public function render_dalle_image_size_field(): void { $options = get_option('aisprtsw_post_settings'); $current_size = $options['dalle_image_size'] ?? '1024x1024'; $size_options = [ '1024x1024' => 'Square (1024x1024) - Classic format', '1792x1024' => 'Landscape (1792x1024) - Stadium scenes', '1024x1792' => 'Portrait (1024x1792) - Social media' ]; echo ''; echo 'Choose the aspect ratio that best fits your content layout.
'; } // Render dropdown for DALL-E image quality public function render_dalle_image_quality_field(): void { $options = get_option('aisprtsw_post_settings'); $current_quality = $options['dalle_image_quality'] ?? 'standard'; $quality_options = [ 'standard' => 'Standard - Faster generation, lower cost', 'hd' => 'HD - Higher detail, premium quality' ]; echo ''; echo 'HD quality provides more detailed images but costs more to generate.
'; } // Sanitize input settings before saving public function sanitize_settings($input): array { $sanitized = []; // Max games per day validation if ($input['max_games_per_day'] < 1 || $input['max_games_per_day'] > 100) { add_settings_error( 'aisprtsw_post_settings', 'invalid_max_games_per_day', __('Maximum games per day should be between 1 and 100.', 'ai-sports-writer') ); $sanitized['max_games_per_day'] = 5; } else { $sanitized['max_games_per_day'] = (int) $input['max_games_per_day']; } // Max games per hour validation if ($input['max_games_per_hour'] < 1 || $input['max_games_per_hour'] > 24) { add_settings_error( 'aisprtsw_post_settings', 'invalid_max_games_per_hour', __('Maximum games per hour should be between 1 and 24.', 'ai-sports-writer') ); $sanitized['max_games_per_hour'] = 5; } else { $sanitized['max_games_per_hour'] = (int) $input['max_games_per_hour']; } // Post intervals validation $post_intervals = (int) ($input['post_intervals'] ?? 5); if ($post_intervals < 1 || $post_intervals > 30) { add_settings_error( 'aisprtsw_post_settings', 'invalid_post_intervals', __('Post intervals should be between 1 and 30 minutes.', 'ai-sports-writer') ); $sanitized['post_intervals'] = 5; } else { $sanitized['post_intervals'] = $post_intervals; } // Featured image url validator $featured_image_url = esc_url_raw($input['featured_image_url'] ?? ''); if (!empty($featured_image_url)) { $file_type = wp_check_filetype($featured_image_url); $allowed_image_types = ['jpg', 'jpeg', 'png', 'gif']; if (!filter_var($featured_image_url, FILTER_VALIDATE_URL)) { add_settings_error( 'aisprtsw_post_settings', 'invalid_featured_image_url', __('The featured image URL is not a valid URL.', 'ai-sports-writer') ); $sanitized['featured_image_url'] = ''; } elseif (!in_array($file_type['ext'], $allowed_image_types)) { add_settings_error( 'aisprtsw_post_settings', 'invalid_featured_image_type', __('The featured image URL does not point to a valid image file (jpg, jpeg, png, or gif).', 'ai-sports-writer') ); $sanitized['featured_image_url'] = ''; } else { $sanitized['featured_image_url'] = $featured_image_url; } } else { $sanitized['featured_image_url'] = ''; } $sanitized['dalle_image_generation'] = (int) ($input['dalle_image_generation'] ?? 0); // DALL-E image size validation $allowed_sizes = ['1024x1024', '1792x1024', '1024x1792']; $sanitized['dalle_image_size'] = in_array($input['dalle_image_size'] ?? '', $allowed_sizes, true) ? $input['dalle_image_size'] : '1024x1024'; // DALL-E image quality validation $allowed_qualities = ['standard', 'hd']; $sanitized['dalle_image_quality'] = in_array($input['dalle_image_quality'] ?? '', $allowed_qualities, true) ? $input['dalle_image_quality'] : 'standard'; $sanitized['post_author'] = (int) ($input['post_author'] ?? get_current_user_id()); $sanitized['post_category'] = (int) ($input['post_category'] ?? 0); $allowed_html = [ 'p' => [], 'br' => [], 'strong' => [], 'em' => [], 'ul' => [], 'ol' => [], 'li' => [], ]; $sanitized['ai_content_prompt'] = wp_kses($input['ai_content_prompt'] ?? '', $allowed_html); $allowed_models = [ 'gpt-3.5-turbo', 'gpt-4o-mini', 'gpt-4-turbo', 'gpt-4o', 'gpt-4o-2024-08-06', 'o1-mini' ]; $sanitized['openai_model'] = in_array($input['openai_model'] ?? '', $allowed_models, true) ? $input['openai_model'] : 'gpt-3.5-turbo'; return $sanitized; } }