File manager - Edit - /home/colomboelectrici/public_html/wp-content/plugins/page-generator-pro/includes/admin/generate.php
Back
<?php /** * Generate class * * @package Page_Generator_Pro * @author Tim Carr * @version 1.0 */ class Page_Generator_Pro_Generate { /** * Holds the class object. * * @since 1.1.3 * * @var object */ public static $instance; /** * Holds the array of found keywords across all settings. * * @since 1.2.0 * * @var array */ public $required_keywords = array(); /** * Holds the array of keywords to replace e.g. {city} * * @since 1.3.1 * * @var array */ public $searches = array(); /** * Holds the array of keyword values to replace e.g. Birmingham * * @since 1.3.1 * * @var array */ public $replacements = array(); /** * Calculates the maximum number of pages that will be generated based * on the settings and keywords * * @since 1.1.5 * * @param int $group_id Group ID * @return mixed WP_Error | integer */ public function get_max_number_of_pages( $group_id ) { // Get instances $common_instance = Page_Generator_Pro_Common::get_instance(); $keywords_instance = Page_Generator_Pro_Keywords::get_instance(); $groups_instance = Page_Generator_Pro_Groups::get_instance(); // Get group $settings = $groups_instance->get_settings( $group_id ); if ( ! $settings ) { return new WP_Error( 'group_error', sprintf( __( 'Group ID %s could not be found.', 'page-generator-pro' ), $group_id ) ); } // Get an array of required keywords that need replacing with data $required_keywords = $this->find_keywords_in_settings( $settings ); if ( count( $required_keywords ) == 0 ) { return 0; } // Get the terms for each required keyword $keywords = array(); foreach ( $required_keywords as $key => $keyword ) { // Get terms for this keyword $terms = $keywords_instance->get_by( 'keyword', $keyword ); if ( ! is_array( $terms ) ) { // Remove this keyword unset( $required_keywords[ $key ] ); continue; } $keywords[ $keyword ] = $terms['dataArr']; } // Depending on the generation method chosen, for each keyword, define the term // that will replace it. switch ( $settings['method'] ) { /** * All * - Generates all possible term combinations across keywords */ case 'all': // Generate all possible term combinations, and return the count $combinations = $this->generate_all_array_combinations( $keywords ); return count( $combinations ); break; /** * Sequential * - Generates term combinations across keywords matched by index */ case 'sequential': $total = 0; foreach ( $keywords as $keyword => $terms ) { if ( count( $terms ) > 0 && ( count( $terms ) < $total || $total == 0 ) ) { $total = count( $terms ); } } return $total; break; /** * Random * - Gets a random term for each keyword */ case 'random': return 0; break; } } /** * Main function to generate a Page, Post or Custom Post Type * * @since 1.0 * * @param int $group_id Group ID * @param int $index Keyword Index * @param bool $test_mode Test Mode * @return mixed WP_Error | URL */ public function generate( $group_id, $index = 0, $test_mode = false ) { // Get instances $common_instance = Page_Generator_Pro_Common::get_instance(); $keywords_instance = Page_Generator_Pro_Keywords::get_instance(); $groups_instance = Page_Generator_Pro_Groups::get_instance(); $spintax = Page_Generator_Pro_Spintax::get_instance(); // Get group settings $settings = $groups_instance->get_settings( $group_id ); if ( ! $settings ) { return new WP_Error( 'group_error', sprintf( __( 'Group ID %s could not be found.', 'page-generator-pro' ), $group_id ) ); } // Get an array of required keywords that need replacing with data $required_keywords = $this->find_keywords_in_settings( $settings ); if ( count( $required_keywords ) == 0 ) { return new WP_Error( 'keyword_error', __( 'No keywords were specified in the title, content or excerpt.', 'page-generator-pro' ) ); die(); } // Get the terms for each required keyword $keywords = array(); foreach ( $required_keywords as $keyword ) { // Get terms for this keyword $terms = $keywords_instance->get_by( 'keyword', $keyword ); if ( ! is_array( $terms ) || empty( $terms ) ) { $terms = array(); } if ( isset( $terms['dataArr'] ) ) { $keywords[ $keyword ] = $terms['dataArr']; } } // Depending on the generation method chosen, for each keyword, define the term // that will replace it. switch ( $settings['method'] ) { /** * All * - Generates all possible term combinations across keywords */ case 'all': // Generate all possible term combinations $combinations = $this->generate_all_array_combinations( $keywords ); // If the current index exceeds the total number of combinations, we've exhausted all // options and don't want to generate any more Pages (otherwise we end up with duplicates) if ( $index > ( count( $combinations ) - 1 ) ) { return new WP_Error( 'keywords_exhausted', __( 'All possible keyword term combinations have been generated. Generating more Pages/Posts would result in duplicate content.', 'page-generator-pro' ) ); die(); } // Define the keyword => term key/value pairs to use based on the current index $keywords_terms = $combinations[ $index ]; break; /** * Sequential * - Generates term combinations across keywords matched by index */ case 'sequential': $keywords_terms = array(); foreach ( $keywords as $keyword => $terms ) { // Use modulo to get the term index for this keyword $term_index = ( $index % count( $terms ) ); // Build the keyword => term key/value pairs $keywords_terms[ $keyword ] = $terms[ $term_index ]; } break; /** * Random * - Gets a random term for each keyword */ case 'random': $keywords_terms = array(); foreach ( $keywords as $keyword => $terms ) { $term_index = rand( 0, ( count( $terms ) - 1 ) ); // Build the keyword => term key/value pairs $keywords_terms[ $keyword ] = $terms[ $term_index ]; } break; } // Rotate Author if ( isset( $settings['rotateAuthors'] ) ) { $authors = $common_instance->get_authors(); $userIndex = ( $index % count( $authors ) ); } // Iterate through each keyword and term key/value pair foreach ( $keywords_terms as $keyword => $term ) { // Define the search and replace queries // We have multiple queries as we're looking for: // - keyword: {keyword} // - keyword with transformation {keyword:uppercase_all} $term = trim( html_entity_decode( $term ) ); $this->searches = array( '{' . $keyword . '}', // Keyword Term '{' . $keyword . ':uppercase_all}', // Keyword Term, uppercase '{' . $keyword . ':lowercase_all}', // Keyword Term, lowercase '{' . $keyword . ':uppercase_first_character}', // Keyword Term, first char uppercase '{' . $keyword . ':uppercase_first_character_words}', // Keyword Term, first char of each word uppercase '{' . $keyword . ':url}', // Keyword Term, as a URL / permalink friendly string ); $this->replacements = array( $term, strtoupper( $term ), strtolower( $term ), ucfirst( $term ), ucwords( $term ), sanitize_title( $term ), ); // Go through each of the group's settings, replacing $search with $replacement foreach ( $settings as $key => $value ) { // Depending on the setting key, process the search and replace switch ( $key ) { /** * Taxonomies */ case 'tax': // If the submitted taxonomies are an array, iterate through each one // This allows hierarchical taxonomies to have keyword replacements carried out on nested arrays e.g. // $settings[tax][category][0] if ( is_array( $settings[ $key ] ) ) { foreach ( $settings[ $key ] as $taxonomy => $terms ) { // Hierarchical based taxonomy - first key may contain new tax terms w/ keywords that need replacing now if ( is_array( $terms ) && isset( $terms[0] ) ) { $settings[ $key ][ $taxonomy ][0] = str_ireplace( $this->searches, $this->replacements, $settings[ $key ][ $taxonomy ][0] ); } // Tag based taxonomy if ( ! is_array( $terms ) ) { $settings[ $key ][ $taxonomy ] = str_ireplace( $this->searches, $this->replacements, $settings[ $key ][ $taxonomy ] ); } } } break; /** * Default * - Will also cover keyword search / replace for Page Builders data */ default: // Don't do anything if there's no data if ( empty( $settings[ $key ] ) ) { break; } // If the settings key's value is an array, walk through it recursively to search/replace // Otherwise do a standard search/replace on the string if ( is_array( $settings[ $key ] ) ) { // Array array_walk_recursive( $settings[ $key ], array( $this, 'replace_keywords_in_array' ) ); } elseif( is_object( $settings[ $key ] ) ) { // Object array_walk_recursive( $settings[ $key ], array( $this, 'replace_keywords_in_array' ) ); } else { // Keyword search/replace $settings[ $key ] = str_ireplace( $this->searches, $this->replacements, $settings[ $key ] ); } break; } } } // Spin all settings foreach ( $settings as $key => $value ) { // Skip if value is not a string if ( ! is_string( $value ) ) { continue; } // Spin content $settings[ $key ] = $spintax->process( $settings[ $key ] ); } // Remove all shortcode processors, so we don't process any shortcodes. This ensures page builders, galleries etc // will work as their shortcodes will be processed when the generated page is viewed. remove_all_shortcodes(); // Add Page Generator Pro's shortcodes, so they're processed now. Page_Generator_Pro_Shortcode::get_instance()->add_shortcodes(); // Execute shortcodes in content, so actual HTML is output instead of shortcodes for this plugin's shortcodes $content = do_shortcode( $settings['content'] ); // Build Post args $post_args = array( 'post_type' => $settings['type'], 'post_title' => $spintax->process( $settings['title'] ), 'post_content' => $content, 'post_excerpt' => $spintax->process( $settings['excerpt'] ), 'post_status' => ( $test_mode ? 'draft' : $settings['status'] ), 'post_author' => ( ( isset( $settings['rotateAuthors'] ) && $settings['rotateAuthors'] == 1 ) ? $authors[ $userIndex ]->ID : $settings['author'] ), // ID 'comment_status'=> ( ( isset( $settings['comments'] ) && $settings['comments'] == 1 ) ? 'open' : 'closed' ), 'ping_status' => ( ( isset( $settings['trackbacks'] ) && $settings['trackbacks'] == 1 ) ? 'open' : 'closed' ), 'post_parent' => ( ( isset( $settings['pageParent'] ) && isset( $settings['pageParent'][ $settings['type'] ] ) ) ? $settings['pageParent'][ $settings['type'] ] : 0 ), ); // Define Post Name // If no Permalink exists, use the Post Title if ( ! empty( $settings['permalink'] ) ) { $post_args['post_name'] = sanitize_title( $settings['permalink'] ); } else { $post_args['post_name'] = sanitize_title( $post_args['post_title'] ); } // Define the Post Date switch ( $settings['date_option'] ) { /** * Now */ case 'now': if ( $settings['status'] == 'future' ) { // Increment the current date by the schedule hours and unit $post_args['post_date'] = date( 'Y-m-d H:i:s', strtotime( '+' . ( $settings['schedule'] * ( $index + 1 ) ) . ' ' . $settings['scheduleUnit'] ) ); } else { $post_args['post_date'] = date( 'Y-m-d H:i:s' ); } break; /** * Specific Date */ case 'specific': if ( $settings['status'] == 'future' ) { // Increment the specific date by the schedule hours and unit $post_args['post_date'] = date( 'Y-m-d H:i:s', strtotime( $settings['date_specific'] ) . ' +' . ( $settings['schedule'] * ( $index + 1 ) ) . ' ' . $settings['scheduleUnit'] ); } else { $post_args['post_date'] = $settings['date_specific']; } break; /** * Random */ case 'random': $min = strtotime( $settings['date_min'] ); $max = strtotime( $settings['date_max'] ); $post_args['post_date'] = date( 'Y-m-d H:i:s', rand( $min, $max ) ); break; } // Allow filtering $post_args = apply_filters( 'page_generator_pro_generate_post_args', $post_args, $settings ); // If overwrite is enabled, attempt to find an existing Post generated by this Group // with the same Permalink if ( $settings['overwrite'] ) { $existing_post = new WP_Query( array( 'post_type' => $post_args['post_type'], 'post_status' => array( 'publish', 'pending', 'draft', 'future', 'private' ), 'post_name__in' => array( $post_args['post_name'] ), 'meta_query' => array( array( 'key' => '_page_generator_pro_group', 'value' => $group_id, ), ), // For performance, just return the Post ID and don't update meta or term caches 'fields' => 'ids', 'cache_results' => false, 'update_post_meta_cache'=> false, 'update_post_term_cache'=> false, ) ); // If a Post was found, update it if ( count( $existing_post->posts ) > 0 ) { // Update Page, Post or CPT $post_args['ID'] = $existing_post->posts[0]; $post_id = wp_update_post( $post_args, true ); } else { // Create Page, Post or CPT $post_id = wp_insert_post( $post_args, true ); } } else { // Create Page, Post or CPT $post_id = wp_insert_post( $post_args, true ); } // Check Post creation / update worked if ( is_wp_error( $post_id ) ) { // UTF-8 encode the Title, Excerpt and Content $post_args['post_title'] = utf8_encode( $post_args['post_title'] ); $post_args['post_excerpt'] = utf8_encode( $post_args['post_excerpt'] ); $post_args['post_content'] = utf8_encode( $post_args['post_content'] ); // Try again if ( count( $existing_post->posts ) > 0 ) { // Update Page, Post or CPT $post_id = wp_update_post( $post_args, true ); } else { // Create Page, Post or CPT $post_id = wp_insert_post( $post_args, true ); } } // If Post creation / update still didn't work, bail if ( is_wp_error( $post_id ) ) { $post_id->add_data( $post_args, $post_id->get_error_code() ); return $post_id; } // Store this Generation ID in the Post's meta, so we can edit/delete the generated Post(s) in the future update_post_meta( $post_id, '_page_generator_pro_group', $group_id ); // Page Template if ( $settings['type'] == 'page' ) { update_post_meta( $post_id, '_wp_page_template', $settings['pageTemplate'] ); } // Featured Image if ( ! empty( $settings['featured_image_source'] ) ) { switch ( $settings['featured_image_source'] ) { /** * Media Library ID */ case 'id': $image_id = $settings['featured_image']; break; /** * Image URL */ case 'url': $image_id = Page_Generator_Pro_Import::get_instance()->import_remote_image( $settings['featured_image'], $post_id ); break; /** * 500px Image by Tag */ case '500px': // Setup 500px API instance $instance_500px = Page_Generator_Pro_500px::get_instance(); // If a featured image location has been specified, get its latitude and longitude now if ( ! empty( $settings['featured_image_location'] ) ) { // Get geo instance $geo_instance = Page_Generator_Pro_Geo::get_instance(); // If a Google Geocoding API key has been specified, use it instead of the class default. $google_geocoding_api_key = Page_Generator_Pro_Settings::get_instance()->get_setting( 'page-generator-pro-google', 'google_geocoding_api_key' ); if ( ! empty( $google_geocoding_api_key ) ) { $geo_instance->api_key = $google_geocoding_api_key; } $lat_lng = $geo_instance->google_get_lat_lng( $settings['featured_image_location'] ); } else { $lat_lng = false; } // If latitude and longitude returned an error, bail if ( is_wp_error( $lat_lng ) ) { return $lat_lng; } // Run images query, and skip if no images were found or an error occured $images = $instance_500px->photos_search( 2048, 100, $settings['featured_image'], $lat_lng ); if ( is_wp_error( $images ) || ! is_array( $images ) || count( $images ) == 0 ) { break; } // Pick an image at random from the resultset $image_index = rand( 0, ( count( $images ) - 1 ) ); // Import the first image $image_id = Page_Generator_Pro_Import::get_instance()->import_remote_image( $images[ $image_index ]['url'], $post_id, $images[ $image_index ]['title'], $images[ $image_index ]['caption'] ); break; } // If an image ID is specified, and it's not an error, set it now if ( isset( $image_id ) && ! is_wp_error( $image_id ) ) { update_post_meta( $post_id, '_thumbnail_id', $image_id ); // If an ALT tag was specified, set that against the Media Library image ID now if ( ! empty( $settings['featured_image_alt'] ) ) { update_post_meta( $image_id, '_wp_attachment_image_alt', $spintax->process( $settings['featured_image_alt'] ) ); } } } // Custom Fields if ( isset( $settings['meta'] ) ) { foreach ( $settings['meta']['key'] as $meta_index => $meta_key ) { $meta_value = $spintax->process( $settings['meta']['value'][ $meta_index ] ); update_post_meta( $post_id, $meta_key, $meta_value ); } } // Post Meta // This will copy e.g. ACF, Page Builder data etc. if ( isset( $settings['post_meta'] ) ) { foreach ( $settings['post_meta'] as $meta_key => $meta_value ) { update_post_meta( $post_id, $meta_key, $meta_value ); } } // Taxonomies // Get taxonomies for this Post Type // @TODO Move spintax to keyword search/replace routine above if ( isset( $settings['tax'] ) ) { $taxonomies = $common_instance->get_post_type_taxonomies( $settings['type'] ); $ignored_taxonomies = $common_instance->get_excluded_taxonomies(); if ( is_array( $taxonomies ) && count( $taxonomies ) > 0 ) { // Iterate through taxonomies foreach ( $taxonomies as $taxonomy ) { // Skip ignored taxonomies if ( in_array( $taxonomy->name, $ignored_taxonomies ) ) { continue; } // Clear vars from the last iteration unset( $terms ); // Check if hierarchal or tag based switch ( $taxonomy->hierarchical ) { case true: // Category based taxonomy if ( isset( $settings['tax'][ $taxonomy->name ] ) ) { $terms = array(); foreach ( $settings['tax'][ $taxonomy->name ] as $taxID => $enabled ) { // If tax ID is zero, the value will be a string of new taxonomy terms we need to create if ( $taxID == 0 ) { // String $terms_string = $spintax->process( $enabled ); // Convert to array $terms_arr = explode( ',', $terms_string ); // Add each term to the taxonomy foreach ( $terms_arr as $new_term ) { // Check if this named term already exists in the taxonomy $result = term_exists( $new_term, $taxonomy->name ); if ( $result !== 0 && $result !== null ) { $terms[] = (int) $result['term_id']; continue; } // Term does not exist in the taxonomy - create it $result = wp_insert_term( $new_term, $taxonomy->name ); // Skip if something went wrong if ( is_wp_error( $result ) ) { continue; } // Add to term IDs $terms[] = (int) $result['term_id']; } continue; } $terms[] = (int) $taxID; } } break; case false: // Tag based taxonomy $terms = $spintax->process( $settings['tax'][ $taxonomy->name ] ); break; } // Set terms if they exist if ( isset( $terms ) ) { $result = wp_set_post_terms( $post_id, $terms, $taxonomy->name, false ); } } } } // Get URL of Page/Post/CPT just generated $url = get_bloginfo( 'url' ) . '?page_id=' . $post_id . '&preview=true'; // Request that the user review the plugin. Notification displayed later, // can be called multiple times and won't re-display the notification if dismissed. if ( ! $test_mode ) { Page_Generator_Pro::get_instance()->dashboard->request_review(); } return $url; } /** * Generate all the possible combinations among a set of nested arrays. * * @since 1.1.5 * * @param array $data The entrypoint array container. * @param array $all The final container (used internally). * @param array $group The sub container (used internally). * @param mixed $val The value to append (used internally). * @param int $i The key index (used internally). */ private function generate_all_array_combinations( array $data, array &$all = array(), array $group = array(), $value = null, $i = 0, $key = null ) { $keys = array_keys( $data ); if ( isset( $value ) === true ) { $group[ $key ] = $value; } if ( $i >= count( $data ) ) { array_push( $all, $group ); } else { $current_key = $keys[ $i ]; $current_element = $data[ $current_key ]; if ( count( $data[ $current_key ] ) <= 0 ) { $this->generate_all_array_combinations( $data, $all, $group, null, $i + 1, $current_key ); } else { foreach ( $current_element as $val ) { $this->generate_all_array_combinations( $data, $all, $group, $val, $i + 1, $current_key ); } } } return $all; } /** * Recursively goes through the settings array, finding any {keywords} * specified, to build up an array of keywords we need to fetch. * * @since 1.0.0 * * @param array $settings Settings * @return array Found Keywords */ public function find_keywords_in_settings( $settings ) { // Get all keywords $keywords = Page_Generator_Pro_Keywords::get_instance()->get_all( 'keyword', 'ASC', -1 ); // Recursively walk through all settings to find all keywords array_walk_recursive( $settings, array( $this, 'find_keywords_in_string' ) ); // Return the required keywords object return $this->required_keywords; } /** * Performs a search on the given string to find any {keywords} * * @since 1.2.0 * * @param string $content Array Value (string to search) * @param string $key Array Key */ private function find_keywords_in_string( $content, $key ) { // Define array to store found keywords in $required_keywords = array(); // If $content is an object, iterate this call if ( is_object( $content ) ) { return array_walk_recursive( $content, array( $this, 'find_keywords_in_string' ) ); } // Get keywords and spins preg_match_all( "|{(.+?)}|", $content, $matches ); // Continue if no matches found if ( ! is_array( $matches ) ) { return; } if ( count( $matches[1] ) == 0 ) { return; } // Iterate through matches foreach ( $matches[1] as $m_key => $keyword ) { // Ignore spins if ( strpos( $keyword, "|" ) !== false ) { continue; } // If a keyword is within spintax at the start of the string (e.g. {{service}|{service2}} ), // we get an additional leading curly brace for some reason. Remove it $keyword = str_replace( '{', '', $keyword ); $keyword = str_replace( '}', '', $keyword ); // If there's a transformation flag applied to the keyword, remove it if ( strpos( $keyword, ':' ) !== false ) { list( $keyword, $transformation ) = explode( ':', $keyword ); } // Lowercase keyword, to avoid duplicates e.g. {City} and {city} $keyword = strtolower( $keyword ); // If this keyword is not in our required_keywords array, add it if ( ! in_array( $keyword, $required_keywords ) ) { $required_keywords[ $keyword ] = $keyword; } } // Add the found keywords to the class array $this->required_keywords = array_merge( $this->required_keywords, $required_keywords ); } /** * array_walk_recursive callback, which finds $this->searches, replacing with * $this->replacements in $item * * @since 1.3.1 * * @param mixed $item Item (array, object, string) * @param string $key Key */ private function replace_keywords_in_array( &$item, $key ) { // If $item is an object, iterate this call if ( is_object( $item ) ) { array_walk_recursive( $item, array( $this, 'replace_keywords_in_array' ) ); } else { $item = str_ireplace( $this->searches, $this->replacements, $item ); } // If $item is a string, spintax it if ( is_string( $item ) ) { $item = Page_Generator_Pro_Spintax::get_instance()->process( $item ); } } /** * Main function to delete previously generated Pages, Posts or Custom Post Types * for the given Group ID * * @since 1.2.3 * * @param int $group_id Group ID * @return mixed WP_Error | Success */ public function delete( $group_id ) { // Get all Posts $posts = new WP_Query( array ( 'post_type' => 'any', 'post_status' => 'publish', 'posts_per_page'=> -1, 'meta_query' => array( array( 'key' => '_page_generator_pro_group', 'value' => absint( $group_id ), ), ), 'fields' => 'ids', ) ); // If no Posts found, return false, as there's nothing to delete if ( count( $posts->posts ) == 0 ) { return new WP_Error( __( 'No content has been generated by this group, so there is no content to delete.', 'page-generator-pro' ) ); } // Delete Posts by their IDs foreach ( $posts->posts as $post_id ) { $result = wp_trash_post( $post_id ); if ( ! $result ) { return new WP_Error( __( 'Unable to delete generated content with ID = ' . $post_id, 'page-generator-pro' ) ); } } // Done return true; } /** * Returns the singleton instance of the class. * * @since 1.1.3 * * @return object Class. */ public static function get_instance() { if ( ! isset( self::$instance ) && ! ( self::$instance instanceof self ) ) { self::$instance = new self; } return self::$instance; } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.06 |
proxy
|
phpinfo
|
Settings