PluginProbe
Embed Privacy / 1.10.7
Embed Privacy v1.10.7
1.14.0 1.13.0 trunk 0.1 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.1.3 1.10.0 1.10.1 1.10.10 1.10.2 1.10.3 1.10.4 1.10.5 1.10.6 1.10.7 1.10.8 1.10.9 1.11.0 1.11.1 1.11.2 All 68 releases
embed-privacy / inc / integration / class-elementor.php

class-elementor.php in Embed Privacy 1.10.7, at inc/integration/class-elementor.php

175 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace epiphyt\Embed_Privacy\integration;
3
4 use DOMDocument;
5 use DOMElement;
6 use DOMNode;
7 use Elementor\Plugin;
8 use epiphyt\Embed_Privacy\data\Providers;
9 use epiphyt\Embed_Privacy\embed\Template;
10 use epiphyt\Embed_Privacy\Embed_Privacy;
11 use epiphyt\Embed_Privacy\System;
12
13 /**
14 * Elementor integration for Embed Privacy.
15 *
16 * @author Epiphyt
17 * @license GPL2
18 * @package epiphyt\Embed_Privacy
19 * @since 1.10.0
20 */
21 final class Elementor {
22 /**
23 * Initialize functionality.
24 */
25 public static function init() {
26 \add_action( 'embed_privacy_print_assets', [ self::class, 'enqueue_assets' ] );
27 \add_action( 'embed_privacy_register_assets', [ self::class, 'register_assets' ], 10, 2 );
28 \add_filter( 'embed_privacy_overlay_replaced_content', [ self::class, 'replace_youtube' ] );
29 }
30
31 /**
32 * Enqueue assets.
33 */
34 public static function enqueue_assets() {
35 if ( self::is_used() ) {
36 \wp_enqueue_script( 'embed-privacy-elementor-video' );
37 \wp_enqueue_style( 'embed-privacy-elementor' );
38 }
39 }
40
41 /**
42 * Get an overlay for Elementor YouTube videos.
43 *
44 * @param string $content The content
45 * @return string The content with an embed overlay (if needed)
46 */
47 private static function get_youtube_overlay( $content ) {
48 $provider = Providers::get_instance()->get_by_name( 'youtube' );
49 $replacements = [];
50
51 // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
52 $use_errors = \libxml_use_internal_errors( true );
53 $dom = new DOMDocument();
54 $dom->loadHTML(
55 '<html><meta charset="utf-8">' . $content . '</html>',
56 \LIBXML_HTML_NOIMPLIED | \LIBXML_HTML_NODEFDTD
57 );
58 $template_dom = new DOMDocument();
59
60 /** @var \DOMElement $element */
61 foreach ( $dom->getElementsByTagName( 'div' ) as $element ) {
62 if ( ! \str_contains( $element->getAttribute( 'data-settings' ), 'youtube_url' ) ) {
63 continue;
64 }
65
66 $settings = \json_decode( $element->getAttribute( 'data-settings' ) );
67 $args = [];
68
69 if ( ! empty( $settings->youtube_url ) ) {
70 $args['embed_url'] = $settings->youtube_url;
71 }
72
73 // get overlay template as DOM element
74 $template_dom->loadHTML(
75 '<html><meta charset="utf-8">' . Template::get( $provider, $dom->saveHTML( $element ), $args ) . '</html>',
76 \LIBXML_HTML_NOIMPLIED | \LIBXML_HTML_NODEFDTD
77 );
78 $overlay = null;
79
80 /** @var \DOMElement $div */
81 foreach ( $template_dom->getElementsByTagName( 'div' ) as $div ) {
82 if ( \stripos( $div->getAttribute( 'class' ), 'embed-privacy-container' ) !== false ) {
83 $overlay = $div;
84 break;
85 }
86 }
87
88 // store the elements to replace (see regressive loop down below)
89 if ( $overlay instanceof DOMNode || $overlay instanceof DOMElement ) {
90 $replacements[] = [
91 'element' => $element,
92 'replace' => $dom->importNode( $overlay, true ),
93 ];
94 }
95 }
96
97 if ( ! empty( $replacements ) ) {
98 Embed_Privacy::get_instance()->did_replacements = \array_merge( Embed_Privacy::get_instance()->did_replacements, $replacements );
99 Embed_Privacy::get_instance()->has_embed = true;
100 $elements = $dom->getElementsByTagName( 'div' );
101 $i = $elements->length - 1;
102
103 // use regressive loop for replaceChild()
104 // see: https://www.php.net/manual/en/domnode.replacechild.php#50500
105 while ( $i > -1 ) {
106 $element = $elements->item( $i );
107
108 foreach ( $replacements as $replacement ) {
109 if ( $replacement['element'] === $element ) {
110 $element->parentNode->replaceChild( $replacement['replace'], $replacement['element'] );
111 }
112 }
113
114 --$i;
115 }
116
117 $content = \str_replace( [ '<html><meta charset="utf-8">', '</html>' ], '', $dom->saveHTML( $dom->documentElement ) );
118 }
119
120 \libxml_use_internal_errors( $use_errors );
121 // phpcs:enable
122
123 return $content;
124 }
125
126 /**
127 * Check if a post is written in Elementor.
128 *
129 * @return bool Whether Elementor has been used
130 */
131 public static function is_used() {
132 return System::is_plugin_active( 'elementor/elementor.php' )
133 && \get_the_ID()
134 && Plugin::$instance->documents->get( \get_the_ID() )->is_built_with_elementor();
135 }
136
137 /**
138 * Register assets.
139 *
140 * @param bool $is_debug Whether debug mode is enabled
141 * @param string $suffix A filename suffix
142 */
143 public static function register_assets( $is_debug, $suffix ) {
144 $js_file_url = \EPI_EMBED_PRIVACY_URL . 'assets/js/elementor-video' . $suffix . '.js';
145 $file_version = $is_debug ? \filemtime( \EPI_EMBED_PRIVACY_BASE . 'assets/js/elementor-video' . $suffix . '.js' ) : \EMBED_PRIVACY_VERSION;
146
147 \wp_register_script( 'embed-privacy-elementor-video', $js_file_url, [], $file_version, [ 'strategy' => 'defer' ] );
148
149 $css_file_url = \EPI_EMBED_PRIVACY_URL . 'assets/style/elementor' . $suffix . '.css';
150 $file_version = $is_debug ? \filemtime( \EPI_EMBED_PRIVACY_BASE . 'assets/style/elementor' . $suffix . '.css' ) : \EMBED_PRIVACY_VERSION;
151
152 \wp_register_style( 'embed-privacy-elementor', $css_file_url, [], $file_version );
153 }
154
155 /**
156 * Replace YouTube videos.
157 * As they are not embedded via regular iframe, we need to handle them manually.
158 *
159 * @param string $content Current replaced content
160 * @return string Updated replaced content
161 */
162 public static function replace_youtube( $content ) {
163 if ( ! self::is_used() ) {
164 return $content;
165 }
166
167 if ( \str_contains( $content, 'youtube.com\/watch' ) ) {
168 $content = self::get_youtube_overlay( $content );
169 Embed_Privacy::get_instance()->frontend->print_assets();
170 }
171
172 return $content;
173 }
174 }
175