File "Front_Page_View.php"
Full Path: /home/romayxjt/public_html/wp-content/plugins/the-events-calendar/src/Tribe/Front_Page_View.php
File size: 10.81 KB
MIME-type: text/x-php
Charset: utf-8
<?php
/**
* Provides an option to position the main events view on the site homepage.
*/
class Tribe__Events__Front_Page_View {
/**
* The ID used to identify the virtual page, using a -10 for no particular reason, but avoiding -1 as is regular
* used as infinite or any other popular reference.
*
* @since 4.6.15
*
* @var int
*/
private $home_virtual_ID = -10;
public function hook() {
// Prevent breaking changing on sites with the old implementation
add_action( 'admin_init', [ $this, 'backwards_compatible' ] );
// Allow to set negative numbers on the homepage.
add_action( 'sanitize_option_show_on_front', [ $this, 'save_show_on_front' ], 10, 3 );
add_action( 'sanitize_option_page_on_front', [ $this, 'save_page_on_front' ], 10, 3 );
// Insert the main Events page on the Customizer and Reading settings option
add_filter( 'wp_dropdown_pages', [ $this, 'add_events_page_option' ], 10, 3 );
if ( tribe_get_option( 'front_page_event_archive', false ) ) {
// Implement front page view
add_action( 'parse_query', [ $this, 'parse_query' ], 5 );
add_filter( 'tribe_events_get_link', [ $this, 'main_event_page_links' ] );
add_filter( 'pre_option_page_on_front', [ $this, 'hydrate_virtual_page_cache' ] );
}
add_action( 'parse_query', [ $this, 'parse_customizer_query' ] );
}
/**
* Inspect and possibly adapt the main query in order to force the main events page to the
* front of the house.
*
* @param WP_Query $query
*/
public function parse_query( WP_Query $query ) {
if ( $this->is_virtual_page_id( $query->get( 'page_id' ) ) ) {
$query->is_home = true;
}
// We're only interested in the main query (when it runs in relation to the site homepage),
// we also need to make an exception for compatibility with Community Events (WP_Route)
if (
! $query->is_main_query()
|| ! $query->is_home()
|| $query->is_posts_page
|| $query->get( 'WP_Route' )
) {
return;
}
// We don't need this to run again after this point
remove_action( 'parse_query', [ $this, 'parse_query' ], 5 );
// Let's set the relevant flags in order to cause the main events page to show
$query->set( 'page_id', 0 );
$query->set( 'post_type', Tribe__Events__Main::POSTTYPE );
$query->set( 'eventDisplay', 'default' );
$query->set( 'tribe_events_front_page', true );
// Some extra tricks required to help avoid problems when the default view is list view
$query->is_page = false;
$query->is_singular = false;
$query->query['post_type'] = Tribe__Events__Main::POSTTYPE;
}
/**
* Parse the query when the customizer sends request to preview specific page to avoid 404 pages
* or the wrong page.
*
* @since 4.6.15
*
* @param WP_Query $query
*/
public function parse_customizer_query( $query ) {
$data = tribe_get_request_var( 'customized', [] );
if ( empty( $data ) ) {
return;
}
$data = json_decode( wp_unslash( $data ), true );
$does_not_have_data = empty( $data['show_on_front'] ) && empty( $data['page_on_front'] );
if ( ! $query->is_main_query() || $does_not_have_data ) {
return;
}
// Fallback to the data that is missing with the current settings
$data = wp_parse_args( $data, [
'show_on_front' => get_option( 'show_on_front' ),
'page_on_front' => get_option( 'page_on_front' ),
] );
if ( 'posts' === $data['show_on_front'] ) {
$query->query_vars = wp_parse_args( $query->query_vars, [
'is_post_type_archive' => false,
'post_type' => '',
'eventDisplay' => '',
'page_id' => 0,
] );
unset( $query->query_vars['is_post_type_archive'] );
unset( $query->query_vars['post_type'] );
unset( $query->query_vars['eventDisplay'] );
unset( $query->query_vars['page_id'] );
if ( ! empty ( $query->query['page_id'] ) ) {
unset( $query->query['page_id'] );
}
$query->is_singular = false;
$query->is_page = false;
$query->is_home = true;
} elseif ( 'page' === $data['show_on_front'] && $this->is_virtual_page_id( $data['page_on_front'] ) ) {
$query->is_404 = false;
$query->is_home = true;
$query->set( 'page_id', 0 );
$query->set( 'post_type', Tribe__Events__Main::POSTTYPE );
$query->set( 'eventDisplay', 'default' );
$query->set( 'tribe_events_front_page', true );
$query->is_page = false;
$query->is_singular = false;
}
}
/**
* Where TEC generates a link to the nominal main events page replace it with a link to the
* front page instead.
*
* We'll only do this if pretty permalinks are in use.
*
* @param string $url
*
* @return string
*/
public function main_event_page_links( $url ) {
// Capture the main events URL and break it into its constituent pieces for future comparison.
static $event_url;
if ( ! isset( $event_url ) ) {
$event_url = parse_url( $this->get_main_events_url() );
}
// Don't interfere if we're using ugly permalinks
if ( '' === get_option( 'permalink_structure' ) ) {
return $url;
}
// Break apart the requested URL.
$current = parse_url( $url );
// If the URLs can't be inspected then bail
if ( false === $event_url || false === $current ) {
return $url;
}
// If this is not a request for the main events URL, bail
if ( $event_url['path'] !== $current['path'] || $event_url['host'] !== $current['host'] ) {
return $url;
}
// Reform the query
$query = ! empty( $current['query'] ) ? '?' . $current['query'] : '';
return home_url() . $query;
}
/**
* Supplies the nominal main events page URL (ie, the regular /events/ page that is used
* when front page event view is not enabled).
*
* @return string
*/
protected function get_main_events_url() {
$events_slug = tribe_get_option( 'eventsSlug', 'events' );
if ( false !== strpos( get_option( 'permalink_structure' ), 'index.php' ) ) {
return trailingslashit( home_url() . '/index.php/' . sanitize_title( $events_slug ) );
} else {
return trailingslashit( home_url() . '/' . sanitize_title( $events_slug ) );
}
}
/**
* Return the $original_value to avoid convert to a positive integer if the $original_value is the same as
* the ID of the virtual page.
*
* @since 4.6.15
*
* @param $value
* @param $option
* @param $original_value
*
* @return mixed
*/
public function save_page_on_front( $value, $option, $original_value ) {
$is_front_page_event_archive = $this->is_virtual_page_id( $original_value );
tribe_update_option( 'front_page_event_archive', $is_front_page_event_archive );
return $is_front_page_event_archive ? $original_value : $value;
}
/**
* Add "Main Events Page" option to the Customizer's "Homepage Settings" and the reading settings of the admin
*
* @since 4.6.15
*
* @param string $output HTML output for drop down list of pages.
* @param array $args The parsed arguments array.
* @param array $pages List of WP_Post objects returned by `get_pages()`
*
* @return string
*/
public function add_events_page_option( $output, $args, $pages ) {
// Ensures we only modify the Homepage dropdown.
$valid_names = [ '_customize-dropdown-pages-page_on_front', 'page_on_front' ];
if ( ! isset( $args['name'] ) || ! in_array( $args['name'], $valid_names ) ) {
return $output;
}
$this->hydrate_virtual_page_cache();
$label = sprintf(
esc_html_x( 'Main %s Page', 'Customizer static front page setting', 'the-events-calendar' ),
tribe_get_event_label_plural()
);
$selected = $this->is_page_on_front() ? 'selected' : '';
$option = '<option class="level-0" value="' . $this->get_virtual_id() . '" ' . $selected . '>' . $label . '</option></select>';
return str_replace( '</select>', $option, $output );
}
/**
* Reset the values for:
*
* - page_on_front
* - page_for_posts
* - front_page_event_archive
*
* if only the value for show_on_front is changed.
*
* @since 4.6.15
*
* @param $value
*
* @return mixed
*/
public function save_show_on_front( $value ) {
if ( $value === 'posts' && ! doing_action( 'wp_initialize_site' ) ) {
update_option( 'page_on_front', 0 );
update_option( 'page_for_posts', 0 );
}
if ( $value === 'posts' ) {
tribe_update_option( 'front_page_event_archive', false );
} elseif ( 'page' === $value && $this->is_virtual_page_on_front() ) {
tribe_update_option( 'front_page_event_archive', true );
}
return $value;
}
/**
* Make sure to set the correct values if we need to update old versions using the previous logic.
*
* @since 4.6.15
* @return boolean
*/
public function backwards_compatible() {
$modified = false;
if ( $this->is_page_on_front() ) {
return $modified;
}
// If the archive option is false we don't need to update anything
if ( $this->has_event_archive_option() && 'posts' === get_option( 'show_on_front' ) ) {
update_option( 'show_on_front', 'page' );
$modified = update_option( 'page_on_front', $this->get_virtual_id() );
}
return $modified;
}
/**
* Returns `true` if the 'front_page_event_archive' is `true` and the `page_on_front` is same as the virtual page ID
*
* @since 4.6.15
*
* @return bool
*/
public function is_page_on_front() {
return $this->has_event_archive_option() && $this->is_virtual_page_on_front();
}
/**
* Returns `true` if the `front_page_event_archive` is `true` otherwise `false`
*
* @since 4.6.15
*
* @return bool
*/
public function has_event_archive_option() {
return tribe_get_option( 'front_page_event_archive', false );
}
/**
* Compares the value of the setting `page_on_front` is same as the one used for the virtual page ID.
*
* @since 4.6.15
*
* @return bool
*/
public function is_virtual_page_on_front() {
return $this->is_virtual_page_id( get_option( 'page_on_front' ) );
}
/**
* Compare a value with the value used on the virtual page ID and converts the var $compare to an integer
* to make sure the strict comparison is done correctly between two integers.
*
* @since 4.6.15
*
* @param $compare
*
* @return bool
*/
public function is_virtual_page_id( $compare ) {
return $this->get_virtual_id() === (int) $compare;
}
/**
* Return the ID of the virtual page.
*
* @since 4.6.15
*
* @return int
*/
public function get_virtual_id() {
return $this->home_virtual_ID;
}
/**
* Hydrates the post cache for the post that should represent the virtual page.
*
* @since 6.0.6
*
* @param mixed|null $input The first input of the method, when used as a filter.
*
* @return mixed|null The first input of the method, when used as a filter, unmodified.
*/
public function hydrate_virtual_page_cache( $input = null ) {
if ( wp_cache_get( $this->home_virtual_ID, 'posts' ) instanceof WP_Post ) {
return $input;
}
// Since the page is a virtual one, do not set the post ID, it will be set to `0` by default.
wp_cache_set( $this->home_virtual_ID, new WP_Post( (object) [ 'post_type' => 'page' ] ), 'posts' );
return $input;
}
}