File: /var/www/lipovac/wp-content/plugins/the-events-calendar/src/Tribe/Views/V2/Template/Page.php
<?php
/**
* Initializer for The Events Calendar for the template structure using Page
*
* Can be changed on Events > Settings > Display
*
* @since 4.9.2
*
* @package Tribe\Events\Views\V2
*/
namespace Tribe\Events\Views\V2\Template;
use Tribe\Events\Views\V2\Kitchen_Sink;
use Tribe\Events\Views\V2\Template_Bootstrap;
use Tribe__Events__Main as TEC;
use Tribe__Utils__Array as Arr;
class Page {
/**
* Determines the Path for the PHP file to be used as the main template
* For Page base template setting it will select from theme or child theme
*
* @since 4.9.2
*
* @return string
*/
public function get_path() {
// Fetches the WP default path for Page
$template = get_page_template();
// If there wasn't any defined we fetch the Index
if ( empty( $template ) ) {
$template = get_index_template();
}
return $template;
}
/**
* When using Page template we need to specifically hijack the WordPress templating
* system at a specific point after `loop_start`.
*
* @since 4.9.2
*
* @param \WP_Query $query WordPress query executed to get here.
*
* @return boolean
*/
public function maybe_hijack_page_template( \WP_Query $query ) {
if ( ! $this->should_hijack_page_template( $query ) ) {
return false;
}
$mock_page = $this->get_mocked_page();
// don't query the database for the spoofed post
wp_cache_set( $mock_page->ID, $mock_page, 'posts' );
wp_cache_set( $mock_page->ID, [ true ], 'post_meta' );
// on loop start, unset the global post so that template tags don't work before the_content()
add_action( 'the_post', [ $this, 'hijack_the_post' ], 25 );
// Load our page Content
add_filter( 'the_content', [ $this, 'filter_hijack_page_content' ], 25 );
// Prevent edit link from showing
add_filter( 'get_edit_post_link', [ $this, 'filter_prevent_edit_link' ], 25, 2 );
// Makes sure Comments are not active
add_filter( 'comments_template', [ $this, 'filter_remove_comments' ], 25 );
}
/**
* Remove any possible comments template from Page that the theme might have
*
* @todo Take in consideration tribe_get_option( 'showComments', false ) values later on
*
* @since 4.9.2
*/
public function filter_remove_comments( $template ) {
remove_filter( 'comments_template', [ $this, 'filter_remove_comments' ], 25 );
return false;
}
/**
* Prevents the Edit link to ever be displayed on any well designed theme
* Ideally this method is here to return an empty string for the Mock Page
*
* @since 4.9.2
*
* @param string $url Old URL for editing the post
* @param string|int $post_id Post ID in question
*
* @return string
*/
public function filter_prevent_edit_link( $url, $post_id ) {
$query = tribe_get_global_query_object();
// Bail in case of any other page template.
if ( ! $this->should_hijack_page_template( $query ) ) {
return $url;
}
$mock_page = $this->get_mocked_page();
// If passed ID is not the Mock page one bail.
if ( (int) $post_id !== (int) $mock_page->ID ) {
return $url;
}
// Return empty edit link.
return '';
}
/**
* Inject a Ghost Post into `the_post`
*
* @since 4.9.2
*
* @return void
*/
public function hijack_the_post() {
remove_filter( 'the_post', [ $this, 'hijack_the_post' ], 25 );
$GLOBALS['post'] = $this->get_mocked_page();
}
/**
* Depending on params from Default templating for events we will Hijack
* the main query for events to mimick a ghost page element so the theme
* can propely run `the_content` so we can hijack the content of that page
* as well as `the_title`.
*
* @since 4.9.2
*
* @return void
*/
public function maybe_hijack_main_query() {
$wp_query = tribe_get_global_query_object();
if ( ! $this->should_hijack_page_template( $wp_query ) ) {
return false;
}
// Store old posts
$wp_query->tribe_hijacked_posts = $wp_query->posts;
$mocked_post = $this->get_mocked_page();
// Replace the Mocked post in a couple of places
$GLOBALS['post'] = $mocked_post;
$wp_query->posts = [ $mocked_post ];
$wp_query->post_count = count( $wp_query->posts );
// re-do counting
$wp_query->rewind_posts();
}
/**
* Restored the Hijacked posts from the main query so that we can run
* the template method properly with a fully populated WP_Query object
*
* @since 4.9.2
*
* @return void
*/
private function restore_main_query() {
$wp_query = tribe_get_global_query_object();
// If the query doesnt have hijacked posts
if ( ! isset( $wp_query->tribe_hijacked_posts ) ) {
return;
}
$wp_query->posts = $wp_query->tribe_hijacked_posts;
$wp_query->post_count = count( $wp_query->posts );
// If we have other posts besides the spoof, rewind and reset
if ( $wp_query->post_count > 0 ) {
$wp_query->rewind_posts();
wp_reset_postdata();
}
// If there are no other posts, unset the $post property
elseif ( 0 === $wp_query->post_count ) {
$wp_query->current_post = -1;
unset( $wp_query->post );
}
// Unset the Posts Prop
unset( $wp_query->tribe_hijacked_posts );
}
/**
* Prevents Looping multiple pages when including Page templates
* by modifing the global WP_Query object by pretending there are
* no posts to loop
*
* @since 4.9.2
*
* @return void
*/
private function prevent_page_looping() {
$wp_query = tribe_get_global_query_object();
$wp_query->current_post = -1;
$wp_query->post_count = 0;
}
/**
* Include our own Page template into `the_content` of their Page template
*
* @todo Integrate with Template + Context classes
*
* @since 4.9.2
*
* @param string $content Default content of the page we hijacked
*
* @return string
*/
public function filter_hijack_page_content( $content = '' ) {
remove_filter( 'the_content', [ $this, 'filter_hijack_page_content' ], 25 );
$this->restore_main_query();
$html = tribe( Template_Bootstrap::class )->get_view_html();
$this->prevent_page_looping();
return $html;
}
/**
* When using Page template we need to specifically hijack the WordPress templating
* system at a specific point after `loop_start`.
*
* @since 4.9.2
*
* @param \WP_Query $query WordPress query executed to get here.
*
* @return boolean
*/
public function should_hijack_page_template( \WP_Query $query ) {
$should_hijack = true;
// Dont hijack non-page event based
if ( 'page' !== tribe( Template_Bootstrap::class )->get_template_setting() ) {
$should_hijack = false;
}
// We dont want the main Query
if ( ! $query->is_main_query() ) {
$should_hijack = false;
}
// We wont hijack in case we are not dealing with a Post Type query
if ( ! in_array( TEC::POSTTYPE, (array) $query->get( 'post_type' ) ) ) {
$should_hijack = false;
}
/**
* Allows third-party to influence when we will hijack the page template
*
* @since 4.9.2
*
* @param boolean $should_hijack Will we hijack and include our page template
* @param WP_Query $query WordPress query excuted to get here
*/
return apply_filters( 'tribe_events_views_v2_should_hijack_page_template', $should_hijack, $query );
}
/**
* Object to allow the Bootstrap to manipulate page Requests and avoid 404s when
* no events are available by default.
*
* @since 4.9.2
*
* @return object A Mocked stdClass that mimicks a WP_Post
*/
protected function get_mocked_page() {
$page = [
'ID' => 0,
'post_status' => 'publish',
'post_author' => 0,
'post_parent' => 0,
'post_type' => 'page',
'post_date' => 0,
'post_date_gmt' => 0,
'post_modified' => 0,
'post_modified_gmt' => 0,
'post_content' => '',
'post_title' => '',
'post_excerpt' => '',
'post_content_filtered' => '',
'post_mime_type' => '',
'post_password' => '',
'post_name' => '',
'guid' => '',
'menu_order' => 0,
'pinged' => '',
'to_ping' => '',
'ping_status' => '',
'comment_status' => 'closed',
'comment_count' => 0,
];
return (object) $page;
}
}