PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / 1.0.0
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more v1.0.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
18 */
19 class Shortcode
20 {
21 /**
22 * The WP_oEmbed class instance.
23 *
24 * @since 1.0
25 * @access private
26 *
27 * @var string $oEmbedInstance
28 */
29 private static $oEmbedInstance = null;
30
31 /**
32 * Register the plugin's shortcode into WordPress.
33 *
34 * @since 1.0
35 * @static
36 */
37 public static function register()
38 {
39 // Register the new shortcode for embeds.
40 add_shortcode(EMBEDPRESS_SHORTCODE, array('\\EmbedPress\\Shortcode', 'do_shortcode'), 1);
41 }
42
43 /**
44 * Method that converts the plugin shortcoded-string into its complex content.
45 *
46 * @since 1.0
47 * @static
48 *
49 * @param array $attributes @TODO
50 * @param string $subject The given string
51 * @return string
52 */
53 public static function do_shortcode($attributes = array(), $subject = null)
54 {
55 $decodedSubject = self::parseContent($subject, true, $attributes);
56
57 return $decodedSubject;
58 }
59
60 /**
61 * Replace a given content with its embeded HTML code.
62 *
63 * @since 1.0
64 * @static
65 *
66 * @param string The raw content that will be replaced.
67 * @param boolean Optional. If true, new lines at the end of the embeded code are stripped.
68 * @return string
69 */
70 public static function parseContent($subject, $stripNewLine = false, $customAttributes = array())
71 {
72 if (!empty($subject)) {
73 if (empty($customAttributes)) {
74 $customAttributes = self::parseContentAttributesFromString($subject);
75 }
76
77 $content = preg_replace('/(\['. EMBEDPRESS_SHORTCODE .'(?:\]|.+?\])|\[\/'. EMBEDPRESS_SHORTCODE .'\])/i', "", $subject);
78
79 // Check if the WP_oEmbed class is loaded
80 if (!self::$oEmbedInstance) {
81 require_once ABSPATH .'wp-includes/class-oembed.php';
82
83 self::$oEmbedInstance = _wp_oembed_get_object();
84 }
85
86 $emberaInstanceSettings = array(
87 'params' => array()
88 );
89
90 $attributes = self::parseContentAttributes($customAttributes);
91 if (isset($attributes['width']) || isset($attributes['height'])) {
92 if (isset($attributes['width'])) {
93 $emberaInstanceSettings['params']['width'] = $attributes['width'];
94 unset($attributes['width']);
95 }
96
97 if (isset($attributes['height'])) {
98 $emberaInstanceSettings['params']['height'] = $attributes['height'];
99 unset($attributes['height']);
100 }
101 }
102
103 // Identify what service provider the shortcode's link belongs to
104 $serviceProvider = self::$oEmbedInstance->get_provider($content);
105
106 // Gather info about the shortcode's link
107 $urlData = self::$oEmbedInstance->fetch($serviceProvider, $content, $attributes);
108
109 // Transform all shortcode attributes into html form. I.e.: {foo: "joe"} -> foo="joe"
110 $attributesHtml = array();
111 foreach ($attributes as $attrName => $attrValue) {
112 $attributesHtml[] = $attrName .'="'. $attrValue .'"';
113 }
114
115 // Define the EmbedPress html template where the generated embed will be injected in
116 $embedTemplate = '<div '. implode(' ', $attributesHtml) .'>{html}</div>';
117
118 // Try to generate the embed using WP API
119 $parsedContent = self::$oEmbedInstance->get_html($content, $attributes);
120 if (!$parsedContent) {
121 // If the embed couldn't be generated, we'll try to use Embera's API
122 $emberaInstance = new Embera($emberaInstanceSettings);
123 // Add support to the user's custom service providers
124 $additionalServiceProviders = Plugin::getAdditionalServiceProviders();
125 if (!empty($additionalServiceProviders)) {
126 foreach ($additionalServiceProviders as $serviceProviderClassName => $serviceProviderUrls) {
127 self::addServiceProvider($serviceProviderClassName, $serviceProviderUrls, $emberaInstance);
128 }
129
130 unset($serviceProviderUrls, $serviceProviderClassName);
131 }
132
133 // Register the html template
134 $emberaFormaterInstance = new Formatter($emberaInstance, true);
135 $emberaFormaterInstance->setTemplate($embedTemplate);
136
137 // Try to generate the embed using Embera API
138 $parsedContent = $emberaFormaterInstance->transform($content);
139
140 unset($emberaFormaterInstance, $additionalServiceProviders, $emberaInstance);
141 } else {
142 // Inject the generated code inside the html template
143 $parsedContent = str_replace('{html}', $parsedContent, $embedTemplate);
144
145 // Replace all single quotes to double quotes. I.e: foo='joe' -> foo="joe"
146 $parsedContent = str_replace("'", '"', $parsedContent);
147
148 // Replace the flag `{provider_alias}` which is used by Embera with the "ose-<serviceProviderAlias>". I.e: YouTube -> "ose-youtube"
149 $parsedContent = preg_replace('/((?:ose-)?\{provider_alias\})/i', "ose-". strtolower($urlData->provider_name), $parsedContent);
150 }
151
152 unset($embedTemplate, $urlData, $serviceProvider);
153
154 // This assure that the iframe has the same dimensions the user wants to
155 if (isset($emberaInstanceSettings['params']['width']) || isset($emberaInstanceSettings['params']['height'])) {
156 if (isset($emberaInstanceSettings['params']['width']) && isset($emberaInstanceSettings['params']['height'])) {
157 $customWidth = (int)$emberaInstanceSettings['params']['width'];
158 $customHeight = (int)$emberaInstanceSettings['params']['height'];
159 } else {
160 preg_match_all('/\<iframe\s+width="(\d+)"\s+height="(\d+)"/i', $parsedContent, $matches);
161 $iframeWidth = (int)$matches[1][0];
162 $iframeHeight = (int)$matches[2][0];
163 $iframeRatio = ceil($iframeWidth / $iframeHeight);
164
165 if (isset($emberaInstanceSettings['params']['width'])) {
166 $customWidth = (int)$emberaInstanceSettings['params']['width'];
167 $customHeight = ceil($customWidth / $iframeRatio);
168 } else {
169 $customHeight = (int)$emberaInstanceSettings['params']['height'];
170 $customWidth = $iframeRatio * $customHeight;
171 }
172
173 unset($iframeRatio, $iframeHeight, $iframeWidth, $matches);
174 }
175
176 $parsedContent = preg_replace('/\s+width\=\"(\d+)\"/i', ' width="'. $customWidth .'"', $parsedContent);
177 $parsedContent = preg_replace('/\s+height\=\"(\d+)\"/i', ' height="'. $customHeight .'"', $parsedContent);
178 }
179
180 if ($stripNewLine) {
181 $parsedContent = preg_replace('/\n/', '', $parsedContent);
182 }
183
184 if (!empty($parsedContent)) {
185 return $parsedContent;
186 }
187 }
188
189 return $subject;
190 }
191
192 /**
193 * Method that adds support to a given new service provider (SP).
194 *
195 * @since 1.0
196 * @static
197 *
198 * @param string $className The new SP class name.
199 * @param string $reference The new SP reference name.
200 * @param \Embera\Embera $emberaInstance The embera's instance where the SP will be registered in.
201 *
202 * @return boolean
203 */
204 public static function addServiceProvider($className, $reference, &$emberaInstance)
205 {
206 if (empty($className) || empty($reference)) {
207 return false;
208 }
209
210 if (is_string($reference)) {
211 $emberaInstance->addProvider($reference, EMBEDPRESS_NAMESPACE ."\\Providers\\{$className}");
212 } else if (is_array($reference)) {
213 foreach ($reference as $serviceProviderUrl) {
214 self::addServiceProvider($className, $serviceProviderUrl, $emberaInstance);
215 }
216 } else {
217 return false;
218 }
219 }
220
221 /**
222 * Method that retrieves all custom parameters from a shortcoded string.
223 *
224 * @since 1.0
225 * @static
226 *
227 * @param string $subject The given shortcoded string.
228 *
229 * @return array
230 */
231 public static function parseContentAttributesFromString($subject)
232 {
233 $customAttributes = array();
234 if (preg_match('/\[embed\s*(.*?)\]/i', stripslashes($subject), $m)) {
235 if (preg_match_all('/(\!?\w+-?\w*)(?:="(.+?)")?/i', stripslashes($m[1]), $matches)) {
236 $attributes = $matches[1];
237 $attrValues = $matches[2];
238
239 foreach ($attributes as $attrIndex => $attrName) {
240 $customAttributes[$attrName] = $attrValues[$attrIndex];
241 }
242 }
243 }
244
245 return $customAttributes;
246 }
247
248 /**
249 * Method that parses and adds the "data-" prefix to the given custom shortcode attributes.
250 *
251 * @since 1.0
252 * @static
253 *
254 * @param array $attributes The array containing the embed attributes.
255 *
256 * @return array
257 */
258 private static function parseContentAttributes(array $customAttributes)
259 {
260 $attributes = array(
261 'class' => array("embedpress-wrapper")
262 );
263
264 $embedShouldBeResponsive = true;
265 $embedShouldHaveCustomDimensions = false;
266 if (!empty($customAttributes)) {
267 if (isset($customAttributes['class'])) {
268 if (!empty($customAttributes['class'])) {
269 $customAttributes['class'] = explode(' ', $customAttributes['class']);
270
271 $attributes['class'] = array_merge($attributes['class'], $customAttributes['class']);
272 }
273
274 unset($customAttributes['class']);
275 }
276
277 if (isset($customAttributes['width'])) {
278 if (!empty($customAttributes['width'])) {
279 $attributes['width'] = (int)$customAttributes['width'];
280 $embedShouldHaveCustomDimensions = true;
281 }
282 }
283
284 if (isset($customAttributes['height'])) {
285 if (!empty($customAttributes['height'])) {
286 $attributes['height'] = (int)$customAttributes['height'];
287 $embedShouldHaveCustomDimensions = true;
288 }
289 }
290
291 if (!empty($customAttributes)) {
292 $attrNameDefaultPrefix = "data-";
293 foreach ($customAttributes as $attrName => $attrValue) {
294 if (is_numeric($attrName)) {
295 $attrName = $attrValue;
296 $attrValue = "";
297 }
298
299 $attrName = str_replace($attrNameDefaultPrefix, "", $attrName);
300
301 if (!strlen($attrValue)) {
302 if ($attrName[0] === "!") {
303 $attrValue = "false";
304 $attrName = substr($attrName, 1);
305 } else {
306 $attrValue = "true";
307 }
308 }
309
310 $attributes[$attrNameDefaultPrefix . $attrName] = $attrValue;
311 }
312 }
313
314 // Check if there's any "responsive" parameter
315 $responsiveAttributes = array("responsive", "data-responsive");
316 foreach ($responsiveAttributes as $responsiveAttr) {
317 if (isset($attributes[$responsiveAttr])) {
318 if (!strlen($attributes[$responsiveAttr])) { // If the parameter is passed but have no value, it will be true by default
319 $embedShouldBeResponsive = true;
320 } else {
321 $embedShouldBeResponsive = !self::valueIsFalse($attributes[$responsiveAttr]);
322 }
323
324 break;
325 }
326 }
327 unset($responsiveAttr, $responsiveAttributes);
328 }
329
330 if ($embedShouldBeResponsive && !$embedShouldHaveCustomDimensions) {
331 $attributes['class'][] = 'ose-{provider_alias} responsive';
332 } else {
333 $attributes['data-responsive'] = "false";
334 }
335
336 $attributes['class'] = implode(' ', array_unique(array_filter($attributes['class'])));
337
338 return $attributes;
339 }
340
341 /**
342 * Method that checks if a given value is/can be identified as (bool)false.
343 *
344 * @since 1.0
345 * @static
346 *
347 * @param mixed $subject The value to be checked.
348 *
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