<?php
ob_start();
/**
* Plugin Name: Meta Generator AI
* Description: This Plugin is a useful way to automatically generate product descriptions based on the product name, which can save time and effort when creating large numbers of products.
* Version: 1.2.4
* Author: SJ innovation
* Author URI: https://sjinnovation.com/
*/
add_filter('https_ssl_verify', '__return_false');
function add_my_custom_button() {
global $post;
if (isset($post) && 'product' === $post->post_type) { ?>
<script>
jQuery(document).ready(function () {
// Append the buttons after the "Product Name" field
jQuery('#titlediv').after('<div id="my-custom-buttons"><button id="chatgpt-generate-desc-btn">Generate Description<span class="button-info">Click this button to automatically generate a product description based on the product name.</span></button><button id="chatgpt-enter-details-btn">Enter custom description<span class="button-info">Click this button to enter a custom product description.</span></button></div>');
});
</script>
<?php }
}
add_action('edit_form_after_title', 'add_my_custom_button');
function add_custom_buttons_post_new() {
if ('post-new.php' === $GLOBALS['pagenow']) { ?>
<style>
.custom-buttons-container {
position: fixed;
top: -6px;
right: 500px;
z-index: 9999;
display: flex;
justify-content: flex-end;
margin-top: 13px;
}
.custom-buttons-container button {
padding: 10px 15px;
font-size: 13px;
cursor: pointer;
text-align: center;
text-decoration: none;
outline: none;
margin: 4px 2px;
color: #fff;
background-color: #115ea1;
border: none;
border-radius: 3px;
}
.custom-buttons-container button:hover {
background-color: #074982;
color: rgb(205, 162, 162);
box-shadow: 0 12px 16px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19);
}
.custom-buttons-container button:active {
background-color: #115ea1;
transform: translateY(4px);
}
</style>
<script>
jQuery(document).ready(function ($) {
var isPostNewPage = $('body').hasClass('post-new-php') && $('body').hasClass('post-type-post');
if (isPostNewPage) {
var buttonsContainer = $('<div class="custom-buttons-container"></div>');
buttonsContainer.append('<button id="custom-button-3">Generate Description</button>');
buttonsContainer.append('<button id="custom-button-4">Enter Custom Description</button>');
$('body').prepend(buttonsContainer); // Prepend buttons to the body element
}
});
</script>
<?php }
}
add_action('admin_footer', 'add_custom_buttons_post_new');
function enqueue_chatgpt_css() {
wp_enqueue_style('chatgpt-style', plugin_dir_url(__FILE__) . 'style.css');
}
add_action('admin_enqueue_scripts', 'enqueue_chatgpt_css');
function enqueue_chatgpt_scripts() {
wp_enqueue_script('chatgpt-script', plugin_dir_url(__FILE__) . 'product-description-script.js', array('jquery'), '1.0.0', true);
wp_localize_script('chatgpt-script', 'openai_product_description', array(
'ajax_url' => admin_url('admin-ajax.php'),
));
}
add_action('admin_enqueue_scripts', 'enqueue_chatgpt_scripts');
// Save short description and focus keyphrase on product save
function save_short_description($post_id) {
if (isset($_POST['short_description'])) {
$short_desc = sanitize_textarea_field($_POST['short_description']);
update_post_meta($post_id, '_short_description', $short_desc);
}
if (isset($_POST['focus_keyphrase'])) {
$focus_keyphrase = sanitize_text_field($_POST['focus_keyphrase']);
update_post_meta($post_id, '_focus_keyphrase', $focus_keyphrase);
}
}
add_action('woocommerce_process_product_meta', 'save_short_description');
// Define global variable for generated title and focus keyphrase
$generated_title = '';
$generated_focus_keyphrase = '';
function openai_product_description_generator($post_id) {
global $generated_title;
$product_name = get_the_title($post_id);
$short_description = get_post_meta($post_id, '_short_description', true);
$description = '';
// Generate a new description if short description exists
if ($short_description) {
$description = 'Introducing the ' . $product_name . '! This amazing product is perfect for anyone looking for ' . $short_description . '.';
}
// Generate a new description if short description is empty
else {
$description = 'Introducing the ' . $product_name . '! This amazing product is perfect for anyone.';
}
// Update the product description
wp_update_post(array(
'ID' => $post_id,
'post_content' => $description,
));
// Update the Yoast SEO meta description field
update_post_meta($post_id, '_yoast_wpseo_metadesc', $description);
// Remove existing tags before adding new ones
$existing_tags = wp_get_post_terms($post_id, 'product_tag', array('fields' => 'ids'));
if (!empty($existing_tags)) {
foreach ($existing_tags as $tag_id) {
wp_remove_object_terms($post_id, $tag_id, 'product_tag');
}
}
// Update the product tags
$tags = str_replace('#', '', $short_description);
$tags = explode(',', $tags);
$tags = array_map('trim', $tags);
$tags = array_filter($tags); // Remove empty tags
$tags = array_unique($tags); // Remove duplicate tags
foreach ($tags as $tag) {
wp_set_object_terms($post_id, $tag, 'product_tag', true);
}
// Update the Yoast SEO focus keyphrase field
$focus_keyphrase = implode(', ', $tags);
update_post_meta($post_id, '_yoast_wpseo_focuskw', $focus_keyphrase);
// Update the Yoast SEO title field
if ($generated_title) {
update_post_meta($post_id, '_yoast_wpseo_title', $generated_title . ' | ' . $product_name);
} else {
update_post_meta($post_id, '_yoast_wpseo_title', $product_name);
}
}
add_action('wp_ajax_generate_product_description', 'generate_product_description');
add_action('wp_ajax_nopriv_generate_product_description', 'generate_product_description');
// Register the custom button actions
function register_my_custom_button_actions() {
add_action('wp_ajax_enter_product_details', 'enter_product_details');
add_action('wp_ajax_nopriv_enter_product_details', 'enter_product_details');
}
add_action('init', 'register_my_custom_button_actions');
// Add the custom button functionality
function enter_product_details() {
if (isset($_POST['post_ID'])) {
$post_id = $_POST['post_ID'];
global $generated_title, $generated_focus_keyphrase;
$generated_title = $_POST['generated_title'];
$generated_focus_keyphrase = $_POST['focus_keyphrase'];
openai_product_description_generator($post_id);
echo 'success';
}
exit;
}
// Function to update the Yoast SEO slug field
function updateYoastSEOSlug($post_id) {
$product_name = get_the_title($post_id);
$slug = sanitize_title($product_name);
update_post_meta($post_id, '_yoast_wpseo_slug', $slug);
}
add_action('save_post', 'updateYoastSEOSlug');
// AJAX endpoint for generating post details
add_action('wp_ajax_generate_post_details', 'generate_post_details_callback');
add_action('wp_ajax_nopriv_generate_post_details', 'generate_post_details_callback');
function generate_post_details_callback() {
$generatedTitle = $_POST['generatedTitle'];
// Generate the post details based on the generated title
$postDetails = generate_post_details($generatedTitle);
// Prepare the response
$response = array(
'success' => true,
'data' => array(
'postDetails' => $postDetails,
),
);
// Send the response
wp_send_json_success($response);
}
// Function to generate post details (replace this with your actual implementation)
function generate_post_details($generatedTitle) {
// Implement your logic to generate the post details based on the generated title
// Return the generated post details
return "Sample generated post details for title: " . $generatedTitle;
}
// Add a plugin settings page
function my_plugin_settings_page() {
add_menu_page(
'API Settings',
'API Settings',
'manage_options',
'my-plugin-settings',
'my_plugin_render_settings_page'
);
}
// Render the plugin settings page
function my_plugin_render_settings_page() {
?>
<div class="wrap">
<h1>Meta Generator Settings</h1>
<?php settings_errors();?>//added this line of code to render error of form
<form method="post" action="options.php">
<?php settings_fields('my-plugin-settings-group'); ?>
<?php do_settings_sections('my-plugin-settings'); ?>
<?php submit_button(); ?>
</form>
</div>
<?php
}
// Render the API key input field
function my_plugin_render_api_key_field() {
$api_key = get_option('my_plugin_api_key');
?>
<input type="text" name="my_plugin_api_key" id="my-plugin-api-key" value="<?php echo esc_attr($api_key); ?>" />
<?php
}
// Render the API link input field
function my_plugin_render_api_link_field() {
$api_link = get_option('my_plugin_api_link');
?>
<input type="text" name="my_plugin_api_link" id="my-plugin-api-link" value="<?php echo esc_attr($api_link); ?>" />
<?php
}
// Render the Full Description prompt input field
function my_plugin_render_full_description_prompt_field() {
$fprompt = get_option('my_plugin_full_description_prompt', 'you can write a custom prompt for full description of the product');
?>
<input type="text" name="my_plugin_full_description_prompt" id="my-plugin-full-description-prompt" value="<?php echo esc_attr($fprompt); ?>" />
<?php
echo '<br>';
echo '<b> Example: </b> "Can you write a description for the mentioned product which is SEO friendly:" <br>';
echo '<b>Note:</b> we have used the example prompt as default prompt for the full description<br>';
}
// Render the Short Description prompt input field
function my_plugin_render_short_description_prompt_field() {
$sprompt = get_option('my_plugin_short_description_prompt', 'you write a custom prompt for short description of the product');
?>
<input type="text" name="my_plugin_short_description_prompt" id="my-plugin-short-description-prompt" value="<?php echo esc_attr($sprompt); ?>" />
<?php
echo '<br>';
echo '<b> Example:</b> "Can you write a description for the mentioned product which is SEO friendly:" <br>';
echo '<b> Note: </b> we have used the example prompt as default prompt for the short description<br>';
}
// Render the model selection dropdown
function my_plugin_render_model_selection_field() {
echo 'Select your API Model below. To know more about the models click on : <a href="https://platform.openai.com/docs/models/gpt-3-5" target="_blank">Open AI Models</a>. <br>';
echo '<br>';
$selected_model = get_option('my_plugin_selected_model', 'text-davinci-002');
$models = array(
'text-davinci-002' => 'Text Davinci 002',
'text-davinci-003' => 'Text Davinci 003',
'gpt-3.5-turbo-16k-0613' => 'GPT-3.5 Turbo 16k 0613',
'gpt-3.5-turbo-0613' => 'GPT-3.5 Turbo 0613',
'gpt-3.5-turbo-16k' => 'GPT-3.5 Turbo 16k',
'gpt-3.5-turbo' => 'GPT-3.5 Turbo',
// Add more models as needed
);
?>
<select name="my_plugin_selected_model" id="my-plugin-selected-model">
<?php foreach ($models as $model => $label) : ?>
<option value="<?php echo esc_attr($model); ?>" <?php selected($selected_model, $model); ?>><?php echo esc_html($label); ?></option>
<?php endforeach; ?>
</select>
<?php
echo '<br>';
echo '<br>';
echo '<b> Note: </b> If you are not sure which model to use, then you can use the default model. <br>';
echo 'By default we are using ,<b>Text Davinci 002 </b> model. <br>';
}
// Render the temperature selection dropdown
function my_plugin_render_temperature_field() {
echo 'Select your API temepreture below. To know more click on : <a href="https://community.openai.com/t/cheat-sheet-mastering-temperature-and-top-p-in-chatgpt-api-a-few-tips-and-tricks-on-controlling-the-creativity-deterministic-output-of-prompt-responses/172683" target="_blank">Open AI Tempreture</a>. <br>';
echo '<br>';
$selected_temperature = get_option('my_plugin_selected_temperature', '0.7');
$temperatures = array(
'0' => '0',
'0.1' => '0.1',
'0.2' => '0.2',
'0.3' => '0.3',
'0.4' => '0.4',
'0.5' => '0.5',
'0.6' => '0.6',
'0.7' => '0.7',
'0.8' => '0.8',
'0.9' => '0.9',
'1' => '1',
);
?>
<select name="my_plugin_selected_temperature" id="my-plugin-selected-temperature">
<?php foreach ($temperatures as $temperature => $label) : ?>
<option value="<?php echo esc_attr($temperature); ?>" <?php selected($selected_temperature, $temperature); ?>><?php echo esc_html($label); ?></option>
<?php endforeach; ?>
</select>
<?php
echo '<br>';
echo '<br>';
echo '<b> Note: </b> If you are not sure which temperature to use, then you can use the default temperature. <br>';
echo 'By default we are using <b>0.7</b> temperature. <br>';
}
// Render the settings section
function my_plugin_render_settings_section() {
echo 'Enter your API key and link below. You can get your API key from: <a href="https://platform.openai.com/account/api-keys" target="_blank">OpenAI Key</a>, and the Open AI Link from: <a href="https://platform.openai.com/docs/api-reference/authentication" target="_blank">Open AI Link</a>. <br>';
}
// Register plugin settings
function my_plugin_register_settings() {
register_setting('my-plugin-settings-group', 'my_plugin_api_key', array(
'sanitize_callback' => 'my_plugin_sanitize_api_key',
'show_in_rest' => false, // Add this line to prevent issues with REST API
));
register_setting('my-plugin-settings-group', 'my_plugin_api_link');
register_setting('my-plugin-settings-group', 'my_plugin_api_link', array(
'sanitize_callback' => 'my_plugin_sanitize_api_link',
));
register_setting('my-plugin-settings-group', 'my_plugin_full_description_prompt', array(
'sanitize_callback' => 'my_plugin_sanitize_full_description_prompt',
));
register_setting('my-plugin-settings-group', 'my_plugin_short_description_prompt', array(
'sanitize_callback' => 'my_plugin_sanitize_short_description_prompt',
));
register_setting('my-plugin-settings-group', 'my_plugin_selected_model');
register_setting('my-plugin-settings-group', 'my_plugin_selected_temperature');
}
// Add settings fields to the plugin settings page
function my_plugin_add_settings_fields() {
add_settings_section('my-plugin-api-section', 'API Settings', 'my_plugin_render_settings_section', 'my-plugin-settings');
add_settings_field('my-plugin-api-key-field', 'API Key', 'my_plugin_render_api_key_field', 'my-plugin-settings', 'my-plugin-api-section');
add_settings_field('my-plugin-api-link-field', 'API Link', 'my_plugin_render_api_link_field', 'my-plugin-settings', 'my-plugin-api-section');
add_settings_field('my-plugin-full-description-prompt-field', 'Full Description Prompt', 'my_plugin_render_full_description_prompt_field', 'my-plugin-settings', 'my-plugin-api-section');
add_settings_field('my-plugin-short-description-prompt-field', 'Short Description Prompt', 'my_plugin_render_short_description_prompt_field', 'my-plugin-settings', 'my-plugin-api-section');
add_settings_field('my-plugin-selected-model-field', 'Selected Model', 'my_plugin_render_model_selection_field', 'my-plugin-settings', 'my-plugin-api-section');
add_settings_field('my-plugin-selected-temperature-field', 'Selected Temperature', 'my_plugin_render_temperature_field', 'my-plugin-settings', 'my-plugin-api-section');
}
// Hook into WordPress initialization
function my_plugin_init() {
add_action('admin_menu', 'my_plugin_settings_page');
add_action('admin_init', 'my_plugin_register_settings');
add_action('admin_init', 'my_plugin_add_settings_fields');
// Add a custom button to the plugin row actions
add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'my_plugin_add_custom_button');
}
add_action('init', 'my_plugin_init');
function my_plugin_add_custom_button($actions) {
// Add your custom button to the plugin row actions
$custom_button = '<a href="#" class="button-secondary">Custom Button</a>';
array_push($actions, $custom_button);
return $actions;
}
// Hook into WordPress admin_enqueue_scripts action to enqueue your script file and localize it with the API key and link
function my_plugin_enqueue_scripts() {
wp_enqueue_script('product-description-script', plugins_url('/product-description-script.js', __FILE__), array('jquery'), '1.0', true);
$api_key = get_option('my_plugin_api_key');
$api_link = get_option('my_plugin_api_link');
$full_description_prompt = get_option('my_plugin_full_description_prompt');
$short_description_prompt = get_option('my_plugin_short_description_prompt');
$selected_model = get_option('my_plugin_selected_model');
$selected_temperature = get_option('my_plugin_selected_temperature');
if ($api_key && $api_link) {
// Return the API key and link as an inline script
wp_add_inline_script('product-description-script', 'var my_plugin_api_key = ' . json_encode($api_key) . ';', 'before');
wp_add_inline_script('product-description-script', 'var my_plugin_api_link = ' . json_encode($api_link) . ';', 'before');
wp_add_inline_script('product-description-script', 'var my_plugin_full_description_prompt = ' . json_encode($full_description_prompt) . ';', 'before');
wp_add_inline_script('product-description-script', 'var my_plugin_short_description_prompt = ' . json_encode($short_description_prompt) . ';', 'before');
wp_add_inline_script('product-description-script', 'var my_plugin_selected_model = ' . json_encode($selected_model) . ';', 'before');
wp_add_inline_script('product-description-script', 'var my_plugin_selected_temperature = ' . json_encode($selected_temperature) . ';', 'before');
}
}
add_action('admin_enqueue_scripts', 'my_plugin_enqueue_scripts');
// Hook into plugin activation and deactivation
register_activation_hook(__FILE__, 'my_plugin_activate');
register_deactivation_hook(__FILE__, 'my_plugin_deactivate');
function my_plugin_activate() {
// Perform activation actions, such as showing the settings page
my_plugin_settings_page();
}
function my_plugin_deactivate() {
// Perform deactivation actions, if needed
}
//Functions to sanitize and validate form fields starts
function my_plugin_sanitize_api_key($input) {
// Validate the API Key (e.g., check for length, format, etc.)
if (!preg_match('/^[A-Za-z0-9\-_]+$/', $input)) {
add_settings_error('my_plugin_api_key', 'invalid_api_key', 'Invalid API Key.');
return get_option('my_plugin_api_key'); // Reset to previous value
}
// Sanitize the API Key
$sanitized_input = sanitize_text_field($input);
return $sanitized_input;
}
function my_plugin_sanitize_api_link($input) {
// Validate the API Link (e.g., check for a valid URL format)
if (!filter_var($input, FILTER_VALIDATE_URL)) {
add_settings_error('my_plugin_api_link', 'invalid_api_link', 'Invalid API Link.');
return get_option('my_plugin_api_link'); // Reset to previous value
}
// Sanitize the API Link
$sanitized_input = esc_url_raw($input);
return $sanitized_input;
}
function my_plugin_sanitize_full_description_prompt($input) {
// Validate the Full Description Prompt (e.g., check for length, format, etc.)
if (strlen($input) < 160) { // Adjust the minimum length as needed
add_settings_error('my_plugin_full_description_prompt', 'invalid_full_description_prompt', 'Full Description Prompt is too short.');
return get_option('my_plugin_full_description_prompt'); // Reset to previous value
}
// Sanitize the Full Description Prompt
$sanitized_input = sanitize_text_field($input);
return $sanitized_input;
}
function my_plugin_sanitize_short_description_prompt($input) {
// Validate the Short Description Prompt (e.g., check for length, format, etc.)
if (strlen($input) < 150) { // Adjust the minimum length as needed
add_settings_error('my_plugin_short_description_prompt', 'invalid_short_description_prompt', 'Short Description Prompt is too short.');
return get_option('my_plugin_short_description_prompt'); // Reset to previous value
}
// Sanitize the Short Description Prompt
$sanitized_input = sanitize_text_field($input);
return $sanitized_input;
}