function wpv_filter_limit_query_post_process_filter($query, $view_settings)
{
    remove_filter('wpv_filter_query_post_process', 'wpv_filter_limit_query_post_process_filter', 10, 2);
    if (!empty($query->posts)) {
        $limit = intval($view_settings['limit']);
        $offset = intval($view_settings['offset']);
        if ($limit == -1) {
            $posts = array_slice($query->posts, $offset);
        } else {
            $posts = array_slice($query->posts, $offset, $limit);
        }
        add_filter('wpv_filter_query', 'wpv_filter_limit_arg_post_in', 10, 2);
        global $wpv_limit_post_in;
        if (!empty($posts)) {
            $wpv_limit_post_in = array();
            foreach ($posts as $key => $post) {
                $wpv_limit_post_in[] = $post->ID;
            }
        } else {
            $wpv_limit_post_in = array(0);
        }
        $query = wpv_filter_get_posts($view_settings['view_id']);
        remove_filter('wpv_filter_query', 'wpv_filter_limit_arg_post_in', 10, 2);
        add_filter('wpv_filter_query', 'wpv_filter_limit_arg', 10, 2);
        return $query;
    }
    add_filter('wpv_filter_query', 'wpv_filter_limit_arg', 10, 2);
    return $query;
}
/**
* get_view_query_results
*
* Returns the result of a query filtered by a View.
*
* @param int $view_id ID of the relevant View
* @param object $post_in (optional) Sets the global $post
* @param object $current_user_in (optional) Sets the global $current_user
* @param array $args (optional) Attributes to pass to the View, like shortcode attributes when using [wpv-view]
*
* @return Array of $post objects if the View lists posts, $term objects if the View lists taxonomies or $user objects if the View lists users
*
* @usage  <?php echo get_view_query_results( 80 ); ?>
*
* @since unknown
*
*/
function get_view_query_results($view_id, $post_in = null, $current_user_in = null, $args = array())
{
    $view_post = get_post($view_id);
    if (!$view_post || $view_post->post_status != 'publish' || $view_post->post_type != 'view') {
        return array();
    }
    global $WP_Views, $post, $current_user, $authordata;
    // Save current globals to restore them later
    $post_old = $post;
    $current_user_old = $current_user;
    $authordata_old = $authordata;
    $items = array();
    if ($post_in) {
        $post = $post_in;
    }
    if ($current_user_in) {
        $current_user = $current_user_in;
    }
    $view_settings = $WP_Views->get_view_settings($view_id);
    array_push($WP_Views->view_shortcode_attributes, $args);
    $query_type = isset($view_settings['query_type'][0]) ? $view_settings['query_type'][0] : 'posts';
    switch ($query_type) {
        case 'posts':
            // get the posts using the query settings for this view.
            $archive_query = null;
            if (isset($view_settings['view-query-mode']) && $view_settings['view-query-mode'] == 'archive') {
                // check for an archive loop
                global $WPV_view_archive_loop;
                if (isset($WPV_view_archive_loop)) {
                    $archive_query = $WPV_view_archive_loop->get_archive_loop_query();
                }
            } else {
                if (isset($view_settings['view-query-mode']) && $view_settings['view-query-mode'] == 'layouts-loop') {
                    global $wp_query;
                    $archive_query = isset($wp_query) && $wp_query instanceof WP_Query ? clone $wp_query : null;
                }
            }
            if ($archive_query) {
                $ret_query = $archive_query;
            } else {
                $ret_query = wpv_filter_get_posts($view_id);
            }
            $items = $ret_query->posts;
            break;
        case 'taxonomy':
            $items = $WP_Views->taxonomy_query($view_settings);
            break;
        case 'users':
            $items = $WP_Views->users_query($view_settings);
            break;
    }
    array_pop($WP_Views->view_shortcode_attributes);
    // Restore current globals
    $post = $post_old;
    $current_user = $current_user_old;
    $authordata = $authordata_old;
    return $items;
}
 /**
  * Render the view and loops through the found posts
  *
  */
 function render_view($view_id, $hash)
 {
     global $post;
     global $wplogger;
     static $processed_views = array();
     // increment the view count.
     if (!isset($this->view_count[$this->view_depth])) {
         $this->view_count[$this->view_depth] = 0;
     }
     $this->view_count[$this->view_depth]++;
     $view = get_post($view_id);
     $this->view_used_ids[] = $view_id;
     $out = '';
     /*
     $css = get_post_meta($view_id, '_wpv_css', true);
     if ($css) {
         $out .= "<style type='text/css'>\n";
         $out .= $css;
         $out .= "\n</style>";
     }
     */
     $view_caller_id = isset($post) && isset($post->ID) ? get_the_ID() : 0;
     // post or widget
     if (!isset($processed_views[$view_caller_id][$hash]) || 0 === $view_caller_id) {
         //$processed_views[$view_caller_id][$hash] = true; // mark view as processed for this post
         if (!empty($view)) {
             $post_content = $view->post_content;
             // apply the layout meta html if we have some.
             $view_layout_settings = $this->get_view_layout_settings();
             if (isset($view_layout_settings['layout_meta_html'])) {
                 $post_content = str_replace('[wpv-layout-meta-html]', $view_layout_settings['layout_meta_html'], $post_content);
             }
             $post_content = wpml_content_fix_links_to_translated_content($post_content);
             $view_settings = $this->get_view_settings();
             // find the loop
             if (preg_match('#\\<wpv-loop(.*?)\\>(.*)</wpv-loop>#is', $post_content, $matches)) {
                 // get the loop arguments.
                 $args = $matches[1];
                 $exp = array_map('trim', explode(' ', $args));
                 $args = array();
                 foreach ($exp as $e) {
                     $kv = explode('=', $e);
                     if (sizeof($kv) == 2) {
                         $args[$kv[0]] = trim($kv[1], '\'"');
                     }
                 }
                 if (isset($args['wrap'])) {
                     $args['wrap'] = intval($args['wrap']);
                 }
                 if (isset($args['pad'])) {
                     $args['pad'] = $args['pad'] == 'true';
                 } else {
                     $args['pad'] = false;
                 }
                 $tmpl = $matches[2];
                 $item_indexes = $this->_get_item_indexes($tmpl);
                 if ($view_settings['query_type'][0] == 'posts') {
                     // get the posts using the query settings for this view.
                     $archive_query = null;
                     if ($view_settings['view-query-mode'] == 'archive') {
                         // check for an archive loop
                         global $WPV_view_archive_loop;
                         if (isset($WPV_view_archive_loop)) {
                             $archive_query = $WPV_view_archive_loop->get_archive_loop_query();
                         }
                     }
                     if ($archive_query) {
                         $this->post_query = $archive_query;
                     } else {
                         $this->post_query = wpv_filter_get_posts($view_id);
                     }
                     $items = $this->post_query->posts;
                     $wplogger->log('Found ' . count($items) . ' posts');
                     if ($wplogger->isMsgVisible(WPLOG_DEBUG)) {
                         // simplify the output
                         $out_items = array();
                         foreach ($items as $item) {
                             $out_items[] = array('ID' => $item->ID, 'post_title' => $item->post_title);
                         }
                         $wplogger->log($out_items, WPLOG_DEBUG);
                     }
                 }
                 // save original post
                 global $post, $authordata, $id;
                 $tmp_post = isset($post) ? clone $post : null;
                 if ($authordata) {
                     $tmp_authordata = clone $authordata;
                 } else {
                     $tmp_authordata = null;
                 }
                 $tmp_id = $id;
                 if ($view_settings['query_type'][0] == 'taxonomy') {
                     $items = $this->taxonomy_query($view_settings);
                     $wplogger->log($items, WPLOG_DEBUG);
                     // taxonomy views can be recursive so remove from
                     // the processed array
                     //unset($processed_views[$view_caller_id][$hash]);
                 }
                 $loop = '';
                 for ($i = 0; $i < count($items); $i++) {
                     $index = $i;
                     if (isset($args['wrap'])) {
                         $index %= $args['wrap'];
                     }
                     $index++;
                     // [wpv-item index=xx] uses base 1
                     $index = strval($index);
                     if ($view_settings['query_type'][0] == 'posts') {
                         $post = clone $items[$i];
                         $authordata = new WP_User($post->post_author);
                         $id = $post->ID;
                         $temp_variables = $this->variables;
                         $this->variables = array();
                         do_action('wpv-before-display-post', $post, $view_id);
                     }
                     if ($view_settings['query_type'][0] == 'taxonomy') {
                         $this->taxonomy_data['term'] = $items[$i];
                     }
                     // first output the "all" index.
                     $loop .= wpv_do_shortcode($item_indexes['all']);
                     // Output each index we find
                     // otherwise output 'other'
                     if (isset($item_indexes[$index])) {
                         $loop .= wpv_do_shortcode($item_indexes[$index]);
                     } elseif (isset($item_indexes['other'])) {
                         $loop .= wpv_do_shortcode($item_indexes['other']);
                     }
                     if ($view_settings['query_type'][0] == 'posts') {
                         do_action('wpv-after-display-post', $post, $view_id);
                         $this->variables = $temp_variables;
                     }
                 }
                 // see if we should pad the remaining items.
                 if (isset($args['wrap']) && isset($args['pad'])) {
                     while ($i % $args['wrap'] && $args['pad']) {
                         $index = $i;
                         $index %= $args['wrap'];
                         if ($index == $args['wrap'] - 1) {
                             $loop .= wpv_do_shortcode($item_indexes['pad-last']);
                         } else {
                             $loop .= wpv_do_shortcode($item_indexes['pad']);
                         }
                         $i++;
                     }
                 }
                 $out .= str_replace($matches[0], $loop, $post_content);
                 $post = isset($tmp_post) ? clone $tmp_post : null;
                 // restore original $post
                 if ($tmp_authordata) {
                     $authordata = clone $tmp_authordata;
                 } else {
                     $authordata = null;
                 }
                 $id = $tmp_id;
             }
         } else {
             $out .= sprintf('<!- %s ->', __('View not found', 'wpv-views'));
         }
     } else {
         if ($processed_views[$view_caller_id][$hash] !== true) {
             $out .= $processed_views[$view_caller_id][$hash];
             // use output from cache
         }
     }
     return $out;
 }
 /**
  * Render the view and loops through the found posts
  */
 function render_view($view_id, $hash)
 {
     global $post, $WPVDebug, $wplogger;
     static $processed_views = array();
     // increment the view count.
     // TODO this code is duplicated, maybe create function for it?
     if (!isset($this->view_count[$this->view_depth])) {
         $this->view_count[$this->view_depth] = 0;
     }
     $this->view_count[$this->view_depth]++;
     $view = get_post($view_id);
     $this->view_used_ids[] = $view_id;
     $out = '';
     $view_caller_id = isset($post) && isset($post->ID) ? get_the_ID() : 0;
     // post or widget
     if (!isset($processed_views[$view_caller_id][$hash]) || 0 === $view_caller_id) {
         //$processed_views[$view_caller_id][$hash] = true; // mark view as processed for this post
         $status = get_post_status($view_id);
         // Views should be 'publish'ed to be allowed to produce an output
         // FIXME: Check also that user has permissions to render this view
         if (!empty($view) && $status == 'publish') {
             $post_content = $view->post_content;
             // apply the layout meta html if we have some.
             $view_layout_settings = $this->get_view_layout_settings();
             if (isset($view_layout_settings['layout_meta_html'])) {
                 $post_content = str_replace('[wpv-layout-meta-html]', $view_layout_settings['layout_meta_html'], $post_content);
             }
             $post_content = wpml_content_fix_links_to_translated_content($post_content);
             $view_settings = $this->get_view_settings();
             // find the loop
             if (preg_match('#\\<wpv-loop(.*?)\\>(.*)</wpv-loop>#is', $post_content, $matches)) {
                 // get the loop arguments.
                 $args = $matches[1];
                 $exp = array_map('trim', explode(' ', $args));
                 $args = array();
                 foreach ($exp as $e) {
                     $kv = explode('=', $e);
                     if (sizeof($kv) == 2) {
                         $args[$kv[0]] = trim($kv[1], '\'"');
                     }
                 }
                 if (isset($args['wrap'])) {
                     $args['wrap'] = intval($args['wrap']);
                 }
                 if (isset($args['pad'])) {
                     $args['pad'] = $args['pad'] == 'true';
                 } else {
                     $args['pad'] = false;
                 }
                 // Get templates for items (differentiated by their indices, see [wpv-item] documentation).
                 $tmpl = $matches[2];
                 $item_indexes = $this->_get_item_indexes($tmpl);
                 if ($view_settings['query_type'][0] == 'posts') {
                     // get the posts using the query settings for this view.
                     $archive_query = null;
                     if ($view_settings['view-query-mode'] == 'archive') {
                         // check for an archive loop
                         global $WPV_view_archive_loop;
                         if (isset($WPV_view_archive_loop)) {
                             $archive_query = $WPV_view_archive_loop->get_archive_loop_query();
                         }
                     } else {
                         if ($view_settings['view-query-mode'] == 'layouts-loop') {
                             global $wp_query;
                             $archive_query = isset($wp_query) && $wp_query instanceof WP_Query ? clone $wp_query : null;
                         }
                     }
                     if ($archive_query) {
                         $this->post_query = $archive_query;
                     } else {
                         $this->post_query = wpv_filter_get_posts($view_id);
                     }
                     $items = $this->post_query->posts;
                     $wplogger->log('Found ' . count($items) . ' posts');
                     if ($wplogger->isMsgVisible(WPLOG_DEBUG)) {
                         // simplify the output
                         $out_items = array();
                         foreach ($items as $item) {
                             $out_items[] = array('ID' => $item->ID, 'post_title' => $item->post_title);
                         }
                         $wplogger->log($out_items, WPLOG_DEBUG);
                     }
                 }
                 // save original post
                 global $post, $authordata, $id;
                 $tmp_post = isset($post) && $post instanceof WP_Post ? clone $post : null;
                 $tmp_authordata = isset($authordata) && is_object($authordata) ? clone $authordata : null;
                 $tmp_id = $id;
                 if ($view_settings['query_type'][0] == 'taxonomy') {
                     $items = $this->taxonomy_query($view_settings);
                     $wplogger->log($items, WPLOG_DEBUG);
                     // taxonomy views can be recursive so remove from the processed array
                     //unset($processed_views[$view_caller_id][$hash]);
                 } else {
                     if ($view_settings['query_type'][0] == 'users') {
                         $items = $this->users_query($view_settings);
                         $wplogger->log($items, WPLOG_DEBUG);
                     }
                 }
                 global $WPV_settings;
                 if (isset($WPV_settings->wpv_debug_mode) && !empty($WPV_settings->wpv_debug_mode)) {
                     $WPVDebug->add_log('items_count', count($items));
                 }
                 // The actual loop - render all items
                 $loop = '';
                 for ($i = 0; $i < count($items); $i++) {
                     $WPVDebug->set_index();
                     $index = $i;
                     if (isset($args['wrap'])) {
                         $index %= $args['wrap'];
                     }
                     // [wpv-item index=xx] uses base 1
                     $index++;
                     $index = strval($index);
                     if ($view_settings['query_type'][0] == 'posts') {
                         $post = clone $items[$i];
                         $authordata = new WP_User($post->post_author);
                         $id = $post->ID;
                         $temp_variables = $this->variables;
                         $this->variables = array();
                         do_action('wpv-before-display-post', $post, $view_id);
                     } elseif ($view_settings['query_type'][0] == 'taxonomy') {
                         $this->taxonomy_data['term'] = $items[$i];
                         do_action('wpv-before-display-taxonomy', $items[$i], $view_id);
                     } elseif ($view_settings['query_type'][0] == 'users') {
                         $user_id = $items[$i]->ID;
                         $user_meta = get_user_meta($user_id);
                         $items[$i]->meta = $user_meta;
                         $this->users_data['term'] = $items[$i];
                         do_action('wpv-before-display-user', $items[$i], $view_id);
                     }
                     $WPVDebug->add_log($view_settings['query_type'][0], $items[$i]);
                     // first output the "all" index.
                     $shortcodes_output = wpv_do_shortcode($item_indexes['all']);
                     $loop .= $shortcodes_output;
                     $WPVDebug->add_log_item('shortcodes', $item_indexes['all']);
                     $WPVDebug->add_log_item('output', $shortcodes_output);
                     /* Select a template for this item based on it's index.
                      * Note: It is possible that we won't be rendering this item's content if the index 'other'
                      * isn't set and there is no other match. */
                     $selected_index = null;
                     if (isset($item_indexes[$index])) {
                         $selected_index = $index;
                     } elseif (isset($item_indexes['odd']) && $index % 2 == 1) {
                         $selected_index = 'odd';
                     } elseif (isset($item_indexes['even']) && $index % 2 == 0) {
                         $selected_index = 'even';
                     } elseif (isset($item_indexes['other'])) {
                         $selected_index = 'other';
                     }
                     // Output the item with appropriate template (if we found one)
                     if (null !== $selected_index) {
                         $shortcodes_output = wpv_do_shortcode($item_indexes[$selected_index]);
                         $loop .= $shortcodes_output;
                         $WPVDebug->add_log_item('shortcodes', $item_indexes[$selected_index]);
                         $WPVDebug->add_log_item('output', $shortcodes_output);
                     }
                     // Do wpv-after-display-* action after displaying the item
                     if ($view_settings['query_type'][0] == 'posts') {
                         do_action('wpv-after-display-post', $post, $view_id);
                         $this->variables = $temp_variables;
                     } elseif ($view_settings['query_type'][0] == 'taxonomy') {
                         do_action('wpv-after-display-taxonomy', $items[$i], $view_id);
                     } elseif ($view_settings['query_type'][0] == 'users') {
                         do_action('wpv-after-display-user', $items[$i], $view_id);
                     }
                 }
                 // see if we should pad the remaining items.
                 if (isset($args['wrap']) && isset($args['pad'])) {
                     while ($i % $args['wrap'] && $args['pad']) {
                         $index = $i;
                         $index %= $args['wrap'];
                         if ($index == $args['wrap'] - 1) {
                             $loop .= wpv_do_shortcode($item_indexes['pad-last']);
                         } else {
                             $loop .= wpv_do_shortcode($item_indexes['pad']);
                         }
                         $i++;
                     }
                 }
                 $WPVDebug->clean_index();
                 $out .= str_replace($matches[0], $loop, $post_content);
                 // restore original $post
                 $post = isset($tmp_post) && $tmp_post instanceof WP_Post ? clone $tmp_post : null;
                 $authordata = isset($tmp_authordata) && is_object($tmp_authordata) ? clone $tmp_authordata : null;
                 $id = $tmp_id;
             }
         } else {
             $out .= sprintf('<!- %s ->', __('View not found', 'wpv-views'));
         }
     } else {
         if ($processed_views[$view_caller_id][$hash] !== true) {
             // use output from cache
             $out .= $processed_views[$view_caller_id][$hash];
         }
     }
     return $out;
 }
function wpv_filter_limit_query_post_process_filter($query, $view_settings, $view_id)
{
    remove_filter('wpv_filter_query_post_process', 'wpv_filter_limit_query_post_process_filter', 10, 3);
    if (!empty($query->posts)) {
        $limit = intval($view_settings['limit']);
        $offset = intval($view_settings['offset']);
        $override_values = wpv_override_view_limit_offset($view_id);
        if (isset($override_values['limit'])) {
            $limit = intval($override_values['limit']);
        }
        if (isset($override_values['offset'])) {
            $offset = intval($override_values['offset']);
        }
        if ($limit == -1) {
            $posts = array_slice($query->posts, $offset);
        } else {
            $posts = array_slice($query->posts, $offset, $limit);
        }
        add_filter('wpv_filter_query', 'wpv_filter_limit_arg_post_in', 12, 2);
        // needs to be after post relationships filter
        global $wpv_limit_post_in;
        if (!empty($posts)) {
            $wpv_limit_post_in = array();
            foreach ($posts as $key => $post) {
                $wpv_limit_post_in[] = $post->ID;
            }
        } else {
            $wpv_limit_post_in = array(0);
        }
        $query = wpv_filter_get_posts($view_settings['view_id']);
        remove_filter('wpv_filter_query', 'wpv_filter_limit_arg_post_in', 12, 2);
        add_filter('wpv_filter_query', 'wpv_filter_limit_arg', 10, 3);
        return $query;
    }
    add_filter('wpv_filter_query', 'wpv_filter_limit_arg', 10, 3);
    return $query;
}