page_slug, array( $this, 'render_settings_page' ) ); } /** * Register settings */ public function register_settings() { register_setting( 'aitm_settings_group', 'aitm_settings', array( $this, 'sanitize_settings' ) ); // General Settings Section add_settings_section( 'aitm_general_section', __( 'General Settings', 'ai-thumbnails-maker' ), array( $this, 'render_general_section' ), $this->page_slug ); add_settings_field( 'auto_generation', __( 'Auto Generation', 'ai-thumbnails-maker' ), array( $this, 'render_checkbox_field' ), $this->page_slug, 'aitm_general_section', array( 'label_for' => 'auto_generation', 'description' => __( 'Automatically generate featured images when publishing or updating posts. The plugin will search for the first image in the post content and set it as the featured image. This works only for posts without existing featured images (unless "Overwrite Existing" is enabled).', 'ai-thumbnails-maker' ), ) ); add_settings_field( 'overwrite_existing', __( 'Overwrite Existing', 'ai-thumbnails-maker' ), array( $this, 'render_checkbox_field' ), $this->page_slug, 'aitm_general_section', array( 'label_for' => 'overwrite_existing', 'description' => __( 'Replace existing featured images with newly generated ones. When enabled, the plugin will regenerate featured images even for posts that already have one. This is useful for updating old thumbnails or fixing incorrect featured images. Use with caution as this will overwrite manually set featured images.', 'ai-thumbnails-maker' ), ) ); add_settings_field( 'enabled_post_types', __( 'Enabled Post Types', 'ai-thumbnails-maker' ), array( $this, 'render_post_types_field' ), $this->page_slug, 'aitm_general_section', array( 'label_for' => 'enabled_post_types', 'description' => __( 'Select which post types should have automatic featured image generation enabled. By default, standard Posts and Pages are selected. You can also enable it for custom post types like WooCommerce Products. Only post types that support featured images (post thumbnails) will appear in this list.', 'ai-thumbnails-maker' ), ) ); add_settings_field( 'generation_method', __( 'Generation Method', 'ai-thumbnails-maker' ), array( $this, 'render_method_field' ), $this->page_slug, 'aitm_general_section', array( 'label_for' => 'generation_method', 'description' => __( 'Choose how featured images should be generated. "First Content Image" finds and uses existing images from post content. "AI Generation" creates new unique images using artificial intelligence based on post content.', 'ai-thumbnails-maker' ), ) ); // Image Settings Section add_settings_section( 'aitm_image_section', __( 'Image Requirements', 'ai-thumbnails-maker' ), array( $this, 'render_image_section' ), $this->page_slug ); add_settings_field( 'min_image_width', __( 'Minimum Image Width', 'ai-thumbnails-maker' ), array( $this, 'render_number_field' ), $this->page_slug, 'aitm_image_section', array( 'label_for' => 'min_image_width', 'min' => 0, 'max' => 5000, 'step' => 1, 'description' => __( 'Minimum width in pixels for images to be used as featured images. Images smaller than this width will be skipped. Set to 0 to accept images of any width. Recommended: 800px or higher for good quality thumbnails. This helps avoid using tiny icons or low-resolution images as featured images.', 'ai-thumbnails-maker' ), ) ); add_settings_field( 'min_image_height', __( 'Minimum Image Height', 'ai-thumbnails-maker' ), array( $this, 'render_number_field' ), $this->page_slug, 'aitm_image_section', array( 'label_for' => 'min_image_height', 'min' => 0, 'max' => 5000, 'step' => 1, 'description' => __( 'Minimum height in pixels for images to be used as featured images. Images smaller than this height will be skipped. Set to 0 to accept images of any height. Recommended: 600px or higher for good quality thumbnails. Combined with minimum width, this ensures only suitable images are used as featured images.', 'ai-thumbnails-maker' ), ) ); // AI Settings Section (показывается условно через JS) add_settings_section( 'aitm_ai_section', __( 'AI Generation Settings', 'ai-thumbnails-maker' ), array( $this, 'render_ai_section' ), $this->page_slug ); add_settings_field( 'ai_api_key', __( 'OpenAI API Key', 'ai-thumbnails-maker' ), array( $this, 'render_text_field' ), $this->page_slug, 'aitm_ai_section', array( 'label_for' => 'ai_api_key', 'type' => 'password', 'description' => sprintf( /* translators: %s: URL to OpenAI API keys page */ __( 'Enter your OpenAI API key. How to get API key', 'ai-thumbnails-maker' ), 'https://platform.openai.com/api-keys' ), ) ); add_settings_field( 'ai_prompt_model', __( 'Prompt Model', 'ai-thumbnails-maker' ), array( $this, 'render_ai_model_field' ), $this->page_slug, 'aitm_ai_section', array( 'label_for' => 'ai_prompt_model', 'type' => 'prompt', 'default' => 'gpt-4o-mini', 'description' => __( 'AI model for generating image descriptions (prompts)', 'ai-thumbnails-maker' ), ) ); add_settings_field( 'ai_language', __( 'Language', 'ai-thumbnails-maker' ), array( $this, 'render_select_field' ), $this->page_slug, 'aitm_ai_section', array( 'label_for' => 'ai_language', 'default' => 'en_US', 'options' => array( 'en_US' => 'English', 'ru_RU' => 'Russian', 'es_ES' => 'Spanish', 'fr_FR' => 'French', 'de_DE' => 'German', 'zh_CN' => 'Chinese (Simplified)', 'ja_JP' => 'Japanese', 'it_IT' => 'Italian', 'ko_KR' => 'Korean', 'pt_PT' => 'Portuguese', 'ar_SA' => 'Arabic', 'hi_IN' => 'Hindi', ), 'description' => __( 'Language for prompt generation', 'ai-thumbnails-maker' ), ) ); add_settings_field( 'ai_image_model', __( 'Image Model', 'ai-thumbnails-maker' ), array( $this, 'render_ai_model_field' ), $this->page_slug, 'aitm_ai_section', array( 'label_for' => 'ai_image_model', 'type' => 'image', 'default' => 'dall-e-3', 'description' => __( 'AI model for generating images', 'ai-thumbnails-maker' ), ) ); add_settings_field( 'ai_image_resolution', __( 'Image Resolution', 'ai-thumbnails-maker' ), array( $this, 'render_select_field' ), $this->page_slug, 'aitm_ai_section', array( 'label_for' => 'ai_image_resolution', 'default' => '1024x1024', 'options' => array( '1024x1024' => '1024x1024', '1024x1792' => '1024x1792 (Portrait)', '1792x1024' => '1792x1024 (Landscape)', ), 'description' => __( 'Resolution for generated images', 'ai-thumbnails-maker' ), ) ); add_settings_field( 'ai_image_style', __( 'Image Style', 'ai-thumbnails-maker' ), array( $this, 'render_select_field' ), $this->page_slug, 'aitm_ai_section', array( 'label_for' => 'ai_image_style', 'default' => 'natural', 'options' => array( 'natural' => 'Natural', 'vivid' => 'Vivid', ), 'description' => __( 'Style for generated images', 'ai-thumbnails-maker' ), ) ); } /** * Sanitize settings * * @param array $input Input values. * @return array Sanitized values. */ public function sanitize_settings( $input ) { $sanitized = array(); // Auto generation $sanitized['auto_generation'] = isset( $input['auto_generation'] ) ? true : false; // Overwrite existing $sanitized['overwrite_existing'] = isset( $input['overwrite_existing'] ) ? true : false; // Enabled post types if ( isset( $input['enabled_post_types'] ) && is_array( $input['enabled_post_types'] ) ) { $sanitized['enabled_post_types'] = array_map( 'sanitize_text_field', $input['enabled_post_types'] ); } else { $sanitized['enabled_post_types'] = array(); } // Min image width if ( isset( $input['min_image_width'] ) ) { $sanitized['min_image_width'] = absint( $input['min_image_width'] ); } else { $sanitized['min_image_width'] = 0; } // Min image height if ( isset( $input['min_image_height'] ) ) { $sanitized['min_image_height'] = absint( $input['min_image_height'] ); } else { $sanitized['min_image_height'] = 0; } // Generation method $sanitized['generation_method'] = isset( $input['generation_method'] ) ? sanitize_text_field( $input['generation_method'] ) : 'first_content_image'; // AI Settings if ( isset( $input['ai_content_source'] ) ) { $sanitized['ai_content_source'] = sanitize_text_field( $input['ai_content_source'] ); } if ( isset( $input['ai_api_key'] ) ) { $sanitized['ai_api_key'] = sanitize_text_field( $input['ai_api_key'] ); } if ( isset( $input['ai_prompt_model'] ) ) { $sanitized['ai_prompt_model'] = sanitize_text_field( $input['ai_prompt_model'] ); } if ( isset( $input['ai_language'] ) ) { $sanitized['ai_language'] = sanitize_text_field( $input['ai_language'] ); } if ( isset( $input['ai_image_model'] ) ) { $sanitized['ai_image_model'] = sanitize_text_field( $input['ai_image_model'] ); } if ( isset( $input['ai_image_resolution'] ) ) { $sanitized['ai_image_resolution'] = sanitize_text_field( $input['ai_image_resolution'] ); } if ( isset( $input['ai_image_style'] ) ) { $sanitized['ai_image_style'] = sanitize_text_field( $input['ai_image_style'] ); } // Title Image Settings if ( isset( $input['title_image_width'] ) ) { $sanitized['title_image_width'] = absint( $input['title_image_width'] ); } if ( isset( $input['title_image_height'] ) ) { $sanitized['title_image_height'] = absint( $input['title_image_height'] ); } if ( isset( $input['title_image_bg_color'] ) ) { $sanitized['title_image_bg_color'] = sanitize_hex_color( $input['title_image_bg_color'] ); } if ( isset( $input['title_image_text_color'] ) ) { $sanitized['title_image_text_color'] = sanitize_hex_color( $input['title_image_text_color'] ); } if ( isset( $input['title_image_font_size'] ) ) { $sanitized['title_image_font_size'] = absint( $input['title_image_font_size'] ); } // Default Image Settings if ( isset( $input['default_image_id'] ) ) { $sanitized['default_image_id'] = absint( $input['default_image_id'] ); } // Note: generation_log is now stored in a separate option 'aitm_generation_log' // and doesn't need to be preserved here return $sanitized; } /** * Render general section */ public function render_general_section() { echo '

' . esc_html__( 'Configure how the plugin automatically generates featured images for your posts. These settings control when and how the plugin will create thumbnails from images found in your post content.', 'ai-thumbnails-maker' ) . '

'; } /** * Render image section */ public function render_image_section() { echo '

' . esc_html__( 'Set quality requirements for images that will be used as featured images. These filters help ensure that only high-quality, properly sized images are selected as post thumbnails. Small or low-quality images will be automatically skipped.', 'ai-thumbnails-maker' ) . '

'; } /** * Render checkbox field * * @param array $args Field arguments. */ public function render_checkbox_field( $args ) { $settings = get_option( 'aitm_settings', array() ); $value = $settings[ $args['label_for'] ] ?? false; printf( '', esc_attr( $args['label_for'] ), esc_attr( $args['label_for'] ), checked( $value, true, false ), esc_html( $args['description'] ) ); } /** * Render number field * * @param array $args Field arguments. */ public function render_number_field( $args ) { $settings = get_option( 'aitm_settings', array() ); $value = $settings[ $args['label_for'] ] ?? 0; printf( '', esc_attr( $args['label_for'] ), esc_attr( $args['label_for'] ), esc_attr( $value ), esc_attr( $args['min'] ), esc_attr( $args['max'] ), esc_attr( $args['step'] ) ); if ( ! empty( $args['description'] ) ) { printf( '

%s

', esc_html( $args['description'] ) ); } } /** * Render post types field * * @param array $args Field arguments. */ public function render_post_types_field( $args ) { $settings = get_option( 'aitm_settings', array() ); $enabled_types = $settings[ $args['label_for'] ] ?? array( 'post', 'page' ); $post_types = get_post_types( array( 'public' => true, ), 'objects' ); foreach ( $post_types as $post_type ) { // Пропускаем attachment if ( $post_type->name === 'attachment' ) { continue; } $checked = in_array( $post_type->name, $enabled_types, true ); printf( '
', esc_attr( $args['label_for'] ), esc_attr( $post_type->name ), checked( $checked, true, false ), esc_html( $post_type->label ) ); } if ( ! empty( $args['description'] ) ) { printf( '

%s

', esc_html( $args['description'] ) ); } } /** * Render AI section */ public function render_ai_section() { echo '

' . esc_html__( 'Configure OpenAI settings for AI-powered image generation.', 'ai-thumbnails-maker' ) . '

'; } /** * Render generation method field * * @param array $args Field arguments. */ public function render_method_field( $args ) { $settings = get_option( 'aitm_settings', array() ); $method = $settings['generation_method'] ?? 'first_content_image'; ?> %s

', esc_html( $args['description'] ) ); } } /** * Render text field * * @param array $args Field arguments. */ public function render_text_field( $args ) { $settings = get_option( 'aitm_settings', array() ); $field_name = $args['label_for']; $value = $settings[ $field_name ] ?? ( $args['default'] ?? '' ); $type = $args['type'] ?? 'text'; printf( '', esc_attr( $type ), esc_attr( $field_name ), esc_attr( $field_name ), esc_attr( $value ) ); if ( ! empty( $args['description'] ) ) { printf( '

%s

', wp_kses_post( $args['description'] ) ); } } /** * Render select field * * @param array $args Field arguments. */ public function render_select_field( $args ) { $settings = get_option( 'aitm_settings', array() ); $field_name = $args['label_for']; $value = $settings[ $field_name ] ?? ( $args['default'] ?? '' ); $options = $args['options'] ?? array(); printf( ''; if ( ! empty( $args['description'] ) ) { printf( '

%s

', wp_kses_post( $args['description'] ) ); } } /** * Render AI model field * * @param array $args Field arguments. */ public function render_ai_model_field( $args ) { $settings = get_option( 'aitm_settings', array() ); $field_name = $args['label_for']; $value = $settings[ $field_name ] ?? ( $args['default'] ?? '' ); // Подключить класс AI Generator для получения списка моделей require_once AITM_PLUGIN_DIR . '/includes/class-ai-image-generator.php'; $models = $args['type'] === 'prompt' ? AITM_AI_Image_Generator::get_prompt_models() : AITM_AI_Image_Generator::get_image_models(); printf( ''; if ( ! empty( $args['description'] ) ) { printf( '

%s

', esc_html( $args['description'] ) ); } } /** * Render settings page */ public function render_settings_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } // Check if settings were saved // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['settings-updated'] ) ) { add_settings_error( 'aitm_messages', 'aitm_message', __( 'Settings saved successfully.', 'ai-thumbnails-maker' ), 'updated' ); } $settings = get_option( 'aitm_settings', array() ); $post_types = get_post_types( array( 'public' => true ), 'objects' ); settings_errors( 'aitm_messages' ); ?>

name !== 'attachment' && post_type_supports( $post_type->name, 'thumbnail' ) ) : ?>

page_slug ) === false ) { return; } // Enqueue WordPress media library wp_enqueue_media(); wp_enqueue_style( 'aitm-admin-settings', AITM_PLUGIN_URL . 'assets/dist/admin-settings.css', array(), AITM_VERSION ); wp_enqueue_script( 'aitm-admin-settings', AITM_PLUGIN_URL . 'assets/dist/admin-settings.js', array( 'jquery' ), AITM_VERSION, true ); } }