public function run($new_status, $old_status, $post)
 {
     // verify this is not an auto save routine.
     if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
         return;
     }
     // Only count on post type 'post'
     if ('post' != $post->post_type) {
         return;
     }
     // Post status must be publish
     if ('publish' != $new_status) {
         return;
     }
     // Is automatic linking enabled?
     if (1 != RP4WP::get()->settings->get_option('automatic_linking')) {
         return;
     }
     // Check if the current post is already auto linked
     if (1 != get_post_meta($post->ID, RP4WP_Constants::PM_POST_AUTO_LINKED, true)) {
         // Get automatic linking post amount
         $automatic_linking_post_amount = RP4WP::get()->settings->get_option('automatic_linking_post_amount');
         // Related Posts Manager
         $related_post_manager = new RP4WP_Related_Post_Manager();
         // Link related posts
         $related_post_manager->link_related_post($post->ID, $automatic_linking_post_amount);
         // Set the auto linked meta
         update_post_meta($post->ID, RP4WP_Constants::PM_POST_AUTO_LINKED, 1);
     }
 }
 public function run()
 {
     // Check nonce
     check_ajax_referer(RP4WP_Constants::NONCE_AJAX, 'nonce');
     // Get the PPR
     $ppr = isset($_POST['ppr']) ? $_POST['ppr'] : 5;
     // Get the Post Type
     $post_type = isset($_POST['pt']) ? $_POST['pt'] : null;
     // Check if Post Type is set
     if (null == $post_type) {
         echo 'No Post Type set!';
     }
     // the rel amount
     $rel_amount = 3;
     if (isset(RP4WP::get()->settings['general_' . $post_type])) {
         // set the correct options from step 3
         $rel_amount = RP4WP::get()->settings['general_' . $post_type]->get_option('automatic_linking_post_amount');
     }
     // Related Post Manager object
     $related_post_manager = new RP4WP_Related_Post_Manager();
     // Link posts
     $related_post_manager->link_related_posts($rel_amount, $post_type, $ppr);
     // Get unlinked post count
     $unlinked_post_count = $related_post_manager->get_unlinked_post_count($post_type);
     // Echo the uncached posts
     echo $unlinked_post_count;
     exit;
 }
 public function run()
 {
     // check nonce
     check_ajax_referer(RP4WP_Constants::NONCE_AJAX, 'nonce');
     // get the rel amount
     $rel_amount = isset($_POST['rel_amount']) ? $_POST['rel_amount'] : 3;
     // get the related post age
     $post_age = isset($_POST['rp4wp_related_posts_age']) ? $_POST['rp4wp_related_posts_age'] : 0;
     // check if Post Type is set
     if (!isset($_POST['pt'])) {
         echo 'No Post Type set!';
         exit;
     }
     // post Type
     $post_type = $_POST['pt'];
     if (isset(RP4WP::get()->settings['general_' . $post_type])) {
         // set the correct options from step 3
         $options = RP4WP::get()->settings['general_' . $post_type]->get_options();
         $options['automatic_linking_post_amount'] = $rel_amount;
         $options['max_post_age'] = $post_age;
         update_option('rp4wp_general_' . $post_type, $options);
     }
     // success
     echo 'success';
     exit;
 }
 public function run()
 {
     if (is_single()) {
         $css = trim(RP4WP::get()->settings->get_option('css'));
         if ('' != $css) {
             echo "<style type='text/css'>" . $css . "</style>" . PHP_EOL;
         }
     }
 }
 /**
  * Get the column CSS class
  *
  * @param $row_counter
  *
  * @return string
  */
 public static function get_column_class($row_counter)
 {
     $row_class = '';
     $cols_per_row = RP4WP::get()->settings['configurator']->get_option('posts_per_row');
     $mod = $row_counter % $cols_per_row;
     if (0 === $mod) {
         $row_class .= ' rp4wp-col-first';
     }
     if ($cols_per_row - 1 == $mod) {
         $row_class .= ' rp4wp-col-last';
     }
     return $row_class;
 }
 /**
  * Ran on WP admin_init hook
  */
 public function admin_init()
 {
     $this->load_errors();
     add_action('shutdown', array($this, 'store_errors'));
     add_action('pre_set_site_transient_update_plugins', array($this, 'check_for_updates'));
     add_filter('plugins_api', array($this, 'plugins_api'), 10, 3);
     // Get License options
     $license_options = RP4WP::get()->settings['license']->get_options();
     // Setup plugin data
     $this->plugin_data = get_plugin_data($this->plugin_file);
     $this->api_key = $license_options['licence_key'];
     $this->activation_email = $license_options['email'];
     // Activated notice
     if (!empty($_GET['dismiss-' . sanitize_title($this->plugin_slug)])) {
         update_option($this->plugin_slug . '_hide_key_notice', 1);
     }
     if (false == RP4WP_Updater_Key_API::is_activated() && sizeof($this->errors) === 0 && !get_option($this->plugin_slug . '_hide_key_notice')) {
         add_action('admin_notices', array($this, 'key_notice'));
     }
     add_action('admin_notices', array($this, 'error_notices'));
 }
 public function run($new_status, $old_status, $post)
 {
     // verify this is not an auto save routine.
     if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
         return;
     }
     // Post status must be publish
     if ('publish' != $new_status) {
         return;
     }
     // Check if this post type is installed
     $pt_manager = new RP4WP_Post_Type_Manager();
     if (!$pt_manager->is_post_type_installed($post->post_type)) {
         return;
     }
     // Is automatic linking enabled?
     if (1 != RP4WP::get()->settings['general_' . $post->post_type]->get_option('automatic_linking')) {
         return;
     }
     // Check if the current post is already auto linked
     if (1 != get_post_meta($post->ID, RP4WP_Constants::PM_POST_AUTO_LINKED, true)) {
         // Post Link Manager
         $pl_manager = new RP4WP_Post_Link_Manager();
         // Get automatic linking post amount
         $automatic_linking_post_amount = RP4WP::get()->settings['general_' . $post->post_type]->get_option('automatic_linking_post_amount');
         // Count already linked posts
         $already_linked_posts = $pl_manager->get_children_count($post->ID);
         // Subtract already linked post count from posts to link amount
         if (count($already_linked_posts) > 0) {
             $automatic_linking_post_amount = $automatic_linking_post_amount - $already_linked_posts;
         }
         // Related Posts Manager
         $related_post_manager = new RP4WP_Related_Post_Manager();
         // Link related posts
         $related_post_manager->link_related_post($post->ID, $post->post_type, $automatic_linking_post_amount);
         // Set the auto linked meta
         update_post_meta($post->ID, RP4WP_Constants::PM_POST_AUTO_LINKED, 1);
     }
 }
 /**
  * Generate the children list
  *
  * @param $id
  *
  * @since  1.0.0
  * @access public
  *
  * @return string
  */
 public function generate_children_list($id)
 {
     // The content
     $content = '';
     // Get the children
     $related_posts = $this->get_children($id);
     // Count
     if (count($related_posts) > 0) {
         // The rp4wp block
         $content .= "<div class='rp4wp-related-posts'>\n";
         // Get the heading text
         $heading_text = RP4WP::get()->settings->get_option('heading_text');
         // Check if there is a heading text
         if ('' != $heading_text) {
             // Add heading text plus heading elements
             $heading_text = '<h3>' . $heading_text . '</h3>' . PHP_EOL;
         }
         // Filter complete heading
         $content .= apply_filters('rp4wp_heading', $heading_text);
         // Open the list
         $content .= "<ul>\n";
         foreach ($related_posts as $rp4wp_post) {
             // Setup the postdata
             setup_postdata($rp4wp_post);
             // Output the linked post
             $content .= "<li>";
             if (1 == RP4WP::get()->settings->get_option('display_image')) {
                 if (has_post_thumbnail($rp4wp_post->ID)) {
                     /**
                      * Filter: 'rp4wp_apdc_thumbnail_size' - Allows changing the thumbnail size of the thumbnail in de APDC section
                      *
                      * @api String $thumbnail_size The current/default thumbnail size.
                      */
                     $thumb_size = apply_filters('rp4wp_thumbnail_size', 'thumbnail');
                     $content .= "<div class='rp4wp-related-post-image'>" . PHP_EOL;
                     $content .= "<a href='" . get_permalink($rp4wp_post->ID) . "'>";
                     $content .= get_the_post_thumbnail($rp4wp_post->ID, $thumb_size);
                     $content .= "</a>";
                     $content .= "</div>" . PHP_EOL;
                 }
             }
             $content .= "<div class='rp4wp-related-post-content'>" . PHP_EOL;
             $content .= "<a href='" . get_permalink($rp4wp_post->ID) . "'>" . $rp4wp_post->post_title . "</a>";
             $excerpt_length = RP4WP::get()->settings->get_option('excerpt_length');
             if ($excerpt_length > 0) {
                 $excerpt = '' != $rp4wp_post->post_excerpt ? $rp4wp_post->post_excerpt : wp_trim_words($rp4wp_post->post_content, $excerpt_length);
                 $content .= "<p>" . $excerpt . "</p>";
             }
             $content .= "</div>" . PHP_EOL;
             $content .= "</li>\n";
             // Reset the postdata
             wp_reset_postdata();
         }
         // Close the wrapper div
         $content .= "</ul>\n";
         $content .= "</div>\n";
     }
     return $content;
 }
/**
 * @since  1.0.0
 * @access public
 *
 * @return RP4WP
 */
function RP4WP()
{
    return RP4WP::get();
}
    /**
     * Get the component related CSS
     *
     * @return string
     */
    public function get_component_css()
    {
        // get css from transient
        $css = get_transient(RP4WP_Constants::TRANSIENT_COMPONENT_CSS);
        // check if transient is set
        if (false === $css) {
            $css = '';
            // load configuration
            $components = $this->get_components();
            // check
            if (count($components) > 0) {
                // Get options
                $cols = RP4WP::get()->settings['configurator']->get_option('posts_per_row');
                $fixed_height = RP4WP::get()->settings['configurator']->get_option('fixed_height');
                $col_width_normal = 100 / $cols + 1;
                $col_width_edges = 100 / $cols - 1;
                // Basic component styling
                $css .= 'ul.rp4wp-posts-list {float: left;}
					.rp4wp-col {
						width: 100%;
						margin-bottom: 30px;
						list-style:none;
						box-sizing: border-box;
						overflow:hidden;
						float: left;
					}
					.rp4wp_component_wrapper {
						width: 100%;
						float: left;
					}
					.rp4wp_component {
						width: 100%;
						padding: 0 0 5%;
						box-sizing: border-box;
						float: left;
						overflow: hidden;
					}
					.rp4wp_component a {border:0;}
					.rp4wp_component_image a {display:block; height:100%} .rp4wp_component_image img {width:100%;height:100%;}
					.rp4wp_component_title a {text-decoration: none; font-weight: bold; border: 0;}

					@media (min-width: 768px) {
						.rp4wp-col {
							width: ' . $col_width_normal . '%;
							' . (0 != $fixed_height ? 'height:' . $fixed_height . 'px;' : '') . '
							padding: 0 2%;

						}
						.rp4wp-col-first {
							width: ' . $col_width_edges . '%;
							padding-left:0;
							padding-right: 2%;
						}
						.rp4wp-col-last {
							width: ' . $col_width_edges . '%;
							padding-right:0;
							padding-left: 2%;
						}
						.rp4wp_component_wrapper {
							width: 50%;
						}
						.rp4wp_component_wrapper_left {
							padding-right: 5%;
						}
						.rp4wp_component_wrapper_right {
							padding-left:5%;
						}
					}
			';
                // rtl support
                if (is_rtl()) {
                    $css .= '
				.rp4wp-col {
					float: right;
				}

				@media (min-width: 768px) {
						.rp4wp-col-first {
							padding-right:0;
							padding-left: 2%;
						}
						.rp4wp-col-last {
							padding-left:0;
							padding-right: 2%;
						}
						.rp4wp_component_wrapper_left {
							padding-left: 5%;
							padding-right: 0;
						}
						.rp4wp_component_wrapper_right {
							padding-right:5%;
							padding-left: 0;
						}
					}
				';
                }
                // Loop through components
                foreach ($components as $component) {
                    //	width: ' . ( 50 * $component->width ) . '%;
                    // add component with the correct height
                    $css .= '.rp4wp_component_' . $component->id . '{
					height: ' . 20 * $component->height . '%;
				}';
                    // add dynamic height for components in wrapper
                    if ('wrapper' == $component->type) {
                        foreach ($component->components as $inner_component) {
                            $css .= '.rp4wp_component_' . $inner_component->id . '{
								height: ' . 100 / $component->height * $inner_component->height . '%;
						}';
                        }
                    }
                }
                // Load & add custom CSS
                $custom_css = RP4WP::get()->settings['configurator']->get_option('css');
                if ('' !== $custom_css) {
                    $css .= $custom_css;
                }
                // Output the CSS
                $css = trim($css);
            }
            // set transient
            set_transient(RP4WP_Constants::TRANSIENT_COMPONENT_CSS, $css);
        }
        return $css;
    }
 /**
  * Install a post type. This includes caching and linking post types.
  *
  * ## OPTIONS
  *
  * <post_type>
  * : The post type where related posts are linked to
  *
  * <linked_post_types>
  * : The post types (comma separated) which are linked to the first argument
  *
  * <rel_amount>
  * : The amount of related posts per post
  *
  * [<max_post_age>]
  * : The maximum age of a related post in days
  *
  * ## EXAMPLE
  *
  *     wp rp4wp remove_related post
  *
  * @synopsis <post_type> <linked_post_types> <rel_amount> [<max_post_age>]
  */
 public function install($args, $assoc_args)
 {
     // args
     $post_type = trim($args[0]);
     $linked_post_types = explode(',', trim($args[1]));
     $rel_amount = intval($args[2]);
     $max_post_age = intval(isset($args[3]) ? $args[3] : 0);
     // we need at least one linked post type to continue
     if (count($linked_post_types) > 0) {
         /**
          * SETTINGS
          */
         // set the linked post types
         $ptm = new RP4WP_Post_Type_Manager();
         $ptm->add_post_type($post_type, $linked_post_types);
         // set the post type options
         if (isset(RP4WP::get()->settings['general_' . $post_type])) {
             $options = RP4WP::get()->settings['general_' . $post_type]->get_options();
             $options['automatic_linking_post_amount'] = $rel_amount;
             $options['max_post_age'] = $max_post_age;
             update_option('rp4wp_general_' . $post_type, $options);
         }
         /**
          * CACHE POSTS
          */
         WP_CLI::line('Caching Words');
         // related word manage
         $related_word_manager = new RP4WP_Related_Word_Manager();
         // cache words of parent post type
         $related_word_manager->save_all_words($post_type);
         // cache words of linked post types
         foreach ($linked_post_types as $linked_post_type) {
             $related_word_manager->save_all_words($linked_post_type);
         }
         /**
          * LINK POSTS
          */
         WP_CLI::line('Linking Posts');
         $related_post_manager = new RP4WP_Related_Post_Manager();
         $related_post_manager->link_related_posts($rel_amount, $post_type);
         // output success
         WP_CLI::success(sprintf('Successfully installed %s', $post_type));
     }
 }
 /**
  * An update is required, do it
  *
  * @param $current_version
  */
 private function do_upgrade($current_version)
 {
     global $wpdb;
     // Upgrade to version 1.2.2
     if (version_compare($current_version, '1.2.2', '<')) {
         /**
          * Add a post type to currently existing links
          */
         // Get id's that need an upgrade
         $upgrade_ids = get_posts(array('post_type' => RP4WP_Constants::LINK_PT, 'fields' => 'ids', 'posts_per_page' => -1, 'meta_query' => array(array('key' => RP4WP_Constants::PM_PT_PARENT, 'value' => '1', 'compare' => 'NOT EXISTS'))));
         // Preparing the sql lines
         if (count($upgrade_ids) > 0) {
             $sql_lines = array();
             // Loop
             foreach ($upgrade_ids as $upgrade_id) {
                 $sql_lines[] = "(" . $upgrade_id . ", '" . RP4WP_Constants::PM_PT_PARENT . "', 'post')";
             }
             // Insert the rows
             $wpdb->query("INSERT INTO `{$wpdb->postmeta}` (`post_id`,`meta_key`,`meta_value`) VALUES" . implode(',', $sql_lines) . " ;");
         }
     }
     // Upgrade to 1.3.0
     if (version_compare($current_version, '1.3.0', '<')) {
         /**
          * Upgrade the 'rp4wp_installed_post_types' option
          */
         // Get old post types
         $old_installed_post_types = get_option(RP4WP_Constants::OPTION_INSTALLED_PT, array());
         // Check
         if (count($old_installed_post_types) > 0) {
             // New installed post types
             $installed_post_types = array();
             // Loop
             foreach ($old_installed_post_types as $old_installed_post_type => $old_installed_post_type_children) {
                 if (is_array($old_installed_post_type_children)) {
                     $installed_post_types[$old_installed_post_type] = $old_installed_post_type_children;
                 } else {
                     $installed_post_types[$old_installed_post_type_children] = array($old_installed_post_type_children);
                 }
             }
             // Set new option
             update_option(RP4WP_Constants::OPTION_INSTALLED_PT, $installed_post_types);
         }
         /**
          * Upgrade license key and email
          */
         // Fetch old license key and email
         $plugin_slug = str_replace('.php', '', basename(RP4WP_PLUGIN_FILE));
         $api_key = get_option($plugin_slug . '_licence_key', '');
         $activation_email = get_option($plugin_slug . '_email', '');
         // Check if values exist
         if ('' != $api_key && '' != $activation_email) {
             // Update option
             update_option('rp4wp_license', array('licence_key' => $api_key, 'email' => $activation_email));
             // Set local activation status to true
             RP4WP_Updater_Key_API::set_activated(true);
         }
     }
     // upgrade to 1.4.0, the configurator
     if (version_compare($current_version, '1.4.0', '<')) {
         // get installed post types
         $pt_manager = new RP4WP_Post_Type_Manager();
         $installed_post_types = $pt_manager->get_installed_post_types();
         // check
         if (count($installed_post_types) > 0) {
             // get first pt
             foreach ($installed_post_types as $settings_pt => $dump) {
                 break;
             }
             unset($dump);
             // get current theme option
             $theme_options = get_option('rp4wp_themes', array());
             // get settings
             $pt_settings = RP4WP::get()->settings['general_' . $settings_pt];
             // configurator options
             $configurator_options = array('posts_per_row' => isset($theme_options['theme']) && intval($theme_options['theme']) > 0 ? intval($theme_options['theme']) : 2, 'fixed_height' => 325, 'css' => isset($theme_options['css']) ? $theme_options['css'] : '');
             // get settings from first pt
             $display_image = intval($pt_settings->get_option('display_image'));
             $excerpt_length = intval($pt_settings->get_option('excerpt_length'));
             // set the right configuration
             if (1 == $display_image && $excerpt_length > 0) {
                 // image + title + excerpt
                 $configurator_options['configuration'] = '[{"type":"image","x":0,"y":0,"width":1,"height":5},{"type":"title","x":1,"y":0,"width":1,"height":2},{"type":"excerpt","x":1,"y":2,"width":1,"height":3}]';
             } else {
                 if (1 == $display_image) {
                     // title + image
                     $configurator_options['configuration'] = '[{"type":"title","x":0,"y":0,"width":2,"height":1},{"type":"image","x":0,"y":1,"width":2,"height":4}]';
                 } else {
                     if ($excerpt_length > 0) {
                         // title + excerpt
                         $configurator_options['configuration'] = '[{"type":"title","x":0,"y":0,"width":2,"height":1},{"type":"excerpt","x":0,"y":1,"width":2,"height":4}]';
                     } else {
                         // title only
                         $configurator_options['configuration'] = '[{"type":"title","x":0,"y":0,"width":2,"height":5}]';
                     }
                 }
             }
             // set configuration option
             update_option('rp4wp_configurator', $configurator_options);
             // delete old theme options
             delete_option('rp4wp_themes');
         }
     }
     // Upgrade to 1.5.0
     if (version_compare($current_version, '1.5.0', '<')) {
         /**
          * Add INDEX to word column in cache table
          */
         // check for index
         $wpdb->query("SHOW INDEX FROM  `" . $wpdb->prefix . "rp4wp_cache` WHERE KEY_NAME = 'word'");
         if (0 === intval($wpdb->num_rows)) {
             // add index
             $wpdb->query("ALTER TABLE `" . $wpdb->prefix . "rp4wp_cache` ADD INDEX(`word`);");
         }
         /**
          * Move excluded post meta ID's to option to improve related post query
          */
         // get all post ids that are excluded
         $excluded_ids = get_posts(array('fields' => 'ids', 'posts_per_page' => -1, 'meta_query' => array(array('key' => 'rp4wp_exclude', 'value' => '1'))));
         // check if there are any excluded posts
         if (count($excluded_ids) > 0) {
             // put excluded ids in comma separated string
             $excluded_ids = implode(',', $excluded_ids);
             // put in option
             update_option(RP4WP_Constants::OPTION_EXCLUDED, $excluded_ids);
         }
         /**
          * Delete CSS transient so the new frontend styling will apply after update
          */
         delete_transient(RP4WP_Constants::TRANSIENT_COMPONENT_CSS);
     }
     // Upgrade to 1.5.2
     if (version_compare($current_version, '1.5.2', '<')) {
         // fix the excludes
         $excludes = explode(',', get_option(RP4WP_Constants::OPTION_EXCLUDED, ''));
         if (count($excludes) > 0) {
             // trim values
             $excludes = array_map('trim', $excludes);
             // remove empty values
             $excludes = array_filter($excludes);
             // update option
             update_option(RP4WP_Constants::OPTION_EXCLUDED, implode(',', $excludes));
         }
     }
 }
 /**
  * Dev test flow
  *
  * ## OPTIONS
  *
  * ## EXAMPLES
  *
  *     wp rp4wp-dev test
  */
 public function test($args, $assoc_args)
 {
     $limit = 274;
     //		$limit = 10;
     WP_CLI::line('Start rp4wp-dev test');
     WP_CLI::line('---------------------');
     // args
     $post_type = 'post';
     $linked_post_types = array('post');
     $rel_amount = 3;
     $max_post_age = 0;
     /**
      * UNINSTALL
      */
     // Add the post types
     $ptm = new RP4WP_Post_Type_Manager();
     // Remove post type
     $ptm->remove_post_type($post_type);
     // Related post manager
     $related_post_manager = new RP4WP_Related_Post_Manager();
     // Remove linked related posts
     $related_post_manager->remove_linked_posts($post_type);
     // delete words
     $word_manager = new RP4WP_Related_Word_Manager();
     $word_manager->delete_words_by_post_type($post_type);
     /**
      * SETTINGS
      */
     // set the linked post types
     $ptm->add_post_type($post_type, $linked_post_types);
     // set the post type options
     if (isset(RP4WP::get()->settings['general_' . $post_type])) {
         $options = RP4WP::get()->settings['general_' . $post_type]->get_options();
         $options['automatic_linking_post_amount'] = $rel_amount;
         $options['max_post_age'] = $max_post_age;
         update_option('rp4wp_general_' . $post_type, $options);
     }
     /**
      * CACHE POSTS
      */
     WP_CLI::line('Start building word cache');
     // related word manage
     $related_word_manager = new RP4WP_Related_Word_Manager();
     $start = time();
     // cache words of parent post type
     $related_word_manager->save_all_words($post_type, $limit);
     // cache words of linked post types
     foreach ($linked_post_types as $linked_post_type) {
         $related_word_manager->save_all_words($linked_post_type, $limit);
     }
     $runtime = time() - $start;
     $avg = $runtime / $limit;
     WP_CLI::line(sprintf('Words cached - Runtime: %d - Average: %f', $runtime, $avg));
     $start = time();
     /**
      * LINK POSTS
      */
     WP_CLI::line('Start linking posts');
     $related_post_manager->link_related_posts($rel_amount, $post_type, $limit);
     $runtime = time() - $start;
     $avg = $runtime / $limit;
     WP_CLI::line(sprintf('Posts linked - Runtime: %d - Average: %f', $runtime, $avg));
     // output success
     WP_CLI::success(sprintf('Successfully installed %s', $post_type));
 }
 /**
  * Get related posts by post id and post type
  *
  * @param int $post_id
  * @param String $post_type
  * @param int $limit
  *
  * @return array
  */
 public function get_related_posts($post_id, $post_type, $limit = -1)
 {
     global $wpdb;
     // Post Type Manager
     $ptm = new RP4WP_Post_Type_Manager();
     // Int y'all
     $post_id = intval($post_id);
     // Related post types
     $related_post_types = $ptm->get_installed_post_type($post_type);
     // Only continue of we've got > 1 related post type
     if (0 === count($related_post_types)) {
         return array();
     }
     // Format the related post types
     $formatted_post_types = "( '" . implode("','", esc_sql($related_post_types)) . "' )";
     // Get max post age
     $max_post_age = 0;
     if (isset(RP4WP::get()->settings['general_' . $post_type])) {
         // set the correct options from step 3
         $max_post_age = intval(RP4WP::get()->settings['general_' . $post_type]->get_option('max_post_age'));
     }
     // Build SQl
     $sql = "\n\t\tSELECT R.`post_id` AS `ID`\n\t\tFROM `" . RP4WP_Related_Word_Manager::get_database_table() . "` O\n\t\tINNER JOIN `" . RP4WP_Related_Word_Manager::get_database_table() . "` R ON R.`word` = O.`word` ";
     // only join post table when max post age is set
     if ($max_post_age > 0) {
         $sql .= "INNER JOIN `" . $wpdb->posts . "` P ON P.`ID` = R.`post_id`";
     }
     // add WHERE statements
     $sql .= "\n\t\tWHERE 1=1\n\t\tAND O.`post_id` = %d\n\t\tAND R.`post_type` IN " . $formatted_post_types . "\n\t\tAND R.`post_id` != %d\n\t\t";
     // get excluded ids
     $excluded_ids = get_option(RP4WP_Constants::OPTION_EXCLUDED, '');
     // check if there are excluded ids
     if (false !== $excluded_ids && !empty($excluded_ids)) {
         // add excluded where statement to query
         $sql .= "AND R.`post_id` NOT IN (" . $excluded_ids . ")\n\t\t\t";
     }
     // check if we got a maximum post age for this post type
     // check is max post age is > 0
     if ($max_post_age > 0) {
         // calculate date in past
         $date_time_oldest = new DateTime();
         $date_time_oldest = $date_time_oldest->modify('-' . $max_post_age . 'days');
         // make the post age key filterable
         $post_age_column = apply_filters('rp4wp_post_age_column', 'post_date');
         // add to SQL
         $sql .= "AND P.`" . $post_age_column . "` >= '" . $date_time_oldest->format('Y-m-d') . "'\n\t\t\t\t";
     }
     // add group by and order by to SQL
     $sql .= "GROUP BY R.`post_id`\n\t\tORDER BY SUM( R.`weight` ) DESC\n\t\t";
     // Check & Add Limit
     if (-1 != $limit) {
         $sql .= "\n\t\t\tLIMIT 0,%d";
         // Prepare SQL
         $sql = $wpdb->prepare($sql, $post_id, $post_id, $limit);
     } else {
         // Prepare SQL
         $sql = $wpdb->prepare($sql, $post_id, $post_id);
     }
     // Allow filtering of SQL to find related posts
     $sql = apply_filters('rp4wp_get_related_posts_sql', $sql, $post_id, $post_type, $limit);
     // Get post from related cache
     return $wpdb->get_results($sql);
 }
 /**
  * Get placeholder image
  *
  * @param int $post_id
  * @param string $post_type
  *
  * @return string
  */
 public function get_placeholder_image($post_id, $post_type)
 {
     $thumbnail = '';
     // get post
     $post = get_post($post_id);
     // get placeholder source
     $placeholder = RP4WP::get()->settings['general_' . $post_type]->get_option('thumbnail_placeholder');
     // check if placeholder is set
     if (!empty($placeholder)) {
         // set correct thumbnail
         $thumbnail = sprintf('<img src="%s" class="attachment-thumbnail wp-post-image" alt="%s">', $placeholder, $post->post_title);
     }
     return $thumbnail;
 }