-1, 'orderby' => 'modified', 'order' => 'ASC', 'post_status' => 'publish', ) ); // Loop through each campaign. foreach ( $campaigns as $campaign ) { // Get the content. $campaign_id = $campaign->ID; // Get the content. $keywords = $campaign->post_content; // Check if the campaign needs generating titles. $needs_update = aicw_campaign_needs_update( $campaign_id ); if ( array_key_exists( 'needs_update', $needs_update ) && ! $needs_update['needs_update'] ) { aicw_update_last_run_time( $campaign_id ); continue; } $type = get_post_meta( $campaign_id, '_aicw_campaign_type', true ); $posts_needed = isset( $needs_update['posts_needed'] ) ? absint( $needs_update['posts_needed'] ) : 0; if ( 'articles' === $type ) { Articles::generate_titles( $campaign_id, $keywords, $posts_needed ); // Update the last run time. aicw_update_last_run_time( $campaign_id ); break; } elseif ( 'rss-feed' === $type ) { RSSFeed::generate_titles( $campaign_id, $posts_needed ); // Update the last run time. aicw_update_last_run_time( $campaign_id ); break; } else { // Now request the OpenAI to generate the titles depending on the keywords. $type = empty( $type ) ? get_option( 'aicw_api_model' ) : $type; // TODO: We will remove this option in the future. It's already remove from the settings page. $titles = aicw_generate_titles( $type, $keywords ); } $counter = 0; // Create a new post for each title. foreach ( $titles as $title ) { if ( empty( $title ) ) { continue; } // Check if the line starts with a number followed by a dot and space (e.g., "10. "). If not then skip the line. if ( ! preg_match( '/^\d+\.\s/', $title ) ) { continue; } // Remove leading number, dot, and space (e.g., "10. "). $title = preg_replace( '/^\d+\.\s*/', '', $title ); // Remove surrounding quotes if present. $title = trim( $title, '"' ); // Check if the title already exists. $post_exists = aicw_get_post_by_title( $title ); if ( $post_exists ) { continue; } // Create a new post. $post_id = wp_insert_post( array( 'post_type' => 'aicw_post', 'post_title' => $title, 'post_content' => '', 'post_status' => 'pending', ) ); if ( is_wp_error( $post_id ) ) { continue; } // Add the post meta. update_post_meta( $post_id, '_aicw_campaign_id', $campaign_id ); // Update the counter. ++$counter; // If the counter is greater than or equal to the target then break the loop. if ( array_key_exists( 'posts_needed', $needs_update ) && $counter >= $needs_update['posts_needed'] ) { break; } } // Update the last run time. aicw_update_last_run_time( $campaign_id ); // If this line executed then break the foreach loop. This will ensure that only one campaign is processed at a time. break; } } /** * Generate content. * * @since 1.4.0 * @return void */ public function generate_content() { // Get all posts. $posts = get_posts( array( 'post_type' => 'aicw_post', 'posts_per_page' => -1, 'orderby' => 'modified', 'order' => 'ASC', 'post_status' => 'pending', ) ); // Loop through each post. foreach ( $posts as $post ) { // Get the content. $post_id = $post->ID; // Get the associated campaign ID. $campaign_id = get_post_meta( $post_id, '_aicw_campaign_id', true ); // Check if the post needs generating content. $needs_update = aicw_temp_post_needs_update( $post, $campaign_id ); if ( empty( $needs_update ) || ( array_key_exists( 'content', $needs_update ) && ! $needs_update['content'] ) ) { aicw_update_last_run_time( $post_id ); continue; } // Get the keywords. $keywords = get_post_field( 'post_content', $campaign_id ); // Get the title. $title = get_the_title( $post_id ); if ( empty( $title ) ) { continue; } $campaign_type = get_post_meta( $campaign_id, '_aicw_campaign_type', true ); if ( empty( $campaign_type ) ) { continue; } $is_updated = false; // Check if the campaign type is articles or rss-feed. if ( 'articles' === $campaign_type ) { $is_updated = Articles::generate_content( $post_id, $title, $keywords ); } elseif ( 'rss-feed' === $campaign_type ) { $is_updated = RSSFeed::generate_content( $post_id, $title, $keywords ); } else { $content = aicw_generate_content( $post_id, $title, $keywords ); $updated = wp_update_post( array( 'ID' => $post_id, 'post_content' => wp_kses_post( $content ), ) ); $is_updated = is_wp_error( $updated ) ? false : true; } // Check if the content is updated successfully or not. if ( ! $is_updated ) { // If the content is not updated then handle the itteration occurring. and delete it if the post is not updated with 2 attempts. $attempts = get_post_meta( $post_id, '_aicw_generate_content_attempts', true ); if ( empty( $attempts ) ) { $attempts = 0; } ++$attempts; // Check if the attempts are greater than or equal to 2 then delete the post. if ( $attempts >= 2 ) { wp_delete_post( $post_id, true ); continue; } else { update_post_meta( $post_id, '_aicw_generate_content_attempts', $attempts ); } } // Update the last run time. aicw_update_last_run_time( $post_id ); // If this line executed then break the foreach loop. This will ensure that only one post is processed at a time. break; } } /** * Generate thumbnails. * * @since 1.4.0 * @return void */ public function generate_thumbnails() { // Get all posts. $posts = get_posts( array( 'post_type' => 'aicw_post', 'posts_per_page' => -1, 'orderby' => 'modified', 'order' => 'ASC', 'post_status' => 'pending', ) ); // Loop through each post. foreach ( $posts as $post ) { // Get the content. $post_id = $post->ID; // Get the associated campaign ID. $campaign_id = get_post_meta( $post_id, '_aicw_campaign_id', true ); // Check if the post needs generating thumbnail. $needs_update = aicw_temp_post_needs_update( $post, $campaign_id ); if ( empty( $needs_update ) || ( array_key_exists( 'thumbnail', $needs_update ) && ! $needs_update['thumbnail'] ) ) { aicw_update_last_run_time( $post_id ); continue; } // Get the title. $title = get_the_title( $post_id ); if ( empty( $title ) ) { continue; } // Now request the OpenAI to generate the thumbnail depending on the title and content. $images = ai_content_writer()->generate_images( $title ); if ( is_wp_error( $images ) ) { continue; } if ( empty( $images ) ) { continue; } // Get a random image. $thumbnail = $images[ array_rand( $images ) ]; if ( ! isset( $thumbnail['src']['original'] ) ) { continue; } // Get the media URL. $media_url = $thumbnail['src']['original']; // Check if the media side load function exists. If not then include the required files. if ( ! function_exists( 'media_sideload_image' ) ) { require_once ABSPATH . 'wp-admin/includes/media.php'; require_once ABSPATH . 'wp-admin/includes/file.php'; require_once ABSPATH . 'wp-admin/includes/image.php'; } // Download the image. $media_id = media_sideload_image( $media_url, $post_id, $title, 'id' ); // Set the post thumbnail. set_post_thumbnail( $post_id, $media_id ); // Update the last run time. aicw_update_last_run_time( $post_id ); // If this line executed then break the foreach loop. This will ensure that only one post is processed at a time. break; } } /** * Publish posts. * This will publish the generated posts that are in pending status and completed all the steps. * * @since 1.4.0 * @return void */ public function publish_posts() { // Get all posts. $posts = get_posts( array( 'post_type' => 'aicw_post', 'posts_per_page' => -1, 'orderby' => 'modified', 'order' => 'ASC', 'post_status' => 'pending', ) ); // Loop through each post. foreach ( $posts as $post ) { if ( ! $post && ! $post instanceof \WP_Post ) { continue; } // Get the content. $post_id = $post->ID; if ( empty( $post_id ) ) { continue; } // Get the associated campaign ID. $campaign_id = get_post_meta( $post_id, '_aicw_campaign_id', true ); if ( empty( $campaign_id ) ) { continue; } // Check if the post needs generating thumbnail. $needs_update = aicw_temp_post_needs_update( $post, $campaign_id ); if ( ! empty( $needs_update ) ) { continue; } // Get the post type and status user selected in the campaign. $post_type = get_post_meta( $campaign_id, '_aicw_post_type', true ) ?? 'post'; $post_status = get_post_meta( $campaign_id, '_aicw_completed_post_status', true ) ?? 'publish'; // Update the post type and status. wp_update_post( array( 'ID' => $post_id, 'post_type' => $post_type, 'post_status' => $post_status, ) ); // If this line executed then break the foreach loop. This will ensure that only one post is processed at a time. break; } } }