PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / 1.1.0
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more v1.1.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 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.14 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.10 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.10 4.4.11 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5.0 4.5.1
embedpress / EmbedPress / Shortcode.php
embedpress / EmbedPress Last commit date
Ends 9 years ago Providers 9 years ago AutoLoader.php 9 years ago Disabler.php 9 years ago Loader.php 9 years ago Plugin.php 9 years ago Shortcode.php 9 years ago index.html 9 years ago
Shortcode.php
368 lines
1 <?php
2 namespace EmbedPress;
3
4 use \EmbedPress\Plugin;
5 use \Embera\Embera;
6 use \Embera\Formatter;
7
8 (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
9
10 /**
11 * Entity responsible to handle the plugin's shortcode events and behaviors.
12 *
13 * @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
17 * @since 1.0.0
18 */
19 class Shortcode
20 {
21 /**
22 * The WP_oEmbed class instance.
23 *
24 * @since 1.0.0
25 * @access private
26 * @static
27 *
28 * @var string $oEmbedInstance
29 */
30 private static $oEmbedInstance = null;
31
32 /**
33 * Register the plugin's shortcode into WordPress.
34 *
35 * @since 1.0.0
36 * @static
37 *
38 * @return void
39 */
40 public static function register()
41 {
42 // Register the new shortcode for embeds.
43 add_shortcode(EMBEDPRESS_SHORTCODE, array('\\EmbedPress\\Shortcode', 'do_shortcode'), 1);
44 }
45
46 /**
47 * Method that converts the plugin shortcoded-string into its complex content.
48 *
49 * @since 1.0.0
50 * @static
51 *
52 * @param array $attributes @TODO
53 * @param string $subject The given string
54 * @return string
55 */
56 public static function do_shortcode($attributes = array(), $subject = null)
57 {
58 $decodedSubject = self::parseContent($subject, true, $attributes);
59
60 return $decodedSubject;
61 }
62
63 /**
64 * Replace a given content with its embeded HTML code.
65 *
66 * @since 1.0.0
67 * @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 */
73 public static function parseContent($subject, $stripNewLine = false, $customAttributes = array())
74 {
75 if (!empty($subject)) {
76 if (empty($customAttributes)) {
77 $customAttributes = self::parseContentAttributesFromString($subject);
78 }
79
80 $content = preg_replace('/(\['. EMBEDPRESS_SHORTCODE .'(?:\]|.+?\])|\[\/'. EMBEDPRESS_SHORTCODE .'\])/i', "", $subject);
81
82 // Check if the WP_oEmbed class is loaded
83 if (!self::$oEmbedInstance) {
84 require_once ABSPATH .'wp-includes/class-oembed.php';
85
86 self::$oEmbedInstance = _wp_oembed_get_object();
87 }
88
89 $emberaInstanceSettings = array(
90 'params' => array()
91 );
92
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']);
98 }
99
100 if (isset($attributes['height'])) {
101 $emberaInstanceSettings['params']['height'] = $attributes['height'];
102 unset($attributes['height']);
103 }
104 }
105
106 // Identify what service provider the shortcode's link belongs to
107 $serviceProvider = self::$oEmbedInstance->get_provider($content);
108
109 // Gather info about the shortcode's link
110 $urlData = self::$oEmbedInstance->fetch($serviceProvider, $content, $attributes);
111
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 .'"';
116 }
117
118 // Define the EmbedPress html template where the generated embed will be injected in
119 $embedTemplate = '<div '. implode(' ', $attributesHtml) .'>{html}</div>';
120
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);
131 }
132
133 unset($serviceProviderUrls, $serviceProviderClassName);
134 }
135
136 // Register the html template
137 $emberaFormaterInstance = new Formatter($emberaInstance, true);
138 $emberaFormaterInstance->setTemplate($embedTemplate);
139
140 // Try to generate the embed using Embera API
141 $parsedContent = $emberaFormaterInstance->transform($content);
142
143 unset($emberaFormaterInstance, $additionalServiceProviders, $emberaInstance);
144 } else {
145 // Inject the generated code inside the html template
146 $parsedContent = str_replace('{html}', $parsedContent, $embedTemplate);
147
148 // 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);
153 }
154
155 unset($embedTemplate, $urlData, $serviceProvider);
156
157 // 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'];
162 } 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;
174 }
175
176 unset($iframeRatio, $iframeHeight, $iframeWidth, $matches);
177 }
178
179 $parsedContent = preg_replace('/\s+width\=\"(\d+)\"/i', ' width="'. $customWidth .'"', $parsedContent);
180 $parsedContent = preg_replace('/\s+height\=\"(\d+)\"/i', ' height="'. $customHeight .'"', $parsedContent);
181 }
182
183 if ($stripNewLine) {
184 $parsedContent = preg_replace('/\n/', '', $parsedContent);
185 }
186
187 if (!empty($parsedContent)) {
188 return $parsedContent;
189 }
190 }
191
192 return $subject;
193 }
194
195 /**
196 * Method that adds support to a given new service provider (SP).
197 *
198 * @since 1.0.0
199 * @static
200 *
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 */
206 public static function addServiceProvider($className, $reference, &$emberaInstance)
207 {
208 if (empty($className) || empty($reference)) {
209 return false;
210 }
211
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);
217 }
218 } else {
219 return false;
220 }
221 }
222
223 /**
224 * Method that retrieves all custom parameters from a shortcoded string.
225 *
226 * @since 1.0.0
227 * @static
228 *
229 * @param string $subject The given shortcoded string.
230 * @return array
231 */
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];
242 }
243 }
244 }
245
246 return $customAttributes;
247 }
248
249 /**
250 * Method that parses and adds the "data-" prefix to the given custom shortcode attributes.
251 *
252 * @since 1.0.0
253 * @access private
254 * @static
255 *
256 * @param array $attributes The array containing the embed attributes.
257 * @return array
258 */
259 private static function parseContentAttributes(array $customAttributes)
260 {
261 $attributes = array(
262 'class' => array("embedpress-wrapper")
263 );
264
265 $embedShouldBeResponsive = true;
266 $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']);
273 }
274
275 unset($customAttributes['class']);
276 }
277
278 if (isset($customAttributes['width'])) {
279 if (!empty($customAttributes['width'])) {
280 $attributes['width'] = (int)$customAttributes['width'];
281 $embedShouldHaveCustomDimensions = true;
282 }
283 }
284
285 if (isset($customAttributes['height'])) {
286 if (!empty($customAttributes['height'])) {
287 $attributes['height'] = (int)$customAttributes['height'];
288 $embedShouldHaveCustomDimensions = true;
289 }
290 }
291
292 if (!empty($customAttributes)) {
293 $attrNameDefaultPrefix = "data-";
294 foreach ($customAttributes as $attrName => $attrValue) {
295 if (is_numeric($attrName)) {
296 $attrName = $attrValue;
297 $attrValue = "";
298 }
299
300 $attrName = str_replace($attrNameDefaultPrefix, "", $attrName);
301
302 if (!strlen($attrValue)) {
303 if ($attrName[0] === "!") {
304 $attrValue = "false";
305 $attrName = substr($attrName, 1);
306 } else {
307 $attrValue = "true";
308 }
309 }
310
311 $attributes[$attrNameDefaultPrefix . $attrName] = $attrValue;
312 }
313 }
314
315 // 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
320 $embedShouldBeResponsive = true;
321 } else {
322 $embedShouldBeResponsive = !self::valueIsFalse($attributes[$responsiveAttr]);
323 }
324
325 break;
326 }
327 }
328 unset($responsiveAttr, $responsiveAttributes);
329 }
330
331 if ($embedShouldBeResponsive && !$embedShouldHaveCustomDimensions) {
332 $attributes['class'][] = 'ose-{provider_alias} responsive';
333 } else {
334 $attributes['data-responsive'] = "false";
335 }
336
337 $attributes['class'] = implode(' ', array_unique(array_filter($attributes['class'])));
338
339 return $attributes;
340 }
341
342 /**
343 * Method that checks if a given value is/can be identified as (bool)false.
344 *
345 * @since 1.0.0
346 * @static
347 *
348 * @param mixed $subject The value to be checked.
349 * @return boolean
350 */
351 public static function valueIsFalse($subject)
352 {
353 $subject = strtolower(trim((string)$subject));
354 switch ($subject) {
355 case "0":
356 case "false":
357 case "off":
358 case "no":
359 case "n":
360 case "nil":
361 case "null":
362 return true;
363 default:
364 return false;
365 }
366 }
367 }
368