0

I have created a CPT (esp-publicitarios) using Metabox plugin with the following code:

add_filter('rwmb_meta_boxes', 'elclarin_register_meta_boxes');

function elclarin_register_meta_boxes($meta_boxes)
{
    // Better has an underscore as last sign
    $prefix = 'rw_';

    // meta box - advertising related news
    $meta_boxes[] = array(
        'id' => 'advertising_related_news',
        'title' => __('Crear espacio publicitario'),
        'post_types' => array('esp-publicitarios'),
        'fields' => array(
            array(
                'name' => __('Choose related news'),
                'id' => "{$prefix}advertising_related_link",
                'type' => 'select_advanced',
                'options' => $options,
                'clone' => false,
            ),
            array(
                'name' => __('Choose an image'),
                'id' => "{$prefix}adversiting_image",
                'type' => 'image_advanced',
                'force_delete' => true,
                'max_file_uploads' => 1,
            ),
            array(
                'name' => __('Choose a position'),
                'id' => "{$prefix}adversiting_position",
                'type' => 'select',
                'options' => array(
                    '2' => 'Position 3',
                    '5' => 'Position 6',
                    '8' => 'Position 9',
                ),
            ),
            array(
                'name' => __('Position'),
                'id' => "{$prefix}show_at_position",
                'type' => 'hidden',
                'std' => 1,
            ),
        ),
        'validation' => array(
            'rules' => array(
                "{$prefix}advertising_related_link" => array(
                    'required' => true,
                ),
            ),
            'messages' => array(
                "{$prefix}advertising_related_link" => array(
                    'required' => __('You must choose a related news', $prefix),
                ),
            ),
        ),
    );

    return $meta_boxes;
}

That works perfect. I need to insert the adversiting in a given position (3, 6 or 9 as shown above) so I have made the following function:

/**
 * Extracts from an array posts with positional metadata and re-inserts them at the proper
 * indices. See http://wordpress.stackexchange.com/questions/210493
 **/
function wpse_210493_apply_advertising_position(&$posts, $return = false)
{
    $ad_posts = array();
    $content_posts = array();
    $related_post = array();
    // Seperate $posts into "Ads" and "Content" arrays based on whether or not they have 'rw_adversiting_position' meta-data
    foreach ($posts as $post) {
        $position = get_post_meta($post->ID, 'rw_adversiting_position', true);
        $post_date = $post->post_date;
        $post_modified = $post->post_modified;
        if (get_post_meta($post->ID, 'rw_advertising_related_link', true) !== 0) {
            $related_post[] = get_post_meta($post->ID, 'rw_advertising_related_link', true);
        }
        if (!empty($position)) {
            if (isset($ad_posts[$position])) {
                if ($post_date > $ad_posts[$position]->post_date || $post_modified > $ad_posts[$position]->post_modified) {
                    $ad_posts[$position] = $post;
                }
            } else {
                $ad_posts[$position] = $post;
            }
        } else {
            $content_posts[] = $post;
        }
    }
    // Sort the ads from smallest position index to greatest such that re-insertion properly factors in all ads
    ksort($ad_posts);
    // Add the ads back into the content at their specified positions
    foreach ($ad_posts as $position => $ad) {
        array_splice($content_posts, $position, 0, array($ad));
    }
    foreach ($content_posts as $key => $post) {
        if (in_array($post->ID, $related_post)) {
            unset($content_posts[$key]);
        }
    }

    return $content_posts;
}

Next, this is how I use the code above in then front page:

$normal_args = array(
    'order' => 'desc',
    'ignore_sticky_posts' => 1,
    'meta_query' => array(
        array(
            'key' => 'rw_show_at_position',
            'value' => '1',
            'compare' => '=',
        ),
    ),
    'post__not_in' => $prev_post_ids,
    'post_status' => 'publish',
    'posts_per_page' => get_option('column_right'),
    'post_type' => array(
        'opinion',
        'especiales',
        'clasificados',
        'portadadeldia',
        'anunciantes',
        'post',
        'pages',
        'esp-publicitarios',
    ),
);
$normal_query = new WP_Query($normal_args);
$i = 0;
// Espacios publicitarios hook
$filtered_posts = wpse_210493_apply_advertising_position($normal_query->posts);
if (count($filtered_posts)) {
    foreach ($filtered_posts as $post) {
       // ....
    }
}

That "works" but I have a problem, because the CPT is tied to the post then it moves out any time I add a new post and I need to keep it stick to its position, in other words if I set the CPT to be on the position 3 and link a post to it then that CPT and the post should remain on the position 3 until I remove from there, can I get some help from the community? I am stuck at this point.

0

If you index $related_posts by position along with $ad_posts, you can probably splice/insert them in at the same position... eg.

function wpse_210493_apply_advertising_position(&$posts, $return = false)
{
    $ad_posts = array();
    $content_posts = array();
    $related_post = array();
    // Seperate $posts into "Ads" and "Content" arrays based on whether or not they have 'rw_adversiting_position' meta-data
    foreach ($posts as $post) {
        $position = get_post_meta($post->ID, 'rw_adversiting_position', true);
        $post_date = $post->post_date;
        $post_modified = $post->post_modified;

        // add an index to related_posts inside the position check
        if (!empty($position)) {
            // move this inside position check
            $related_post = get_post_meta($post->ID, 'rw_advertising_related_link', true);
            if (isset($ad_posts[$position])) {
                if ($post_date > $ad_posts[$position]->post_date || $post_modified > $ad_posts[$position]->post_modified) {
                    $ad_posts[$position] = $post;
                    // add position index to related post
                    if ($related_post) {$related_post[$position] = $related_post;}
                }
            } else {
                $ad_posts[$position] = $post;
                // add position index to related post
                if ($related_post) {$related_post[$position] = $related_post;}
            }
        } else {
            $content_posts[] = $post;
        }

    }

    // Sort the ads from smallest position index to greatest such that re-insertion properly factors in all ads
    ksort($ad_posts);
    // Add the ads back into the content at their specified positions
    foreach ($ad_posts as $position => $ad) {
        array_splice($content_posts, $position, 0, array($ad));
        // add the match related post in
        array_splice($content_posts, $position, 0, array($related_post[$position]));
    }

    // then there is no need for this now
    // foreach ($content_posts as $key => $post) {
    //     if (in_array($post->ID, $related_post)) {
    //        unset($content_posts[$key]);
    //    }
    // }

    return $content_posts;
}
  • Can you add the full function? I am not following you at all – ReynierPM Jun 2 '16 at 10:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.