├── testfile123
├── index.php
├── admin
├── index.php
├── class-foyer-admin-slide-format-iframe.php
├── class-foyer-admin-slide-format-production.php
├── class-foyer-admin-slide-background-image.php
├── class-foyer-admin-slide-format-text.php
├── class-foyer-admin-slide-format-upcoming-productions.php
├── class-foyer-admin-slide-format-post.php
├── class-foyer-admin-preview.php
├── class-foyer-admin-slide-format-recent-posts.php
├── class-foyer-admin-slide-background-video.php
├── class-foyer-admin-slide-background-html5-video.php
├── class-foyer-admin.php
├── class-foyer-admin-slide-format-pdf.php
├── class-foyer-admin-slide.php
└── class-foyer-admin-display.php
├── public
├── index.php
├── assets
│ └── manifest.json
├── templates
│ ├── slides
│ │ ├── backgrounds
│ │ │ ├── default.php
│ │ │ ├── default-upcoming-productions.php
│ │ │ ├── image.php
│ │ │ ├── default-production.php
│ │ │ ├── html5-video.php
│ │ │ └── video.php
│ │ ├── default.php
│ │ ├── iframe.php
│ │ ├── production.php
│ │ ├── pdf.php
│ │ ├── text.php
│ │ ├── upcoming-productions.php
│ │ ├── post.php
│ │ └── recent-posts.php
│ ├── partials
│ │ ├── slide.php
│ │ └── channel.php
│ ├── single-channel.php
│ ├── single-slide.php
│ ├── single-display.php
│ └── preview.php
├── class-foyer-public.php
├── class-foyer-templates.php
├── js
│ └── foyer-public-min.js
└── css
│ └── foyer-public.css
├── includes
├── index.php
├── class-foyer-addons.php
├── class-foyer-theater.php
├── class-foyer-channels.php
├── class-foyer-deactivator.php
├── class-foyer-activator.php
├── class-foyer-displays.php
├── class-foyer-i18n.php
├── class-foyer-setup.php
├── class-foyer-slide-backgrounds.php
├── class-foyer-image-editor-imagick.php
├── class-foyer-channel.php
├── class-foyer-display.php
├── class-foyer.php
├── class-foyer-updater.php
├── class-foyer-slides.php
├── class-foyer-slide.php
└── class-foyer-slide-formats.php
├── .gitattributes
├── uninstall.php
└── foyer.php
/testfile123:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | default_background( $template_args );
12 |
--------------------------------------------------------------------------------
/public/templates/partials/slide.php:
--------------------------------------------------------------------------------
1 | get_format().'.php');
12 |
--------------------------------------------------------------------------------
/public/templates/single-channel.php:
--------------------------------------------------------------------------------
1 |
9 |
12 | >
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/public/templates/single-slide.php:
--------------------------------------------------------------------------------
1 |
10 |
13 | >
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/public/templates/slides/default.php:
--------------------------------------------------------------------------------
1 | classes(); ?>data_attr();?>>
12 |
13 |
14 | background(); ?>
15 |
--------------------------------------------------------------------------------
/public/templates/slides/iframe.php:
--------------------------------------------------------------------------------
1 | ID, 'slide_iframe_website_url', true ) );
10 |
11 | ?>classes(); ?>data_attr();?>>
12 |
13 |
14 |
15 | background(); ?>
16 |
--------------------------------------------------------------------------------
/includes/class-foyer-addons.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class Foyer_Addons {
13 |
14 | /**
15 | * Triggers the 'foyer_loaded' action so add-ons can initialize.
16 | *
17 | * @since 1.7.2
18 | *
19 | * @return void
20 | */
21 | static function trigger_foyer_loaded() {
22 | do_action( 'foyer_loaded' );
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/public/templates/slides/backgrounds/default-upcoming-productions.php:
--------------------------------------------------------------------------------
1 | thumbnail() ) {
11 |
12 | ?>background_classes(); ?>background_data_attr();?>>
13 |
14 |
15 |
16 |
get_active_channel() );
12 |
13 | ?>
14 |
17 |
18 | >classes(); ?>>ID );
22 | setup_postdata( $post );
23 |
24 | Foyer_Templates::get_template('partials/channel.php');
25 |
26 | wp_reset_postdata();
27 | ?>
32 |
33 |
--------------------------------------------------------------------------------
/public/templates/slides/backgrounds/image.php:
--------------------------------------------------------------------------------
1 | ID, 'slide_bg_image_image', true );
13 |
14 | if ( ! empty( $attachment_id ) ) {
15 |
16 | ?>background_classes(); ?>background_data_attr();?>>
17 |
18 |
19 |
20 |
classes(); ?>>
15 |
get_slides() as $slide ) {
18 |
19 | $post = get_post( $slide->ID );
20 | setup_postdata( $post );
21 |
22 | Foyer_Templates::get_template('partials/slide.php');
23 |
24 | wp_reset_postdata();
25 | }
26 |
27 | ?>
28 |
--------------------------------------------------------------------------------
/includes/class-foyer-theater.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | class Foyer_Theater {
15 |
16 | /**
17 | * Checks if the Theater for Wordpress plugin is activated.
18 | *
19 | * @since 1.0.0
20 | * @since 1.1.0 Changed method to static.
21 | *
22 | * @return bool
23 | */
24 | static function is_theater_activated() {
25 | return class_exists( 'WP_Theatre' );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/includes/class-foyer-channels.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class Foyer_Channels {
13 |
14 | /**
15 | * Gets all channel posts.
16 | *
17 | * @since 1.4.0
18 | *
19 | * @param array $args Additional args for get_posts().
20 | * @return array of WP_Post The channel posts.
21 | */
22 | static function get_posts( $args = array() ) {
23 | $defaults = array(
24 | 'post_type' => Foyer_Channel::post_type_name,
25 | 'posts_per_page' => -1,
26 | );
27 |
28 | $args = wp_parse_args( $args, $defaults );
29 |
30 | return get_posts( $args );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/public/templates/slides/backgrounds/default-production.php:
--------------------------------------------------------------------------------
1 | ID, 'slide_production_production_id', true );
13 | $production = new WPT_Production( $production_id );
14 |
15 | if ( ! empty( $production) && $production_attachment_id = $production->thumbnail() ) {
16 |
17 | ?>background_classes(); ?>background_data_attr();?>>
18 |
19 |
20 |
21 |
10 | */
11 | class Foyer_Deactivator {
12 |
13 | /**
14 | * Does some housekeeping at plugin deactivation.
15 | *
16 | * Fired during plugin deactivation. Though when network activated only for the primary site.
17 | *
18 | * @since 1.0.0
19 | * @since 1.5.3 Flushes the rewrite rules to make sure our rewrite rules are removed.
20 | *
21 | * @return void
22 | */
23 | public static function deactivate() {
24 |
25 | // Our custom post types are not registered at this point
26 | // Re-building rewrite rules, excluding those for our custom post types
27 | flush_rewrite_rules();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/includes/class-foyer-activator.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | class Foyer_Activator {
12 |
13 | /**
14 | * Does some housekeeping at plugin activation.
15 | *
16 | * Fired during plugin activation. Though when network activated only for the primary site.
17 | *
18 | * @since 1.0.0
19 | * @since 1.5.3 Flushes the rewrite rules to make sure pretty permalinks for our custom post types
20 | * work properly after plugin is activated. Fixes #19 for new installs.
21 | *
22 | * @return void
23 | */
24 | public static function activate() {
25 |
26 | // Make sure our custom post types are registered
27 | Foyer_Setup::register_post_types();
28 |
29 | // Re-build rewrite rules, including those for our custom post types
30 | flush_rewrite_rules();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/public/templates/slides/production.php:
--------------------------------------------------------------------------------
1 | ID, 'slide_production_production_id', true );
14 | $production = new WPT_Production( $production_id );
15 |
16 | ?>classes(); ?>data_attr();?>>
17 |
18 |
19 |
20 |
title(); ?>
21 |
dates_html(); ?>
22 |
23 |
24 |
25 | background(); ?>
26 |
--------------------------------------------------------------------------------
/public/templates/slides/pdf.php:
--------------------------------------------------------------------------------
1 | classes(); ?>data_attr();?>>
25 |
26 |
31 |
32 | background(); ?>
33 |
11 | */
12 | class Foyer_Displays {
13 |
14 | /**
15 | * Gets all display posts.
16 | *
17 | * @since 1.4.0
18 | *
19 | * @param array $args Additional args for get_posts().
20 | * @return array of WP_Post The display posts.
21 | */
22 | static function get_posts( $args = array() ) {
23 | $defaults = array(
24 | 'post_type' => Foyer_Display::post_type_name,
25 | 'posts_per_page' => -1,
26 | );
27 |
28 | $args = wp_parse_args( $args, $defaults );
29 |
30 | return get_posts( $args );
31 | }
32 |
33 | /**
34 | * Adds a request for each display to be reset.
35 | *
36 | * @return void
37 | */
38 | static function reset_all_displays() {
39 | $display_posts = self::get_posts();
40 |
41 | foreach ( $display_posts as $display_post ) {
42 | $display = new Foyer_Display( $display_post );
43 | $display->add_reset_request();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/public/templates/preview.php:
--------------------------------------------------------------------------------
1 |
9 |
12 |
13 | >
22 | $orientation_name ) {
24 | ?>
31 |
32 |
--------------------------------------------------------------------------------
/uninstall.php:
--------------------------------------------------------------------------------
1 | ID, 'slide_bg_html5_video_video_url', true );
11 | $video_start = get_post_meta( $slide->ID, 'slide_bg_html5_video_video_start', true );
12 | $video_end = get_post_meta( $slide->ID, 'slide_bg_html5_video_video_end', true );
13 | $hold_slide = get_post_meta( $slide->ID, 'slide_bg_html5_video_hold_slide', true );
14 | $enable_sound = get_post_meta( $slide->ID, 'slide_bg_html5_video_enable_sound', true );
15 |
16 | if ( ! empty( $video_url ) ) {
17 |
18 | ?>background_classes(); ?>background_data_attr();?>>
19 |
25 |
26 |
27 |
28 |
29 |
20 | */
21 | class Foyer_i18n {
22 |
23 | /**
24 | * Load the plugin text domain for translation.
25 | *
26 | * @since 1.0.0
27 | * @since 1.3.2 Changed method to static.
28 | */
29 | static function load_plugin_textdomain() {
30 |
31 | load_plugin_textdomain(
32 | 'foyer',
33 | false,
34 | dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/'
35 | );
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/public/templates/slides/backgrounds/video.php:
--------------------------------------------------------------------------------
1 | ID, 'slide_bg_video_video_url', true );
13 | $video_start = get_post_meta( $slide->ID, 'slide_bg_video_video_start', true );
14 | $video_end = get_post_meta( $slide->ID, 'slide_bg_video_video_end', true );
15 | $hold_slide = get_post_meta( $slide->ID, 'slide_bg_video_hold_slide', true );
16 | $enable_sound = get_post_meta( $slide->ID, 'slide_bg_video_enable_sound', true );
17 |
18 | // URL is saved in format https://youtu.be/r9tbusKyvMY
19 | // We need the ID, the last bit
20 | $video_id = substr( $video_url, strrpos( $video_url, '/' ) + 1 );
21 |
22 | if ( ! empty( $video_id ) ) {
23 |
24 | ?>background_classes(); ?>background_data_attr();?>>
25 |
32 |
ID, 'slide_text_pretitle', true );
11 | $slide_text_title = get_post_meta( $slide->ID, 'slide_text_title', true );
12 | $slide_text_subtitle = get_post_meta( $slide->ID, 'slide_text_subtitle', true );
13 | $slide_text_content = get_post_meta( $slide->ID, 'slide_text_content', true );
14 |
15 | ?>classes(); ?>data_attr(); ?>>
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | background(); ?>
33 |
--------------------------------------------------------------------------------
/public/templates/slides/upcoming-productions.php:
--------------------------------------------------------------------------------
1 | ID, 'slide_upcoming_productions_limit', true ) );
14 | $categories = get_post_meta( $slide->ID, 'slide_upcoming_productions_categories', true );
15 |
16 | // Prepare categories for Theater productions query
17 | if ( empty( $categories ) ) {
18 | $categories = array();
19 | }
20 | else {
21 | $categories = array_map( 'intval', $categories );
22 | }
23 |
24 | $production_args = array(
25 | 'end_after' => 'now',
26 | 'cat' => implode( ',', $categories ),
27 | 'limit' => $limit,
28 | 'context' => 'foyer_slide_upcoming_productions',
29 | );
30 |
31 | foreach ( $wp_theatre->productions->get( $production_args ) as $production ) {
32 |
33 | ?>classes(); ?>data_attr();?>>
34 |
35 |
36 |
title(); ?>
37 |
dates_html(); ?>
38 |
39 |
$production );
42 | $slide->background( $background_args );
43 |
44 | ?>
ID, 'slide_post_post_id', true );
12 | $slide_post = get_post( $slide_post_id );
13 |
14 | $slide_post_display_thumbnail = get_post_meta( $slide->ID, 'slide_post_display_thumbnail', true );
15 | $slide_post_use_excerpt = get_post_meta( $slide->ID, 'slide_post_use_excerpt', true );
16 |
17 | if ( ! empty( $slide_post_use_excerpt ) ) {
18 | $content = apply_filters( 'the_content', $slide_post->post_excerpt );
19 | }
20 | else {
21 | $content = apply_filters( 'the_content', $slide_post->post_content );
22 | }
23 |
24 | ?>classes(); ?>data_attr(); ?>>
25 |
26 | ID ) ) { ?>
27 | ID ) ) { ?>
28 |
29 |
30 |
31 |
32 |
33 |
ID ); ?>
34 |
ID ); ?>
35 |
36 |
37 |
38 |
39 |
40 |
41 | background(); ?>
42 |
--------------------------------------------------------------------------------
/admin/class-foyer-admin-slide-format-iframe.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class Foyer_Admin_Slide_Format_Iframe {
13 |
14 | /**
15 | * Saves additional data for the Iframe slide format.
16 | *
17 | * @since 1.3.0
18 | *
19 | * @param int $post_id The ID of the post being saved.
20 | * @return void
21 | */
22 | static function save_slide( $post_id ) {
23 | $slide_iframe_website_url = sanitize_text_field( $_POST['slide_iframe_website_url'] );
24 | update_post_meta( $post_id, 'slide_iframe_website_url', $slide_iframe_website_url );
25 | }
26 |
27 | /**
28 | * Outputs the meta box for the Iframe slide format.
29 | *
30 | * @since 1.3.0
31 | *
32 | * @param WP_Post $post The post of the current slide.
33 | * @return void
34 | */
35 | static function slide_meta_box( $post ) {
36 | $slide_iframe_website_url = get_post_meta( $post->ID, 'slide_iframe_website_url', true );
37 |
38 | $https = ( 0 === stripos( 'https://', get_permalink() ) );
39 | $placeholder = __( 'https://...', 'foyer' );
40 |
41 | ?>ID, 'slide_recent_posts_limit', true ) );
11 | $slide_recent_posts_categories = get_post_meta( $slide->ID, 'slide_recent_posts_categories', true );
12 |
13 | $slide_recent_posts_display_thumbnail = get_post_meta( $slide->ID, 'slide_recent_posts_display_thumbnail', true );
14 | $slide_recent_posts_use_excerpt = get_post_meta( $slide->ID, 'slide_recent_posts_use_excerpt', true );
15 |
16 | // Prepare categories and limit for get_posts() query
17 | $post_args = array();
18 |
19 | if ( ! empty( $slide_recent_posts_categories ) ) {
20 | $post_args['category__in'] = array_map( 'intval', $slide_recent_posts_categories );
21 | }
22 |
23 | if ( ! empty( $slide_recent_posts_limit ) ) {
24 | $post_args['posts_per_page'] = $slide_recent_posts_limit;
25 | }
26 | else {
27 | $post_args['nopaging'] = true;
28 | }
29 |
30 | foreach ( get_posts( $post_args ) as $slide_post ) {
31 |
32 | if ( ! empty( $slide_recent_posts_use_excerpt ) ) {
33 | $content = apply_filters( 'the_content', $slide_post->post_excerpt );
34 | }
35 | else {
36 | $content = apply_filters( 'the_content', $slide_post->post_content );
37 | }
38 |
39 | ?>classes(); ?>data_attr(); ?>>
40 |
41 | ID ) ) { ?>
42 | ID ) ) { ?>
43 |
44 |
45 |
46 |
47 |
48 |
ID ); ?>
49 |
ID ); ?>
50 |
51 |
52 |
53 |
54 |
55 |
56 | background(); ?>
57 |
11 | */
12 | class Foyer_Admin_Slide_Format_Production {
13 |
14 | /**
15 | * Saves additional data for the Production slide format.
16 | *
17 | * @since 1.0.0
18 | * @since 1.0.1 Improved validating & sanitizing of the user input.
19 | * @since 1.1.0 Moved here from Foyer_Theater, and changed to static.
20 | * @since 1.4.0 Removed saving of slide_production_image since background images are now handled by slide backgrounds.
21 | *
22 | * @param int $post_id The ID of the post being saved.
23 | * @return void
24 | */
25 | static function save_slide_production( $post_id ) {
26 | $slide_production_production_id = intval( $_POST['slide_production_production_id'] );
27 | if ( empty( $slide_production_production_id ) ) {
28 | $slide_production_production_id = '';
29 | }
30 |
31 | update_post_meta( $post_id, 'slide_production_production_id', $slide_production_production_id );
32 | }
33 |
34 | /**
35 | * Outputs the meta box for the Production slide format.
36 | *
37 | * @since 1.0.0
38 | * @since 1.0.1 Escaped & sanitized the output.
39 | * @since 1.1.0 Moved here from Foyer_Theater, and changed to static.
40 | * @since 1.2.6 Changed the displayed name from Production to Event, same terminology as in Theater for WordPress.
41 | * @since 1.3.1 Fixed two labels that pointed to a non-existent field slide_default_subtitle, via for.
42 | * @since 1.4.0 Removed the slide_production_image admin field since background images are now handled by slide backgrounds.
43 | *
44 | * @param WP_Post $post The post of the current slide.
45 | * @return void
46 | */
47 | static function slide_production_meta_box( $post ) {
48 |
49 | global $wp_theatre;
50 |
51 | ?>
13 | */
14 | class Foyer_Admin_Slide_Background_Image {
15 |
16 | /**
17 | * Saves the additional data of the Image slide background.
18 | *
19 | * @since 1.4.0
20 | *
21 | * @param int $post_id The Post ID of the slide being saved.
22 | * @return void
23 | */
24 | static function save_slide_background( $post_id ) {
25 | $slide_bg_image_image = intval( $_POST['slide_bg_image_image'] );
26 | if ( empty( $slide_bg_image_image ) ) {
27 | $slide_bg_image_image = '';
28 | }
29 |
30 | update_post_meta( $post_id, 'slide_bg_image_image', $slide_bg_image_image );
31 | }
32 |
33 | /**
34 | * Outputs the meta box for the Image slide background.
35 | *
36 | * @since 1.4.0
37 | * @since 1.5.2 Added a hint about minimal image sizes.
38 | * Removed the height attribute of the preview image, sizing is now done with CSS.
39 | * @since 1.6.0 Renamed everything slide_image_* to slide_file_*, and 'Upload image' to 'Select image'.
40 | *
41 | * @param WP_Post $post The post of the slide that is being edited.
42 | * @return void
43 | */
44 | static function slide_background_meta_box( $post ) {
45 |
46 | wp_enqueue_media();
47 |
48 | $slide_bg_image_image = get_post_meta( $post->ID, 'slide_bg_image_image', true );
49 |
50 | ?>
12 | */
13 | class Foyer_Setup {
14 |
15 | /**
16 | * Registers the custom post type for slides and channels.
17 | *
18 | * @since 1.0.0
19 | * @since 1.3.2 Changed method to static.
20 | *
21 | * @return void
22 | */
23 | static function register_post_types() {
24 |
25 | register_post_type( Foyer_Display::post_type_name,
26 | array(
27 | 'labels' => array(
28 | 'name' => _x( 'Displays', 'display cpt', 'foyer' ),
29 | 'singular_name' => _x( 'Display', 'display cpt', 'foyer'),
30 | 'add_new' => _x( 'Add New', 'display cpt', 'foyer'),
31 | 'new_item' => _x( 'New display', 'display cpt', 'foyer' ),
32 | 'view_item' => _x( 'View display', 'display cpt', 'foyer' ),
33 | 'add_new_item' => _x( 'Add new display', 'display cpt', 'foyer' ),
34 | 'edit_item' => _x( 'Edit display', 'display cpt', 'foyer' ),
35 | ),
36 | 'public' => true,
37 | 'has_archive' => false,
38 | 'show_in_menu' => 'foyer',
39 | 'show_in_admin_bar' => true,
40 | 'supports' => array( 'title' ),
41 | 'taxonomies' => array(),
42 | 'rewrite' => array( 'slug' => 'foyer' ),
43 | )
44 | );
45 |
46 | register_post_type( Foyer_Channel::post_type_name,
47 | array(
48 | 'labels' => array(
49 | 'name' => _x( 'Channels', 'channel cpt', 'foyer' ),
50 | 'singular_name' => _x( 'Channel', 'channel cpt', 'foyer'),
51 | 'add_new' => _x( 'Add New', 'channel cpt', 'foyer'),
52 | 'new_item' => _x( 'New channel', 'channel cpt', 'foyer' ),
53 | 'view_item' => _x( 'View channel', 'channel cpt', 'foyer' ),
54 | 'add_new_item' => _x( 'Add new channel', 'channel cpt', 'foyer' ),
55 | 'edit_item' => _x( 'Edit channel', 'channel cpt', 'foyer' ),
56 | ),
57 | 'public' => true,
58 | 'has_archive' => false,
59 | 'show_in_menu' => 'foyer',
60 | 'show_in_admin_bar' => true,
61 | 'supports' => array( 'title' ),
62 | 'taxonomies' => array(),
63 | 'rewrite' => false,
64 | )
65 | );
66 |
67 | register_post_type( Foyer_Slide::post_type_name,
68 | array(
69 | 'labels' => array(
70 | 'name' => _x( 'Slides', 'slide cpt', 'foyer' ),
71 | 'singular_name' => _x( 'Slide', 'slide cpt', 'foyer' ),
72 | 'add_new' => _x( 'Add New', 'slide cpt', 'foyer'),
73 | 'new_item' => _x( 'New slide', 'slide cpt', 'foyer' ),
74 | 'view_item' => _x( 'View slide', 'slide cpt', 'foyer' ),
75 | 'add_new_item' => _x( 'Add new slide', 'slide cpt', 'foyer' ),
76 | 'edit_item' => _x( 'Edit slide', 'slide cpt', 'foyer' ),
77 | ),
78 | 'public' => true,
79 | 'has_archive' => false,
80 | 'show_in_menu' => 'foyer',
81 | 'show_in_admin_bar' => true,
82 | 'supports' => array( 'title' ),
83 | 'taxonomies' => array(),
84 | 'rewrite' => false,
85 | )
86 | );
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/includes/class-foyer-slide-backgrounds.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class Foyer_Slide_Backgrounds {
13 |
14 | /**
15 | * Adds the Default slide background.
16 | *
17 | * @since 1.4.0
18 | *
19 | * @param array $slide_backgrounds The current slide backgrounds.
20 | * @return array The slide backgrounds with the Default slide background added.
21 | */
22 | static function add_default_slide_background( $slide_backgrounds ) {
23 |
24 | $slide_backgrounds['default'] = array(
25 | 'title' => _x( 'Default / none', 'slide-background', 'foyer' ),
26 | 'description' => __( 'Displays the default background for the chosen slide format, if any, or no background.', 'foyer' ),
27 | );
28 | return $slide_backgrounds;
29 | }
30 |
31 | /**
32 | * Adds the HTML5 Video slide background.
33 | *
34 | * @since 1.6.0
35 | *
36 | * @param array $slide_backgrounds The current slide backgrounds.
37 | * @return array The slide backgrounds with the HTML5 Video slide background added.
38 | */
39 | static function add_html5_video_slide_background( $slide_backgrounds ) {
40 |
41 | $slide_backgrounds['html5-video'] = array(
42 | 'title' => _x( 'Video', 'slide-background', 'foyer' ),
43 | 'meta_box' => array( 'Foyer_Admin_Slide_Background_Html5_Video', 'slide_background_meta_box' ),
44 | 'save_post' => array( 'Foyer_Admin_Slide_Background_Html5_Video', 'save_slide_background' ),
45 | );
46 | return $slide_backgrounds;
47 | }
48 |
49 | /**
50 | * Adds the Image slide background.
51 | *
52 | * @since 1.4.0
53 | *
54 | * @param array $slide_backgrounds The current slide backgrounds.
55 | * @return array The slide backgrounds with the Image slide background added.
56 | */
57 | static function add_image_slide_background( $slide_backgrounds ) {
58 |
59 | $slide_backgrounds['image'] = array(
60 | 'title' => _x( 'Image', 'slide-background', 'foyer' ),
61 | 'meta_box' => array( 'Foyer_Admin_Slide_Background_Image', 'slide_background_meta_box' ),
62 | 'save_post' => array( 'Foyer_Admin_Slide_Background_Image', 'save_slide_background' ),
63 | );
64 | return $slide_backgrounds;
65 | }
66 |
67 | /**
68 | * Adds the YouTube Video slide background.
69 | *
70 | * @since 1.4.0
71 | * @since 1.6.0 Renamed the slide background from 'Video' to 'YouTube', without changing internal names.
72 | *
73 | * @param array $slide_backgrounds The current slide backgrounds.
74 | * @return array The slide backgrounds with the YouTube Video slide background added.
75 | */
76 | static function add_video_slide_background( $slide_backgrounds ) {
77 |
78 | $slide_backgrounds['video'] = array(
79 | 'title' => _x( 'YouTube', 'slide-background', 'foyer' ),
80 | 'meta_box' => array( 'Foyer_Admin_Slide_Background_Video', 'slide_background_meta_box' ),
81 | 'save_post' => array( 'Foyer_Admin_Slide_Background_Video', 'save_slide_background' ),
82 | );
83 | return $slide_backgrounds;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/includes/class-foyer-image-editor-imagick.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class Foyer_Image_Editor_Imagick extends WP_Image_Editor_Imagick {
11 |
12 | /**
13 | * Get the number of pages in the pdf file.
14 | *
15 | * @since 1.1.0
16 | *
17 | * @return int|WP_Error Number of pages or WP_Error on failure.
18 | */
19 | public function pdf_get_number_of_pages() {
20 |
21 | try {
22 | $number_of_pages = $this->image->getNumberImages();
23 | }
24 | catch ( Exception $e ) {
25 | return new WP_Error( 'invalid_image', __( 'Could not read number of pages in image.' ), $this->file );
26 | }
27 |
28 | return $number_of_pages;
29 | }
30 |
31 | /**
32 | * Prepares a specific page so it can be loaded.
33 | *
34 | * Stores the page number to be used on load().
35 | * Ddestroys the previously used Imagick object and resets the file pointer to enable loading of a new page.
36 | *
37 | * @since 1.1.0
38 | *
39 | * @param int $page_number The number of the page to prepare for loading.
40 | * @return void
41 | */
42 | public function pdf_prepare_page_for_load( $page_number ) {
43 |
44 | // Destroy Imagick object, otherwise load() would not load a new page but just return the existing object.
45 | if ( $this->image instanceof Imagick ) {
46 | $this->image->clear();
47 | $this->image->destroy();
48 | $this->image = null;
49 | }
50 |
51 | // Restore to initial clean file path without page specifier, otherwise load() would fail because file not found.
52 | $this->file = $this->pdf_file;
53 |
54 | // Store page number to be used on load().
55 | $this->pdf_page_number = $page_number;
56 | }
57 | /**
58 | * Sets up Imagick for PDF processing.
59 | *
60 | * Overrides WP_Image_Editor_Imagick default PDF setup, since WP 4.7, to allow for loading of individual pages in PDF files.
61 | *
62 | * @since 1.1.0
63 | * @since 1.3.1 Changed access to public, to allow invoking PDF setup on WP < 4.7.
64 | *
65 | * @return string|WP_Error File to load or WP_Error on failure.
66 | */
67 | public function pdf_setup() {
68 |
69 | try {
70 | // By default, PDFs are rendered in 72 DPI.
71 | // This will generate an output file that has the same width and height in pixels as the PDF input.
72 | $this->image->setResolution( 72, 72 );
73 |
74 | // Store the clean file path without page specifier, for later use.
75 | if ( ! isset( $this->pdf_file ) ) {
76 | $this->pdf_file = $this->file;
77 | }
78 |
79 | // If no page number is set, assume the entire PDF should be loaded.
80 | if ( ! isset( $this->pdf_page_number ) ) {
81 | $this->pdf_page_number = 0;
82 | return $this->pdf_file;
83 | }
84 |
85 | // Add page specifier to file path, to load this specific page.
86 | return $this->pdf_file . '[' . $this->pdf_page_number . ']';
87 | }
88 | catch ( Exception $e ) {
89 | return new WP_Error( 'pdf_setup_failed', $e->getMessage(), $this->file );
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/admin/class-foyer-admin-slide-format-text.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class Foyer_Admin_Slide_Format_Text {
13 |
14 | /**
15 | * Saves additional data for the Text slide format.
16 | *
17 | * @since 1.5.0
18 | *
19 | * @param int $post_id The ID of the post being saved.
20 | * @return void
21 | */
22 | static function save_slide( $post_id ) {
23 | $slide_text_pretitle = sanitize_text_field( $_POST['slide_text_pretitle'] );
24 | $slide_text_title = sanitize_text_field( $_POST['slide_text_title'] );
25 | $slide_text_subtitle = sanitize_text_field( $_POST['slide_text_subtitle'] );
26 | $slide_text_content = wp_kses_post( $_POST['slide_text_content'] );
27 |
28 | update_post_meta( $post_id, 'slide_text_pretitle', $slide_text_pretitle );
29 | update_post_meta( $post_id, 'slide_text_title', $slide_text_title );
30 | update_post_meta( $post_id, 'slide_text_subtitle', $slide_text_subtitle );
31 | update_post_meta( $post_id, 'slide_text_content', $slide_text_content );
32 | }
33 |
34 | /**
35 | * Outputs the meta box for the Text slide format.
36 | *
37 | * @since 1.5.0
38 | *
39 | * @param WP_Post $post The post of the current slide.
40 | * @return void
41 | */
42 | static function slide_meta_box( $post ) {
43 | $slide_text_pretitle = get_post_meta( $post->ID, 'slide_text_pretitle', true );
44 | $slide_text_title = get_post_meta( $post->ID, 'slide_text_title', true );
45 | $slide_text_subtitle = get_post_meta( $post->ID, 'slide_text_subtitle', true );
46 | $slide_text_content = get_post_meta( $post->ID, 'slide_text_content', true );
47 |
48 | ?>
11 | */
12 | class Foyer_Admin_Slide_Format_Upcoming_Productions {
13 |
14 | /**
15 | * Saves additional data for the Upcoming Productions slide format.
16 | *
17 | * @since 1.7.0
18 | *
19 | * @param int $post_id The ID of the post being saved.
20 | * @return void
21 | */
22 | static function save_slide( $post_id ) {
23 | $slide_upcoming_productions_limit = intval( $_POST['slide_upcoming_productions_limit'] );
24 | if ( empty( $slide_upcoming_productions_limit ) ) {
25 | $slide_upcoming_productions_limit = '';
26 | }
27 |
28 | $slide_upcoming_productions_categories = '';
29 | if (
30 | ! empty( $_POST['slide_upcoming_productions_categories'] ) &&
31 | ! empty( $_POST['slide_upcoming_productions_categories'][0] )
32 | ) {
33 | $slide_upcoming_productions_categories = array_map( 'intval', $_POST['slide_upcoming_productions_categories'] );
34 | }
35 |
36 | update_post_meta( $post_id, 'slide_upcoming_productions_limit', $slide_upcoming_productions_limit );
37 | update_post_meta( $post_id, 'slide_upcoming_productions_categories', $slide_upcoming_productions_categories );
38 | }
39 |
40 | /**
41 | * Outputs the meta box for the Upcoming Productions slide format.
42 | *
43 | * @since 1.7.0
44 | *
45 | * @param WP_Post $post The post of the current slide.
46 | * @return void
47 | */
48 | static function slide_meta_box( $post ) {
49 |
50 | $slide_upcoming_productions_limit = intval( get_post_meta( $post->ID, 'slide_upcoming_productions_limit', true ) );
51 |
52 | $slide_upcoming_productions_categories = get_post_meta( $post->ID, 'slide_upcoming_productions_categories', true );
53 | if ( empty( $slide_upcoming_productions_categories ) ) {
54 | $slide_upcoming_productions_categories = array();
55 | }
56 |
57 | ?>
11 | */
12 | class Foyer_Admin_Slide_Format_Post {
13 |
14 | /**
15 | * Saves additional data for the Post slide format.
16 | *
17 | * @since 1.5.0
18 | *
19 | * @param int $post_id The ID of the post being saved.
20 | * @return void
21 | */
22 | static function save_slide( $post_id ) {
23 | $slide_post_post_id = intval( $_POST['slide_post_post_id'] );
24 | if ( empty( $slide_post_post_id ) ) {
25 | $slide_post_post_id = '';
26 | }
27 |
28 | $slide_post_display_thumbnail = '';
29 | if ( isset( $_POST['slide_post_display_thumbnail'] ) ) {
30 | $slide_post_display_thumbnail = intval( $_POST['slide_post_display_thumbnail'] );
31 | if ( empty( $slide_post_display_thumbnail ) ) {
32 | $slide_post_display_thumbnail = '';
33 | }
34 | }
35 |
36 | $slide_post_use_excerpt = '';
37 | if ( isset( $_POST['slide_post_use_excerpt'] ) ) {
38 | $slide_post_use_excerpt = intval( $_POST['slide_post_use_excerpt'] );
39 | if ( empty( $slide_post_use_excerpt ) ) {
40 | $slide_post_use_excerpt = '';
41 | }
42 | }
43 |
44 | update_post_meta( $post_id, 'slide_post_post_id', $slide_post_post_id );
45 | update_post_meta( $post_id, 'slide_post_display_thumbnail', $slide_post_display_thumbnail );
46 | update_post_meta( $post_id, 'slide_post_use_excerpt', $slide_post_use_excerpt );
47 | }
48 |
49 | /**
50 | * Outputs the meta box for the Post slide format.
51 | *
52 | * @since 1.5.0
53 | *
54 | * @param WP_Post $post The post of the current slide.
55 | * @return void
56 | */
57 | static function slide_meta_box( $post ) {
58 |
59 | $args = array(
60 | 'post_type' => 'post',
61 | 'posts_per_page' => -1,
62 | );
63 | $posts = get_posts( $args );
64 |
65 | $slide_post_display_thumbnail = get_post_meta( $post->ID, 'slide_post_display_thumbnail', true );
66 | $slide_post_use_excerpt = get_post_meta( $post->ID, 'slide_post_use_excerpt', true );
67 |
68 | ?>
12 | */
13 | class Foyer_Admin_Preview {
14 |
15 | /**
16 | * Enqueues the admin javascript when previewing a slide.
17 | *
18 | * @since 1.0.0
19 | * @since 1.2.5 Register scripts before they are enqueued.
20 | * Makes it possible to enqueue foyer scripts outside of the foyer plugin.
21 | * @since 1.3.2 Changed method to static.
22 | *
23 | * return void
24 | */
25 | static function enqueue_scripts() {
26 |
27 | wp_register_script( Foyer::get_plugin_name() . '-admin', plugin_dir_url( __FILE__ ) . 'js/foyer-admin-min.js', array( 'jquery', 'jquery-ui-sortable' ), Foyer::get_version(), false );
28 |
29 | wp_localize_script( Foyer::get_plugin_name() . '-admin', 'foyer_preview', array(
30 | 'ajax_url' => admin_url( 'admin-ajax.php' ),
31 | 'object_id' => get_the_id(),
32 | 'orientations' => self::get_orientations(),
33 | ) );
34 |
35 | if ( ! is_user_logged_in() ) {
36 | return;
37 | }
38 |
39 | if ( ! empty( $_GET['foyer-preview'] ) ) {
40 | return;
41 | }
42 |
43 | if ( ! is_singular( array( Foyer_Display::post_type_name, Foyer_Channel::post_type_name, Foyer_Slide::post_type_name) ) ) {
44 | return;
45 | }
46 |
47 | wp_enqueue_script( Foyer::get_plugin_name() . '-admin' );
48 | }
49 |
50 | /**
51 | * Get the current user's orientation choice for a Display, Channel or Slide.
52 | *
53 | * @since 1.0.0
54 | * @param int $object_id
55 | * @return string
56 | */
57 | static function get_orientation_choice( $object_id ) {
58 |
59 | $default_orientation_choice = '16-9';
60 |
61 | if ( !is_user_logged_in( ) ) {
62 | return $default_orientation_choice;
63 | }
64 |
65 | $orientation_choices = get_user_meta( get_current_user_id( ), 'foyer_preview_orientation_choices', true );
66 |
67 | if ( empty( $orientation_choices[ $object_id ] ) ) {
68 | return $default_orientation_choice;
69 | }
70 |
71 | return $orientation_choices[ $object_id ];
72 | }
73 |
74 | /**
75 | * Gets all available preview orientations.
76 | *
77 | * @since 1.0.0
78 | * @return array
79 | */
80 | static function get_orientations() {
81 |
82 | $orientations = array(
83 | '16-9' => __( 'Landscape', 'foyer' ),
84 | '9-16' => __( 'Portrait', 'foyer' ),
85 | );
86 |
87 | return $orientations;
88 | }
89 |
90 | /**
91 | * Hides the admin bar when a Display, Channel of Slides is shown inside a preview iframe.
92 | *
93 | * @since 1.0.0
94 | * @return bool
95 | */
96 | static function hide_admin_bar( $show_admin_bar ) {
97 |
98 | // Leave alone if admin bar is already hidden.
99 | if ( !$show_admin_bar ) {
100 | return $show_admin_bar;
101 | }
102 |
103 | // Don't hide if not inside preview iframe.
104 | if ( empty( $_GET['foyer-preview'] ) ) {
105 | return true;
106 | }
107 |
108 | // Don't hide if not viewing a Display, Channel of Slide.
109 | if (!is_singular( array( Foyer_Display::post_type_name, Foyer_Channel::post_type_name, Foyer_Slide::post_type_name) ) ) {
110 | return true;
111 | }
112 |
113 | return false;
114 | }
115 |
116 | /**
117 | * Save a user's orientation choice for a Display, Channel of Slide.
118 | *
119 | * Hooked to orientation button via AJAX.
120 | *
121 | * @since 1.0.0
122 | * @since 1.0.1 Improved validating & sanitizing of the user input.
123 | * @since 1.3.2 Changed method to static.
124 | *
125 | * @return void
126 | */
127 | static function save_orientation_choice( ) {
128 |
129 | if ( !is_user_logged_in( ) ) {
130 | return;
131 | }
132 |
133 | $orientation = sanitize_title( $_POST[ 'orientation' ] );
134 | if ( empty( $orientation ) ) {
135 | return;
136 | }
137 |
138 | $object_id = intval( $_POST[ 'object_id' ] );
139 | if ( empty( $object_id ) ) {
140 | return;
141 | }
142 |
143 | $orientation_choices = get_user_meta( get_current_user_id( ), 'foyer_preview_orientation_choices', true );
144 |
145 | if (empty( $orientation_choices )) {
146 | $orientation_choices = array();
147 | }
148 |
149 | $orientation_choices[ $object_id ] = $orientation;
150 |
151 | update_user_meta( get_current_user_id( ), 'foyer_preview_orientation_choices', $orientation_choices );
152 |
153 | wp_die();
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/admin/class-foyer-admin-slide-format-recent-posts.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class Foyer_Admin_Slide_Format_Recent_Posts {
13 |
14 | /**
15 | * Saves additional data for the Recent Posts slide format.
16 | *
17 | * @since 1.7.1
18 | *
19 | * @param int $post_id The ID of the post being saved.
20 | * @return void
21 | */
22 | static function save_slide( $post_id ) {
23 | $slide_recent_posts_limit = intval( $_POST['slide_recent_posts_limit'] );
24 | if ( empty( $slide_recent_posts_limit ) ) {
25 | $slide_recent_posts_limit = '';
26 | }
27 |
28 | $slide_recent_posts_categories = '';
29 | if (
30 | ! empty( $_POST['slide_recent_posts_categories'] ) &&
31 | ! empty( $_POST['slide_recent_posts_categories'][0] )
32 | ) {
33 | $slide_recent_posts_categories = array_map( 'intval', $_POST['slide_recent_posts_categories'] );
34 | }
35 |
36 | $slide_recent_posts_display_thumbnail = '';
37 | if ( isset( $_POST['slide_recent_posts_display_thumbnail'] ) ) {
38 | $slide_recent_posts_display_thumbnail = intval( $_POST['slide_recent_posts_display_thumbnail'] );
39 | if ( empty( $slide_recent_posts_display_thumbnail ) ) {
40 | $slide_recent_posts_display_thumbnail = '';
41 | }
42 | }
43 |
44 | $slide_recent_posts_use_excerpt = '';
45 | if ( isset( $_POST['slide_recent_posts_use_excerpt'] ) ) {
46 | $slide_recent_posts_use_excerpt = intval( $_POST['slide_recent_posts_use_excerpt'] );
47 | if ( empty( $slide_recent_posts_use_excerpt ) ) {
48 | $slide_recent_posts_use_excerpt = '';
49 | }
50 | }
51 |
52 | update_post_meta( $post_id, 'slide_recent_posts_limit', $slide_recent_posts_limit );
53 | update_post_meta( $post_id, 'slide_recent_posts_categories', $slide_recent_posts_categories );
54 | update_post_meta( $post_id, 'slide_recent_posts_display_thumbnail', $slide_recent_posts_display_thumbnail );
55 | update_post_meta( $post_id, 'slide_recent_posts_use_excerpt', $slide_recent_posts_use_excerpt );
56 | }
57 |
58 | /**
59 | * Outputs the meta box for the Recent Posts slide format.
60 | *
61 | * @since 1.7.1
62 | *
63 | * @param WP_Post $post The post of the current slide.
64 | * @return void
65 | */
66 | static function slide_meta_box( $post ) {
67 |
68 | $slide_recent_posts_limit = intval( get_post_meta( $post->ID, 'slide_recent_posts_limit', true ) );
69 |
70 | $slide_recent_posts_categories = get_post_meta( $post->ID, 'slide_recent_posts_categories', true );
71 | if ( empty( $slide_recent_posts_categories ) ) {
72 | $slide_recent_posts_categories = array();
73 | }
74 |
75 | $slide_recent_posts_display_thumbnail = get_post_meta( $post->ID, 'slide_recent_posts_display_thumbnail', true );
76 | $slide_recent_posts_use_excerpt = get_post_meta( $post->ID, 'slide_recent_posts_use_excerpt', true );
77 |
78 | ?>
11 | */
12 | class Foyer_Channel {
13 |
14 | /**
15 | * The Foyer Channel post type name.
16 | *
17 | * @since 1.0.0
18 | * @access private
19 | * @var string $post_type_name The Foyer Channel post type name.
20 | */
21 | const post_type_name = 'foyer_channel';
22 |
23 | public $ID;
24 | private $post;
25 |
26 | /**
27 | * The slides of this channel.
28 | *
29 | * @since 1.0.0
30 | * @access private
31 | * @var string $slides The slides of this channel.
32 | */
33 | private $slides;
34 |
35 | /**
36 | * The slides duration setting of this channel.
37 | *
38 | * @since 1.0.0
39 | * @access private
40 | * @var string $slides The slides duration setting of this channel.
41 | */
42 | private $slides_duration;
43 |
44 | /**
45 | * The slides transition setting of this channel.
46 | *
47 | * @since 1.0.0
48 | * @access private
49 | * @var string $slides The slides transition setting of this channel.
50 | */
51 | private $slides_transition;
52 |
53 | /**
54 | * Initialize the class and set its properties.
55 | *
56 | * @since 1.0.0
57 | * @param int or WP_Post $ID The id or the WP_Post object of the channel.
58 | */
59 | public function __construct( $ID = false ) {
60 |
61 | if ( $ID instanceof WP_Post ) {
62 | // $ID is a WP_Post object
63 | $this->post = $ID;
64 | $ID = $ID->ID;
65 | }
66 |
67 | $this->ID = $ID;
68 | }
69 |
70 | /**
71 | * Outputs the channel classes for use in the template.
72 | *
73 | * The output is escaped, so this method can be used in templates without further escaping.
74 | *
75 | * @since 1.0.1 Escaped the output.
76 | *
77 | * @param array $classes
78 | * @return string
79 | */
80 | public function classes( $classes = array() ) {
81 |
82 | $classes[] = 'foyer-channel';
83 | $classes[] = 'foyer-channel-' . intval( $this->ID );
84 | $classes[] = 'foyer-transition-' . $this->get_slides_transition();
85 |
86 | if ( empty( $classes ) ) {
87 | return;
88 | }
89 |
90 | ?> class="" slides ) ) {
105 |
106 | $slides = array();
107 |
108 | $posts = get_post_meta( $this->ID, Foyer_Slide::post_type_name, true );
109 |
110 | if ( ! empty( $posts ) ) {
111 | foreach ( $posts as $post ) {
112 |
113 | // Only include slides with post status 'publish'
114 | if ( 'publish' != get_post_status( $post ) ) {
115 | continue;
116 | }
117 |
118 | $slide = new Foyer_Slide( $post );
119 | $slides[] = $slide;
120 | }
121 | }
122 |
123 | $this->slides = $slides;
124 | }
125 |
126 | return $this->slides;
127 | }
128 |
129 | /**
130 | * Get slides duration setting for this channel as saved in the database.
131 | *
132 | * @since 1.0.0
133 | * @access public
134 | * @return string The slides duration setting for this channel as saved in the database.
135 | */
136 | public function get_saved_slides_duration() {
137 | return get_post_meta( $this->ID, Foyer_Channel::post_type_name . '_slides_duration', true );
138 | }
139 |
140 | /**
141 | * Get slides transition setting for this channel as saved in the database.
142 | *
143 | * @since 1.0.0
144 | * @access public
145 | * @return string The slides transition setting for this channel as saved in the database.
146 | */
147 | public function get_saved_slides_transition() {
148 | return get_post_meta( $this->ID, Foyer_Channel::post_type_name . '_slides_transition', true );
149 | }
150 |
151 | /**
152 | * Get slides duration setting for this channel, or the default slides duration when not set.
153 | *
154 | * @since 1.0.0
155 | * @access public
156 | * @return string The slides duration setting for this channel, or the default slides duration when not set.
157 | */
158 | public function get_slides_duration() {
159 |
160 | if ( ! isset( $this->slides_duration ) ) {
161 |
162 | $slides_duration = self::get_saved_slides_duration();
163 | if ( empty( $slides_duration ) ) {
164 | $slides_duration = Foyer_Slides::get_default_slides_duration();
165 | }
166 | $this->slides_duration = $slides_duration;
167 | }
168 |
169 | return $this->slides_duration;
170 | }
171 |
172 | /**
173 | * Get slides transition setting for this channel, or the default slides transition when not set.
174 | *
175 | * @since 1.0.0
176 | * @access public
177 | * @return string The slides transition setting for this channel, or the default slides transition when not set.
178 | */
179 | public function get_slides_transition() {
180 |
181 | if ( ! isset( $this->slides_transition ) ) {
182 |
183 | $slides_transition = self::get_saved_slides_transition();
184 | if ( empty( $slides_transition ) ) {
185 | $slides_transition = Foyer_Slides::get_default_slides_transition();
186 | }
187 | $this->slides_transition = $slides_transition;
188 | }
189 |
190 | return $this->slides_transition;
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/public/class-foyer-public.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | class Foyer_Public {
16 |
17 | /**
18 | * Loads dependencies and registers hooks for the public-facing side of the plugin.
19 | *
20 | * @since 1.3.2
21 | * @since 1.5.4 Added a wp_head action to add the Web App manifest to displays.
22 | */
23 | static function init() {
24 | self::load_dependencies();
25 |
26 | /* Foyer_Public */
27 | add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_styles' ) );
28 | add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
29 | add_action( 'init', array( __CLASS__, 'add_image_sizes' ) );
30 | add_action( 'wp_head', array( __CLASS__, 'add_web_app_manifest' ) );
31 |
32 | /* Foyer_Templates */
33 | add_action( 'template_include', array( 'Foyer_Templates', 'template_include' ) );
34 | }
35 |
36 | /**
37 | * Adds image sizes used throughout the front-end of the plugin.
38 | *
39 | * See https://en.wikipedia.org/wiki/Display_resolution for a list of display resolutions and their names.
40 | *
41 | * @since 1.0.0
42 | * @since 1.3.2 Changed method to static.
43 | * @since 1.5.2 Moved away from hard cropped images, instead introduced the soft cropped 'foyer' image size,
44 | * ready for responsive images and higher resolutions.
45 | *
46 | * @return void
47 | */
48 | static function add_image_sizes() {
49 |
50 | /*
51 | * To be used in templates.
52 | */
53 | add_image_size( 'foyer', 1920, 1920, false ); // to be set to the same dimensions as the largest internal image size
54 |
55 | /*
56 | * Internal image sizes, to force cropping of different intermediate sizes.
57 | */
58 | add_image_size( 'foyer_fhd', 1920, 1920, false ); // soft crop: scaled down to fit within 1920x1920 (Full HD)
59 | // add_image_size( 'foyer_4kuhd', 3840, 3840, false ); // soft crop: scaled down to fit within 3840x3840 (4K Ultra HD)
60 | // 4K UHD is disabled for now.
61 |
62 | /*
63 | * @deprecated 1.5.2
64 | * Use 'foyer' instead.
65 | */
66 | add_image_size( 'foyer_fhd_square', 1920, 1920, true ); // hard cropped to 1920x1920
67 | }
68 |
69 |
70 | /**
71 | * Adds the Web App manifest to the head of Foyer displays.
72 | *
73 | * Only for users that are not logged in.
74 | *
75 | * @since 1.5.4
76 | *
77 | * @return void
78 | */
79 | static function add_web_app_manifest() {
80 | if ( ! is_singular( Foyer_Display::post_type_name ) ) {
81 | return;
82 | }
83 |
84 | if ( is_user_logged_in() ) {
85 | return;
86 | }
87 |
88 | ?>
11 | */
12 | class Foyer_Display {
13 |
14 | /**
15 | * The Foyer Display post type name.
16 | *
17 | * @since 1.0.0
18 | * @access private
19 | * @var string $post_type_name The Foyer Display post type name.
20 | */
21 | const post_type_name = 'foyer_display';
22 |
23 | public $ID;
24 | private $post;
25 |
26 | /**
27 | * The currently active channel of this display.
28 | *
29 | * @since 1.0.0
30 | * @access private
31 | * @var string $channel The currently active channel of this display.
32 | */
33 | private $active_channel;
34 |
35 | /**
36 | * The default channel of this display.
37 | *
38 | * @since 1.0.0
39 | * @access private
40 | * @var string $channel The default channel of this display.
41 | */
42 | private $default_channel;
43 |
44 | /**
45 | * Initialize the class and set its properties.
46 | *
47 | * @since 1.0.0
48 | * @param int or WP_Post $ID The id or the WP_Post object of the display.
49 | */
50 | public function __construct( $ID = false ) {
51 |
52 | if ( $ID instanceof WP_Post ) {
53 | // $ID is a WP_Post object
54 | $this->post = $ID;
55 | $ID = $ID->ID;
56 | }
57 |
58 | $this->ID = $ID;
59 | }
60 |
61 | /**
62 | * Adds a request for the display to be reset.
63 | *
64 | * @since 1.4.0
65 | *
66 | * @return void
67 | */
68 | public function add_reset_request() {
69 | update_post_meta( $this->ID, 'foyer_reset_display', 1 );
70 | }
71 |
72 | /**
73 | * Outputs the display classes for use in the template.
74 | *
75 | * The output is escaped, so this method can be used in templates without further escaping.
76 | *
77 | * @since 1.4.0
78 | *
79 | * @param array $classes
80 | * @return void
81 | */
82 | public function classes( $classes = array() ) {
83 |
84 | $classes[] = 'foyer-display';
85 |
86 | if ( $this->is_reset_requested() && empty( $_GET['foyer-preview'] ) ) {
87 | // Reset is requested and we are not previewing, add class to invoke reset
88 | $classes[] = 'foyer-reset-display';
89 |
90 | // Display will be reset, delete reset request
91 | $this->delete_reset_request();
92 | }
93 |
94 | if ( empty( $classes ) ) {
95 | return;
96 | }
97 |
98 | ?> class="" ID, 'foyer_reset_display' );
110 | }
111 |
112 | /**
113 | * Get the currently active channel for this display.
114 | *
115 | * @since 1.0.0
116 | * @since 1.3.2 Only uses a schedule if the schedule's channel is set and published.
117 | *
118 | * @access public
119 | * @return Foyer_Channel The currently active channel for this display.
120 | */
121 | public function get_active_channel() {
122 |
123 | if ( ! isset( $this->active_channel ) ) {
124 |
125 | $active_channel = $this->get_default_channel();
126 |
127 | $this->active_channel = $active_channel;
128 |
129 | /**
130 | * Check if a temporary channel is scheduled.
131 | */
132 | $schedule = $this->get_schedule();
133 |
134 | // Nothing scheduled at all. Return the default channel.
135 | if ( empty( $schedule ) ) {
136 | return $this->active_channel;
137 | }
138 |
139 | // Return the first scheduled channel that matches the current time, has a channel set, and channel is published.
140 | foreach ( $schedule as $scheduled_channel ) {
141 |
142 | if ( $scheduled_channel['start'] > time() ) {
143 | continue;
144 | }
145 |
146 | if ( $scheduled_channel['end'] < time() ) {
147 | continue;
148 | }
149 |
150 | if ( empty( $scheduled_channel['channel'] ) ) {
151 | continue;
152 | }
153 |
154 | // Only use channel with post status 'publish'
155 | if ( 'publish' != get_post_status( $scheduled_channel['channel'] ) ) {
156 | continue;
157 | }
158 |
159 | $this->active_channel = $scheduled_channel['channel'];
160 |
161 | }
162 | }
163 |
164 | return $this->active_channel;
165 | }
166 |
167 |
168 | /**
169 | * Get the default channel for this display.
170 | *
171 | * @since 1.0.0
172 | * @since 1.3.2 Only returns a channel if it is published.
173 | *
174 | * @access public
175 | * @return Foyer_Channel The default channel for this display.
176 | */
177 | public function get_default_channel() {
178 |
179 | if ( ! isset( $this->default_channel ) ) {
180 |
181 | $default_channel = get_post_meta( $this->ID, Foyer_Channel::post_type_name, true );
182 |
183 | // Only use channel with post status 'publish'
184 | if ( 'publish' != get_post_status( $default_channel ) ) {
185 | $this->default_channel = false;
186 | }
187 | else {
188 | $this->default_channel = $default_channel;
189 | }
190 | }
191 |
192 | return $this->default_channel;
193 | }
194 |
195 | /**
196 | * Gets all scheduled channels for this display.
197 | *
198 | * @since 1.0.0
199 | * @return array|string All scheduled channels or an empty string if no channels are scheduled.
200 | */
201 | public function get_schedule() {
202 | $schedule = array();
203 |
204 | $schedule = get_post_meta( $this->ID, 'foyer_display_schedule', false );
205 |
206 | return $schedule;
207 | }
208 |
209 | /**
210 | * Checks if a reset is requested for this display.
211 | *
212 | * @since 1.4.0
213 | *
214 | * @return bool True if reset is requested for this display, false otherwise.
215 | */
216 | private function is_reset_requested() {
217 | return (bool) get_post_meta( $this->ID, 'foyer_reset_display', true );
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/admin/class-foyer-admin-slide-background-video.php:
--------------------------------------------------------------------------------
1 |
13 | */
14 | class Foyer_Admin_Slide_Background_Video {
15 |
16 | /**
17 | * Saves additional data for the Video slide background.
18 | *
19 | * Functionality was copied from Foyer_Admin_Slide_Format_Video (removed).
20 | *
21 | * @since 1.4.0
22 | * @since 1.5.1 Added saving of the slide_bg_video_enable_sound option.
23 | *
24 | * @param int $post_id The ID of the post being saved.
25 | * @return void
26 | */
27 | static function save_slide_background( $post_id ) {
28 | $slide_bg_video_video_url = sanitize_text_field( $_POST['slide_bg_video_video_url'] );
29 |
30 | $slide_bg_video_video_start = intval( $_POST['slide_bg_video_video_start'] );
31 | if ( empty( $slide_bg_video_video_start ) ) {
32 | $slide_bg_video_video_start = '';
33 | }
34 |
35 | $slide_bg_video_video_end = intval( $_POST['slide_bg_video_video_end'] );
36 | if ( empty( $slide_bg_video_video_end ) ) {
37 | $slide_bg_video_video_end = '';
38 | }
39 |
40 | $slide_bg_video_hold_slide = '';
41 | if ( isset( $_POST['slide_bg_video_hold_slide'] ) ) {
42 | $slide_bg_video_hold_slide = intval( $_POST['slide_bg_video_hold_slide'] );
43 | if ( empty( $slide_bg_video_hold_slide ) ) {
44 | $slide_bg_video_hold_slide = '';
45 | }
46 | }
47 |
48 | $slide_bg_video_enable_sound = '';
49 | if ( isset( $_POST['slide_bg_video_enable_sound'] ) ) {
50 | $slide_bg_video_enable_sound = intval( $_POST['slide_bg_video_enable_sound'] );
51 | if ( empty( $slide_bg_video_enable_sound ) ) {
52 | $slide_bg_video_enable_sound = '';
53 | }
54 | }
55 |
56 | update_post_meta( $post_id, 'slide_bg_video_video_url', $slide_bg_video_video_url );
57 | update_post_meta( $post_id, 'slide_bg_video_video_start', $slide_bg_video_video_start );
58 | update_post_meta( $post_id, 'slide_bg_video_video_end', $slide_bg_video_video_end );
59 | update_post_meta( $post_id, 'slide_bg_video_hold_slide', $slide_bg_video_hold_slide );
60 | update_post_meta( $post_id, 'slide_bg_video_enable_sound', $slide_bg_video_enable_sound );
61 | }
62 |
63 | /**
64 | * Outputs the meta box for the Video slide background.
65 | *
66 | * @since 1.4.0
67 | * @since 1.5.1 Added a slide_bg_video_enable_sound option.
68 | * @since 1.6.0 Displayed the YouTube video URL input with class large-text.
69 | *
70 | * @param WP_Post $post The post of the current slide.
71 | * @return void
72 | */
73 | static function slide_background_meta_box( $post ) {
74 |
75 | $slide_bg_video_video_url = get_post_meta( $post->ID, 'slide_bg_video_video_url', true );
76 | $slide_bg_video_video_start = get_post_meta( $post->ID, 'slide_bg_video_video_start', true );
77 | $slide_bg_video_video_end = get_post_meta( $post->ID, 'slide_bg_video_video_end', true );
78 | $slide_bg_video_hold_slide = get_post_meta( $post->ID, 'slide_bg_video_hold_slide', true );
79 | $slide_bg_video_enable_sound = get_post_meta( $post->ID, 'slide_bg_video_enable_sound', true );
80 |
81 | ?>
11 | */
12 | class Foyer_Templates {
13 |
14 | /**
15 | * Gets a template.
16 | *
17 | * Search for the template and include the file.
18 | *
19 | * Inspired by https://jeroensormani.com/how-to-add-template-files-in-your-plugin/
20 | *
21 | * @since 1.0.0
22 | * @since 1.5.7 Renamed the overly generic $args to $template_args so it can be re-used within templates.
23 | *
24 | * @param string $template_name Template to load.
25 | * @param array $template_args Args passed for the template file.
26 | * @param string $string $template_path Path to templates.
27 | * @param string $default_path Default path to template files.
28 | * @return void
29 | */
30 | static function get_template( $template_name, $template_args = array(), $template_path = '', $default_path = '' ) {
31 | if ( is_array( $template_args ) && isset( $template_args ) ) {
32 | extract( $template_args );
33 | }
34 | $template_file = self::locate_template( $template_name, $template_path, $default_path );
35 | if ( ! file_exists( $template_file ) ) {
36 | _doing_it_wrong( __FUNCTION__, sprintf( '%s does not exist.', $template_file ), FOYER_PLUGIN_VERSION );
37 | return false;
38 | }
39 | include $template_file;
40 | }
41 |
42 | /**
43 | * Gets all template paths registered by plugins.
44 | *
45 | * Add-ons can add their plugin template path using Foyer_Templates::register_plugin_template_path().
46 | *
47 | * @since 1.7.2
48 | *
49 | * @return array All registered plugin template paths.
50 | */
51 | static function get_plugin_template_paths() {
52 |
53 | $plugin_template_paths = array();
54 |
55 | /**
56 | * Filter the plugin template paths.
57 | *
58 | * @since 1.7.2
59 | * @param array $plugin_template_paths The currently registered plugin template paths.
60 | */
61 | $plugin_template_paths = apply_filters( 'foyer/templates/plugin_template_paths', $plugin_template_paths );
62 |
63 | return $plugin_template_paths;
64 | }
65 |
66 | /**
67 | * Locates a Foyer template.
68 | *
69 | * Search Order:
70 | * 1. /themes/theme/foyer/$template_name
71 | * 2. /$template_name.
72 | * 3. /plugins/foyer/public/templates/$template_name.
73 | *
74 | * Inspired by https://jeroensormani.com/how-to-add-template-files-in-your-plugin/
75 | *
76 | * @since 1.0.0
77 | * @since 1.7.2 Removed searching the /themes/theme/$template_name path as this is bound to cause
78 | * conflicts with generic template names.
79 | * @since 1.7.2 Added searching registered plugin template paths. This adds add-on plugin support.
80 | *
81 | * @param string $template_name Template to load.
82 | * @param string $template_path Path to templates.
83 | * @param string $default_path Default path to template files.
84 | * @return string Path to the template file.
85 | */
86 | static function locate_template( $template_name, $template_path = '', $default_path = '' ) {
87 |
88 | // Set template path to foyer folder of theme / registered plugin.
89 | if ( ! $template_path ) {
90 | $template_path = 'foyer/';
91 | }
92 | // Set default path to templates folder of Foyer plugin.
93 | if ( ! $default_path ) {
94 | $default_path = plugin_dir_path( __FILE__ ) . 'templates/'; // Path to the template folder
95 | }
96 |
97 | // 1. Search template file in active (child)theme.
98 | $template = locate_template( array(
99 | $template_path . $template_name,
100 | ) );
101 |
102 | // 2. Search template file in registered plugin template paths (if no template found in previous step).
103 | if ( ! $template && $plugin_paths = self::get_plugin_template_paths() ) {
104 | foreach ( $plugin_paths as $plugin_path ) {
105 | $full_path = trailingslashit( $plugin_path ) . $template_name;
106 | if ( file_exists( $full_path ) ) {
107 | $template = $full_path;
108 | break;
109 | }
110 | }
111 | }
112 |
113 | // 3. Fall back to template file in Foyer plugin (if no template found in previous step).
114 | if ( ! $template ) {
115 | $template = $default_path . $template_name;
116 | }
117 |
118 | return apply_filters( 'foyer/templates/template', $template, $template_name, $template_path, $default_path );
119 | }
120 |
121 | /**
122 | * Registers the template path for an add-on.
123 | *
124 | * @since 1.7.2
125 | *
126 | * @param string $template_path Path to templates for this plugin.
127 | * @return void
128 | */
129 | static function register_plugin_template_path( $template_path ) {
130 | add_filter(
131 | 'foyer/templates/plugin_template_paths',
132 | function( $plugin_template_paths ) use ( $template_path ) {
133 | $plugin_template_paths[] = $template_path;
134 | return $plugin_template_paths;
135 | },
136 | 5
137 | );
138 | }
139 |
140 | /**
141 | * Template loader.
142 | *
143 | * The template loader will check if WP is loading a template for a Foyer post type
144 | * and will try to load the template from our 'templates' directory.
145 | *
146 | * @since 1.0.0
147 | *
148 | * @param string $template Template file that is being loaded.
149 | * @return string Template file that should be loaded.
150 | */
151 | static function template_include( $template ) {
152 |
153 | $file = '';
154 |
155 | if (
156 | is_singular( array( Foyer_Slide::post_type_name, Foyer_Channel::post_type_name, Foyer_Display::post_type_name ) ) &&
157 | is_user_logged_in( ) &&
158 | empty( $_GET['foyer-preview'] )
159 | ) {
160 | // Show inside preview iframe when logged in.
161 | $file = 'preview.php';
162 | }
163 | else if ( is_singular( Foyer_Slide::post_type_name ) ) {
164 | $file = 'single-slide.php';
165 | }
166 | else if ( is_singular( Foyer_Channel::post_type_name ) ) {
167 | $file = 'single-channel.php';
168 | }
169 | else if ( is_singular( Foyer_Display::post_type_name ) ) {
170 | $file = 'single-display.php';
171 | }
172 | else {
173 | return $template;
174 | }
175 |
176 | if ( file_exists( self::locate_template( $file ) ) ) {
177 | $template = self::locate_template( $file );
178 | }
179 |
180 | return $template;
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/includes/class-foyer.php:
--------------------------------------------------------------------------------
1 |
17 | */
18 | class Foyer {
19 |
20 | /**
21 | * Initializes the plugin.
22 | *
23 | * Loads dependencies, defines the locale and registers all of the hooks related to the
24 | * general functionality of the plugin (not public/admin specific).
25 | *
26 | * @since 1.3.2 Changed method to static.
27 | * @since 1.4.0 Registered hooks for slide backgrounds.
28 | * Changed priority of slide format filters to make sure they are triggered before
29 | * filters with default priority.
30 | * @since 1.5.3 Changed priority of Foyer_Setup::register_post_types() on init to 5 to make sure it is
31 | * triggered before filters with default priority, and before the occasional flush_rewrite_rules()
32 | * after updating.
33 | * @since 1.6.0 Registered a hook that adds the HTML5 Video slide background.
34 | * @since 1.7.0 Registered a hook that adds the Upcoming Events slide format.
35 | * @since 1.7.1 Registered a hook that adds the Recent Posts slide format.
36 | * @since 1.7.2 Registered a hook to trigger the 'foyer_loaded' action that can be used by add-ons.
37 | */
38 | static function init() {
39 |
40 | self::load_dependencies();
41 |
42 | /* Foyer_Updater */
43 | add_action( 'plugins_loaded', array( 'Foyer_Updater', 'update' ) );
44 |
45 | /* Foyer_i18n */
46 | add_action( 'plugins_loaded', array( 'Foyer_i18n', 'load_plugin_textdomain' ) );
47 |
48 | /* Foyer_Addons */
49 | add_action( 'plugins_loaded', array( 'Foyer_Addons', 'trigger_foyer_loaded' ) );
50 |
51 | /* Foyer_Setup */
52 | add_action( 'init', array( 'Foyer_Setup', 'register_post_types' ), 5 );
53 |
54 | /* Foyer_Slide_Backgrounds */
55 | add_filter( 'foyer/slides/backgrounds', array( 'Foyer_Slide_Backgrounds', 'add_default_slide_background' ), 5 );
56 | add_filter( 'foyer/slides/backgrounds', array( 'Foyer_Slide_Backgrounds', 'add_image_slide_background' ), 5 );
57 | add_filter( 'foyer/slides/backgrounds', array( 'Foyer_Slide_Backgrounds', 'add_video_slide_background' ), 5 );
58 | add_filter( 'foyer/slides/backgrounds', array( 'Foyer_Slide_Backgrounds', 'add_html5_video_slide_background' ), 5 );
59 |
60 | /* Foyer_Slide_Formats */
61 | add_filter( 'foyer/slides/formats', array( 'Foyer_Slide_Formats', 'add_default_slide_format' ), 5 );
62 | add_filter( 'foyer/slides/formats', array( 'Foyer_Slide_Formats', 'add_text_slide_format' ), 5 );
63 | add_filter( 'foyer/slides/formats', array( 'Foyer_Slide_Formats', 'add_post_slide_format' ), 5 );
64 | add_filter( 'foyer/slides/formats', array( 'Foyer_Slide_Formats', 'add_production_slide_format' ), 5 );
65 | add_filter( 'foyer/slides/formats', array( 'Foyer_Slide_Formats', 'add_iframe_slide_format' ), 5 );
66 | add_filter( 'foyer/slides/formats', array( 'Foyer_Slide_Formats', 'add_recent_posts_slide_format' ), 5 );
67 | add_filter( 'foyer/slides/formats', array( 'Foyer_Slide_Formats', 'add_upcoming_productions_slide_format' ), 5 );
68 | add_filter( 'foyer/slides/formats', array( 'Foyer_Slide_Formats', 'add_pdf_slide_format' ), 5 );
69 | }
70 |
71 | /**
72 | * The name of the plugin used to uniquely identify it within the context of
73 | * WordPress and to define internationalization functionality.
74 | *
75 | * @since 1.0.0
76 | * @since 1.3.2 Changed method to static.
77 | * Now uses a named constant.
78 | *
79 | * @return string The name of the plugin.
80 | */
81 | static function get_plugin_name() {
82 | return FOYER_PLUGIN_NAME;
83 | }
84 |
85 | /**
86 | * Retrieve the version number of the plugin.
87 | *
88 | * @since 1.0.0
89 | * @since 1.3.2 Changed method to static.
90 | * Now uses a named constant.
91 | *
92 | * @return string The version of the plugin.
93 | */
94 | static function get_version() {
95 | return FOYER_PLUGIN_VERSION;
96 | }
97 |
98 | /**
99 | * Load the required dependencies for this plugin.
100 | *
101 | * Includes the following files that make up the plugin:
102 | *
103 | * - All general (not public/admin) classes.
104 | * - Foyer_Admin: Defines all functionality for the admin area and registers its hooks.
105 | * - Foyer_Public: Defines all functionality for the public side of the site and registers its hooks.
106 | *
107 | * @since 1.0.0
108 | * @since 1.3.2 Changed method to static.
109 | * @since 1.4.0 Included includes/class-foyer-slide-backgrounds.php.
110 | * Included includes/class-foyer-updater.php.
111 | * Included includes/class-foyer-displays.php.
112 | * Included includes/class-foyer-channels.php.
113 | * @since 1.7.2 Included includes/class-foyer-addons.php.
114 | *
115 | * @access private
116 | */
117 | private static function load_dependencies() {
118 |
119 | /**
120 | * ------ General (not public/admin) ------
121 | */
122 |
123 | /* Display, channel and slide models. */
124 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-display.php';
125 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-channel.php';
126 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-slide.php';
127 |
128 | /* Display, channel and slide helper functions. */
129 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-displays.php';
130 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-channels.php';
131 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-slides.php';
132 |
133 | /* Database updater. */
134 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-updater.php';
135 |
136 | /* Setup of internationalization. */
137 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-i18n.php';
138 |
139 | /* Add-ons. */
140 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-addons.php';
141 |
142 | /* General (not public/admin) setup actions. */
143 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-setup.php';
144 |
145 | /* Slide backgrounds. */
146 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-slide-backgrounds.php';
147 |
148 | /* Slide formats. */
149 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-slide-formats.php';
150 |
151 | /* Theater for WordPress helper functions. */
152 | require_once FOYER_PLUGIN_PATH . 'includes/class-foyer-theater.php';
153 |
154 |
155 | /**
156 | * ------ Admin ------
157 | */
158 |
159 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin.php';
160 | Foyer_Admin::init();
161 |
162 | /**
163 | * ------ Public ------
164 | */
165 |
166 | require_once FOYER_PLUGIN_PATH . 'public/class-foyer-public.php';
167 | Foyer_Public::init();
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/admin/class-foyer-admin-slide-background-html5-video.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class Foyer_Admin_Slide_Background_Html5_Video {
13 |
14 | /**
15 | * Saves additional data for the Video slide background.
16 | *
17 | * @since 1.6.0
18 | *
19 | * @param int $post_id The ID of the post being saved.
20 | * @return void
21 | */
22 | static function save_slide_background( $post_id ) {
23 | $slide_bg_html5_video_video = intval( $_POST['slide_bg_html5_video_video'] );
24 | if ( empty( $slide_bg_html5_video_video ) ) {
25 | $slide_bg_html5_video_video = '';
26 | }
27 |
28 | $slide_bg_html5_video_video_url = sanitize_text_field( $_POST['slide_bg_html5_video_video_url'] );
29 |
30 | $slide_bg_html5_video_video_start = intval( $_POST['slide_bg_html5_video_video_start'] );
31 | if ( empty( $slide_bg_html5_video_video_start ) ) {
32 | $slide_bg_html5_video_video_start = '';
33 | }
34 |
35 | $slide_bg_html5_video_video_end = intval( $_POST['slide_bg_html5_video_video_end'] );
36 | if ( empty( $slide_bg_html5_video_video_end ) ) {
37 | $slide_bg_html5_video_video_end = '';
38 | }
39 |
40 | $slide_bg_html5_video_hold_slide = '';
41 | if ( isset( $_POST['slide_bg_html5_video_hold_slide'] ) ) {
42 | $slide_bg_html5_video_hold_slide = intval( $_POST['slide_bg_html5_video_hold_slide'] );
43 | if ( empty( $slide_bg_html5_video_hold_slide ) ) {
44 | $slide_bg_html5_video_hold_slide = '';
45 | }
46 | }
47 |
48 | $slide_bg_html5_video_enable_sound = '';
49 | if ( isset( $_POST['slide_bg_html5_video_enable_sound'] ) ) {
50 | $slide_bg_html5_video_enable_sound = intval( $_POST['slide_bg_html5_video_enable_sound'] );
51 | if ( empty( $slide_bg_html5_video_enable_sound ) ) {
52 | $slide_bg_html5_video_enable_sound = '';
53 | }
54 | }
55 |
56 | update_post_meta( $post_id, 'slide_bg_html5_video_video', $slide_bg_html5_video_video );
57 | update_post_meta( $post_id, 'slide_bg_html5_video_video_url', $slide_bg_html5_video_video_url );
58 | update_post_meta( $post_id, 'slide_bg_html5_video_video_start', $slide_bg_html5_video_video_start );
59 | update_post_meta( $post_id, 'slide_bg_html5_video_video_end', $slide_bg_html5_video_video_end );
60 | update_post_meta( $post_id, 'slide_bg_html5_video_hold_slide', $slide_bg_html5_video_hold_slide );
61 | update_post_meta( $post_id, 'slide_bg_html5_video_enable_sound', $slide_bg_html5_video_enable_sound );
62 | }
63 |
64 | /**
65 | * Outputs the meta box for the Video slide background.
66 | *
67 | * @since 1.6.0
68 | *
69 | * @param WP_Post $post The post of the current slide.
70 | * @return void
71 | */
72 | static function slide_background_meta_box( $post ) {
73 |
74 | wp_enqueue_media();
75 |
76 | $slide_bg_html5_video_video = get_post_meta( $post->ID, 'slide_bg_html5_video_video', true );
77 | $slide_bg_html5_video_video_url = get_post_meta( $post->ID, 'slide_bg_html5_video_video_url', true );
78 | $slide_bg_html5_video_video_start = get_post_meta( $post->ID, 'slide_bg_html5_video_video_start', true );
79 | $slide_bg_html5_video_video_end = get_post_meta( $post->ID, 'slide_bg_html5_video_video_end', true );
80 | $slide_bg_html5_video_hold_slide = get_post_meta( $post->ID, 'slide_bg_html5_video_hold_slide', true );
81 | $slide_bg_html5_video_enable_sound = get_post_meta( $post->ID, 'slide_bg_html5_video_enable_sound', true );
82 |
83 | ?>
14 | */
15 | class Foyer_Admin {
16 |
17 | /**
18 | * Loads dependencies and registers hooks for the admin-facing side of the plugin.
19 | *
20 | * @since 1.3.2
21 | */
22 | static function init() {
23 | self::load_dependencies();
24 |
25 | /* Foyer_Admin */
26 | add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_styles' ) );
27 | add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
28 | add_action( 'admin_menu', array( __CLASS__, 'admin_menu' ) );
29 |
30 | /* Foyer_Admin_Display */
31 | add_action( 'admin_enqueue_scripts', array( 'Foyer_Admin_Display', 'localize_scripts' ) );
32 | add_action( 'add_meta_boxes', array( 'Foyer_Admin_Display', 'add_channel_editor_meta_box' ) );
33 | add_action( 'add_meta_boxes', array( 'Foyer_Admin_Display', 'add_channel_scheduler_meta_box' ) );
34 | add_action( 'save_post', array( 'Foyer_Admin_Display', 'save_display' ) );
35 | add_filter( 'manage_'.Foyer_Display::post_type_name.'_posts_columns', array( 'Foyer_Admin_Display', 'add_channel_columns' ) );
36 | add_action( 'manage_'.Foyer_Display::post_type_name.'_posts_custom_column', array( 'Foyer_Admin_Display', 'do_channel_columns' ), 10, 2 );
37 | /* Foyer_Admin_Channel */
38 | add_action( 'admin_enqueue_scripts', array( 'Foyer_Admin_Channel', 'localize_scripts' ) );
39 | add_action( 'add_meta_boxes', array( 'Foyer_Admin_Channel', 'add_slides_editor_meta_box' ), 20 );
40 | add_action( 'add_meta_boxes', array( 'Foyer_Admin_Channel', 'add_slides_settings_meta_box' ), 40 );
41 | add_action( 'save_post', array( 'Foyer_Admin_Channel', 'save_channel' ) );
42 | add_action( 'wp_ajax_foyer_slides_editor_add_slide', array( 'Foyer_Admin_Channel', 'add_slide_over_ajax' ) );
43 | add_action( 'wp_ajax_foyer_slides_editor_remove_slide', array( 'Foyer_Admin_Channel', 'remove_slide_over_ajax' ) );
44 | add_action( 'wp_ajax_foyer_slides_editor_reorder_slides', array( 'Foyer_Admin_Channel', 'reorder_slides_over_ajax' ) );
45 | add_filter( 'get_sample_permalink_html', array( 'Foyer_Admin_Channel', 'remove_sample_permalink' ) );
46 | add_filter( 'manage_'.Foyer_Channel::post_type_name.'_posts_columns', array( 'Foyer_Admin_Channel', 'add_slides_count_column' ) );
47 | add_action( 'manage_'.Foyer_Channel::post_type_name.'_posts_custom_column', array( 'Foyer_Admin_Channel', 'do_slides_count_column' ), 10, 2 );
48 |
49 | /* Foyer_Admin_Slide */
50 | add_action( 'admin_enqueue_scripts', array( 'Foyer_Admin_Slide', 'localize_scripts' ) );
51 | add_action( 'add_meta_boxes', array( 'Foyer_Admin_Slide', 'add_slide_editor_meta_boxes' ) );
52 | add_action( 'save_post', array( 'Foyer_Admin_Slide', 'save_slide' ) );
53 | add_filter( 'get_sample_permalink_html', array( 'Foyer_Admin_Slide', 'remove_sample_permalink' ) );
54 | add_filter( 'manage_'.Foyer_Slide::post_type_name.'_posts_columns', array( 'Foyer_Admin_Slide', 'add_slide_format_column' ) );
55 | add_action( 'manage_'.Foyer_Slide::post_type_name.'_posts_custom_column', array( 'Foyer_Admin_Slide', 'do_slide_format_column' ), 10, 2 );
56 |
57 | /* Foyer_Admin_Preview */
58 | add_action( 'wp_enqueue_scripts', array( 'Foyer_Admin_Preview', 'enqueue_scripts' ) );
59 | add_filter( 'show_admin_bar', array( 'Foyer_Admin_Preview', 'hide_admin_bar' ) );
60 | add_action( 'wp_ajax_foyer_preview_save_orientation_choice', array( 'Foyer_Admin_Preview', 'save_orientation_choice' ) );
61 | add_action( 'wp_ajax_nopriv_foyer_preview_save_orientation_choice', array( 'Foyer_Admin_Preview', 'save_orientation_choice' ) );
62 |
63 | /* Foyer_Admin_Slide_Format_PDF */
64 | add_filter( 'wp_image_editors', array( 'Foyer_Admin_Slide_Format_PDF', 'add_foyer_imagick_image_editor' ) );
65 | add_action( 'delete_attachment', array( 'Foyer_Admin_Slide_Format_PDF', 'delete_pdf_images_for_attachment' ) );
66 | add_action( 'admin_notices', array( 'Foyer_Admin_Slide_Format_PDF', 'display_admin_notice' ) );
67 | }
68 |
69 | /**
70 | * Adds the top-level Foyer admin menu item.
71 | *
72 | * @since 1.0.0
73 | * @since 1.3.2 Changed method to static.
74 | * Added context for translations.
75 | * @since 1.5.1 Improved the context of the translatable string 'Foyer' to make translation easier.
76 | */
77 | static function admin_menu() {
78 | add_menu_page(
79 | _x( 'Foyer', 'plugin name in admin menu', 'foyer' ),
80 | _x( 'Foyer', 'plugin name in admin menu', 'foyer' ),
81 | 'edit_posts',
82 | 'foyer',
83 | array(),
84 | 'dashicons-welcome-view-site',
85 | 31
86 | );
87 | }
88 |
89 | /**
90 | * Enqueues the JavaScript for the admin area.
91 | *
92 | * @since 1.0.0
93 | * @since 1.2.5 Register scripts before they are enqueued.
94 | * Makes it possible to enqueue Foyer scripts outside of the Foyer plugin.
95 | * Changed handle of script to {plugin_name}-admin.
96 | * @since 1.3.2 Changed method to static.
97 | */
98 | static function enqueue_scripts() {
99 |
100 | wp_register_script( Foyer::get_plugin_name() . '-admin', plugin_dir_url( __FILE__ ) . 'js/foyer-admin-min.js', array( 'jquery', 'jquery-ui-sortable' ), Foyer::get_version(), false );
101 | wp_enqueue_script( Foyer::get_plugin_name() . '-admin' );
102 | }
103 |
104 | /**
105 | * Enqueues the stylesheets for the admin area.
106 | *
107 | * @since 1.0.0
108 | * @since 1.3.2 Changed method to static.
109 | */
110 | static function enqueue_styles() {
111 |
112 | wp_enqueue_style( Foyer::get_plugin_name(), plugin_dir_url( __FILE__ ) . 'css/foyer-admin.css', array(), Foyer::get_version(), 'all' );
113 | }
114 |
115 | /**
116 | * Loads the required dependencies for the admin-facing side of the plugin.
117 | *
118 | * @since 1.3.2
119 | * @since 1.4.0 Included admin/class-foyer-admin-slide-background-image.php.
120 | * Included admin/class-foyer-admin-slide-background-video.php.
121 | * Removed include admin/class-foyer-admin-slide-format-video.php.
122 | * @since 1.6.0 Included the HTML5 Video slide background admin.
123 | * @since 1.7.0 Included the Upcoming Productions slide background admin.
124 | *
125 | * @access private
126 | */
127 | private static function load_dependencies() {
128 |
129 | /**
130 | * Admin area functionality for display, channel and slide.
131 | */
132 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-display.php';
133 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-channel.php';
134 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-slide.php';
135 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-preview.php';
136 |
137 | /**
138 | * Admin area functionality for specific slide backgrounds.
139 | */
140 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-slide-background-image.php';
141 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-slide-background-video.php';
142 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-slide-background-html5-video.php';
143 |
144 | /**
145 | * Admin area functionality for specific slide formats.
146 | */
147 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-slide-format-iframe.php';
148 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-slide-format-pdf.php';
149 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-slide-format-post.php';
150 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-slide-format-production.php';
151 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-slide-format-recent-posts.php';
152 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-slide-format-text.php';
153 | require_once FOYER_PLUGIN_PATH . 'admin/class-foyer-admin-slide-format-upcoming-productions.php';
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/includes/class-foyer-updater.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | class Foyer_Updater {
12 |
13 | /**
14 | * Adds an action on init that flushes the rewrite rules.
15 | *
16 | * @since 1.5.4
17 | * @since 1.5.6 Changed the callback from the non-existing method Foyer_Updater::flush_rewrite_rules()
18 | * to the WordPress core method flush_rewrite_rules(). Fixes #26.
19 | *
20 | * @return void
21 | */
22 | static function add_flush_rewrite_rules_action() {
23 |
24 | /*
25 | * Flush the rewrite rules on init, right after custom post types are registered.
26 | *
27 | * Fired on the first page load after plugin update.
28 | * When network activated fired for each site.
29 | * When network activated fired when a new site is created on the multisite network.
30 | *
31 | * When network deactivated and later network activated again this is _not_ fired.
32 | * In this situation rewrite rules could go missing for all sites other than the primary site.
33 | */
34 | add_action( 'init', 'flush_rewrite_rules', 6 );
35 | }
36 |
37 | /**
38 | * Gets the database version.
39 | *
40 | * @since 1.4.0
41 | *
42 | * @return string The plugin version string stored in the database.
43 | */
44 | static function get_db_version() {
45 | return get_option( 'foyer_plugin_version' );
46 | }
47 |
48 | /**
49 | * Renames a meta_key for a post.
50 | *
51 | * @since 1.4.0
52 | *
53 | * @param WP_Post $post The post to rename the meta_key for.
54 | * @param string $old_key The meta_key to rename.
55 | * @param string $new_key The new name for the meta_key.
56 | * @return bool False if meta_key does not exist or value is empty, true otherwise.
57 | */
58 | static function rename_meta_key_for_post( $post, $old_key, $new_key ) {
59 |
60 | $value = get_post_meta( $post->ID, $old_key, true );
61 |
62 | if ( empty( $value ) ) {
63 | // Post meta does not exist or contains an empty string, delete just to be sure
64 | delete_post_meta( $post->ID, $old_key, $value );
65 | return false;
66 | }
67 |
68 | update_post_meta( $post->ID, $new_key, $value );
69 | delete_post_meta( $post->ID, $old_key, $value );
70 |
71 | return true;
72 | }
73 |
74 | /**
75 | * Resets all displays for certain updates.
76 | *
77 | * @since 1.5.4
78 | * @since 1.5.5 Added 1.5.5 to the list of versions that need displays to reset.
79 | * @since 1.6.0 Added 1.6.0 to the list of versions that need displays to reset.
80 | * @since 1.7.0 Added 1.7.0 to the list of versions that need displays to reset.
81 | * @since 1.7.1 Added 1.7.1 to the list of versions that need displays to reset.
82 | *
83 | * @param string $db_version The current database version.
84 | * @return void
85 | */
86 | static function reset_displays_for_certain_updates( $db_version ) {
87 |
88 | $reset_displays = false;
89 |
90 | $reset_displays_versions = array(
91 | '1.4.0',
92 | '1.5.0',
93 | '1.5.1',
94 | '1.5.5',
95 | '1.6.0',
96 | '1.7.0',
97 | '1.7.1',
98 | );
99 |
100 | foreach( $reset_displays_versions as $reset_displays_version ) {
101 | if ( version_compare( $db_version, $reset_displays_version, '<' ) ) {
102 | $reset_displays = true;
103 | }
104 | }
105 |
106 | if ( $reset_displays ) {
107 | // Update contains changes that require CSS/JS to be reloaded, reset displays
108 | Foyer_Displays::reset_all_displays();
109 | }
110 | }
111 |
112 | /**
113 | * Updates the database to the latest plugin version, if plugin was updated.
114 | *
115 | * Triggered at 'plugins_loaded', before 'init', thus before custom post types are registered.
116 | *
117 | * @since 1.4.0
118 | * @since 1.5.0 Added update code for 1.5.0.
119 | * @since 1.5.1 Added update code for 1.5.1.
120 | * @since 1.5.3 Made sure the rewrite rules are flushed after each update. Fixes #19 for existing installs.
121 | * @since 1.5.4 Made sure no update scripts are run for fresh installs.
122 | * Added a call to a new method that resets displays for certain versions, and removed
123 | * two calls to update methods for versions that only needed to reset displays.
124 | * Moved hooking of flush rewrite rules to its own method.
125 | *
126 | * @return bool True if database was updated, false otherwise.
127 | */
128 | static function update() {
129 | $db_version = self::get_db_version();
130 |
131 | if ( $db_version === Foyer::get_version() ) {
132 | // No update needed, bail
133 | return false;
134 | }
135 |
136 | if ( empty( $db_version ) ) {
137 | // Fresh install, make sure all update code is skipped,
138 | // but still continue to flush the rewrite rules and update the db version
139 | $db_version = Foyer::get_version();
140 | }
141 |
142 | if ( version_compare( $db_version, '1.4.0', '<' ) ) {
143 | // Initial db version is lower than 1.4.0, and this requires some update code
144 |
145 | // Run update to 1.4.0
146 | self::update_to_1_4_0();
147 |
148 | // Update db version
149 | self::update_db_version( '1.4.0' );
150 | }
151 |
152 | // Reset displays for certain updates only
153 | self::reset_displays_for_certain_updates( $db_version );
154 |
155 | // All updates were successful, update db version to current plugin version
156 | self::update_db_version( Foyer::get_version() );
157 |
158 | // Flush rewrite rules
159 | self::add_flush_rewrite_rules_action();
160 |
161 | return true;
162 | }
163 |
164 | /**
165 | * Updates the database version.
166 | *
167 | * @since 1.4.0
168 | *
169 | * @param string $version The plugin version string to be stored in the database.
170 | * @return void
171 | */
172 | static function update_db_version( $version ) {
173 | update_option( 'foyer_plugin_version', $version );
174 | }
175 |
176 | /**
177 | * Updates the database to version 1.4.0.
178 | *
179 | * All slides in the database are converted to the new slide formats and slide backgrounds introduced in 1.4.0.
180 | * Additionally resets all displays.
181 | *
182 | * @since 1.4.0
183 | *
184 | * @return bool True, update is always successful.
185 | */
186 | static function update_to_1_4_0() {
187 |
188 | $args = array(
189 | 'post_status' => array( 'any', 'trash' ),
190 | );
191 | $slides = Foyer_Slides::get_posts( $args );
192 |
193 | // Loop over all slides and convert them to new slide formats and slide backgrounds
194 | foreach ( $slides as $slide ) {
195 |
196 | $slide_format = get_post_meta( $slide->ID, 'slide_format', true );
197 |
198 | if ( 'default' == $slide_format ) {
199 | $renamed = self::rename_meta_key_for_post( $slide, 'slide_default_image', 'slide_bg_image_image' );
200 |
201 | // Always set background to 'image'
202 | update_post_meta( $slide->ID, 'slide_background', 'image' );
203 | }
204 | elseif ( 'production' == $slide_format ) {
205 | $renamed = self::rename_meta_key_for_post( $slide, 'slide_production_image', 'slide_bg_image_image' );
206 | if ( $renamed ) {
207 | // Post meta was not empty, set background to 'image'
208 | update_post_meta( $slide->ID, 'slide_background', 'image' );
209 | }
210 | }
211 | elseif ( 'video' == $slide_format ) {
212 | $renamed = self::rename_meta_key_for_post( $slide, 'slide_video_video_url', 'slide_bg_video_video_url' );
213 | self::rename_meta_key_for_post( $slide, 'slide_video_video_start', 'slide_bg_video_video_start' );
214 | self::rename_meta_key_for_post( $slide, 'slide_video_video_end', 'slide_bg_video_video_end' );
215 | self::rename_meta_key_for_post( $slide, 'slide_video_hold_slide', 'slide_bg_video_hold_slide' );
216 |
217 | // Always set background to 'video'
218 | update_post_meta( $slide->ID, 'slide_background', 'video' );
219 |
220 | // Set slide format to 'default'
221 | update_post_meta( $slide->ID, 'slide_format', 'default' );
222 | }
223 |
224 | $slide_background = get_post_meta( $slide->ID, 'slide_background', true );
225 |
226 | if ( empty( $slide_background ) ) {
227 | // Slide background is empty, set to 'default'
228 | update_post_meta( $slide->ID, 'slide_background', 'default' );
229 | }
230 | }
231 |
232 | return true;
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/includes/class-foyer-slides.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class Foyer_Slides {
13 |
14 | /**
15 | * Gets the default slides duration.
16 | *
17 | * @since 1.0.0
18 | * @return int The default slides duration.
19 | */
20 | static function get_default_slides_duration() {
21 | $default_slides_duration = 8;
22 |
23 | /**
24 | * Filter the default slides duration.
25 | *
26 | * @since 1.0.0
27 | * @param int $default_slides_duration The current default slides duration.
28 | */
29 | $default_slides_duration = apply_filters( 'foyer/slides/duration/default', $default_slides_duration );
30 |
31 | return $default_slides_duration;
32 | }
33 |
34 | /**
35 | * Gets the default slides transition.
36 | *
37 | * @since 1.0.0
38 | * @return int The default slides transition.
39 | */
40 | static function get_default_slides_transition() {
41 | $default_slides_transition = 'fade';
42 |
43 | /**
44 | * Filter the default slides transition.
45 | *
46 | * @since 1.0.0
47 | * @param int $default_slides_transition The current default slides transition.
48 | */
49 | $default_slides_transition = apply_filters( 'foyer/slides/transition/default', $default_slides_transition );
50 |
51 | return $default_slides_transition;
52 | }
53 |
54 | /**
55 | * Gets all slide posts.
56 | *
57 | * @since 1.4.0
58 | *
59 | * @param array $args Additional args for get_posts().
60 | * @return array of WP_Post The slide posts.
61 | */
62 | static function get_posts( $args = array() ) {
63 | $defaults = array(
64 | 'post_type' => Foyer_Slide::post_type_name,
65 | 'posts_per_page' => -1,
66 | );
67 |
68 | $args = wp_parse_args( $args, $defaults );
69 |
70 | return get_posts( $args );
71 | }
72 |
73 | /**
74 | * Gets a slide background by its slug.
75 | *
76 | * @since 1.4.0
77 | * @param string $slug The slug of the background to get.
78 | * @return array The slide background properties.
79 | */
80 | static function get_slide_background_by_slug( $slug ) {
81 |
82 | $slide_backgrounds = self::get_slide_backgrounds();
83 |
84 | if ( empty( $slide_backgrounds[$slug] ) ) {
85 | return false;
86 | }
87 |
88 | return $slide_backgrounds[$slug];
89 | }
90 |
91 | /**
92 | * Gets the available slide backgrounds for a slide format, by its slug.
93 | *
94 | * Only returns slide format backgrounds that are registered according to Foyer_Slides::get_slide_backgrounds().
95 | *
96 | * @since 1.4.0
97 | * @param string $slug The slug of the slide format to get the slide backgrounds for.
98 | * @return array The slide backgrounds with their properties.
99 | */
100 | static function get_slide_format_backgrounds_by_slug( $slug ) {
101 |
102 | $slide_format = self::get_slide_format_by_slug( $slug );
103 |
104 | if ( ! empty( $slide_format['slide_backgrounds'] ) ) {
105 | $slide_backgrounds = $slide_format['slide_backgrounds'];
106 | }
107 | else {
108 | // Each slide format should have at least one background, use 'default'
109 | $slide_backgrounds = array( 'default' );
110 | }
111 |
112 | $slide_format_backgrounds = array();
113 |
114 | foreach ( $slide_backgrounds as $slide_background_slug ) {
115 | $slide_background_data = self::get_slide_background_by_slug( $slide_background_slug );
116 | if ( ! empty( $slide_background_data ) ) {
117 | // Only add to backgrounds if this background is registered
118 | $slide_format_backgrounds[$slide_background_slug] = $slide_background_data;
119 | }
120 | }
121 |
122 | return $slide_format_backgrounds;
123 | }
124 |
125 | /**
126 | * Gets a slide background by its slug, for a specific slide format.
127 | *
128 | * Only returns a slide background if it is registered to the slide format.
129 | *
130 | * @since 1.4.0
131 | * @param string $slide_background_slug The slug of the slide background to get.
132 | * @param string $slide_format_slug The slug of the slide format to get the slide background for.
133 | * @return array The slide background properties.
134 | */
135 | static function get_slide_background_by_slug_for_slide_format( $slide_background_slug, $slide_format_slug ) {
136 | $slide_format_backgrounds = self::get_slide_format_backgrounds_by_slug( $slide_format_slug );
137 | if ( empty( $slide_format_backgrounds[$slide_background_slug] ) ) {
138 | return false;
139 | }
140 |
141 | return $slide_format_backgrounds[$slide_background_slug];
142 | }
143 |
144 | /**
145 | * Gets all available slide backgrounds.
146 | *
147 | * Slide backgrounds are added through filters.
148 | *
149 | * @since 1.4.0
150 | * @return array All backgrounds with their properties.
151 | */
152 | static function get_slide_backgrounds() {
153 |
154 | $slide_backgrounds = array();
155 |
156 | /**
157 | * Filter available slide backgrounds.
158 | *
159 | * @see Foyer_Slide_Backgrounds::add_image_slide_background() for an example.
160 | *
161 | * @since 1.4.0
162 | * @param array $slide_backgrounds The currently available slide backgrounds.
163 | */
164 | $slide_backgrounds = apply_filters( 'foyer/slides/backgrounds', $slide_backgrounds );
165 |
166 | return $slide_backgrounds;
167 | }
168 |
169 | /**
170 | * Gets a slide format by its slug.
171 | *
172 | * @since 1.0.0
173 | * @param string $slug The slug of the format to get.
174 | * @return array The slide format properties.
175 | */
176 | static function get_slide_format_by_slug( $slug ) {
177 |
178 | foreach( self::get_slide_formats() as $slide_format_key => $slide_format_data ) {
179 | if ( $slug == $slide_format_key ) {
180 | return $slide_format_data;
181 | }
182 | }
183 |
184 | return false;
185 | }
186 |
187 | /**
188 | * Gets all available slide formats.
189 | *
190 | * Slide formats are added through filters.
191 | *
192 | * @since 1.0.0
193 | * @since 1.4.0 Default slide format is now also added through filter, instead of here.
194 | *
195 | * @return array All formats with their properties.
196 | */
197 | static function get_slide_formats() {
198 |
199 | $slide_formats = array();
200 |
201 | /**
202 | * Filter available slide formats.
203 | *
204 | * @see Foyer_Slide_Formats::add_production_slide_format() for an example.
205 | *
206 | * @since 1.0.0
207 | * @param array $slide_formats The currently available slide formats.
208 | */
209 | $slide_formats = apply_filters( 'foyer/slides/formats', $slide_formats );
210 |
211 | return $slide_formats;
212 | }
213 |
214 | /**
215 | * Gets the available slide backgrounds for each available slide format.
216 | *
217 | * @since 1.4.0
218 | * @return array The slide formats with their backgrounds with their properties.
219 | */
220 | static function get_slide_formats_backgrounds() {
221 | $slide_formats_backgrounds = array();
222 |
223 | foreach( self::get_slide_formats() as $slide_format_key => $slide_format_data ) {
224 | $slide_formats_backgrounds[$slide_format_key] = self::get_slide_format_backgrounds_by_slug( $slide_format_key );
225 | }
226 |
227 | return $slide_formats_backgrounds;
228 | }
229 |
230 | /**
231 | * Checks if the slide format has a default background template.
232 | *
233 | * @since 1.4.0
234 | *
235 | * @param string $slug The slug of the slide format.
236 | * @return bool True if the slide format is known to have a default background template, false otherwise.
237 | */
238 | static function slide_format_has_default_background_template( $slug ) {
239 | $slide_format_data = self::get_slide_format_by_slug( $slug );
240 |
241 | if ( empty( $slide_format_data['default_background_template'] ) ) {
242 | return false;
243 | }
244 | return true;
245 | }
246 |
247 | /**
248 | * Checks if the slide format results in a stack of slides.
249 | *
250 | * @since 1.5.0
251 | *
252 | * @param string $slug The slug of the slide format.
253 | * @return bool True if the slide format is known to result in a stack of slides, false otherwise.
254 | */
255 | static function slide_format_is_stack( $slug ) {
256 | $slide_format_data = self::get_slide_format_by_slug( $slug );
257 |
258 | if ( empty( $slide_format_data['stack'] ) ) {
259 | return false;
260 | }
261 | return true;
262 | }
263 | }
264 |
--------------------------------------------------------------------------------
/includes/class-foyer-slide.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class Foyer_Slide {
13 |
14 | /**
15 | * The Foyer Slide post type name.
16 | *
17 | * @since 1.0.0
18 | * @access private
19 | * @var string $post_type_name The Foyer Slide post type name.
20 | */
21 | const post_type_name = 'foyer_slide';
22 |
23 | public $ID;
24 | private $post;
25 |
26 | /**
27 | * Initialize the class and set its properties.
28 | *
29 | * @since 1.0.0
30 | * @param int or WP_Post $ID The id or the WP_Post object of the slide.
31 | */
32 | public function __construct( $ID = false ) {
33 |
34 | if ( $ID instanceof WP_Post ) {
35 | // $ID is a WP_Post object
36 | $this->post = $ID;
37 | $ID = $ID->ID;
38 | }
39 |
40 | $this->ID = $ID;
41 | }
42 |
43 | /**
44 | * Outputs the background template HTML for use in the slide format template.
45 | *
46 | * @since 1.4.0
47 | * @since 1.5.7 Added support for template args.
48 | *
49 | * @return string The background template HTML.
50 | */
51 | public function background( $template_args = false ) {
52 | Foyer_Templates::get_template( 'slides/backgrounds/' . $this->get_background() . '.php', $template_args );
53 | }
54 |
55 | /**
56 | * Outputs the slide background classes for use in the template.
57 | *
58 | * The output is escaped, so this method can be used in templates without further escaping.
59 | *
60 | * @since 1.4.0
61 | *
62 | * @param array $classes
63 | * @return void
64 | */
65 | public function background_classes( $classes = array() ) {
66 |
67 | $classes[] = 'foyer-slide-background';
68 | $classes[] = 'foyer-slide-background-' . $this->get_background();
69 |
70 | if ( empty( $classes ) ) {
71 | return;
72 | }
73 |
74 | ?> class="" $value ) {
94 | ?> data-=""get_format();
114 | $classes[] = 'foyer-slide-background-' . $this->get_background();
115 |
116 | if ( Foyer_Channel::post_type_name == get_post_type( get_queried_object_id() ) ) {
117 | $channel = new Foyer_Channel( get_queried_object_id() );
118 | }
119 |
120 | if ( Foyer_Display::post_type_name == get_post_type( get_queried_object_id() ) ) {
121 | $display = new Foyer_Display( get_queried_object_id() );
122 | $channel = new Foyer_Channel( $display->get_active_channel() );
123 | }
124 |
125 | if ( ! empty ( $channel ) ) {
126 | $slides = $channel->get_slides();
127 | if ( ! empty( $slides ) && $this->ID == $slides[0]->ID ) {
128 | $classes[] = 'next';
129 | }
130 | }
131 |
132 | if ( empty( $classes ) ) {
133 | return;
134 | }
135 |
136 | ?> class="" get_format() . '.php', $template_args );
152 | }
153 | }
154 |
155 | /**
156 | * Outputs the slide data attributes for use in the template.
157 | *
158 | * The output is escaped, so this method can be used in templates without further escaping.
159 | *
160 | * @since 1.0.0
161 | * @since 1.0.1 Escaped the output.
162 | *
163 | * @param array $data
164 | * @return string
165 | */
166 | public function data_attr( $data = array() ) {
167 |
168 | if ( Foyer_Channel::post_type_name == get_post_type( get_queried_object_id() ) ) {
169 | $channel = new Foyer_Channel( get_queried_object_id() );
170 | }
171 |
172 | if ( Foyer_Display::post_type_name == get_post_type( get_queried_object_id() ) ) {
173 | $display = new Foyer_Display( get_queried_object_id() );
174 | $channel = new Foyer_Channel( $display->get_active_channel() );
175 | }
176 |
177 | if (!empty ($channel) ) {
178 | $data['foyer-slide-duration'] = $channel->get_slides_duration();
179 | }
180 |
181 | if (empty($data)) {
182 | return;
183 | }
184 |
185 | foreach ( $data as $key=>$value ) {
186 | ?> data-=""ID, 'slide_background', true );
200 |
201 | $slide_background_keys = array_keys( Foyer_Slides::get_slide_backgrounds() );
202 |
203 | if ( empty ( $slide_background ) || ! in_array( $slide_background, $slide_background_keys ) ) {
204 | $slide_background = $slide_background_keys[0];
205 | }
206 |
207 | return $slide_background;
208 | }
209 |
210 | /**
211 | * Gets the format of the slide.
212 | *
213 | * @since 1.0.0
214 | * @since 1.0.1 Renamed from format() to get_format().
215 | *
216 | * @return string The format key.
217 | */
218 | public function get_format() {
219 |
220 | $slide_format = get_post_meta( $this->ID, 'slide_format', true );
221 |
222 | $slide_format_keys = array_keys( Foyer_Slides::get_slide_formats() );
223 |
224 | if ( empty ( $slide_format ) || ! in_array( $slide_format, $slide_format_keys ) ) {
225 | $slide_format = $slide_format_keys[0];
226 | }
227 |
228 | return $slide_format;
229 | }
230 |
231 | /**
232 | * Gets the URL of the slide image.
233 | *
234 | * @deprecated 1.4.0
235 | *
236 | * @since 1.0.0
237 | * @since 1.0.1 Renamed from image() to get_image_url().
238 | * @since 1.3.1 Now returns the image uploaded on the production slide, for production slides.
239 | * @since 1.4.0 Now returns the background image, instead of the default slide or production slide image.
240 | *
241 | * @return string The URL of the slide image.
242 | */
243 | public function get_image_url() {
244 | _deprecated_function( 'Foyer_Slide::get_image_url()', '1.4.0', '' );
245 |
246 | $attachment_id = get_post_meta( $this->ID, 'slide_bg_image_image', true );
247 | $attachment_src = wp_get_attachment_image_src( $attachment_id, 'foyer_fhd_square' );
248 |
249 | if ( empty ( $attachment_src[0] ) ) {
250 | return false;
251 | }
252 |
253 | return $attachment_src[0];
254 | }
255 |
256 | /**
257 | * Outputs the URL of the slide image.
258 | *
259 | * The output is escaped, so this method can be used in templates without further escaping.
260 | *
261 | * @deprecated 1.4.0
262 | *
263 | * @since 1.0.1
264 | * @return void
265 | */
266 | public function image_url() {
267 | _deprecated_function( 'Foyer_Slide::image_url()', '1.4.0', '' );
268 | echo esc_url( $this->get_image_url() );
269 | }
270 |
271 | /**
272 | * Checks if the slide results in a stack of slides.
273 | *
274 | * @since 1.5.0
275 | *
276 | * @return bool True if the slide is a stack, false otherwise.
277 | */
278 | public function is_stack() {
279 | return Foyer_Slides::slide_format_is_stack( self::get_format() );
280 | }
281 | }
282 |
--------------------------------------------------------------------------------
/admin/class-foyer-admin-slide-format-pdf.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | class Foyer_Admin_Slide_Format_PDF {
12 |
13 | /**
14 | * Adds our own Foyer_Image_Editor_Imagick image editor to the list of available image editors.
15 | *
16 | * @since 1.1.0
17 | *
18 | * @param array The current list of image editors.
19 | * @return array The list of image editors with our own Foyer_Image_Editor_Imagick added.
20 | */
21 | static function add_foyer_imagick_image_editor( $editors ) {
22 |
23 | // Image Editor classes are lazy loaded, so we can't just extend them on init
24 | // Include our own image editor now and extend WP_Image_Editor_Imagick
25 | require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-foyer-image-editor-imagick.php';
26 |
27 | $editors[] = 'Foyer_Image_Editor_Imagick';
28 | return $editors;
29 | }
30 |
31 | /**
32 | * Adds PDF images to an attachment, for each page in a PDF.
33 | *
34 | * @since 1.1.0
35 | *
36 | * @param int $attachment_id The ID of the attachment to add PDF images to.
37 | * @return WP_Error|void Returns a WP error if generating of images failed, void otherwise.
38 | */
39 | static function add_pdf_images_to_attachment( $attachment_id ) {
40 |
41 | $current_pdf_images = get_post_meta( $attachment_id, '_foyer_pdf_images', true );
42 |
43 | if ( ! empty( $current_pdf_images ) ) {
44 | // Images already added, no need to generate them
45 | return;
46 | }
47 |
48 | $pdf_file_path = get_attached_file( $attachment_id );
49 | $pdf_images = self::generate_images_for_pdf_pages( $pdf_file_path );
50 |
51 | if ( is_wp_error( $pdf_images ) ) {
52 | return $pdf_images;
53 | }
54 |
55 | // Convert full paths to paths relative to uploads base, eg. 2017/03/upload_file.pdf
56 | $pdf_images = array_map(
57 | array( __CLASS__, 'get_file_path_relative_to_uploads_base' ),
58 | $pdf_images
59 | );
60 |
61 | update_post_meta( $attachment_id, '_foyer_pdf_images', $pdf_images );
62 | }
63 |
64 | /**
65 | * Deletes generated PDF images for an attachment.
66 | *
67 | * @since 1.1.0
68 | *
69 | * @param int $attachment_id The ID of the attachment to delete PDF images for.
70 | * @return void
71 | */
72 | static function delete_pdf_images_for_attachment( $attachment_id ) {
73 |
74 | $slide_images = get_post_meta( $attachment_id, '_foyer_pdf_images', true );
75 |
76 | if ( empty( $slide_images ) ) {
77 | // No images were generated, bail
78 | return;
79 | }
80 |
81 | $uploads = wp_upload_dir( null, false );
82 |
83 | foreach ( $slide_images as $slide_image ) {
84 |
85 | $slide_image_path = trailingslashit( $uploads['basedir'] ) . $slide_image;
86 | wp_delete_file( $slide_image_path );
87 | }
88 | }
89 |
90 | /**
91 | * Displays an admin notice on the Slide edit screen if something went wrong during saving.
92 | *
93 | * Error is stored in a transient.
94 | *
95 | * @since 1.3.2
96 | *
97 | * @return void
98 | */
99 | static function display_admin_notice() {
100 |
101 | // Bail if not on Slide edit screen.
102 | $screen = get_current_screen();
103 | if ( empty( $screen ) || Foyer_Slide::post_type_name != $screen->post_type ) {
104 | return;
105 | }
106 |
107 | if ( $error = get_transient( 'foyer_save_slide_pdf_notice_' . get_the_ID() . '_' . get_current_user_id() ) ) { ?>
108 |
109 |
110 |
111 |
112 | get_error_message(); ?>
113 |
114 |
array( 'pdf_get_number_of_pages', 'pdf_prepare_page_for_load' ) ) );
149 | if ( is_wp_error( $editor ) ) {
150 | return $editor;
151 | }
152 |
153 | // Check if WordPress install has WP_Image_Editor_Imagick PDF setup support (WP 4.7 and up)
154 | if ( ! method_exists( 'WP_Image_Editor_Imagick', 'pdf_setup' ) ) {
155 | return new WP_Error(
156 | 'wp_image_editor_imagick_pdf_setup',
157 | __( 'Your WordPress version lacks support for PDF processing.', 'foyer' ),
158 | $editor
159 | );
160 | }
161 |
162 | // Get the number of pages in the PDF
163 | $number_of_pages = $editor->pdf_get_number_of_pages();
164 | if ( is_wp_error( $number_of_pages ) ) {
165 | return $number_of_pages;
166 | }
167 |
168 | // Loop over all pages
169 | for ( $p = 0; $p < $number_of_pages; $p++ ) {
170 |
171 | $editor->pdf_prepare_page_for_load( $p );
172 | $loaded = $editor->load();
173 |
174 | if ( is_wp_error( $loaded ) ) {
175 | return $loaded;
176 | }
177 |
178 | // Created a unique filename that will not overwrite any PNG images that already exist
179 | $dirname = dirname( $pdf_file ) . '/';
180 | $ext = '.' . pathinfo( $pdf_file, PATHINFO_EXTENSION );
181 | $png_file = $dirname . wp_unique_filename( $dirname, wp_basename( $pdf_file, $ext ) . '-p' . ( $p + 1 ) . '-pdf.png' );
182 |
183 | $saved = $editor->save( $png_file, 'image/png' );
184 |
185 | if ( is_wp_error( $saved ) ) {
186 | return $saved;
187 | }
188 |
189 | // Store file path of the saved PNG image for this page
190 | $png_files[] = $saved['path'];
191 | }
192 |
193 | unset( $editor );
194 |
195 | return $png_files;
196 | }
197 |
198 | /**
199 | * Gets the file path relative to the uploads base.
200 | *
201 | * Eg. 2017/03/upload_file.pdf
202 | *
203 | * @since 1.1.0
204 | *
205 | * @param string $file_path The full file path to get the relative path for.
206 | * @return string The file path relative to the uploads base.
207 | */
208 | static function get_file_path_relative_to_uploads_base( $file_path ) {
209 | $uploads = wp_upload_dir( null, false );
210 | $relative_file_path = str_replace( trailingslashit( $uploads['basedir'] ), '', $file_path );
211 |
212 | return $relative_file_path;
213 | }
214 |
215 | /**
216 | * Saves additional data for the PDF slide format.
217 | *
218 | * Converts newly selected PDF file to images.
219 | *
220 | * @since 1.1.0
221 | *
222 | * @param int $post_id The ID of the post being saved.
223 | * @return void
224 | */
225 | static function save_slide_pdf( $post_id ) {
226 | $slide_pdf_file = intval( $_POST['slide_pdf_file'] );
227 | if ( empty( $slide_pdf_file ) ) {
228 | $slide_pdf_file = '';
229 | }
230 |
231 | if ( empty( $slide_pdf_file ) ) {
232 | delete_post_meta( $post_id, 'slide_pdf_file' );
233 | }
234 | else {
235 |
236 | $added = self::add_pdf_images_to_attachment( $slide_pdf_file );
237 | if ( is_wp_error( $added ) ) {
238 |
239 | // Store our error in a transient so it can be displayed to the user on the Slide edit screen
240 | set_transient( 'foyer_save_slide_pdf_notice_' . $post_id . '_' . get_current_user_id(), $added, 45 );
241 |
242 | return $added;
243 | }
244 |
245 | update_post_meta( $post_id, 'slide_pdf_file', $slide_pdf_file );
246 | }
247 | }
248 |
249 | /**
250 | * Outputs the meta box for the Production slide format.
251 | *
252 | * @since 1.0.0
253 | * @since 1.0.1 Escaped & sanitized the output.
254 | * @since 1.1.0 Moved here from Foyer_Theater, and changed to static.
255 | * @since 1.3.1 Added notifications when PDF processing is not supported (no Imagick/Ghostscript installed),
256 | * and when PDF file previews don’t work (PHP < 4.7).
257 | * @since 1.3.2 Removed the notifications added in 1.3.1 as they proved to be unreliable.
258 | * @since 1.6.0 Renamed everything slide_image_* to slide_file_*, and 'Upload PDF' to 'Select PDF'.
259 | *
260 | * @param WP_Post $post The post of the current slide.
261 | * @return void
262 | */
263 | static function slide_pdf_meta_box( $post ) {
264 | $slide_pdf_file_preview_url = '';
265 |
266 | $slide_pdf_file = get_post_meta( $post->ID, 'slide_pdf_file', true );
267 | $slide_pdf_file_src = wp_get_attachment_image_src( $slide_pdf_file, 'full' );
268 | if ( ! empty( $slide_pdf_file_src ) ) {
269 | $slide_pdf_file_preview_url = $slide_pdf_file_src[0];
270 | }
271 |
272 | ?>
11 | */
12 | class Foyer_Slide_Formats {
13 |
14 | /**
15 | * Adds the Default slide format.
16 | *
17 | * @since 1.4.0 Default slide format is now also added through filter, instead of in Foyer_Slides.
18 | * Added appropriate slide backgrounds to the properties of this slide format.
19 | * @since 1.6.0 Added the HTML5 Video slide background to this slide format's list of available backgrounds.
20 | *
21 | * @param array $slide_formats The current slide formats.
22 | * @return array The slide formats with the Default slide format added.
23 | */
24 | static function add_default_slide_format( $slide_formats ) {
25 |
26 | $slide_format_backgrounds = array( 'image', 'html5-video', 'video' );
27 |
28 | /**
29 | * Filter available slide backgrounds for this slide format.
30 | *
31 | * @since 1.4.0
32 | * @param array $slide_format_backgrounds The currently available slide backgrounds for this slide format.
33 | */
34 | $slide_format_backgrounds = apply_filters( 'foyer/slides/backgrounds/format=default', $slide_format_backgrounds );
35 |
36 | $slide_formats['default'] = array(
37 | 'title' => _x( 'Default', 'slide-format', 'foyer' ),
38 | 'description' => __( 'Displays a background only.', 'foyer' ),
39 | 'slide_backgrounds' => $slide_format_backgrounds,
40 | );
41 | return $slide_formats;
42 | }
43 |
44 | /**
45 | * Adds the Iframe slide format.
46 | *
47 | * @since 1.3.0
48 | * @since 1.4.0 Added appropriate slide backgrounds to the properties of this slide format.
49 | *
50 | * @param array $slide_formats The current slide formats.
51 | * @return array The slide formats with the Iframe slide format added.
52 | */
53 | static function add_iframe_slide_format( $slide_formats ) {
54 |
55 | $slide_format_backgrounds = array( 'default' );
56 |
57 | /**
58 | * Filter available slide backgrounds for this slide format.
59 | *
60 | * @since 1.4.0
61 | * @param array $slide_format_backgrounds The currently available slide backgrounds for this slide format.
62 | */
63 | $slide_format_backgrounds = apply_filters( 'foyer/slides/backgrounds/format=iframe', $slide_format_backgrounds );
64 |
65 | $slide_formats['iframe'] = array(
66 | 'title' => _x( 'External web page', 'slide-format', 'foyer' ),
67 | 'description' => __( 'Displays a web page to your liking.', 'foyer' ),
68 | 'meta_box' => array( 'Foyer_Admin_Slide_Format_Iframe', 'slide_meta_box' ),
69 | 'save_post' => array( 'Foyer_Admin_Slide_Format_Iframe', 'save_slide' ),
70 | 'slide_backgrounds' => $slide_format_backgrounds,
71 | );
72 | return $slide_formats;
73 | }
74 |
75 | /**
76 | * Adds the PDF slide format.
77 | *
78 | * @since 1.1.0
79 | * @since 1.4.0 Added appropriate slide backgrounds to the properties of this slide format.
80 | * @since 1.5.0 Added the stack property.
81 | * @since 1.6.0 Added the HTML5 Video slide background to this slide format's list of available backgrounds.
82 | *
83 | * @param array $slide_formats The current slide formats.
84 | * @return array The slide formats with the PDF slide format added.
85 | */
86 | static function add_pdf_slide_format( $slide_formats ) {
87 |
88 | $slide_format_backgrounds = array( 'default', 'image', 'html5-video', 'video' );
89 |
90 | /**
91 | * Filter available slide backgrounds for this slide format.
92 | *
93 | * @since 1.4.0
94 | * @param array $slide_format_backgrounds The currently available slide backgrounds for this slide format.
95 | */
96 | $slide_format_backgrounds = apply_filters( 'foyer/slides/backgrounds/format=default', $slide_format_backgrounds );
97 |
98 | $slide_formats['pdf'] = array(
99 | 'title' => _x( 'PDF', 'slide-format', 'foyer' ),
100 | 'description' => __( 'Displays a slide for each page in the uploaded PDF.', 'foyer' ),
101 | 'meta_box' => array( 'Foyer_Admin_Slide_Format_PDF', 'slide_pdf_meta_box' ),
102 | 'save_post' => array( 'Foyer_Admin_Slide_Format_PDF', 'save_slide_pdf' ),
103 | 'slide_backgrounds' => $slide_format_backgrounds,
104 | 'stack' => true,
105 | );
106 | return $slide_formats;
107 | }
108 |
109 | /**
110 | * Adds the Post slide format.
111 | *
112 | * @since 1.5.0
113 | * @since 1.6.0 Added the HTML5 Video slide background to this slide format's list of available backgrounds.
114 | *
115 | * @param array $slide_formats The current slide formats.
116 | * @return array The slide formats with the Post slide format added.
117 | */
118 | static function add_post_slide_format( $slide_formats ) {
119 |
120 | $slide_format_backgrounds = array( 'default', 'image', 'html5-video', 'video' );
121 |
122 | /**
123 | * Filter available slide backgrounds for this slide format.
124 | *
125 | * @since 1.5.0
126 | * @param array $slide_format_backgrounds The currently available slide backgrounds for this slide format.
127 | */
128 | $slide_format_backgrounds = apply_filters( 'foyer/slides/backgrounds/format=post', $slide_format_backgrounds );
129 |
130 | $slide_formats['post'] = array(
131 | 'title' => _x( 'Post', 'slide-format', 'foyer' ),
132 | 'description' => __( 'Displays title, date and content of a post.', 'foyer' ),
133 | 'meta_box' => array( 'Foyer_Admin_Slide_Format_Post', 'slide_meta_box' ),
134 | 'save_post' => array( 'Foyer_Admin_Slide_Format_Post', 'save_slide' ),
135 | 'slide_backgrounds' => $slide_format_backgrounds,
136 | );
137 | return $slide_formats;
138 | }
139 |
140 | /**
141 | * Adds the Production slide format.
142 | *
143 | * @since 1.0.0
144 | * @since 1.1.0 Moved here from Foyer_Theater, and changed to static.
145 | * @since 1.2.6 Changed the displayed name from Production to Event, same terminology as in Theater for WordPress.
146 | * @since 1.4.0 Added appropriate slide backgrounds to the properties of this slide format.
147 | * @since 1.6.0 Added the HTML5 Video slide background to this slide format's list of available backgrounds.
148 | *
149 | * @param array $slide_formats The current slide formats.
150 | * @return array The slide formats with the Production slide format added.
151 | */
152 | static function add_production_slide_format( $slide_formats ) {
153 |
154 | if ( ! Foyer_Theater::is_theater_activated() ) {
155 | return $slide_formats;
156 | }
157 |
158 | $slide_format_backgrounds = array( 'default', 'image', 'html5-video', 'video' );
159 |
160 | /**
161 | * Filter available slide backgrounds for this slide format.
162 | *
163 | * @since 1.4.0
164 | * @param array $slide_format_backgrounds The currently available slide backgrounds for this slide format.
165 | */
166 | $slide_format_backgrounds = apply_filters( 'foyer/slides/backgrounds/format=production', $slide_format_backgrounds );
167 |
168 | $slide_formats['production'] = array(
169 | 'title' => _x( 'Event', 'slide-format', 'foyer' ),
170 | 'description' => __( 'Displays title and details of an event, with its image as default background.', 'foyer' ),
171 | 'meta_box' => array( 'Foyer_Admin_Slide_Format_Production', 'slide_production_meta_box' ),
172 | 'save_post' => array( 'Foyer_Admin_Slide_Format_Production', 'save_slide_production' ),
173 | 'slide_backgrounds' => $slide_format_backgrounds,
174 | 'default_background_template' => true,
175 | );
176 |
177 | return $slide_formats;
178 | }
179 |
180 | /**
181 | * Adds the Recent Posts slide format.
182 | *
183 | * @since 1.7.1
184 | *
185 | * @param array $slide_formats The current slide formats.
186 | * @return array The slide formats with the Recent Posts slide format added.
187 | */
188 | static function add_recent_posts_slide_format( $slide_formats ) {
189 |
190 | $slide_format_backgrounds = array( 'default', 'image' );
191 |
192 | /**
193 | * Filter available slide backgrounds for this slide format.
194 | *
195 | * @since 1.7.0
196 | * @param array $slide_format_backgrounds The currently available slide backgrounds for this slide format.
197 | */
198 | $slide_format_backgrounds = apply_filters( 'foyer/slides/backgrounds/format=recent-posts', $slide_format_backgrounds );
199 |
200 | $slide_formats['recent-posts'] = array(
201 | 'title' => 'Recent posts',
202 | 'description' => 'Displays a slide for each recent post.',
203 | 'meta_box' => array( 'Foyer_Admin_Slide_Format_Recent_Posts', 'slide_meta_box'),
204 | 'save_post' => array( 'Foyer_Admin_Slide_Format_Recent_Posts', 'save_slide'),
205 | 'slide_backgrounds' => $slide_format_backgrounds,
206 | 'stack' => true,
207 | );
208 |
209 | return $slide_formats;
210 | }
211 |
212 | /**
213 | * Adds the Text slide format.
214 | *
215 | * @since 1.5.0
216 | * @since 1.5.1 Renamed the slide format from 'Manual text' to 'Text'.
217 | * @since 1.6.0 Added the HTML5 Video slide background to this slide format's list of available backgrounds.
218 | *
219 | * @param array $slide_formats The current slide formats.
220 | * @return array The slide formats with the Text slide format added.
221 | */
222 | static function add_text_slide_format( $slide_formats ) {
223 |
224 | $slide_format_backgrounds = array( 'default', 'image', 'html5-video', 'video' );
225 |
226 | /**
227 | * Filter available slide backgrounds for this slide format.
228 | *
229 | * @since 1.5.0
230 | * @param array $slide_format_backgrounds The currently available slide backgrounds for this slide format.
231 | */
232 | $slide_format_backgrounds = apply_filters( 'foyer/slides/backgrounds/format=text', $slide_format_backgrounds );
233 |
234 | $slide_formats['text'] = array(
235 | 'title' => _x( 'Text', 'slide-format', 'foyer' ),
236 | 'description' => __( 'Displays some text.', 'foyer' ),
237 | 'meta_box' => array( 'Foyer_Admin_Slide_Format_Text', 'slide_meta_box' ),
238 | 'save_post' => array( 'Foyer_Admin_Slide_Format_Text', 'save_slide' ),
239 | 'slide_backgrounds' => $slide_format_backgrounds,
240 | );
241 | return $slide_formats;
242 | }
243 |
244 | /**
245 | * Adds the Upcoming Productions slide format.
246 | *
247 | * @since 1.7.0
248 | *
249 | * @param array $slide_formats The current slide formats.
250 | * @return array The slide formats with the Upcoming Productions slide format added.
251 | */
252 | static function add_upcoming_productions_slide_format( $slide_formats ) {
253 |
254 | if ( ! Foyer_Theater::is_theater_activated() ) {
255 | return $slide_formats;
256 | }
257 |
258 | $slide_format_backgrounds = array( 'default' );
259 |
260 | /**
261 | * Filter available slide backgrounds for this slide format.
262 | *
263 | * @since 1.7.0
264 | * @param array $slide_format_backgrounds The currently available slide backgrounds for this slide format.
265 | */
266 | $slide_format_backgrounds = apply_filters( 'foyer/slides/backgrounds/format=upcoming-productions', $slide_format_backgrounds );
267 |
268 | $slide_formats['upcoming-productions'] = array(
269 | 'title' => 'Upcoming events',
270 | 'description' => 'Displays a slide for each upcoming event.',
271 | 'meta_box' => array( 'Foyer_Admin_Slide_Format_Upcoming_Productions', 'slide_meta_box'),
272 | 'save_post' => array( 'Foyer_Admin_Slide_Format_Upcoming_Productions', 'save_slide'),
273 | 'slide_backgrounds' => $slide_format_backgrounds,
274 | 'default_background_template' => true,
275 | 'stack' => true,
276 | );
277 |
278 | return $slide_formats;
279 | }
280 | }
281 |
--------------------------------------------------------------------------------
/public/js/foyer-public-min.js:
--------------------------------------------------------------------------------
1 | function foyer_display_setup_slide_group_classes(){jQuery(foyer_slides_selector).children().addClass("foyer-slide-group-1")}function foyer_display_setup(){jQuery(this).css("cursor","none"),major_refresh_timeout=setTimeout(foyer_display_reload_window,288e5),foyer_loader_intervalObject=window.setInterval(foyer_display_load_data,3e5)}function foyer_display_load_data(){var e,o;jQuery(".foyer-slide-group-1").length?jQuery(".foyer-slide-group-2").length||(o="foyer-slide-group-2",e="foyer-slide-group-1"):(o="foyer-slide-group-1",e="foyer-slide-group-2"),o&&jQuery.get(window.location,function(t){if($new_html=jQuery(jQuery.parseHTML(jQuery.trim(t))),$new_html.filter(foyer_display_selector).hasClass("foyer-reset-display"))foyer_ticker_shutdown(foyer_display_reload_window);else if($new_html.find(foyer_channel_selector).attr("class")!==jQuery(foyer_channel_selector).attr("class"))foyer_ticker_shutdown(foyer_display_replace_channel,$new_html.find(foyer_channel_selector));else{var i=$new_html.find(foyer_slides_selector).children().addClass(o);1===jQuery(foyer_slides_selector).children().length&&1===$new_html.find(foyer_slides_selector).children().length?(jQuery(foyer_slides_selector).trigger("slides:removing-old-slide-group",e).html(i).trigger("slides:loaded-new-slide-group",o).trigger("slides:removed-old-slide-group"),foyer_ticker_set_slide_active_next_classes()):(jQuery(foyer_slides_selector).children().last().after(i),jQuery(foyer_slides_selector).trigger("slides:loaded-new-slide-group",o),jQuery("body").one("slide:left-active","."+o,function(o){return jQuery(foyer_slides_selector).trigger("slides:removing-old-slide-group",e),jQuery(foyer_slides_selector).find("."+e).remove(),jQuery(foyer_slides_selector).trigger("slides:removed-old-slide-group"),!0}))}})}function foyer_display_replace_channel(e){jQuery(foyer_channel_selector).replaceWith(e),jQuery(foyer_channel_selector).trigger("channel:replaced-channel"),foyer_display_setup_slide_group_classes(),setTimeout(foyer_ticker_init,100)}function foyer_display_reload_window(){window.location.reload()}function foyer_slide_bg_video_bind_display_loading_events(){jQuery("body").on("channel:replaced-channel",foyer_channel_selector,function(e){foyer_yt_api_ready?(foyer_slide_bg_video_init_video_placeholders(),foyer_slide_bg_video_cleanup_youtube_players()):foyer_slide_bg_video_load_youtube_api()}),jQuery("body").on("slides:loaded-new-slide-group",foyer_slides_selector,function(e){foyer_yt_api_ready?foyer_slide_bg_video_init_video_placeholders():foyer_slide_bg_video_load_youtube_api()}),jQuery("body").on("slides:removed-old-slide-group",foyer_slides_selector,function(e){foyer_slide_bg_video_cleanup_youtube_players()})}function foyer_slide_bg_video_bind_ticker_events(){jQuery("body").on("slides:before-binding-events",foyer_slides_selector,function(e){jQuery("body").on("slides:next-slide",foyer_slides_selector,function(e){var o=jQuery(foyer_slide_bg_video_selector).filter(".active").find(".youtube-video-container"),t=window.foyer_yt_players[o.attr("id")];if(1==o.data("foyer-hold-slide")&&t&&"function"==typeof t.playVideo){var i=o.data("foyer-video-end"),r=t.getDuration(),s=t.getCurrentTime();(r=i-foyer_ticker_css_transition_duration||(e.stopImmediatePropagation(),setTimeout(function(){jQuery(foyer_slides_selector).trigger("slides:next-slide")},500))}})}),jQuery("body").on("slide:became-active",foyer_slide_bg_video_selector,function(e){var o=jQuery(this).find(".youtube-video-container"),t=window.foyer_yt_players[o.attr("id")];t&&"function"==typeof t.playVideo&&t.playVideo()}),jQuery("body").on("slide:left-active",foyer_slide_bg_video_selector,function(e){var o=jQuery(this).find(".youtube-video-container"),t=window.foyer_yt_players[o.attr("id")];t&&"function"==typeof t.playVideo&&setTimeout(function(){t.seekTo(o.data("foyer-video-start")),t.pauseVideo()},1e3*foyer_ticker_css_transition_duration)})}function foyer_slide_bg_video_cleanup_youtube_players(){for(var e in window.foyer_yt_players)jQuery("#"+e).length||(delete window.foyer_yt_players[e],jQuery(window).off("resize",function(){foyer_slide_bg_video_resize_youtube_to_cover(e)}))}function foyer_slide_bg_video_init_video_placeholders(){jQuery("div.youtube-video-container").each(function(){var e=jQuery(this);e.attr("id","player-"+Math.random().toString(36).substr(2,16));var o=e.attr("id"),t=e.data("foyer-video-id");o&&t&&(window.foyer_yt_players[o]=new YT.Player(o,{width:"1920",height:"1080",videoId:t,playerVars:{controls:0,modestbranding:1,rel:0,showinfo:0,playsinline:1},events:{onReady:foyer_slide_bg_video_prepare_player_for_playback(o)}}))})}function foyer_slide_bg_video_load_youtube_api(){var e=document.createElement("script");e.src="https://www.youtube.com/iframe_api";var o=document.getElementsByTagName("script")[0];o.parentNode.insertBefore(e,o)}function foyer_slide_bg_video_prepare_player_for_playback(e){return function(o){var t=jQuery("#"+e),i=window.foyer_yt_players[e];foyer_slide_bg_video_resize_youtube_to_cover(e),jQuery(window).on("resize",function(){foyer_slide_bg_video_resize_youtube_to_cover(e)}),window.self!=window.top&&-1!=top.location.href.search("/post.php?")||(t.data("foyer-output-sound")||i.mute(),i.seekTo(t.data("foyer-video-start")),jQuery(foyer_slides_selector).length&&!jQuery("#"+e).parents(foyer_slide_bg_video_selector).hasClass("active")&&i.pauseVideo())}}function foyer_slide_bg_video_resize_youtube_to_cover(e){var o=jQuery("#"+e),t=window.foyer_yt_players[e],i=jQuery(window).width()+0,r=jQuery(window).height()+0;if(i/r>16/9){var s=i/16*9;t.setSize(i,s),o.css({left:"0px"})}else{var _=r/9*16;t.setSize(_,r),o.css({left:-(_-i)/2})}}function onYouTubeIframeAPIReady(){foyer_yt_api_ready=!0,foyer_slide_bg_video_init_video_placeholders()}function foyer_slide_bg_html5_video_bind_ticker_events(){jQuery("body").on("slides:before-binding-events",foyer_slides_selector,function(e){jQuery("body").on("slides:next-slide",foyer_slides_selector,function(e){var o=jQuery(foyer_slide_bg_html5_video_selector).filter(".active").find(".html5-video-container"),t=o.find("video").get(0);t&&1==o.data("foyer-hold-slide")&&t.currentTime>0&&!t.paused&&!t.ended&&t.readyState>2&&(foyer_slide_bg_html5_video_is_almost_ended(o,t)||(e.stopImmediatePropagation(),setTimeout(function(){jQuery(foyer_slides_selector).trigger("slides:next-slide")},500)))})}),jQuery("body").on("slide:became-active",foyer_slide_bg_html5_video_selector,function(e){objectFitPolyfill();var o=jQuery(this).find(".html5-video-container"),t=o.find("video").get(0);t&&(o.data("foyer-output-sound")?t.muted=!1:t.muted=!0,t.addEventListener("playing",function e(){this.removeEventListener("playing",e,!1),this.currentTime=o.data("foyer-video-start")},!1),t.play())}),jQuery("body").on("slide:left-active",foyer_slide_bg_html5_video_selector,function(e){var o=jQuery(this).find(".html5-video-container"),t=o.find("video").get(0);t&&setTimeout(function(){t.pause()},1e3*foyer_ticker_css_transition_duration)})}function foyer_slide_bg_html5_video_is_almost_ended(e,o){if(o){var t=e.data("foyer-video-end"),i=o.duration,r=o.currentTime;if((i=t-foyer_ticker_css_transition_duration)return!0}return!1}function foyer_ticker_bind_events(){jQuery(foyer_slides_selector).trigger("slides:before-binding-events"),jQuery("body").on("slides:next-slide",foyer_slides_selector,function(e){var o=jQuery(foyer_slide_selector+".active");o.trigger("slide:leaving-active");var t=o.next();t.length||(t=jQuery(foyer_slide_selector).first());var i=t.next();i.length||(i=jQuery(foyer_slide_selector).first()),foyer_ticker_shutdown_status?(foyer_ticker_shutdown_status=!1,setTimeout(function(){foyer_ticker_shutdown_callback(foyer_ticker_shutdown_callback_options)},1e3*foyer_ticker_css_transition_duration_safe)):(t.trigger("slide:becoming-active"),i.trigger("slide:becoming-next"),foyer_ticker_set_active_slide_timeout())}),jQuery("body").on("slide:becoming-next",foyer_slide_selector,function(e){jQuery(this).addClass("next").trigger("slide:became-next")}),jQuery("body").on("slide:becoming-active",foyer_slide_selector,function(e){jQuery(this).removeClass("next").addClass("active").trigger("slide:became-active")}),jQuery("body").on("slide:leaving-active",foyer_slide_selector,function(e){jQuery(this).removeClass("active").trigger("slide:left-active")}),jQuery(foyer_slides_selector).trigger("slides:after-binding-events")}function foyer_ticker_init(){foyer_ticker_set_slide_active_next_classes(),foyer_ticker_set_active_slide_timeout()}function foyer_ticker_set_slide_active_next_classes(){jQuery(foyer_slide_selector).first().trigger("slide:becoming-active"),jQuery(foyer_slide_selector).first().next().trigger("slide:becoming-next")}function foyer_ticker_set_active_slide_timeout(){var e=parseFloat(jQuery(foyer_slide_selector+".active").data("foyer-slide-duration"));!e>0&&(e=5),setTimeout(foyer_ticker_next_slide,1e3*e)}function foyer_ticker_next_slide(){jQuery(foyer_slides_selector).trigger("slides:next-slide")}function foyer_ticker_shutdown(e,o){foyer_ticker_shutdown_status=!0,foyer_ticker_shutdown_callback=e,foyer_ticker_shutdown_callback_options=o}var foyer_display_selector=".foyer-display",foyer_channel_selector=".foyer-channel",foyer_slides_selector=".foyer-slides",foyer_slide_selector=".foyer-slide";jQuery(document).ready(function(){jQuery(foyer_display_selector).length&&(foyer_display_setup(),foyer_display_setup_slide_group_classes())}),function(){"use strict";if("undefined"!=typeof window){var e=window.navigator.userAgent.match(/Edge\/(\d{2})\./),o=!!e&&parseInt(e[1],10)>=16;if("objectFit"in document.documentElement.style!=0&&!o)return void(window.objectFitPolyfill=function(){return!1});var t=function(e){var o=window.getComputedStyle(e,null),t=o.getPropertyValue("position"),i=o.getPropertyValue("overflow"),r=o.getPropertyValue("display");t&&"static"!==t||(e.style.position="relative"),"hidden"!==i&&(e.style.overflow="hidden"),r&&"inline"!==r||(e.style.display="block"),0===e.clientHeight&&(e.style.height="100%"),-1===e.className.indexOf("object-fit-polyfill")&&(e.className=e.className+" object-fit-polyfill")},i=function(e){var o=window.getComputedStyle(e,null),t={"max-width":"none","max-height":"none","min-width":"0px","min-height":"0px",top:"auto",right:"auto",bottom:"auto",left:"auto","margin-top":"0px","margin-right":"0px","margin-bottom":"0px","margin-left":"0px"};for(var i in t)o.getPropertyValue(i)!==t[i]&&(e.style[i]=t[i])},r=function(e){var o=e.parentNode;t(o),i(e),e.style.position="absolute",e.style.height="100%",e.style.width="auto",e.clientWidth>o.clientWidth?(e.style.top="0",e.style.marginTop="0",e.style.left="50%",e.style.marginLeft=e.clientWidth/-2+"px"):(e.style.width="100%",e.style.height="auto",e.style.left="0",e.style.marginLeft="0",e.style.top="50%",e.style.marginTop=e.clientHeight/-2+"px")},s=function(e){if(void 0===e)e=document.querySelectorAll("[data-object-fit]");else if(e&&e.nodeName)e=[e];else{if("object"!=typeof e||!e.length||!e[0].nodeName)return!1;e=e}for(var t=0;t0?r(e[t]):e[t].addEventListener("loadedmetadata",function(){r(this)})):e[t].complete?r(e[t]):e[t].addEventListener("load",function(){r(this)})}return!0};document.addEventListener("DOMContentLoaded",function(){s()}),window.addEventListener("resize",function(){s()}),window.objectFitPolyfill=s}}();var foyer_slide_bg_video_selector=".foyer-slide-background-video",foyer_yt_players={},foyer_yt_api_ready=!1;jQuery(document).ready(function(){foyer_slide_bg_video_load_youtube_api(),foyer_slide_bg_video_bind_display_loading_events(),foyer_slide_bg_video_bind_ticker_events()});var foyer_slide_bg_html5_video_selector=".foyer-slide-background-html5-video";jQuery(document).ready(function(){foyer_slide_bg_html5_video_bind_ticker_events()});var foyer_ticker_shutdown_status=!1,foyer_ticker_shutdown_callback,foyer_ticker_shutdown_callback_options,foyer_ticker_css_transition_duration=1.5,foyer_ticker_css_transition_duration_safe=foyer_ticker_css_transition_duration+.5;jQuery(document).ready(function(){jQuery(foyer_slides_selector).length&&(foyer_ticker_bind_events(),foyer_ticker_init())});
--------------------------------------------------------------------------------
/admin/class-foyer-admin-slide.php:
--------------------------------------------------------------------------------
1 |
12 | */
13 | class Foyer_Admin_Slide {
14 |
15 | /**
16 | * Adds the channel editor meta box to the display admin page.
17 | *
18 | * @since 1.0.0
19 | * @since 1.3.1 Updated the slide_default_meta_box callback, after method was moved to Foyer_Admin_Slide_Format_Default.
20 | * @since 1.3.2 Changed method to static.
21 | * @since 1.4.0 Removed value for $meta_box_callback for default slide format, as this value is now defined in the
22 | * slide format properties, same as for the other slide formats.
23 | * Switched to a single metabox holding format and background selects and content.
24 | */
25 | static function add_slide_editor_meta_boxes() {
26 | add_meta_box(
27 | 'foyer_slide_content',
28 | __( 'Slide content' , 'foyer' ),
29 | array( __CLASS__, 'slide_content_meta_box' ),
30 | Foyer_Slide::post_type_name,
31 | 'normal',
32 | 'low'
33 | );
34 | }
35 |
36 | /**
37 | * Adds a Slide Format column to the Slides admin table, just after the title column.
38 | *
39 | * @since 1.0.0
40 | * @since 1.3.2 Changed method to static.
41 | * @since 1.5.1 Renamed column from 'Slide format' to 'Slide format, background'.
42 | *
43 | * @param array $columns The current columns.
44 | * @return array The new columns.
45 | */
46 | static function add_slide_format_column( $columns ) {
47 | $new_columns = array();
48 |
49 | foreach( $columns as $key => $title ) {
50 | $new_columns[$key] = $title;
51 |
52 | if ( 'title' == $key ) {
53 | // Add slides count column after the title column
54 | $new_columns['slide_format'] = __( 'Slide format, background', 'foyer' );
55 | }
56 | }
57 | return $new_columns;
58 | }
59 |
60 | /**
61 | * Outputs the Slide Format column.
62 | *
63 | * @since 1.0.0
64 | * @since 1.3.2 Changed method to static.
65 | * @since 1.5.1 Added the slide background to the output.
66 | *
67 | * @param string $column The current column that needs output.
68 | * @param int $post_id The current display ID.
69 | * @return void
70 | */
71 | static function do_slide_format_column( $column, $post_id ) {
72 | if ( 'slide_format' == $column ) {
73 |
74 | $slide = new Foyer_Slide( $post_id );
75 |
76 | $format = Foyer_Slides::get_slide_format_by_slug( $slide->get_format() );
77 | $background = Foyer_Slides::get_slide_background_by_slug( $slide->get_background() );
78 |
79 | echo esc_html( $format['title'] ) . ' ' . esc_html( $background['title'] );
80 | }
81 | }
82 |
83 | /**
84 | * Localizes the JavaScript for the slide admin area.
85 | *
86 | * @since 1.0.0
87 | * @since 1.0.1 Escaped the output.
88 | * @since 1.1.3 Fixed a Javascript issue where adding an image to a slide was only possible when
89 | * the image was already in the media library. Removed 'photo' default as it is no
90 | * longer needed by our Javascript.
91 | * @since 1.3.1 Changed handle of script to {plugin_name}-admin.
92 | * @since 1.3.2 Changed method to static.
93 | * @since 1.4.0 Renamed slide_format_default to slide_image_defaults.
94 | * Added the slide formats backgrounds.
95 | * @since 1.6.0 Renamed slide_image_defaults to slide_file_defaults and added texts for different file types.
96 | *
97 | */
98 | static function localize_scripts() {
99 | $slide_file_defaults = array(
100 | 'image' => array(
101 | 'text_select' => esc_html__( 'Select an image', 'foyer' ),
102 | 'text_use' => esc_html__( 'Use this image', 'foyer' ),
103 | ),
104 | 'application/pdf' => array(
105 | 'text_select' => esc_html__( 'Select a PDF', 'foyer' ),
106 | 'text_use' => esc_html__( 'Use this PDF', 'foyer' ),
107 | ),
108 | 'video' => array(
109 | 'text_select' => esc_html__( 'Select a video', 'foyer' ),
110 | 'text_use' => esc_html__( 'Use this video', 'foyer' ),
111 | ),
112 | );
113 | wp_localize_script( Foyer::get_plugin_name() . '-admin', 'foyer_slide_file_defaults', $slide_file_defaults );
114 |
115 | $slide_formats_backgrounds = Foyer_Slides::get_slide_formats_backgrounds();
116 | wp_localize_script( Foyer::get_plugin_name() . '-admin', 'foyer_slide_formats_backgrounds', $slide_formats_backgrounds );
117 | }
118 |
119 | /**
120 | * Removes the sample permalink from the Slide edit screen.
121 | *
122 | * @since 1.0.0
123 | * @since 1.3.2 Changed method to static.
124 | *
125 | * @param string $sample_permalink
126 | * @return string
127 | */
128 | static function remove_sample_permalink( $sample_permalink ) {
129 |
130 | $screen = get_current_screen();
131 |
132 | // Bail if not on Slide edit screen.
133 | if ( empty( $screen ) || Foyer_Slide::post_type_name != $screen->post_type ) {
134 | return $sample_permalink;
135 | }
136 |
137 | return '';
138 | }
139 |
140 | /**
141 | * Saves all custom fields for a display.
142 | *
143 | * Triggered when a display is submitted from the display admin form.
144 | *
145 | * @since 1.0.0
146 | * @since 1.3.1 Updated the save_slide_default call, after method was moved to Foyer_Admin_Slide_Format_Default.
147 | * @since 1.3.2 Changed method to static.
148 | * @since 1.4.0 Removed call_user_func_array() for default slide format, as the callback is now defined in the
149 | * slide format properties, same as for the other slide formats.
150 | * Saves the slide background value, and invokes saving the background's fields through a callback.
151 | *
152 | * @param int $post_id The channel id.
153 | * @return void
154 | */
155 | static function save_slide( $post_id ) {
156 |
157 | /*
158 | * We need to verify this came from our screen and with proper authorization,
159 | * because save_post can be triggered at other times.
160 | */
161 |
162 | /* Check if our nonce is set */
163 | if ( ! isset( $_POST[Foyer_Slide::post_type_name.'_nonce'] ) ) {
164 | return $post_id;
165 | }
166 |
167 | $nonce = $_POST[Foyer_Slide::post_type_name.'_nonce'];
168 |
169 | /* Verify that the nonce is valid */
170 | if ( ! wp_verify_nonce( $nonce, Foyer_Slide::post_type_name ) ) {
171 | return $post_id;
172 | }
173 |
174 | /* If this is an autosave, our form has not been submitted, so we don't want to do anything */
175 | if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
176 | return $post_id;
177 | }
178 |
179 | /* Check the user's permissions */
180 | if ( ! current_user_can( 'edit_post', $post_id ) ) {
181 | return $post_id;
182 | }
183 |
184 | if ( ! isset( $_POST['slide_format'] ) || ! isset( $_POST['slide_background'] ) ) {
185 | return $post_id;
186 | }
187 |
188 | /* Slide format */
189 | $slide_format_slug = sanitize_title( $_POST['slide_format'] );
190 | $slide_format = Foyer_Slides::get_slide_format_by_slug( $slide_format_slug );
191 |
192 | /* Slide background */
193 | $slide_background_slug = sanitize_title( $_POST['slide_background'] );
194 | $slide_background = Foyer_Slides::get_slide_background_by_slug_for_slide_format( $slide_background_slug, $slide_format_slug );
195 |
196 | if ( empty( $slide_format ) || empty( $slide_background ) ) {
197 | // Submitted slide format or slide background does not exist, bail
198 | return $post_id;
199 | }
200 |
201 | update_post_meta( $post_id, 'slide_format', $slide_format_slug );
202 |
203 | if ( ! empty( $slide_format['save_post'] ) ) {
204 | call_user_func_array( $slide_format['save_post'], array( $post_id ) );
205 | }
206 |
207 | update_post_meta( $post_id, 'slide_background', $slide_background_slug );
208 |
209 | if ( ! empty( $slide_background['save_post'] ) ) {
210 | call_user_func_array( $slide_background['save_post'], array( $post_id ) );
211 | }
212 | }
213 |
214 | /**
215 | * Outputs the content of the meta box holding all slide background choices.
216 | *
217 | * @since 1.4.0
218 | *
219 | * @param WP_Post $post The post object of the current slide.
220 | * @return void
221 | */
222 | static function slide_background_meta_box( $post ) {
223 |
224 | wp_nonce_field( Foyer_Slide::post_type_name, Foyer_Slide::post_type_name.'_nonce' );
225 |
226 | $slide = new Foyer_Slide( $post->ID );
227 |
228 | ?> $slide_background_data ) {
232 | ?>
233 | get_background(), $slide_background_key, true ); ?> />
234 |
235 | ID );
262 |
263 | ?>
291 |
292 |
293 |
320 |
321 | $slide_background_data ) {
324 |
325 | ?>
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 | ID ) ) ); ?>
341 |
342 |
343 |
345 |
346 |
$slide_format_data ) {
361 | if ( $stack == Foyer_Slides::slide_format_is_stack( $slide_format_key ) ) {
362 |
363 | ?>get_format(), $slide_format_key, true ); ?>>
364 |
365 |
12 | */
13 | class Foyer_Admin_Display {
14 |
15 | /**
16 | * Adds Default Channel and Active Channel columns to the Displays admin table.
17 | *
18 | * Also removes the Date column.
19 | *
20 | * @since 1.0.0
21 | * @since 1.3.2 Changed method to static.
22 | *
23 | * @param array $columns The current columns.
24 | * @return array The new columns.
25 | */
26 | static function add_channel_columns($columns) {
27 | unset($columns['date']);
28 | return array_merge($columns,
29 | array(
30 | 'default_channel' => __('Default channel', 'foyer'),
31 | 'active_channel' => __('Active channel', 'foyer'),
32 | )
33 | );
34 | }
35 |
36 | /**
37 | * Adds the channel editor meta box to the display admin page.
38 | *
39 | * @since 1.0.0
40 | * @since 1.3.2 Changed method to static.
41 | * @since 1.5.1 Added context to the translatable string 'Channel' to make translation easier.
42 | */
43 | static function add_channel_editor_meta_box() {
44 | add_meta_box(
45 | 'foyer_channel_editor',
46 | _x( 'Channel', 'channel cpt', 'foyer' ),
47 | array( __CLASS__, 'channel_editor_meta_box' ),
48 | Foyer_Display::post_type_name,
49 | 'normal',
50 | 'high'
51 | );
52 | }
53 |
54 | /**
55 | * Adds the channel scheduler meta box to the display admin page.
56 | *
57 | * @since 1.0.0
58 | * @since 1.3.2 Changed method to static.
59 | */
60 | static function add_channel_scheduler_meta_box() {
61 | add_meta_box(
62 | 'foyer_channel_scheduler',
63 | __( 'Schedule temporary channel' , 'foyer' ),
64 | array( __CLASS__, 'channel_scheduler_meta_box' ),
65 | Foyer_Display::post_type_name,
66 | 'normal',
67 | 'high'
68 | );
69 | }
70 |
71 | /**
72 | * Outputs the content of the channel editor meta box.
73 | *
74 | * @since 1.0.0
75 | * @since 1.0.1 Sanitized the output.
76 | * @since 1.3.2 Changed method to static.
77 | *
78 | * @param WP_Post $post The post object of the current display.
79 | */
80 | static function channel_editor_meta_box( $post ) {
81 |
82 | wp_nonce_field( Foyer_Display::post_type_name, Foyer_Display::post_type_name.'_nonce' );
83 |
84 | ob_start();
85 |
86 | ?>
87 |
89 |
90 |
99 |
100 |
123 |
125 |
126 |
135 |
136 | get_active_channel() ) {
165 | _e( 'None', 'foyer' );
166 | break;
167 | }
168 |
169 | $channel = new Foyer_Channel( $active_channel_id );
170 |
171 | ?>ID ) );
173 | ?> get_default_channel() ) {
182 | _e( 'None', 'foyer' );
183 | break;
184 | }
185 |
186 | $channel = new Foyer_Channel( $default_channel_id );
187 |
188 | ?>ID ) );
190 | ?> 'Y-m-d H:i',
209 | 'duration' => 1 * 60 * 60, // one hour in seconds
210 | 'locale' => $language_parts[0], // locale formatted as 'en' instead of 'en-US'
211 | 'start_of_week' => get_option( 'start_of_week' ),
212 | );
213 |
214 | /**
215 | * Filters the channel scheduler defaults.
216 | *
217 | * @since 1.0.0
218 | *
219 | * @param array $defaults The current defaults to be used in the channel scheduler.
220 | */
221 | return apply_filters( 'foyer/channel_scheduler/defaults', $defaults );
222 | }
223 |
224 | /**
225 | * Gets the HTML that lists the default channel in the channel editor.
226 | *
227 | * @since 1.0.0
228 | * @since 1.0.1 Escaped and sanitized the output.
229 | * @since 1.2.3 Changed the list of available channels from limited to unlimited.
230 | * @since 1.3.2 Changed method to static.
231 | *
232 | * @param WP_Post $post
233 | * @return string $html The HTML that lists the default channel in the channel editor.
234 | */
235 | static function get_default_channel_html( $post ) {
236 |
237 | $display = new Foyer_Display( $post );
238 | $default_channel = $display->get_default_channel();
239 |
240 | ob_start();
241 |
242 | ?>
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 | ()
252 | ID ) {
257 | $checked = 'selected="selected"';
258 | }
259 | ?>
260 | >ID ) ); ?>
261 |
264 |
265 |
266 |
267 | get_schedule();
291 |
292 | if ( !empty( $schedule ) ) {
293 | $scheduled_channel = $schedule[0];
294 | }
295 |
296 | $channel_scheduler_defaults = self::get_channel_scheduler_defaults();
297 |
298 | ob_start();
299 |
300 | ?>
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 | ()
310 | ID ) {
315 | $checked = 'selected="selected"';
316 | }
317 | ?>
318 | >post_title ); ?>
319 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 | $foyer_channel_editor_scheduled_channel,
481 | 'start' => $start,
482 | 'end' => $end,
483 | );
484 |
485 | add_post_meta( $display_id, 'foyer_display_schedule', $schedule, false );
486 | }
487 | }
488 |
--------------------------------------------------------------------------------
/public/css/foyer-public.css:
--------------------------------------------------------------------------------
1 | body.single-foyer_display.admin-bar,
2 | body.single-foyer_channel.admin-bar,
3 | body.single-foyer_slide.admin-bar {
4 | display: -webkit-box;
5 | display: -ms-flexbox;
6 | display: flex;
7 | -webkit-box-align: center;
8 | -ms-flex-align: center;
9 | align-items: center;
10 | height: auto;
11 | background-color: #555;
12 | }
13 | .foyer-preview-9-16,
14 | .foyer-preview-16-9 {
15 | margin: 0 auto;
16 | display: block;
17 | border: none;
18 | -webkit-transition: .5s all ease;
19 | transition: .5s all ease;
20 | margin-top: -45px;
21 | }
22 | @media screen and (max-width: 782px) {
23 | .foyer-preview-9-16,
24 | .foyer-preview-16-9 {
25 | margin-top: -45px;
26 | }
27 | }
28 | .foyer-preview-9-16 {
29 | width: calc(54vh - 43.3125px);
30 | height: calc(96vh - 77px);
31 | }
32 | @media screen and (max-width: 782px) {
33 | .foyer-preview-9-16 {
34 | width: calc(54vh - 51.1875px);
35 | height: calc(96vh - 91px);
36 | }
37 | }
38 | .foyer-preview-16-9 {
39 | width: calc(96vh - 77px);
40 | height: calc(54vh - 43.3125px);
41 | }
42 | @media screen and (max-width: 782px) {
43 | .foyer-preview-16-9 {
44 | width: calc(96vh - 91px);
45 | height: calc(54vh - 51.1875px);
46 | }
47 | }
48 | .foyer-preview-actions {
49 | position: fixed;
50 | z-index: 999;
51 | bottom: 0;
52 | height: 45px;
53 | border-top: 1px solid #eee;
54 | background: #eee;
55 | width: 100%;
56 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
57 | font-size: 13px;
58 | font-weight: 400;
59 | line-height: 32px;
60 | -webkit-font-smoothing: subpixel-antialiased;
61 | -moz-osx-font-smoothing: auto;
62 | text-align: center;
63 | }
64 | .foyer-preview-actions div {
65 | display: inline-block;
66 | cursor: pointer;
67 | border: none;
68 | height: 44px;
69 | margin: 0;
70 | padding: 4px 8px;
71 | -webkit-box-shadow: none;
72 | box-shadow: none;
73 | border-bottom: 4px solid transparent;
74 | -webkit-transition: 0.15s color ease-in-out, 0.15s background-color ease-in-out, 0.15s border-color ease-in-out;
75 | transition: 0.15s color ease-in-out, 0.15s background-color ease-in-out, 0.15s border-color ease-in-out;
76 | font: inherit;
77 | color: #72777c;
78 | outline: none;
79 | }
80 | .foyer-preview-actions div:hover {
81 | background-color: #fff;
82 | color: #0073aa;
83 | }
84 | .foyer-preview-actions div:hover.active {
85 | border-color: #0073aa;
86 | }
87 | .foyer-preview-actions div.active {
88 | border-color: #23282d;
89 | color: #23282d;
90 | }
91 | .foyer-preview-actions div.active:hover {
92 | color: #0073aa;
93 | border-color: #0073aa;
94 | }
95 | body.single-foyer_display,
96 | body.single-foyer_channel,
97 | body.single-foyer_slide {
98 | margin: 0;
99 | padding: 0;
100 | width: 100vw;
101 | height: 100vh;
102 | max-width: none;
103 | max-height: none;
104 | -webkit-font-smoothing: antialiased;
105 | -moz-font-smoothing: antialiased;
106 | -o-font-smoothing: antialiased;
107 | -moz-osx-font-smoothing: grayscale;
108 | -webkit-text-size-adjust: 100%;
109 | -ms-text-size-adjust: 100%;
110 | -webkit-box-sizing: border-box;
111 | box-sizing: border-box;
112 | }
113 | body.single-foyer_display *,
114 | body.single-foyer_channel *,
115 | body.single-foyer_slide * {
116 | -webkit-box-sizing: border-box;
117 | box-sizing: border-box;
118 | }
119 | body.single-foyer_display:not(.custom-background-image):before,
120 | body.single-foyer_channel:not(.custom-background-image):before,
121 | body.single-foyer_slide:not(.custom-background-image):before,
122 | body.single-foyer_display:not(.custom-background-image):after,
123 | body.single-foyer_channel:not(.custom-background-image):after,
124 | body.single-foyer_slide:not(.custom-background-image):after {
125 | display: none;
126 | }
127 | .foyer-display,
128 | .foyer-channel,
129 | .foyer-slides {
130 | width: 100%;
131 | height: 100%;
132 | }
133 | .foyer-slide {
134 | overflow: hidden;
135 | }
136 | .foyer-transition-fade .foyer-slides {
137 | position: relative;
138 | overflow: hidden;
139 | width: 100%;
140 | z-index: 1;
141 | }
142 | .foyer-transition-fade .foyer-slides .foyer-slide {
143 | width: 100%;
144 | position: absolute;
145 | left: 100%;
146 | top: 0;
147 | -webkit-backface-visibility: hidden;
148 | /* fixes a Chrome opacity transition bug */
149 | opacity: 0;
150 | -webkit-transition: opacity 1.5s ease, left 0s ease 1.5s;
151 | transition: opacity 1.5s ease, left 0s ease 1.5s;
152 | }
153 | .foyer-transition-fade .foyer-slides .foyer-slide:first-child {
154 | position: relative;
155 | opacity: 0;
156 | left: 0;
157 | z-index: 2;
158 | }
159 | .foyer-transition-fade .foyer-slides .foyer-slide.active {
160 | opacity: 1;
161 | left: 0;
162 | z-index: 3;
163 | -webkit-transition: left 0s, opacity 1.5s ease;
164 | transition: left 0s, opacity 1.5s ease;
165 | }
166 | .foyer-transition-slide .foyer-slides {
167 | position: relative;
168 | overflow: hidden;
169 | width: 100%;
170 | z-index: 1;
171 | }
172 | .foyer-transition-slide .foyer-slides .foyer-slide {
173 | width: 100%;
174 | position: absolute;
175 | left: -100%;
176 | top: 0;
177 | bottom: 0;
178 | opacity: 0;
179 | -webkit-transition: left 1.5s ease, opacity 0s ease 1.5s;
180 | transition: left 1.5s ease, opacity 0s ease 1.5s;
181 | }
182 | .foyer-transition-slide .foyer-slides .foyer-slide.active {
183 | left: 0;
184 | opacity: 1;
185 | z-index: 2;
186 | -webkit-transition: opacity 0s, left 1.5s ease;
187 | transition: opacity 0s, left 1.5s ease;
188 | }
189 | .foyer-transition-slide .foyer-slides .foyer-slide.next {
190 | left: 100%;
191 | opacity: 1;
192 | z-index: 2;
193 | -webkit-transition: left 0s ease, opacity 0s ease;
194 | transition: left 0s ease, opacity 0s ease;
195 | }
196 | .foyer-transition-none .foyer-slides {
197 | position: relative;
198 | overflow: hidden;
199 | width: 100%;
200 | z-index: 1;
201 | }
202 | .foyer-transition-none .foyer-slides .foyer-slide {
203 | display: none;
204 | }
205 | .foyer-transition-none .foyer-slides .foyer-slide.active {
206 | display: block;
207 | }
208 | html {
209 | font-size: 100% !important;
210 | font-size: 1.48148148vmin !important;
211 | }
212 | .foyer-slide {
213 | width: 100%;
214 | height: 100%;
215 | background-color: #fff;
216 | position: relative;
217 | z-index: 1;
218 | overflow: hidden;
219 | }
220 | .foyer-slide .foyer-slide-field {
221 | color: #000;
222 | font-size: 2rem;
223 | line-height: 1.2;
224 | }
225 | .foyer-slide .foyer-slide-field.foyer-slide-field-title {
226 | font-size: 5rem;
227 | font-weight: bold;
228 | margin-bottom: 1rem;
229 | }
230 | .foyer-slide .foyer-slide-field.foyer-slide-field-pretitle,
231 | .foyer-slide .foyer-slide-field.foyer-slide-field-subtitle {
232 | font-size: 3rem;
233 | font-weight: bold;
234 | margin-bottom: 1rem;
235 | }
236 | .foyer-slide .foyer-slide-field.foyer-slide-field-date {
237 | font-size: 3rem;
238 | margin-bottom: 1rem;
239 | }
240 | .foyer-slide .foyer-slide-field.foyer-slide-field-content > *:last-child {
241 | margin-bottom: 0;
242 | }
243 | .foyer-slide .foyer-slide-background {
244 | position: absolute;
245 | top: 0;
246 | bottom: 0;
247 | left: 0;
248 | right: 0;
249 | z-index: -1;
250 | overflow: hidden;
251 | }
252 | .foyer-slide.foyer-slide-iframe iframe {
253 | width: 100%;
254 | height: 100%;
255 | border: none;
256 | margin: 0;
257 | padding: 0;
258 | }
259 | .foyer-slide.foyer-slide-pdf figure {
260 | margin: 0;
261 | }
262 | .foyer-slide.foyer-slide-pdf figure img {
263 | width: 100%;
264 | height: 100%;
265 | -o-object-fit: contain;
266 | object-fit: contain;
267 | }
268 | .foyer-slide.foyer-slide-post .inner {
269 | display: -webkit-box;
270 | display: -ms-flexbox;
271 | display: flex;
272 | width: 100%;
273 | height: 100%;
274 | }
275 | .foyer-slide.foyer-slide-post .inner figure,
276 | .foyer-slide.foyer-slide-post .inner .foyer-slide-fields {
277 | -webkit-box-flex: 0;
278 | -ms-flex: 0 0 auto;
279 | flex: 0 0 auto;
280 | width: auto;
281 | height: auto;
282 | }
283 | .foyer-slide.foyer-slide-post .inner figure {
284 | margin: 0;
285 | }
286 | .foyer-slide.foyer-slide-post .inner figure img {
287 | width: 100%;
288 | height: 100%;
289 | -o-object-fit: cover;
290 | object-fit: cover;
291 | }
292 | .foyer-slide.foyer-slide-post .inner .foyer-slide-fields {
293 | display: -webkit-box;
294 | display: -ms-flexbox;
295 | display: flex;
296 | -webkit-box-orient: vertical;
297 | -webkit-box-direction: normal;
298 | -ms-flex-direction: column;
299 | flex-direction: column;
300 | -webkit-box-pack: center;
301 | -ms-flex-pack: center;
302 | justify-content: center;
303 | padding: 4vmin;
304 | }
305 | .foyer-slide.foyer-slide-post .inner .foyer-slide-fields .foyer-slide-field-title span,
306 | .foyer-slide.foyer-slide-post .inner .foyer-slide-fields .foyer-slide-field-date span,
307 | .foyer-slide.foyer-slide-post .inner .foyer-slide-fields .foyer-slide-field-content {
308 | line-height: 1.5;
309 | padding: 0.5rem 1rem;
310 | background-color: rgba(255, 255, 255, 0.8);
311 | -webkit-box-decoration-break: clone;
312 | box-decoration-break: clone;
313 | }
314 | .foyer-slide.foyer-slide-post .inner .foyer-slide-fields .foyer-slide-field-date span {
315 | line-height: 1.7;
316 | }
317 | .foyer-slide.foyer-slide-post .inner .foyer-slide-fields .foyer-slide-field-content {
318 | padding: 1.5rem 1rem;
319 | }
320 | @media (min-aspect-ratio: 1/1) {
321 | .foyer-slide.foyer-slide-post .inner {
322 | -webkit-box-orient: horizontal;
323 | -webkit-box-direction: normal;
324 | -ms-flex-direction: row;
325 | flex-direction: row;
326 | }
327 | .foyer-slide.foyer-slide-post .inner .foyer-slide-fields {
328 | width: 66.66666667%;
329 | }
330 | .foyer-slide.foyer-slide-post .inner figure,
331 | .foyer-slide.foyer-slide-post .inner figure + .foyer-slide-fields {
332 | width: 50%;
333 | }
334 | }
335 | @media (max-aspect-ratio: 1/1) {
336 | .foyer-slide.foyer-slide-post .inner {
337 | -webkit-box-orient: vertical;
338 | -webkit-box-direction: normal;
339 | -ms-flex-direction: column;
340 | flex-direction: column;
341 | -webkit-box-pack: end;
342 | -ms-flex-pack: end;
343 | justify-content: flex-end;
344 | }
345 | .foyer-slide.foyer-slide-post .inner figure,
346 | .foyer-slide.foyer-slide-post .inner figure + .foyer-slide-fields {
347 | height: 50%;
348 | }
349 | }
350 | .foyer-slide.foyer-slide-production .foyer-slide-fields {
351 | position: absolute;
352 | bottom: 0;
353 | left: 0;
354 | right: 0;
355 | padding: 2vmin 4vmin;
356 | background-color: rgba(255, 255, 255, 0.8);
357 | }
358 | .foyer-slide.foyer-slide-recent-posts .inner {
359 | display: -webkit-box;
360 | display: -ms-flexbox;
361 | display: flex;
362 | width: 100%;
363 | height: 100%;
364 | }
365 | .foyer-slide.foyer-slide-recent-posts .inner figure,
366 | .foyer-slide.foyer-slide-recent-posts .inner .foyer-slide-fields {
367 | -webkit-box-flex: 0;
368 | -ms-flex: 0 0 auto;
369 | flex: 0 0 auto;
370 | width: auto;
371 | height: auto;
372 | }
373 | .foyer-slide.foyer-slide-recent-posts .inner figure {
374 | margin: 0;
375 | }
376 | .foyer-slide.foyer-slide-recent-posts .inner figure img {
377 | width: 100%;
378 | height: 100%;
379 | -o-object-fit: cover;
380 | object-fit: cover;
381 | }
382 | .foyer-slide.foyer-slide-recent-posts .inner .foyer-slide-fields {
383 | display: -webkit-box;
384 | display: -ms-flexbox;
385 | display: flex;
386 | -webkit-box-orient: vertical;
387 | -webkit-box-direction: normal;
388 | -ms-flex-direction: column;
389 | flex-direction: column;
390 | -webkit-box-pack: center;
391 | -ms-flex-pack: center;
392 | justify-content: center;
393 | padding: 4vmin;
394 | }
395 | .foyer-slide.foyer-slide-recent-posts .inner .foyer-slide-fields .foyer-slide-field-title span,
396 | .foyer-slide.foyer-slide-recent-posts .inner .foyer-slide-fields .foyer-slide-field-date span,
397 | .foyer-slide.foyer-slide-recent-posts .inner .foyer-slide-fields .foyer-slide-field-content {
398 | line-height: 1.5;
399 | padding: 0.5rem 1rem;
400 | background-color: rgba(255, 255, 255, 0.8);
401 | -webkit-box-decoration-break: clone;
402 | box-decoration-break: clone;
403 | }
404 | .foyer-slide.foyer-slide-recent-posts .inner .foyer-slide-fields .foyer-slide-field-date span {
405 | line-height: 1.7;
406 | }
407 | .foyer-slide.foyer-slide-recent-posts .inner .foyer-slide-fields .foyer-slide-field-content {
408 | padding: 1.5rem 1rem;
409 | }
410 | @media (min-aspect-ratio: 1/1) {
411 | .foyer-slide.foyer-slide-recent-posts .inner {
412 | -webkit-box-orient: horizontal;
413 | -webkit-box-direction: normal;
414 | -ms-flex-direction: row;
415 | flex-direction: row;
416 | }
417 | .foyer-slide.foyer-slide-recent-posts .inner .foyer-slide-fields {
418 | width: 66.66666667%;
419 | }
420 | .foyer-slide.foyer-slide-recent-posts .inner figure,
421 | .foyer-slide.foyer-slide-recent-posts .inner figure + .foyer-slide-fields {
422 | width: 50%;
423 | }
424 | }
425 | @media (max-aspect-ratio: 1/1) {
426 | .foyer-slide.foyer-slide-recent-posts .inner {
427 | -webkit-box-orient: vertical;
428 | -webkit-box-direction: normal;
429 | -ms-flex-direction: column;
430 | flex-direction: column;
431 | -webkit-box-pack: end;
432 | -ms-flex-pack: end;
433 | justify-content: flex-end;
434 | }
435 | .foyer-slide.foyer-slide-recent-posts .inner figure,
436 | .foyer-slide.foyer-slide-recent-posts .inner figure + .foyer-slide-fields {
437 | height: 50%;
438 | }
439 | }
440 | .foyer-slide.foyer-slide-text .inner {
441 | display: -webkit-box;
442 | display: -ms-flexbox;
443 | display: flex;
444 | width: 100%;
445 | height: 100%;
446 | }
447 | .foyer-slide.foyer-slide-text .inner .foyer-slide-fields {
448 | -webkit-box-flex: 0;
449 | -ms-flex: 0 0 auto;
450 | flex: 0 0 auto;
451 | width: auto;
452 | height: auto;
453 | }
454 | .foyer-slide.foyer-slide-text .inner .foyer-slide-fields {
455 | display: -webkit-box;
456 | display: -ms-flexbox;
457 | display: flex;
458 | -webkit-box-orient: vertical;
459 | -webkit-box-direction: normal;
460 | -ms-flex-direction: column;
461 | flex-direction: column;
462 | -webkit-box-pack: center;
463 | -ms-flex-pack: center;
464 | justify-content: center;
465 | padding: 4vmin;
466 | }
467 | .foyer-slide.foyer-slide-text .inner .foyer-slide-fields .foyer-slide-field-pretitle span,
468 | .foyer-slide.foyer-slide-text .inner .foyer-slide-fields .foyer-slide-field-title span,
469 | .foyer-slide.foyer-slide-text .inner .foyer-slide-fields .foyer-slide-field-subtitle span,
470 | .foyer-slide.foyer-slide-text .inner .foyer-slide-fields .foyer-slide-field-content {
471 | line-height: 1.5;
472 | padding: 0.5rem 1rem;
473 | background-color: rgba(255, 255, 255, 0.8);
474 | -webkit-box-decoration-break: clone;
475 | box-decoration-break: clone;
476 | }
477 | .foyer-slide.foyer-slide-text .inner .foyer-slide-fields .foyer-slide-field-pretitle span,
478 | .foyer-slide.foyer-slide-text .inner .foyer-slide-fields .foyer-slide-field-subtitle span {
479 | line-height: 1.7;
480 | }
481 | .foyer-slide.foyer-slide-text .inner .foyer-slide-fields .foyer-slide-field-content {
482 | padding: 1.5rem 1rem;
483 | }
484 | @media (min-aspect-ratio: 1/1) {
485 | .foyer-slide.foyer-slide-text .inner {
486 | -webkit-box-orient: horizontal;
487 | -webkit-box-direction: normal;
488 | -ms-flex-direction: row;
489 | flex-direction: row;
490 | }
491 | .foyer-slide.foyer-slide-text .inner .foyer-slide-fields {
492 | width: 66.66666667%;
493 | }
494 | }
495 | @media (max-aspect-ratio: 1/1) {
496 | .foyer-slide.foyer-slide-text .inner {
497 | -webkit-box-orient: vertical;
498 | -webkit-box-direction: normal;
499 | -ms-flex-direction: column;
500 | flex-direction: column;
501 | -webkit-box-pack: end;
502 | -ms-flex-pack: end;
503 | justify-content: flex-end;
504 | }
505 | }
506 | .foyer-slide.foyer-slide-upcoming-productions .foyer-slide-fields {
507 | position: absolute;
508 | bottom: 0;
509 | left: 0;
510 | right: 0;
511 | padding: 2vmin 4vmin;
512 | background-color: rgba(255, 255, 255, 0.8);
513 | }
514 | .foyer-slide-background.foyer-slide-background-image figure,
515 | .foyer-slide-background.foyer-slide-background-default figure {
516 | margin: 0;
517 | width: 100%;
518 | height: 100%;
519 | }
520 | .foyer-slide-background.foyer-slide-background-image figure img,
521 | .foyer-slide-background.foyer-slide-background-default figure img {
522 | width: 100%;
523 | height: 100%;
524 | -o-object-fit: cover;
525 | object-fit: cover;
526 | }
527 | .foyer-slide-background.foyer-slide-background-video iframe {
528 | position: absolute;
529 | top: 0;
530 | right: 0;
531 | bottom: 0;
532 | left: 0;
533 | margin: auto;
534 | max-width: none;
535 | }
536 | .foyer-slide-background.foyer-slide-background-html5-video video {
537 | width: 100%;
538 | height: 100%;
539 | -o-object-fit: cover;
540 | object-fit: cover;
541 | }
542 |
--------------------------------------------------------------------------------