PluginProbe
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 2.7.0
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v2.7.0
4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 All 189 releases
← All changes | EmbedPress/Shortcode.php +512 -199 1.1.22.7.0 View file →
@@ -1,24 +1,24 @@
1 1 <?php
2 +
2 3 namespace EmbedPress;
3 4
4 -use \EmbedPress\Plugin;
5 -use \Embera\Embera;
6 -use \Embera\Formatter;
5 +use Embera\Embera;
6 +use Embera\ProviderCollection\DefaultProviderCollection;
7 +use WP_oEmbed;
7 8
8 -(defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
9 +( defined( 'ABSPATH' ) && defined( 'EMBEDPRESS_IS_LOADED' ) ) or die( "No direct script access allowed." );
9 10
10 11 /**
11 12 * Entity responsible to handle the plugin's shortcode events and behaviors.
12 13 *
13 14 * @package EmbedPress
14 - * @author PressShack <help@pressshack.com>
15 - * @copyright Copyright (C) 2016 Open Source Training, LLC. All rights reserved.
16 - * @license GPLv2 or later
15 + * @author EmbedPress <help@embedpress.com>
16 + * @copyright Copyright (C) 2020 WPDeveloper. All rights reserved.
17 + * @license GPLv3 or later
17 18 * @since 1.0.0
18 19 */
19 -class Shortcode
20 -{
20 +class Shortcode {
21 21 /**
22 22 * The WP_oEmbed class instance.
23 23 *
24 24 * @since 1.0.0
@@ -24,172 +24,336 @@
24 24 * @since 1.0.0
25 25 * @access private
26 26 * @static
27 27 *
28 - * @var string $oEmbedInstance
28 + * @var WP_oEmbed $oEmbedInstance
29 29 */
30 30 private static $oEmbedInstance = null;
31 + /**
32 + * The DefaultProviderCollection class instance.
33 + *
34 + * @since 1.0.0
35 + * @access private
36 + * @static
37 + *
38 + * @var DefaultProviderCollection $collection
39 + */
40 + private static $collection = null;
31 41
32 42 /**
33 43 * Register the plugin's shortcode into WordPress.
34 44 *
45 + * @return void
35 46 * @since 1.0.0
36 47 * @static
37 48 *
38 - * @return void
39 49 */
40 - public static function register()
41 - {
50 + public static function register() {
42 51 // Register the new shortcode for embeds.
43 - add_shortcode(EMBEDPRESS_SHORTCODE, array('\\EmbedPress\\Shortcode', 'do_shortcode'), 1);
52 + add_shortcode( EMBEDPRESS_SHORTCODE, ['\\EmbedPress\\Shortcode', 'do_shortcode'] );
53 + add_shortcode( 'embed_oembed_html', ['\\EmbedPress\\Shortcode', 'do_shortcode'] );
44 54 }
45 -
55 +
46 56 /**
47 57 * Method that converts the plugin shortcoded-string into its complex content.
48 58 *
59 + * @param array $attributes Array of attributes
60 + * @param string $subject The given string
61 + *
62 + * @return string
49 63 * @since 1.0.0
50 64 * @static
51 65 *
52 - * @param array $attributes @TODO
53 - * @param string $subject The given string
54 - * @return string
55 66 */
56 - public static function do_shortcode($attributes = array(), $subject = null)
57 - {
58 - $decodedSubject = self::parseContent($subject, true, $attributes);
59 -
60 - return $decodedSubject;
67 +
68 + public static function do_shortcode( $attributes = [], $subject = null ) {
69 + $plgSettings = Core::getSettings();
70 + $default = [];
71 + if ( $plgSettings->enableGlobalEmbedResize ) {
72 + $default = [
73 + 'width' => $plgSettings->enableEmbedResizeWidth,
74 + 'height' => $plgSettings->enableEmbedResizeHeight
75 + ];
76 + }
77 + $attributes = wp_parse_args( $attributes, $default );
78 + $embed = self::parseContent( $subject, true, $attributes );
79 +
80 + return is_object( $embed ) ? $embed->embed : $embed;
61 81 }
62 82
63 83 /**
64 84 * Replace a given content with its embeded HTML code.
65 85 *
86 + * @param string The raw content that will be replaced.
87 + * @param bool $stripNewLine
88 + * @param array $customAttributes
89 + * @return string
66 90 * @since 1.0.0
67 91 * @static
68 - *
69 - * @param string The raw content that will be replaced.
70 - * @param boolean Optional. If true, new lines at the end of the embeded code are stripped.
71 - * @return string
72 92 */
73 - public static function parseContent($subject, $stripNewLine = false, $customAttributes = array())
74 - {
75 - if (!empty($subject)) {
76 - if (empty($customAttributes)) {
77 - $customAttributes = self::parseContentAttributesFromString($subject);
93 + public static function parseContent( $subject, $stripNewLine = false, $customAttributes = [] ) {
94 + if ( !empty( $subject ) ) {
95 + if ( empty( $customAttributes ) ) {
96 + $customAttributes = self::parseContentAttributesFromString( $subject );
78 97 }
79 -
80 - $content = preg_replace('/(\['. EMBEDPRESS_SHORTCODE .'(?:\]|.+?\])|\[\/'. EMBEDPRESS_SHORTCODE .'\])/i', "", $subject);
81 -
98 +
99 + $content = preg_replace( '/(\[' . EMBEDPRESS_SHORTCODE . '(?:\]|.+?\])|\[\/' . EMBEDPRESS_SHORTCODE . '\])/i',
100 + "", $subject );
101 +
102 + // Converts any special HTML entities back to characters.
103 + $content = htmlspecialchars_decode( $content );
104 +
82 105 // Check if the WP_oEmbed class is loaded
83 - if (!self::$oEmbedInstance) {
84 - require_once ABSPATH .'wp-includes/class-oembed.php';
85 -
106 + if ( !self::$oEmbedInstance ) {
107 + global $wp_version;
108 + if ( version_compare( $wp_version, '5.3.0', '>=' ) ) {
109 + require_once ABSPATH . 'wp-includes/class-wp-oembed.php';
110 + } else {
111 + require_once ABSPATH . 'wp-includes/class-oembed.php';
112 + }
86 113 self::$oEmbedInstance = _wp_oembed_get_object();
114 + };
115 + if ( !empty( self::get_access_token() ) ) {
116 + self::$oEmbedInstance->providers = array_merge( self::$oEmbedInstance->providers,
117 + self::get_modified_provider( self::get_access_token() ) );
87 118 }
119 + $emberaInstanceSettings = [
120 + 'params' => [],
121 + ];
122 +
123 + $content_uid = md5( $content );
124 +
125 + $attributes = self::parseContentAttributes( $customAttributes, $content_uid );
126 + if ( isset( $attributes[ 'width' ] ) || isset( $attributes[ 'height' ] ) ) {
127 + if ( isset( $attributes[ 'width' ] ) ) {
128 + $emberaInstanceSettings[ 'params' ][ 'width' ] = $attributes[ 'width' ];
129 + unset( $attributes[ 'width' ] );
130 + }
131 +
132 + if ( isset( $attributes[ 'height' ] ) ) {
133 + $emberaInstanceSettings[ 'params' ][ 'height' ] = $attributes[ 'height' ];
134 + unset( $attributes[ 'height' ] );
135 + }
136 + }
88 137
89 - $emberaInstanceSettings = array(
90 - 'params' => array()
91 - );
138 + // Identify what service provider the shortcode's link belongs to
139 + $serviceProvider = self::$oEmbedInstance->get_provider( $content );
92 140
93 - $attributes = self::parseContentAttributes($customAttributes);
94 - if (isset($attributes['width']) || isset($attributes['height'])) {
95 - if (isset($attributes['width'])) {
96 - $emberaInstanceSettings['params']['width'] = $attributes['width'];
97 - unset($attributes['width']);
141 + // Check if OEmbed was unable to detect the url service provider.
142 + if ( empty( $serviceProvider ) ) {
143 + // Attempt to do the same using Embera.
144 + // Add support to the user's custom service providers
145 + $additionalServiceProviders = Core::getAdditionalServiceProviders();
146 + if ( !empty( $additionalServiceProviders ) ) {
147 + foreach ( $additionalServiceProviders as $serviceProviderClassName => $serviceProviderUrls ) {
148 + self::addServiceProvider( $serviceProviderClassName, $serviceProviderUrls );
149 + }
150 + unset( $serviceProviderUrls, $serviceProviderClassName );
98 151 }
152 +
153 + // Attempt to fetch more info about the url-embed.
154 + $emberaInstance = new Embera( $emberaInstanceSettings, self::$collection );
155 + $urlData = $emberaInstance->getUrlData( $content );
156 + } else {
157 + // Attempt to fetch more info about the url-embed.
158 + $urlData = self::$oEmbedInstance->fetch( $serviceProvider, $content, $attributes );
159 + }
99 160
100 - if (isset($attributes['height'])) {
101 - $emberaInstanceSettings['params']['height'] = $attributes['height'];
102 - unset($attributes['height']);
161 +
162 + // Sanitize the data
163 + $urlData = self::sanitizeUrlData( $urlData );
164 + // Stores the original content
165 + if ( is_object( $urlData ) ) {
166 + $urlData->originalContent = $content;
167 + }
168 +
169 + $eventResults = apply_filters( 'embedpress:onBeforeEmbed', $urlData );
170 + if ( empty( $eventResults ) ) {
171 + // EmbedPress seems unable to embed the url.
172 + return $subject;
173 + }
174 +
175 + // Transform all shortcode attributes into html form. I.e.: {foo: "joe"} -> foo="joe"
176 + $attributesHtml = [];
177 + foreach ( $attributes as $attrName => $attrValue ) {
178 + $attributesHtml[] = $attrName . '="' . $attrValue . '"';
179 + }
180 +
181 + // Define the EmbedPress html template where the generated embed will be injected in
182 + $embedTemplate = '<div ' . implode( ' ', $attributesHtml ) . '>{html}</div>';
183 +
184 + // Check if $content is a google shortened url and tries to extract from it which Google service it refers to.
185 + if ( preg_match( '/http[s]?:\/\/goo\.gl\/(?:([a-z]+)\/)?[a-z0-9]+\/?$/i', $content, $matches ) ) {
186 + // Fetch all headers from the short-url so we can know how to handle its original content depending on the service.
187 + $headers = get_headers( $content );
188 +
189 + $supportedServicesHeadersPatterns = [
190 + 'maps' => '/^Location:\s+(http[s]?:\/\/.+)$/i',
191 + ];
192 +
193 + $service = isset( $matches[ 1 ] ) ? strtolower( $matches[ 1 ] ) : null;
194 + // No specific service was found in the url.
195 + if ( empty( $service ) ) {
196 + // Let's try to guess which service the original url belongs to.
197 + foreach ( $headers as $header ) {
198 + // Check if the short-url reffers to a Google Maps url.
199 + if ( preg_match( $supportedServicesHeadersPatterns[ 'maps' ], $header, $matches ) ) {
200 + // Replace the shortened url with its original url.
201 + $content = $matches[ 1 ];
202 + break;
203 + }
204 + }
205 + unset( $header );
206 + } else {
207 + // Check if the Google service is supported atm.
208 + if ( isset( $supportedServicesHeadersPatterns[ $service ] ) ) {
209 + // Tries to extract the url based on its headers.
210 + $originalUrl = self::extractContentFromHeaderAsArray( $supportedServicesHeadersPatterns[ $service ],
211 + $headers );
212 + // Replace the shortened url with its original url if the specific header was found.
213 + if ( !empty( $originalUrl ) ) {
214 + $content = $originalUrl;
215 + }
216 + unset( $originalUrl );
217 + }
103 218 }
219 + unset( $service, $supportedServicesHeadersPatterns, $headers, $matches );
220 +
104 221 }
105 222
106 - // Identify what service provider the shortcode's link belongs to
107 - $serviceProvider = self::$oEmbedInstance->get_provider($content);
108 223
109 - // Gather info about the shortcode's link
110 - $urlData = self::$oEmbedInstance->fetch($serviceProvider, $content, $attributes);
224 + $parsedContent = self::$oEmbedInstance->get_html( $content, $attributes );
111 225
112 - // Transform all shortcode attributes into html form. I.e.: {foo: "joe"} -> foo="joe"
113 - $attributesHtml = array();
114 - foreach ($attributes as $attrName => $attrValue) {
115 - $attributesHtml[] = $attrName .'="'. $attrValue .'"';
226 + $provider_name = '';
227 + if (isset( $urlData->provider_name )) {
228 + $provider_name = isset( $urlData->provider_name );
229 + }elseif ( is_array( $urlData ) && isset( $urlData[ $content ][ 'provider_name' ] ) ) {
230 + $provider_name = $urlData[ $content ][ 'provider_name' ];
116 231 }
117 232
118 - // Define the EmbedPress html template where the generated embed will be injected in
119 - $embedTemplate = '<div '. implode(' ', $attributesHtml) .'>{html}</div>';
233 +
234 + if ( !$parsedContent ) {
235 + // If the embed couldn't be generated, we'll try to use Embera's API
236 + if ( !isset( $emberaInstance ) ) {
237 + // Add support to the user's custom service providers
238 + $additionalServiceProviders = Core::getAdditionalServiceProviders();
239 + if ( !empty( $additionalServiceProviders ) ) {
240 + foreach ( $additionalServiceProviders as $serviceProviderClassName => $serviceProviderUrls ) {
241 + self::addServiceProvider( $serviceProviderClassName, $serviceProviderUrls);
242 + }
120 243
121 - // Try to generate the embed using WP API
122 - $parsedContent = self::$oEmbedInstance->get_html($content, $attributes);
123 - if (!$parsedContent) {
124 - // If the embed couldn't be generated, we'll try to use Embera's API
125 - $emberaInstance = new Embera($emberaInstanceSettings);
126 - // Add support to the user's custom service providers
127 - $additionalServiceProviders = Plugin::getAdditionalServiceProviders();
128 - if (!empty($additionalServiceProviders)) {
129 - foreach ($additionalServiceProviders as $serviceProviderClassName => $serviceProviderUrls) {
130 - self::addServiceProvider($serviceProviderClassName, $serviceProviderUrls, $emberaInstance);
244 + unset( $serviceProviderUrls, $serviceProviderClassName );
131 245 }
132 -
133 - unset($serviceProviderUrls, $serviceProviderClassName);
246 + $emberaInstance = new Embera( $emberaInstanceSettings );
134 247 }
135 248
136 - // Register the html template
137 - $emberaFormaterInstance = new Formatter($emberaInstance, true);
138 - $emberaFormaterInstance->setTemplate($embedTemplate);
249 + // Inject the generated code inside the html template
250 + $parsedContent = str_replace( '{html}', $emberaInstance->autoEmbed($content), $embedTemplate );
139 251
140 - // Try to generate the embed using Embera API
141 - $parsedContent = $emberaFormaterInstance->transform($content);
142 -
143 - unset($emberaFormaterInstance, $additionalServiceProviders, $emberaInstance);
144 252 } else {
145 253 // Inject the generated code inside the html template
146 - $parsedContent = str_replace('{html}', $parsedContent, $embedTemplate);
147 -
254 + $parsedContent = str_replace( '{html}', $parsedContent, $embedTemplate );
148 255 // Replace all single quotes to double quotes. I.e: foo='joe' -> foo="joe"
149 - $parsedContent = str_replace("'", '"', $parsedContent);
150 -
151 - // Replace the flag `{provider_alias}` which is used by Embera with the "ose-<serviceProviderAlias>". I.e: YouTube -> "ose-youtube"
152 - $parsedContent = preg_replace('/((?:ose-)?\{provider_alias\})/i', "ose-". strtolower($urlData->provider_name), $parsedContent);
256 + $parsedContent = str_replace( "'", '"', $parsedContent );
257 + $parsedContent = preg_replace( '/((?:ose-)?\{provider_alias\})/i',
258 + "ose-" . strtolower( $provider_name ), $parsedContent );
153 259 }
154 -
155 - unset($embedTemplate, $urlData, $serviceProvider);
156 -
260 +
261 + if ( !empty($provider_name) ) {
262 + // NFB seems to always return their embed code with all HTML entities into their applicable characters string.
263 + $PROVIDER_NAME_IN_CAP = strtoupper($provider_name);
264 + if ( $PROVIDER_NAME_IN_CAP === "NATIONAL FILM BOARD OF CANADA" ) {
265 + $parsedContent = html_entity_decode( $parsedContent );
266 + } elseif ( $PROVIDER_NAME_IN_CAP === "FACEBOOK" ) {
267 + $plgSettings = Core::getSettings();
268 +
269 + // Check if the user wants to force a certain language into Facebook embeds.
270 + $locale = isset( $plgSettings->fbLanguage ) && !empty( $plgSettings->fbLanguage ) ? $plgSettings->fbLanguage : false;
271 + if ( !!$locale ) {
272 + // Replace the automatically detected language by Facebook's API with the language chosen by the user.
273 + $parsedContent = preg_replace( '/\/[a-z]{2}\_[a-z]{2}\/sdk\.js/i', "/{$locale}/sdk.js",
274 + $parsedContent );
275 + }
276 +
277 + // Make sure `adapt_container_width` parameter is set to false. Setting to true, as it is by default, might cause Facebook to render embeds inside editors (in admin) with only 180px wide.
278 + if ( is_admin() ) {
279 + $parsedContent = preg_replace( '~data\-adapt\-container\-width=\"(?:true|1)\"~i',
280 + 'data-adapt-container-width="0"', $parsedContent );
281 + }
282 +
283 + unset( $locale, $plgSettings );
284 + }
285 + }
286 +
287 + unset( $embedTemplate, $serviceProvider );
288 +
157 289 // This assure that the iframe has the same dimensions the user wants to
158 - if (isset($emberaInstanceSettings['params']['width']) || isset($emberaInstanceSettings['params']['height'])) {
159 - if (isset($emberaInstanceSettings['params']['width']) && isset($emberaInstanceSettings['params']['height'])) {
160 - $customWidth = (int)$emberaInstanceSettings['params']['width'];
161 - $customHeight = (int)$emberaInstanceSettings['params']['height'];
290 + if ( isset( $emberaInstanceSettings[ 'params' ][ 'width' ] ) || isset( $emberaInstanceSettings[ 'params' ][ 'height' ] ) ) {
291 + if ( isset( $emberaInstanceSettings[ 'params' ][ 'width' ] ) && isset( $emberaInstanceSettings[ 'params' ][ 'height' ] ) ) {
292 + $customWidth = (int)$emberaInstanceSettings[ 'params' ][ 'width' ];
293 + $customHeight = (int)$emberaInstanceSettings[ 'params' ][ 'height' ];
162 294 } else {
163 - preg_match_all('/\<iframe\s+width="(\d+)"\s+height="(\d+)"/i', $parsedContent, $matches);
164 - $iframeWidth = (int)$matches[1][0];
165 - $iframeHeight = (int)$matches[2][0];
166 - $iframeRatio = ceil($iframeWidth / $iframeHeight);
167 -
168 - if (isset($emberaInstanceSettings['params']['width'])) {
169 - $customWidth = (int)$emberaInstanceSettings['params']['width'];
170 - $customHeight = ceil($customWidth / $iframeRatio);
171 - } else {
172 - $customHeight = (int)$emberaInstanceSettings['params']['height'];
173 - $customWidth = $iframeRatio * $customHeight;
295 + if ( preg_match( '~width="(\d+)"|width\s+:\s+(\d+)~i', $parsedContent, $matches ) ) {
296 + $iframeWidth = (int)$matches[ 1 ];
174 297 }
175 -
176 - unset($iframeRatio, $iframeHeight, $iframeWidth, $matches);
298 +
299 + if ( preg_match( '~height="(\d+)"|height\s+:\s+(\d+)~i', $parsedContent, $matches ) ) {
300 + $iframeHeight = (int)$matches[ 1 ];
301 + }
302 +
303 + if ( isset( $iframeWidth ) && isset( $iframeHeight ) && $iframeWidth > 0 && $iframeHeight > 0 ) {
304 + $iframeRatio = ceil( $iframeWidth / $iframeHeight );
305 +
306 + if ( isset( $emberaInstanceSettings[ 'params' ][ 'width' ] ) ) {
307 + $customWidth = (int)$emberaInstanceSettings[ 'params' ][ 'width' ];
308 + $customHeight = ceil( $customWidth / $iframeRatio );
309 + } else {
310 + $customHeight = (int)$emberaInstanceSettings[ 'params' ][ 'height' ];
311 + $customWidth = $iframeRatio * $customHeight;
312 + }
313 + }
177 314 }
178 -
179 - $parsedContent = preg_replace('/\s+width\=\"(\d+)\"/i', ' width="'. $customWidth .'"', $parsedContent);
180 - $parsedContent = preg_replace('/\s+height\=\"(\d+)\"/i', ' height="'. $customHeight .'"', $parsedContent);
315 +
316 + if ( isset( $customWidth ) && isset( $customHeight ) ) {
317 + if ( preg_match( '~width="(\d+)"~i', $parsedContent ) ) {
318 + $parsedContent = preg_replace( '~width="(\d+)"~i', 'width="' . $customWidth . '"',
319 + $parsedContent );
320 + }
321 +
322 + if ( preg_match( '~height="(\d+)"~i', $parsedContent ) ) {
323 + $parsedContent = preg_replace( '~height="(\d+)"~i', 'height="' . $customHeight . '"',
324 + $parsedContent );
325 + }
326 +
327 + if ( preg_match( '~width\s+:\s+(\d+)~i', $parsedContent ) ) {
328 + $parsedContent = preg_replace( '~width\s+:\s+(\d+)~i', 'width: ' . $customWidth,
329 + $parsedContent );
330 + }
331 +
332 + if ( preg_match( '~height\s+:\s+(\d+)~i', $parsedContent ) ) {
333 + $parsedContent = preg_replace( '~height\s+:\s+(\d+)~i', 'height: ' . $customHeight,
334 + $parsedContent );
335 + }
336 + }
181 337 }
182 -
183 - if ($stripNewLine) {
184 - $parsedContent = preg_replace('/\n/', '', $parsedContent);
338 +
339 + if ( $stripNewLine ) {
340 + $parsedContent = preg_replace( '/\n/', '', $parsedContent );
185 341 }
186 -
187 - if (!empty($parsedContent)) {
188 - return $parsedContent;
342 +
343 + $parsedContent = apply_filters( 'pp_embed_parsed_content', $parsedContent, $urlData, $attributes );
344 +
345 + if ( !empty( $parsedContent ) ) {
346 + $embed = (object)array_merge( (array)$urlData, [
347 + 'attributes' => (object)$attributes,
348 + 'embed' => $parsedContent,
349 + 'url' => $content,
350 + ] );
351 + $embed = apply_filters( 'embedpress:onAfterEmbed', $embed );
352 + return $embed;
189 353 }
190 354 }
191 -
355 +
192 356 return $subject;
193 357 }
194 358
195 359 /**
@@ -194,165 +358,178 @@
194 358
195 359 /**
196 360 * Method that adds support to a given new service provider (SP).
197 361 *
362 + * @param string $className The new SP class name.
363 + * @param string $reference The new SP reference name.*
364 + * @return DefaultProviderCollection|bool
198 365 * @since 1.0.0
199 366 * @static
200 367 *
201 - * @param string $className The new SP class name.
202 - * @param string $reference The new SP reference name.
203 - * @param \Embera\Embera $emberaInstance The embera's instance where the SP will be registered in.
204 - * @return boolean
205 368 */
206 - public static function addServiceProvider($className, $reference, &$emberaInstance)
207 - {
208 - if (empty($className) || empty($reference)) {
369 + public static function addServiceProvider( $className, $reference ) {
370 + if ( empty( $className ) || empty( $reference ) ) {
209 371 return false;
210 372 }
211 373
212 - if (is_string($reference)) {
213 - $emberaInstance->addProvider($reference, EMBEDPRESS_NAMESPACE ."\\Providers\\{$className}");
214 - } else if (is_array($reference)) {
215 - foreach ($reference as $serviceProviderUrl) {
216 - self::addServiceProvider($className, $serviceProviderUrl, $emberaInstance);
374 + if (is_null(self::$collection)) {
375 + self::$collection = new DefaultProviderCollection();
376 + }
377 + if ( is_string( $reference ) ) {
378 + self::$collection->addProvider( $reference, EMBEDPRESS_NAMESPACE . "\\Providers\\{$className}" );
379 + return self::$collection;
380 + } elseif ( is_array( $reference ) ) {
381 + foreach ( $reference as $serviceProviderUrl ) {
382 + self::addServiceProvider( $className, $serviceProviderUrl);
217 383 }
384 + return self::$collection;
218 385 } else {
219 386 return false;
220 387 }
221 388 }
222 -
389 +
223 390 /**
224 391 * Method that retrieves all custom parameters from a shortcoded string.
225 392 *
393 + * @param string $subject The given shortcoded string.
394 + *
395 + * @return array
226 396 * @since 1.0.0
227 397 * @static
228 398 *
229 - * @param string $subject The given shortcoded string.
230 - * @return array
231 399 */
232 - public static function parseContentAttributesFromString($subject)
233 - {
234 - $customAttributes = array();
235 - if (preg_match('/\[embed\s*(.*?)\]/i', stripslashes($subject), $m)) {
236 - if (preg_match_all('/(\!?\w+-?\w*)(?:="(.+?)")?/i', stripslashes($m[1]), $matches)) {
237 - $attributes = $matches[1];
238 - $attrValues = $matches[2];
239 -
240 - foreach ($attributes as $attrIndex => $attrName) {
241 - $customAttributes[$attrName] = $attrValues[$attrIndex];
400 + public static function parseContentAttributesFromString( $subject ) {
401 + $customAttributes = [];
402 + if ( preg_match( '/\[embed\s*(.*?)\]/i', stripslashes( $subject ), $m ) ) {
403 + if ( preg_match_all( '/(\!?\w+-?\w*)(?:="(.+?)")?/i', stripslashes( $m[ 1 ] ), $matches ) ) {
404 + $attributes = $matches[ 1 ];
405 + $attrValues = $matches[ 2 ];
406 +
407 + foreach ( $attributes as $attrIndex => $attrName ) {
408 + $customAttributes[ $attrName ] = $attrValues[ $attrIndex ];
242 409 }
243 410 }
244 411 }
245 -
412 +
246 413 return $customAttributes;
247 414 }
248 -
415 +
249 416 /**
250 417 * Method that parses and adds the "data-" prefix to the given custom shortcode attributes.
251 418 *
419 + * @param array $customAttributes The array containing the embed attributes.
420 + * @param string $content_uid An optional string specifying a unique ID for the embed
421 + *
422 + * @return array
252 423 * @since 1.0.0
253 424 * @access private
254 425 * @static
255 426 *
256 - * @param array $attributes The array containing the embed attributes.
257 - * @return array
258 427 */
259 - private static function parseContentAttributes(array $customAttributes)
260 - {
261 - $attributes = array(
262 - 'class' => array("embedpress-wrapper")
263 - );
264 -
428 + private static function parseContentAttributes( array $customAttributes, $content_uid = null ) {
429 + $attributes = [
430 + 'class' => ["embedpress-wrapper"],
431 + ];
432 +
265 433 $embedShouldBeResponsive = true;
266 434 $embedShouldHaveCustomDimensions = false;
267 - if (!empty($customAttributes)) {
268 - if (isset($customAttributes['class'])) {
269 - if (!empty($customAttributes['class'])) {
270 - $customAttributes['class'] = explode(' ', $customAttributes['class']);
271 -
272 - $attributes['class'] = array_merge($attributes['class'], $customAttributes['class']);
435 + if ( !empty( $customAttributes ) ) {
436 + if ( isset( $customAttributes[ 'class' ] ) ) {
437 + if ( !empty( $customAttributes[ 'class' ] ) ) {
438 + $customAttributes[ 'class' ] = explode( ' ', $customAttributes[ 'class' ] );
439 +
440 + $attributes[ 'class' ] = array_merge( $attributes[ 'class' ], $customAttributes[ 'class' ] );
273 441 }
274 -
275 - unset($customAttributes['class']);
442 +
443 + unset( $customAttributes[ 'class' ] );
276 444 }
277 -
278 - if (isset($customAttributes['width'])) {
279 - if (!empty($customAttributes['width'])) {
280 - $attributes['width'] = (int)$customAttributes['width'];
445 +
446 + if ( isset( $customAttributes[ 'width' ] ) ) {
447 + if ( !empty( $customAttributes[ 'width' ] ) ) {
448 + $attributes[ 'width' ] = (int)$customAttributes[ 'width' ];
281 449 $embedShouldHaveCustomDimensions = true;
282 450 }
283 451 }
284 -
285 - if (isset($customAttributes['height'])) {
286 - if (!empty($customAttributes['height'])) {
287 - $attributes['height'] = (int)$customAttributes['height'];
452 +
453 + if ( isset( $customAttributes[ 'height' ] ) ) {
454 + if ( !empty( $customAttributes[ 'height' ] ) ) {
455 + $attributes[ 'height' ] = (int)$customAttributes[ 'height' ];
288 456 $embedShouldHaveCustomDimensions = true;
289 457 }
290 458 }
291 -
292 - if (!empty($customAttributes)) {
459 +
460 + if ( !empty( $customAttributes ) ) {
293 461 $attrNameDefaultPrefix = "data-";
294 - foreach ($customAttributes as $attrName => $attrValue) {
295 - if (is_numeric($attrName)) {
462 + foreach ( $customAttributes as $attrName => $attrValue ) {
463 + if ( is_numeric( $attrName ) ) {
296 464 $attrName = $attrValue;
297 465 $attrValue = "";
298 466 }
299 -
300 - $attrName = str_replace($attrNameDefaultPrefix, "", $attrName);
301 -
302 - if (!strlen($attrValue)) {
303 - if ($attrName[0] === "!") {
467 +
468 + $attrName = str_replace( $attrNameDefaultPrefix, "", $attrName );
469 +
470 + if ( !strlen( $attrValue ) ) {
471 + if ( $attrName[ 0 ] === "!" ) {
304 472 $attrValue = "false";
305 - $attrName = substr($attrName, 1);
473 + $attrName = substr( $attrName, 1 );
306 474 } else {
307 475 $attrValue = "true";
308 476 }
309 477 }
310 -
311 - $attributes[$attrNameDefaultPrefix . $attrName] = $attrValue;
478 +
479 + $attributes[ $attrNameDefaultPrefix . $attrName ] = $attrValue;
312 480 }
313 481 }
314 -
482 +
315 483 // Check if there's any "responsive" parameter
316 - $responsiveAttributes = array("responsive", "data-responsive");
317 - foreach ($responsiveAttributes as $responsiveAttr) {
318 - if (isset($attributes[$responsiveAttr])) {
319 - if (!strlen($attributes[$responsiveAttr])) { // If the parameter is passed but have no value, it will be true by default
484 + $responsiveAttributes = ["responsive", "data-responsive"];
485 + foreach ( $responsiveAttributes as $responsiveAttr ) {
486 + if ( isset( $attributes[ $responsiveAttr ] ) ) {
487 + if ( !strlen( $attributes[ $responsiveAttr ] ) ) { // If the parameter is passed but have no value, it will be true by default
320 488 $embedShouldBeResponsive = true;
321 489 } else {
322 - $embedShouldBeResponsive = !self::valueIsFalse($attributes[$responsiveAttr]);
490 + $embedShouldBeResponsive = !self::valueIsFalse( $attributes[ $responsiveAttr ] );
323 491 }
324 -
492 +
325 493 break;
326 494 }
327 495 }
328 - unset($responsiveAttr, $responsiveAttributes);
496 + unset( $responsiveAttr, $responsiveAttributes );
329 497 }
330 -
331 - if ($embedShouldBeResponsive && !$embedShouldHaveCustomDimensions) {
332 - $attributes['class'][] = 'ose-{provider_alias} responsive';
498 +
499 + $attributes[ 'class' ][] = 'ose-{provider_alias}';
500 +
501 + if ( !empty( $content_uid ) ) {
502 + $attributes[ 'class' ][] = 'ose-uid-' . $content_uid;
503 + }
504 +
505 + if ( $embedShouldBeResponsive && !$embedShouldHaveCustomDimensions ) {
506 + $attributes[ 'class' ][] = 'responsive';
333 507 } else {
334 - $attributes['data-responsive'] = "false";
508 + $attributes[ 'data-responsive' ] = "false";
335 509 }
336 -
337 - $attributes['class'] = implode(' ', array_unique(array_filter($attributes['class'])));
338 -
510 +
511 + $attributes[ 'class' ] = implode( ' ', array_unique( array_filter( $attributes[ 'class' ] ) ) );
512 + if ( isset( $attributes[ 'width' ] ) ) {
513 + $attributes[ 'style' ] = "width:{$attributes['width'] }px;height:{$attributes['height'] }px;";
514 + }
515 +
339 516 return $attributes;
340 517 }
341 -
518 +
342 519 /**
343 520 * Method that checks if a given value is/can be identified as (bool)false.
344 521 *
522 + * @param mixed $subject The value to be checked.
523 + *
524 + * @return boolean
345 525 * @since 1.0.0
346 526 * @static
347 527 *
348 - * @param mixed $subject The value to be checked.
349 - * @return boolean
350 528 */
351 - public static function valueIsFalse($subject)
352 - {
353 - $subject = strtolower(trim((string)$subject));
354 - switch ($subject) {
529 + public static function valueIsFalse( $subject ) {
530 + $subject = strtolower( trim( (string)$subject ) );
531 + switch ( $subject ) {
355 532 case "0":
356 533 case "false":
357 534 case "off":
358 535 case "no":
@@ -362,6 +539,142 @@
362 539 return true;
363 540 default:
364 541 return false;
365 542 }
543 + }
544 +
545 + /**
546 + * Return the value from a header which is in an array resulted from a get_headers() call.
547 + * If the header cannot be found, this method will return null instead.
548 + *
549 + * @param string $headerPattern Regex pattern the header and its value must match.
550 + * @param array $headersList A list of headers resulted from a get_headers() call.
551 + *
552 + * @return mixed
553 + * @since 1.1.0
554 + * @access private
555 + * @static
556 + *
557 + */
558 + private static function extractContentFromHeaderAsArray( $headerPattern, $headersList ) {
559 + $headerValue = null;
560 +
561 + foreach ( $headersList as $header ) {
562 + if ( preg_match( $headerPattern, $header, $matches ) ) {
563 + $headerValue = $matches[ 1 ];
564 + break;
565 + }
566 + }
567 +
568 + return $headerValue;
569 + }
570 +
571 + /**
572 + * Sanitize the object returned by the embed source. Sometimes we need to convert
573 + * attributes from "dash" separated to "underline" separated to be able to access
574 + * those attributes from the object, without having to convert it to an array.
575 + *
576 + * @param object $data
577 + *
578 + * @return object
579 + * @since 1.6.1
580 + * @access private
581 + * @static
582 + *
583 + */
584 + private static function sanitizeUrlData( $data ) {
585 + if ( is_object( $data ) ) {
586 + $attributes = get_object_vars( $data );
587 +
588 + foreach ( $attributes as $key => $value ) {
589 + if ( substr_count( $key, '-' ) ) {
590 + unset( $data->$key );
591 +
592 + $key = str_replace( '-', '_', $key );
593 + $data->$key = $value;
594 + }
595 + }
596 + } elseif ( is_array( $data ) ) {
597 + foreach ( $data as $key => $value ) {
598 + if ( substr_count( $key, '-' ) ) {
599 + unset( $data[ $key ] );
600 +
601 + $key = str_replace( '-', '_', $key );
602 + $data[ $key ] = $value;
603 + }
604 + }
605 + }
606 +
607 + return $data;
608 + }
609 +
610 + public static function get_modified_provider( $access_token = null ) {
611 + if ( empty( $access_token ) ) {
612 + return [];
613 + }
614 + return [
615 + '#https?://www\.facebook\.com/.*/posts/.*#i' => [
616 + 'https://graph.facebook.com/v8.0/oembed_post?access_token=' . $access_token,
617 + true
618 + ],
619 + '#https?://www\.facebook\.com/.*/activity/.*#i' => [
620 + 'https://graph.facebook.com/v8.0/oembed_post?access_token=' . $access_token,
621 + true
622 + ],
623 + '#https?://www\.facebook\.com/.*/photos/.*#i' => [
624 + 'https://graph.facebook.com/v8.0/oembed_post?access_token=' . $access_token,
625 + true
626 + ],
627 + '#https?://www\.facebook\.com/photo(s/|\.php).*#i' => [
628 + 'https://graph.facebook.com/v8.0/oembed_post?access_token=' . $access_token,
629 + true
630 + ],
631 + '#https?://www\.facebook\.com/permalink\.php.*#i' => [
632 + 'https://graph.facebook.com/v8.0/oembed_post?access_token=' . $access_token,
633 + true
634 + ],
635 + '#https?://www\.facebook\.com/media/.*#i' => [
636 + 'https://graph.facebook.com/v8.0/oembed_post?access_token=' . $access_token,
637 + true
638 + ],
639 + '#https?://www\.facebook\.com/questions/.*#i' => [
640 + 'https://graph.facebook.com/v8.0/oembed_post?access_token=' . $access_token,
641 + true
642 + ],
643 + '#https?://www\.facebook\.com/notes/.*#i' => [
644 + 'https://graph.facebook.com/v8.0/oembed_post?access_token=' . $access_token,
645 + true
646 + ],
647 + '#https?://www\.facebook\.com/.*/videos/.*#i' => [
648 + 'https://graph.facebook.com/v8.0/oembed_video?access_token=' . $access_token,
649 + true
650 + ],
651 + '#https?://www\.facebook\.com/video\.php.*#i' => [
652 + 'https://graph.facebook.com/v8.0/oembed_video?access_token=' . $access_token,
653 + true
654 + ],
655 + '#https?://www\.facebook\.com/watch/?\?v=\d+#i' => [
656 + 'https://graph.facebook.com/v8.0/oembed_video?access_token=' . $access_token,
657 + true
658 + ],
659 +
660 + '#https?://(www\.)?instagr(\.am|am\.com)/(p|tv)/.*#i' => [
661 + 'https://graph.facebook.com/v8.0/instagram_oembed?access_token=' . $access_token,
662 + true
663 + ]
664 + ];
665 + }
666 +
667 + public static function get_access_token() {
668 + $plgSettings = Core::getSettings();
669 + if ( !empty( $plgSettings->facebook_app_code ) && !empty( $plgSettings->facebook_app_secret ) ) {
670 + return urlencode( $plgSettings->facebook_app_code . '|' . $plgSettings->facebook_app_secret );
671 + } else {
672 + return null;
673 + }
674 + }
675 +
676 + public static function get_collection()
677 + {
678 + return self::$collection;
366 679 }
367 680 }