Version Description
- Fixed #1197
- Added
'oembed'
option type (docs) - fixed:
fw_get_db_customizer_option()
infinite recursion when called with default value insidecustomizer.php
Download this release
Release Info
Developer | Unyson |
Plugin | Unyson |
Version | 2.4.17 |
Comparing to | |
See all releases |
Code changes from version 2.4.16 to 2.4.17
- framework/helpers/class-fw-cache.php +137 -18
- framework/helpers/database.php +35 -37
- framework/helpers/general.php +35 -3
- framework/includes/option-types/init.php +1 -0
- framework/includes/option-types/oembed/class-fw-option-type-oembed.php +124 -0
- framework/includes/option-types/oembed/static/css/styles.css +19 -0
- framework/includes/option-types/oembed/static/js/oembed.js +29 -0
- framework/includes/option-types/oembed/view.php +38 -0
- framework/manifest.php +1 -1
- framework/static/css/fw.css +4 -0
- readme.txt +6 -1
- unyson.php +1 -1
framework/helpers/class-fw-cache.php
CHANGED
@@ -22,12 +22,11 @@
|
|
22 |
*/
|
23 |
class FW_Cache
|
24 |
{
|
25 |
-
protected static $cache = array();
|
26 |
-
|
27 |
/**
|
28 |
-
*
|
|
|
29 |
*/
|
30 |
-
protected static $
|
31 |
|
32 |
/**
|
33 |
* If the PHP will have less that this memory, the cache will try to delete parts from its array to free memory
|
@@ -41,8 +40,33 @@ class FW_Cache
|
|
41 |
*/
|
42 |
protected static $memory_limit = null;
|
43 |
|
|
|
|
|
|
|
|
|
44 |
protected static $not_found_value;
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
protected static function get_memory_limit()
|
47 |
{
|
48 |
if (self::$memory_limit === null) {
|
@@ -74,16 +98,86 @@ class FW_Cache
|
|
74 |
*/
|
75 |
public static function _init()
|
76 |
{
|
77 |
-
self::$is_enabled = function_exists('register_tick_function');
|
78 |
self::$not_found_value = new FW_Cache_Not_Found_Exception();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
80 |
|
|
|
|
|
|
|
|
|
|
|
81 |
public static function is_enabled()
|
82 |
{
|
83 |
-
return
|
84 |
}
|
85 |
|
86 |
-
public static function free_memory()
|
87 |
{
|
88 |
while (self::memory_exceeded() && !empty(self::$cache)) {
|
89 |
reset(self::$cache);
|
@@ -92,6 +186,13 @@ class FW_Cache
|
|
92 |
|
93 |
unset(self::$cache[$key]);
|
94 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
}
|
96 |
|
97 |
/**
|
@@ -101,7 +202,7 @@ class FW_Cache
|
|
101 |
*/
|
102 |
public static function set($keys, $value, $keys_delimiter = '/')
|
103 |
{
|
104 |
-
if (!self
|
105 |
return;
|
106 |
}
|
107 |
|
@@ -149,10 +250,14 @@ class FW_Cache
|
|
149 |
self::free_memory();
|
150 |
|
151 |
if ($value === self::$not_found_value) {
|
|
|
|
|
152 |
throw new FW_Cache_Not_Found_Exception();
|
153 |
-
}
|
|
|
154 |
|
155 |
-
|
|
|
156 |
}
|
157 |
|
158 |
/**
|
@@ -162,15 +267,29 @@ class FW_Cache
|
|
162 |
{
|
163 |
self::$cache = array();
|
164 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
}
|
166 |
|
167 |
class FW_Cache_Not_Found_Exception extends Exception {}
|
168 |
|
169 |
-
FW_Cache::_init();
|
170 |
-
|
171 |
-
// auto free_memory() every X ticks
|
172 |
-
if (FW_Cache::is_enabled()) {
|
173 |
-
declare(ticks=3000);
|
174 |
-
|
175 |
-
register_tick_function(array('FW_Cache', 'free_memory'));
|
176 |
-
}
|
22 |
*/
|
23 |
class FW_Cache
|
24 |
{
|
|
|
|
|
25 |
/**
|
26 |
+
* The actual cache
|
27 |
+
* @var array
|
28 |
*/
|
29 |
+
protected static $cache = array();
|
30 |
|
31 |
/**
|
32 |
* If the PHP will have less that this memory, the cache will try to delete parts from its array to free memory
|
40 |
*/
|
41 |
protected static $memory_limit = null;
|
42 |
|
43 |
+
/**
|
44 |
+
* A special value that is used to detect if value was found in cache
|
45 |
+
* We can't use null|false because these can be values set by user and we can't treat them as not existing values
|
46 |
+
*/
|
47 |
protected static $not_found_value;
|
48 |
|
49 |
+
/**
|
50 |
+
* The amount of times the data was already stored in the cache.
|
51 |
+
* @var int
|
52 |
+
* @since 2.4.17
|
53 |
+
*/
|
54 |
+
protected static $hits = 0;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Amount of times the cache did not have the value in cache.
|
58 |
+
* @var int
|
59 |
+
* @since 2.4.17
|
60 |
+
*/
|
61 |
+
protected static $misses = 0;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Amount of times the cache free was called.
|
65 |
+
* @var int
|
66 |
+
* @since 2.4.17
|
67 |
+
*/
|
68 |
+
protected static $freed = 0;
|
69 |
+
|
70 |
protected static function get_memory_limit()
|
71 |
{
|
72 |
if (self::$memory_limit === null) {
|
98 |
*/
|
99 |
public static function _init()
|
100 |
{
|
|
|
101 |
self::$not_found_value = new FW_Cache_Not_Found_Exception();
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Listen often triggered hooks to clear the memory
|
105 |
+
* instead of tick function https://github.com/ThemeFuse/Unyson/issues/1197
|
106 |
+
* @since 2.4.17
|
107 |
+
*/
|
108 |
+
foreach (array(
|
109 |
+
'query' => true,
|
110 |
+
'plugins_loaded' => true,
|
111 |
+
'wp_get_object_terms' => true,
|
112 |
+
'created_term' => true,
|
113 |
+
'wp_upgrade' => true,
|
114 |
+
'added_option' => true,
|
115 |
+
'updated_option' => true,
|
116 |
+
'deleted_option' => true,
|
117 |
+
'wp_after_admin_bar_render' => true,
|
118 |
+
'http_response' => true,
|
119 |
+
'oembed_result' => true,
|
120 |
+
'customize_post_value_set' => true,
|
121 |
+
'customize_save_after' => true,
|
122 |
+
'customize_render_panel' => true,
|
123 |
+
'customize_render_control' => true,
|
124 |
+
'customize_render_section' => true,
|
125 |
+
'role_has_cap' => true,
|
126 |
+
'user_has_cap' => true,
|
127 |
+
'theme_page_templates' => true,
|
128 |
+
'pre_get_users' => true,
|
129 |
+
'request' => true,
|
130 |
+
'send_headers' => true,
|
131 |
+
'updated_usermeta' => true,
|
132 |
+
'added_usermeta' => true,
|
133 |
+
'image_memory_limit' => true,
|
134 |
+
'upload_dir' => true,
|
135 |
+
'wp_head' => true,
|
136 |
+
'wp_footer' => true,
|
137 |
+
'wp' => true,
|
138 |
+
'wp_init' => true,
|
139 |
+
'fw_init' => true,
|
140 |
+
'init' => true,
|
141 |
+
'updated_postmeta' => true,
|
142 |
+
'deleted_postmeta' => true,
|
143 |
+
'setted_transient' => true,
|
144 |
+
'registered_post_type' => true,
|
145 |
+
'wp_count_posts' => true,
|
146 |
+
'wp_count_attachments' => true,
|
147 |
+
'after_delete_post' => true,
|
148 |
+
'post_updated' => true,
|
149 |
+
'wp_insert_post' => true,
|
150 |
+
'deleted_post' => true,
|
151 |
+
'clean_post_cache' => true,
|
152 |
+
'wp_restore_post_revision' => true,
|
153 |
+
'wp_delete_post_revision' => true,
|
154 |
+
'get_term' => true,
|
155 |
+
'edited_term_taxonomies' => true,
|
156 |
+
'deleted_term_taxonomy' => true,
|
157 |
+
'edited_terms' => true,
|
158 |
+
'created_term' => true,
|
159 |
+
'clean_term_cache' => true,
|
160 |
+
'edited_term_taxonomy' => true,
|
161 |
+
'switch_theme' => true,
|
162 |
+
'wp_get_update_data' => true,
|
163 |
+
'clean_user_cache' => true,
|
164 |
+
'process_text_diff_html' => true,
|
165 |
+
) as $hook => $tmp) {
|
166 |
+
add_filter($hook, array(__CLASS__, 'free_memory'), 9999);
|
167 |
+
}
|
168 |
}
|
169 |
|
170 |
+
/**
|
171 |
+
* This method does nothing @since 2.4.17
|
172 |
+
* but we can't delete it because it's public and maybe somebody is calling it
|
173 |
+
* @return bool
|
174 |
+
*/
|
175 |
public static function is_enabled()
|
176 |
{
|
177 |
+
return true;
|
178 |
}
|
179 |
|
180 |
+
public static function free_memory($dummy = null)
|
181 |
{
|
182 |
while (self::memory_exceeded() && !empty(self::$cache)) {
|
183 |
reset(self::$cache);
|
186 |
|
187 |
unset(self::$cache[$key]);
|
188 |
}
|
189 |
+
|
190 |
+
++self::$freed;
|
191 |
+
|
192 |
+
/**
|
193 |
+
* This method is used add_filter() so to not break anything return filter value
|
194 |
+
*/
|
195 |
+
return $dummy;
|
196 |
}
|
197 |
|
198 |
/**
|
202 |
*/
|
203 |
public static function set($keys, $value, $keys_delimiter = '/')
|
204 |
{
|
205 |
+
if (!self::is_enabled()) {
|
206 |
return;
|
207 |
}
|
208 |
|
250 |
self::free_memory();
|
251 |
|
252 |
if ($value === self::$not_found_value) {
|
253 |
+
++self::$misses;
|
254 |
+
|
255 |
throw new FW_Cache_Not_Found_Exception();
|
256 |
+
} else {
|
257 |
+
++self::$hits;
|
258 |
|
259 |
+
return $value;
|
260 |
+
}
|
261 |
}
|
262 |
|
263 |
/**
|
267 |
{
|
268 |
self::$cache = array();
|
269 |
}
|
270 |
+
|
271 |
+
/**
|
272 |
+
* Debug information
|
273 |
+
* <?php add_action('admin_footer', function(){ FW_Cache::stats(); });
|
274 |
+
* @since 2.4.17
|
275 |
+
*/
|
276 |
+
public static function stats() {
|
277 |
+
echo '<div style="z-index: 10000; position: relative; background: #fff; padding: 15px;">';
|
278 |
+
echo '<p>';
|
279 |
+
echo '<strong>Cache Hits:</strong> '. self::$hits .'<br />';
|
280 |
+
echo '<strong>Cache Misses:</strong> '. self::$misses .'<br />';
|
281 |
+
echo '<strong>Cache Freed:</strong> '. self::$freed .'<br />';
|
282 |
+
echo '<strong>PHP Memory Peak Usage:</strong> '. fw_human_bytes(memory_get_peak_usage(false)) .'<br />';
|
283 |
+
echo '</p>';
|
284 |
+
echo '<ul>';
|
285 |
+
foreach (self::$cache as $group => $cache) {
|
286 |
+
echo "<li><strong>Group:</strong> $group - ( " . number_format( strlen( serialize( $cache ) ) / KB_IN_BYTES, 2 ) . 'k )</li>';
|
287 |
+
}
|
288 |
+
echo '</ul>';
|
289 |
+
echo '</div>';
|
290 |
+
}
|
291 |
}
|
292 |
|
293 |
class FW_Cache_Not_Found_Exception extends Exception {}
|
294 |
|
295 |
+
FW_Cache::_init();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
framework/helpers/database.php
CHANGED
@@ -422,12 +422,12 @@
|
|
422 |
*/
|
423 |
function fw_get_db_customizer_option( $option_id = null, $default_value = null ) {
|
424 |
// note: this contains only changed controls/options
|
425 |
-
$
|
426 |
|
427 |
if (
|
428 |
!is_null($default_value)
|
429 |
&&
|
430 |
-
is_null($option_id ? fw_akg($option_id, $
|
431 |
) {
|
432 |
/**
|
433 |
* Default value was provided in case db value is empty.
|
@@ -439,46 +439,44 @@
|
|
439 |
return $default_value;
|
440 |
}
|
441 |
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
try {
|
447 |
-
$all_default_values = FW_Cache::get( $cache_key );
|
448 |
-
} catch ( FW_Cache_Not_Found_Exception $e ) {
|
449 |
-
// extract the default values from options array
|
450 |
-
$all_default_values = fw_get_options_values_from_input(
|
451 |
-
fw()->theme->get_customizer_options(),
|
452 |
-
array()
|
453 |
-
);
|
454 |
|
455 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
456 |
}
|
457 |
-
}
|
458 |
|
459 |
-
|
460 |
-
$all_db_values = array();
|
461 |
}
|
462 |
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
$all_db_values
|
467 |
-
);
|
468 |
-
} else {
|
469 |
-
$base_key = explode('/', $option_id); // note: option_id can be a multi-key 'a/b/c'
|
470 |
-
$base_key = array_shift($base_key);
|
471 |
-
|
472 |
-
$all_db_values = array_key_exists($base_key, $all_db_values)
|
473 |
-
? $all_db_values
|
474 |
-
: $all_default_values;
|
475 |
-
|
476 |
-
return fw_akg(
|
477 |
-
$option_id,
|
478 |
-
$all_db_values,
|
479 |
-
$default_value
|
480 |
-
);
|
481 |
-
}
|
482 |
}
|
483 |
|
484 |
/**
|
422 |
*/
|
423 |
function fw_get_db_customizer_option( $option_id = null, $default_value = null ) {
|
424 |
// note: this contains only changed controls/options
|
425 |
+
$db_values = get_theme_mod(FW_Option_Type::get_default_name_prefix(), null);
|
426 |
|
427 |
if (
|
428 |
!is_null($default_value)
|
429 |
&&
|
430 |
+
is_null($option_id ? fw_akg($option_id, $db_values) : $db_values)
|
431 |
) {
|
432 |
/**
|
433 |
* Default value was provided in case db value is empty.
|
439 |
return $default_value;
|
440 |
}
|
441 |
|
442 |
+
if (is_null($db_values)) {
|
443 |
+
$db_values = array();
|
444 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
445 |
|
446 |
+
if (
|
447 |
+
is_null($option_id)
|
448 |
+
||
|
449 |
+
(
|
450 |
+
($base_key = explode('/', $option_id)) // note: option_id can be a multi-key 'a/b/c'
|
451 |
+
&&
|
452 |
+
($base_key = array_shift($base_key))
|
453 |
+
&&
|
454 |
+
!array_key_exists($base_key, $db_values)
|
455 |
+
)
|
456 |
+
) {
|
457 |
+
// extract options default values
|
458 |
+
{
|
459 |
+
$cache_key = 'fw_default_options_values/customizer';
|
460 |
+
|
461 |
+
try {
|
462 |
+
$default_values = FW_Cache::get( $cache_key );
|
463 |
+
} catch ( FW_Cache_Not_Found_Exception $e ) {
|
464 |
+
// extract the default values from options array
|
465 |
+
$default_values = fw_get_options_values_from_input(
|
466 |
+
fw()->theme->get_customizer_options(),
|
467 |
+
array()
|
468 |
+
);
|
469 |
+
|
470 |
+
FW_Cache::set( $cache_key, $default_values );
|
471 |
+
}
|
472 |
}
|
|
|
473 |
|
474 |
+
$db_values = array_merge($default_values, $db_values);
|
|
|
475 |
}
|
476 |
|
477 |
+
return is_null($option_id)
|
478 |
+
? $db_values
|
479 |
+
: fw_akg($option_id, $db_values, $default_value);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
480 |
}
|
481 |
|
482 |
/**
|
framework/helpers/general.php
CHANGED
@@ -1143,8 +1143,7 @@ function fw_current_user_can($capabilities, $default_value = null)
|
|
1143 |
* @param int $seconds
|
1144 |
* @return string
|
1145 |
*/
|
1146 |
-
function fw_human_time($seconds)
|
1147 |
-
{
|
1148 |
static $translations = null;
|
1149 |
if ($translations === null) {
|
1150 |
$translations = array(
|
@@ -1191,6 +1190,39 @@ function fw_human_time($seconds)
|
|
1191 |
}
|
1192 |
}
|
1193 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1194 |
function fw_strlen($string) {
|
1195 |
if (function_exists('mb_strlen')) {
|
1196 |
return mb_strlen($string, 'UTF-8');
|
@@ -1265,7 +1297,7 @@ function fw_oembed_get($url, $args = array()) {
|
|
1265 |
|
1266 |
if (!empty($args['width']) and !empty($args['height']) and class_exists('DOMDocument') and !empty($html)) {
|
1267 |
$dom_element = new DOMDocument();
|
1268 |
-
|
1269 |
$obj = $dom_element->getElementsByTagName('iframe')->item(0);
|
1270 |
$obj->setAttribute('width', $args['width']);
|
1271 |
$obj->setAttribute('height', $args['height']);
|
1143 |
* @param int $seconds
|
1144 |
* @return string
|
1145 |
*/
|
1146 |
+
function fw_human_time($seconds) {
|
|
|
1147 |
static $translations = null;
|
1148 |
if ($translations === null) {
|
1149 |
$translations = array(
|
1190 |
}
|
1191 |
}
|
1192 |
|
1193 |
+
/**
|
1194 |
+
* Convert bytes to human readable format
|
1195 |
+
*
|
1196 |
+
* @param integer $bytes Size in bytes to convert
|
1197 |
+
* @param integer $precision
|
1198 |
+
* @return string
|
1199 |
+
* @since 2.4.17
|
1200 |
+
*/
|
1201 |
+
function fw_human_bytes($bytes, $precision = 2) {
|
1202 |
+
$kilobyte = 1024;
|
1203 |
+
$megabyte = $kilobyte * 1024;
|
1204 |
+
$gigabyte = $megabyte * 1024;
|
1205 |
+
$terabyte = $gigabyte * 1024;
|
1206 |
+
|
1207 |
+
if (($bytes >= 0) && ($bytes < $kilobyte)) {
|
1208 |
+
return $bytes . ' B';
|
1209 |
+
|
1210 |
+
} elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
|
1211 |
+
return round($bytes / $kilobyte, $precision) . ' KB';
|
1212 |
+
|
1213 |
+
} elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
|
1214 |
+
return round($bytes / $megabyte, $precision) . ' MB';
|
1215 |
+
|
1216 |
+
} elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
|
1217 |
+
return round($bytes / $gigabyte, $precision) . ' GB';
|
1218 |
+
|
1219 |
+
} elseif ($bytes >= $terabyte) {
|
1220 |
+
return round($bytes / $terabyte, $precision) . ' TB';
|
1221 |
+
} else {
|
1222 |
+
return $bytes . ' B';
|
1223 |
+
}
|
1224 |
+
}
|
1225 |
+
|
1226 |
function fw_strlen($string) {
|
1227 |
if (function_exists('mb_strlen')) {
|
1228 |
return mb_strlen($string, 'UTF-8');
|
1297 |
|
1298 |
if (!empty($args['width']) and !empty($args['height']) and class_exists('DOMDocument') and !empty($html)) {
|
1299 |
$dom_element = new DOMDocument();
|
1300 |
+
@$dom_element->loadHTML($html);
|
1301 |
$obj = $dom_element->getElementsByTagName('iframe')->item(0);
|
1302 |
$obj->setAttribute('width', $args['width']);
|
1303 |
$obj->setAttribute('height', $args['height']);
|
framework/includes/option-types/init.php
CHANGED
@@ -30,6 +30,7 @@ require $dir . '/slider/class-fw-option-type-short-slider.php';
|
|
30 |
require $dir . '/range-slider/class-fw-option-type-range-slider.php';
|
31 |
require $dir . '/rgba-color-picker/class-fw-option-type-rgba-color-picker.php';
|
32 |
require $dir . '/typography-v2/class-fw-option-type-typography-v2.php';
|
|
|
33 |
if (!class_exists('FW_Option_Type_Multi_Select')) {
|
34 |
require $dir . '/multi-select/class-fw-option-type-multi-select.php';
|
35 |
}
|
30 |
require $dir . '/range-slider/class-fw-option-type-range-slider.php';
|
31 |
require $dir . '/rgba-color-picker/class-fw-option-type-rgba-color-picker.php';
|
32 |
require $dir . '/typography-v2/class-fw-option-type-typography-v2.php';
|
33 |
+
require $dir . '/oembed/class-fw-option-type-oembed.php';
|
34 |
if (!class_exists('FW_Option_Type_Multi_Select')) {
|
35 |
require $dir . '/multi-select/class-fw-option-type-multi-select.php';
|
36 |
}
|
framework/includes/option-types/oembed/class-fw-option-type-oembed.php
ADDED
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if ( ! defined( 'FW' ) ) {
|
2 |
+
die( 'Forbidden' );
|
3 |
+
}
|
4 |
+
|
5 |
+
class FW_Option_Type_Oembed extends FW_Option_Type {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Option's unique type, used in option array in 'type' key
|
9 |
+
* @return string
|
10 |
+
*/
|
11 |
+
public function get_type() {
|
12 |
+
return 'oembed';
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Generate html
|
17 |
+
*
|
18 |
+
* @param string $id
|
19 |
+
* @param array $option Option array merged with _get_defaults()
|
20 |
+
* @param array $data {value => _get_value_from_input(), id_prefix => ..., name_prefix => ...}
|
21 |
+
*
|
22 |
+
* @return string HTML
|
23 |
+
* @internal
|
24 |
+
*/
|
25 |
+
protected function _render( $id, $option, $data ) {
|
26 |
+
|
27 |
+
$defaults = $this->_get_defaults();
|
28 |
+
$option['preview'] = array_merge( $defaults['preview'], $option['preview'] );
|
29 |
+
$option['attr'] =array_merge($defaults['attr'], $option['attr']);
|
30 |
+
|
31 |
+
return fw_render_view(
|
32 |
+
fw_get_framework_directory( '/includes/option-types/' . $this->get_type() . '/view.php' ),
|
33 |
+
compact( 'id', 'option', 'data' )
|
34 |
+
);
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Extract correct value for $option['value'] from input array
|
39 |
+
* If input value is empty, will be returned $option['value']
|
40 |
+
*
|
41 |
+
* @param array $option Option array merged with _get_defaults()
|
42 |
+
* @param array|string|null $input_value
|
43 |
+
*
|
44 |
+
* @return string|array|int|bool Correct value
|
45 |
+
* @internal
|
46 |
+
*/
|
47 |
+
protected function _get_value_from_input( $option, $input_value ) {
|
48 |
+
return (string) ( is_null( $input_value ) ? $option['value'] : $input_value );
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Default option array
|
53 |
+
*
|
54 |
+
* This makes possible an option array to have required only one parameter: array('type' => '...')
|
55 |
+
* Other parameters are merged with the array returned by this method.
|
56 |
+
*
|
57 |
+
* @return array
|
58 |
+
*
|
59 |
+
* array(
|
60 |
+
* 'value' => '',
|
61 |
+
* ...
|
62 |
+
* )
|
63 |
+
* @internal
|
64 |
+
*/
|
65 |
+
protected function _get_defaults() {
|
66 |
+
return array(
|
67 |
+
'value' => '',
|
68 |
+
'attr' => array(
|
69 |
+
'placeholder' => 'https://www.youtube.com'
|
70 |
+
),
|
71 |
+
'preview' => array(
|
72 |
+
'width' => 428,
|
73 |
+
'height' => 320,
|
74 |
+
/**
|
75 |
+
* by default wp_get_embed maintain ratio and return changed width and height values of the iframe,
|
76 |
+
* if you set it to false , the dimensions will be forced to change as in preview.width and preview.height
|
77 |
+
*/
|
78 |
+
'keep_ratio' => true
|
79 |
+
)
|
80 |
+
);
|
81 |
+
}
|
82 |
+
|
83 |
+
protected function _enqueue_static( $id, $option, $data ) {
|
84 |
+
wp_enqueue_style(
|
85 |
+
'fw-option-' . $this->get_type(),
|
86 |
+
fw_get_framework_directory_uri( '/includes/option-types/' . $this->get_type() . '/static/css/styles.css' ),
|
87 |
+
array( 'fw' )
|
88 |
+
);
|
89 |
+
|
90 |
+
wp_enqueue_script(
|
91 |
+
'fw-option-' . $this->get_type(),
|
92 |
+
fw_get_framework_directory_uri( '/includes/option-types/' . $this->get_type() . '/static/js/' . $this->get_type() . '.js' ),
|
93 |
+
array( 'underscore', 'fw-events', 'fw', 'wp-util' ),
|
94 |
+
false,
|
95 |
+
true
|
96 |
+
);
|
97 |
+
}
|
98 |
+
|
99 |
+
public static function _action_get_oembed_response() {
|
100 |
+
|
101 |
+
if ( wp_verify_nonce( FW_Request::POST( '_nonce' ), '_action_get_oembed_response' ) ) {
|
102 |
+
|
103 |
+
$url = FW_Request::POST( 'url' );
|
104 |
+
$width = FW_Request::POST( 'preview/width' );
|
105 |
+
$height = FW_Request::POST( 'preview/height' );
|
106 |
+
$keep_ratio = ( FW_Request::POST( 'preview/keep_ratio' ) === 'true' );
|
107 |
+
|
108 |
+
$iframe = empty( $keep_ratio ) ?
|
109 |
+
fw_oembed_get( $url, compact( 'width', 'height' ) ) :
|
110 |
+
wp_oembed_get( $url, compact( 'width', 'height' ) );
|
111 |
+
|
112 |
+
wp_send_json_success( array( 'response' => $iframe ) );
|
113 |
+
}
|
114 |
+
|
115 |
+
wp_send_json_error( array( 'message' => 'Invalid nonce' ) );
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
FW_Option_Type::register( 'FW_Option_Type_Oembed' );
|
120 |
+
|
121 |
+
add_action(
|
122 |
+
'wp_ajax_get_oembed_response',
|
123 |
+
array( "FW_Option_Type_Oembed", '_action_get_oembed_response' )
|
124 |
+
);
|
framework/includes/option-types/oembed/static/css/styles.css
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.fw-oembed-preview img,
|
2 |
+
.fw-oembed-preview iframe,
|
3 |
+
.fw-oembed-preview embed
|
4 |
+
{
|
5 |
+
max-width: 100%;
|
6 |
+
vertical-align: middle;
|
7 |
+
}
|
8 |
+
|
9 |
+
.fw-oembed-preview a {
|
10 |
+
display: inline-block;
|
11 |
+
}
|
12 |
+
|
13 |
+
.fw-oembed-preview img {
|
14 |
+
display: block;
|
15 |
+
height: auto;
|
16 |
+
}
|
17 |
+
.fw-oembed-preview {
|
18 |
+
padding-top: 7px;
|
19 |
+
}
|
framework/includes/option-types/oembed/static/js/oembed.js
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function ($, _, fwEvents) {
|
2 |
+
var oembed = function () {
|
3 |
+
var $wrapper = $(this);
|
4 |
+
var $input = $wrapper.find('input[type=text]');
|
5 |
+
var $iframeWrapper = $wrapper.find('.fw-oembed-preview');
|
6 |
+
|
7 |
+
$input.on('input',
|
8 |
+
_.debounce(function () {
|
9 |
+
wp.ajax.post(
|
10 |
+
'get_oembed_response',
|
11 |
+
{
|
12 |
+
'_nonce': $wrapper.data('nonce'),
|
13 |
+
'preview': $wrapper.data('preview'),
|
14 |
+
'url': $input.val()
|
15 |
+
}).done(function (data) {
|
16 |
+
$iframeWrapper.html(data.response);
|
17 |
+
}).fail(function () {
|
18 |
+
})
|
19 |
+
|
20 |
+
}, 300)
|
21 |
+
);
|
22 |
+
};
|
23 |
+
|
24 |
+
fwEvents.on('fw:options:init', function (data) {
|
25 |
+
data.$elements
|
26 |
+
.find('.fw-option-type-oembed:not(.fw-option-initialized)').each(oembed)
|
27 |
+
.addClass('fw-option-initialized');
|
28 |
+
});
|
29 |
+
})(jQuery, _, fwEvents);
|
framework/includes/option-types/oembed/view.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if ( ! defined( 'FW' ) ) {
|
2 |
+
die( 'Forbidden' );
|
3 |
+
}
|
4 |
+
|
5 |
+
$wrapper_attr = $option['attr'];
|
6 |
+
$wrapper_attr['data-nonce'] = wp_create_nonce( '_action_get_oembed_response' );
|
7 |
+
$wrapper_attr['data-preview'] = json_encode( $option['preview'] );
|
8 |
+
|
9 |
+
unset(
|
10 |
+
$wrapper_attr['value'],
|
11 |
+
$wrapper_attr['name'],
|
12 |
+
$wrapper_attr['placeholder']
|
13 |
+
);
|
14 |
+
|
15 |
+
$input_attr['value'] = $data['value'];
|
16 |
+
$input_attr['name'] = $option['attr']['name'];
|
17 |
+
$input_attr['placeholder'] = $option['attr']['placeholder'];
|
18 |
+
?>
|
19 |
+
<div <?php echo fw_attr_to_html( $wrapper_attr ) ?>>
|
20 |
+
|
21 |
+
<div class="fw-oembed-input">
|
22 |
+
<input type="text" <?php echo fw_attr_to_html( $input_attr ); ?>/>
|
23 |
+
</div>
|
24 |
+
<div class="fw-oembed-preview">
|
25 |
+
<?php
|
26 |
+
$iframe = empty( $option['preview']['keep_ratio'] ) ? fw_oembed_get( $data['value'], array(
|
27 |
+
'height' => $option['preview']['height'],
|
28 |
+
'width' => $option['preview']['width']
|
29 |
+
) ) :
|
30 |
+
wp_oembed_get( $data['value'], array(
|
31 |
+
'height' => $option['preview']['height'],
|
32 |
+
'width' => $option['preview']['width']
|
33 |
+
) );
|
34 |
+
|
35 |
+
echo $iframe;
|
36 |
+
?>
|
37 |
+
</div>
|
38 |
+
</div>
|
framework/manifest.php
CHANGED
@@ -4,4 +4,4 @@ $manifest = array();
|
|
4 |
|
5 |
$manifest['name'] = __('Unyson', 'fw');
|
6 |
|
7 |
-
$manifest['version'] = '2.4.
|
4 |
|
5 |
$manifest['name'] = __('Unyson', 'fw');
|
6 |
|
7 |
+
$manifest['version'] = '2.4.17';
|
framework/static/css/fw.css
CHANGED
@@ -2923,6 +2923,10 @@ body.wp-customizer > div:not(.fw-modal) > .media-modal-backdrop {
|
|
2923 |
transition-duration: .6s;
|
2924 |
}
|
2925 |
|
|
|
|
|
|
|
|
|
2926 |
/* end: open animation */
|
2927 |
|
2928 |
/* close animation */
|
2923 |
transition-duration: .6s;
|
2924 |
}
|
2925 |
|
2926 |
+
.fw-modal.fw-modal-open > .media-modal > .media-modal-close:focus {
|
2927 |
+
outline: 0;
|
2928 |
+
}
|
2929 |
+
|
2930 |
/* end: open animation */
|
2931 |
|
2932 |
/* close animation */
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: unyson
|
|
3 |
Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio, framework
|
4 |
Requires at least: 4.0.0
|
5 |
Tested up to: 4.4
|
6 |
-
Stable tag: 2.4.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -83,6 +83,11 @@ Yes; Unyson will work with any theme.
|
|
83 |
|
84 |
== Changelog ==
|
85 |
|
|
|
|
|
|
|
|
|
|
|
86 |
= 2.4.16 =
|
87 |
* Fixed [#1178](https://github.com/ThemeFuse/Unyson/issues/1178), [#1179](https://github.com/ThemeFuse/Unyson/issues/1179), [#1169](https://github.com/ThemeFuse/Unyson/issues/1169), [#1085](https://github.com/ThemeFuse/Unyson/issues/1085)
|
88 |
|
3 |
Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio, framework
|
4 |
Requires at least: 4.0.0
|
5 |
Tested up to: 4.4
|
6 |
+
Stable tag: 2.4.17
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
83 |
|
84 |
== Changelog ==
|
85 |
|
86 |
+
= 2.4.17 =
|
87 |
+
* Fixed [#1197](https://github.com/ThemeFuse/Unyson/issues/1197)
|
88 |
+
* Added `'oembed'` option type ([docs](http://manual.unyson.io/en/latest/options/built-in-option-types.html#oembed))
|
89 |
+
* fixed: `fw_get_db_customizer_option()` infinite recursion when called with default value inside `customizer.php`
|
90 |
+
|
91 |
= 2.4.16 =
|
92 |
* Fixed [#1178](https://github.com/ThemeFuse/Unyson/issues/1178), [#1179](https://github.com/ThemeFuse/Unyson/issues/1179), [#1169](https://github.com/ThemeFuse/Unyson/issues/1169), [#1085](https://github.com/ThemeFuse/Unyson/issues/1085)
|
93 |
|
unyson.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Unyson
|
4 |
* Plugin URI: http://unyson.io/
|
5 |
* Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
|
6 |
-
* Version: 2.4.
|
7 |
* Author: ThemeFuse
|
8 |
* Author URI: http://themefuse.com
|
9 |
* License: GPL2+
|
3 |
* Plugin Name: Unyson
|
4 |
* Plugin URI: http://unyson.io/
|
5 |
* Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
|
6 |
+
* Version: 2.4.17
|
7 |
* Author: ThemeFuse
|
8 |
* Author URI: http://themefuse.com
|
9 |
* License: GPL2+
|