Version Description
- Fixed #397, #394, #389, 384, #355
- Added option type
runnable
code
Download this release
Release Info
Developer | Unyson |
Plugin | Unyson |
Version | 2.2.3 |
Comparing to | |
See all releases |
Code changes from version 2.2.2 to 2.2.3
- framework/core/components/backend.php +4 -0
- framework/core/components/extensions.php +81 -37
- framework/core/components/extensions/manager/class--fw-extensions-manager.php +21 -25
- framework/core/components/extensions/manager/views/extension.php +1 -1
- framework/core/components/extensions/manager/views/extensions-page.php +7 -2
- framework/core/extends/class-fw-extension.php +1 -0
- framework/helpers/class-fw-form.php +63 -25
- framework/helpers/general.php +2 -0
- framework/includes/option-types.php +1 -0
- framework/includes/option-types/addable-box/view.php +1 -8
- framework/includes/option-types/icon/class-fw-option-type-icon.php +2 -0
- framework/includes/option-types/multi-select/class-fw-option-type-multi-select.php +5 -5
- framework/includes/option-types/runnable/class-fw-option-type-runnable.php +139 -0
- framework/includes/option-types/runnable/static/css/runnable.css +9 -0
- framework/includes/option-types/runnable/static/js/runnable.js +43 -0
- framework/includes/option-types/typography/view.php +2 -2
- framework/manifest.php +1 -1
- framework/static/css/fw.css +1 -1
- framework/views/backend-tabs.php +2 -1
- readme.txt +5 -1
- unyson.php +1 -1
framework/core/components/backend.php
CHANGED
@@ -544,6 +544,7 @@ final class _FW_Component_Backend {
|
|
544 |
|
545 |
unset( $box[ $id ] ); // free memory
|
546 |
}
|
|
|
547 |
}
|
548 |
|
549 |
/**
|
@@ -1098,6 +1099,7 @@ final class _FW_Component_Backend {
|
|
1098 |
)
|
1099 |
);
|
1100 |
}
|
|
|
1101 |
|
1102 |
$html .= '</div>';
|
1103 |
break;
|
@@ -1120,6 +1122,7 @@ final class _FW_Component_Backend {
|
|
1120 |
$html .= $this->render_options( $group['options'], $values, $options_data );
|
1121 |
$html .= '</div>';
|
1122 |
}
|
|
|
1123 |
break;
|
1124 |
case 'option':
|
1125 |
foreach ( $collected_type_options as $id => &$_option ) {
|
@@ -1134,6 +1137,7 @@ final class _FW_Component_Backend {
|
|
1134 |
$design
|
1135 |
);
|
1136 |
}
|
|
|
1137 |
break;
|
1138 |
default:
|
1139 |
$html .= '<p><em>' . __( 'Unknown collected type', 'fw' ) . ': ' . $collected_type . '</em></p>';
|
544 |
|
545 |
unset( $box[ $id ] ); // free memory
|
546 |
}
|
547 |
+
unset($box);
|
548 |
}
|
549 |
|
550 |
/**
|
1099 |
)
|
1100 |
);
|
1101 |
}
|
1102 |
+
unset($box);
|
1103 |
|
1104 |
$html .= '</div>';
|
1105 |
break;
|
1122 |
$html .= $this->render_options( $group['options'], $values, $options_data );
|
1123 |
$html .= '</div>';
|
1124 |
}
|
1125 |
+
unset($group);
|
1126 |
break;
|
1127 |
case 'option':
|
1128 |
foreach ( $collected_type_options as $id => &$_option ) {
|
1137 |
$design
|
1138 |
);
|
1139 |
}
|
1140 |
+
unset($_option);
|
1141 |
break;
|
1142 |
default:
|
1143 |
$html .= '<p><em>' . __( 'Unknown collected type', 'fw' ) . ': ' . $collected_type . '</em></p>';
|
framework/core/components/extensions.php
CHANGED
@@ -302,55 +302,98 @@ final class _FW_Component_Extensions
|
|
302 |
}
|
303 |
}
|
304 |
|
305 |
-
|
306 |
{
|
307 |
-
|
308 |
-
* { '/hello/world/extensions' => 'https://hello.com/world/extensions' }
|
309 |
-
*/
|
310 |
-
$custom_locations = apply_filters('fw_extensions_locations', array());
|
311 |
|
312 |
-
{
|
313 |
-
|
|
|
|
|
|
|
|
|
|
|
314 |
|
315 |
-
|
316 |
-
$customizations_locations
|
317 |
-
= fw_get_stylesheet_customizations_directory_uri('/extensions');
|
318 |
-
}
|
319 |
|
320 |
-
|
321 |
-
|
|
|
|
|
322 |
|
323 |
-
|
324 |
-
|
|
|
|
|
|
|
325 |
|
326 |
-
|
327 |
-
'path' => fw_get_framework_directory('/extensions'),
|
328 |
-
'uri' => fw_get_framework_directory_uri('/extensions'),
|
329 |
-
'customizations_locations' => $customizations_locations,
|
330 |
-
));
|
331 |
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
'path' => $path,
|
336 |
-
'uri' => $uri,
|
337 |
'customizations_locations' => $customizations_locations,
|
338 |
-
|
339 |
-
|
|
|
|
|
|
|
|
|
340 |
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
347 |
|
348 |
-
if (is_child_theme()) {
|
349 |
array_pop($customizations_locations);
|
350 |
-
|
351 |
-
'path' =>
|
352 |
-
'uri' =>
|
353 |
'customizations_locations' => $customizations_locations,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
354 |
));
|
355 |
}
|
356 |
}
|
@@ -409,6 +452,7 @@ final class _FW_Component_Extensions
|
|
409 |
}
|
410 |
}
|
411 |
}
|
|
|
412 |
}
|
413 |
|
414 |
/**
|
302 |
}
|
303 |
}
|
304 |
|
305 |
+
public function get_locations()
|
306 |
{
|
307 |
+
$cache_key = 'fw_extensions_locations';
|
|
|
|
|
|
|
308 |
|
309 |
+
try {
|
310 |
+
return FW_Cache::get($cache_key);
|
311 |
+
} catch (FW_Cache_Not_Found_Exception $e) {
|
312 |
+
/**
|
313 |
+
* { '/hello/world/extensions' => 'https://hello.com/world/extensions' }
|
314 |
+
*/
|
315 |
+
$custom_locations = apply_filters('fw_extensions_locations', array());
|
316 |
|
317 |
+
{
|
318 |
+
$customizations_locations = array();
|
|
|
|
|
319 |
|
320 |
+
if (is_child_theme()) {
|
321 |
+
$customizations_locations[fw_get_stylesheet_customizations_directory('/extensions')]
|
322 |
+
= fw_get_stylesheet_customizations_directory_uri('/extensions');
|
323 |
+
}
|
324 |
|
325 |
+
$customizations_locations[fw_get_template_customizations_directory('/extensions')]
|
326 |
+
= fw_get_template_customizations_directory_uri('/extensions');
|
327 |
+
|
328 |
+
$customizations_locations += $custom_locations;
|
329 |
+
}
|
330 |
|
331 |
+
$locations = array();
|
|
|
|
|
|
|
|
|
332 |
|
333 |
+
$locations[ fw_get_framework_directory('/extensions') ] = array(
|
334 |
+
'path' => fw_get_framework_directory('/extensions'),
|
335 |
+
'uri' => fw_get_framework_directory_uri('/extensions'),
|
|
|
|
|
336 |
'customizations_locations' => $customizations_locations,
|
337 |
+
'is' => array(
|
338 |
+
'framework' => true,
|
339 |
+
'custom' => false,
|
340 |
+
'theme' => false,
|
341 |
+
),
|
342 |
+
);
|
343 |
|
344 |
+
foreach ($custom_locations as $path => $uri) {
|
345 |
+
unset($customizations_locations[$path]);
|
346 |
+
$locations[ $path ] = array(
|
347 |
+
'path' => $path,
|
348 |
+
'uri' => $uri,
|
349 |
+
'customizations_locations' => $customizations_locations,
|
350 |
+
'is' => array(
|
351 |
+
'framework' => false,
|
352 |
+
'custom' => true,
|
353 |
+
'theme' => false,
|
354 |
+
),
|
355 |
+
);
|
356 |
+
}
|
357 |
|
|
|
358 |
array_pop($customizations_locations);
|
359 |
+
$locations[ fw_get_template_customizations_directory('/extensions') ] = array(
|
360 |
+
'path' => fw_get_template_customizations_directory('/extensions'),
|
361 |
+
'uri' => fw_get_template_customizations_directory_uri('/extensions'),
|
362 |
'customizations_locations' => $customizations_locations,
|
363 |
+
'is' => array(
|
364 |
+
'framework' => false,
|
365 |
+
'custom' => false,
|
366 |
+
'theme' => true,
|
367 |
+
),
|
368 |
+
);
|
369 |
+
|
370 |
+
if (is_child_theme()) {
|
371 |
+
array_pop($customizations_locations);
|
372 |
+
$locations[ fw_get_stylesheet_customizations_directory('/extensions') ] = array(
|
373 |
+
'path' => fw_get_stylesheet_customizations_directory('/extensions'),
|
374 |
+
'uri' => fw_get_stylesheet_customizations_directory_uri('/extensions'),
|
375 |
+
'customizations_locations' => $customizations_locations,
|
376 |
+
'is' => array(
|
377 |
+
'framework' => false,
|
378 |
+
'custom' => false,
|
379 |
+
'theme' => true,
|
380 |
+
),
|
381 |
+
);
|
382 |
+
}
|
383 |
+
|
384 |
+
FW_Cache::set($cache_key, $locations);
|
385 |
+
|
386 |
+
return $locations;
|
387 |
+
}
|
388 |
+
}
|
389 |
+
|
390 |
+
private function load_all_extensions()
|
391 |
+
{
|
392 |
+
foreach ($this->get_locations() as $location) {
|
393 |
+
self::load_extensions(array(
|
394 |
+
'path' => $location['path'],
|
395 |
+
'uri' => $location['uri'],
|
396 |
+
'customizations_locations' => $location['customizations_locations'],
|
397 |
));
|
398 |
}
|
399 |
}
|
452 |
}
|
453 |
}
|
454 |
}
|
455 |
+
unset($sub_extensions);
|
456 |
}
|
457 |
|
458 |
/**
|
framework/core/components/extensions/manager/class--fw-extensions-manager.php
CHANGED
@@ -347,7 +347,6 @@ final class _FW_Extensions_Manager
|
|
347 |
* Scan all directories for extensions
|
348 |
*
|
349 |
* @param bool $reset_cache
|
350 |
-
*
|
351 |
* @return array
|
352 |
*/
|
353 |
private function get_installed_extensions($reset_cache = false)
|
@@ -361,21 +360,16 @@ final class _FW_Extensions_Manager
|
|
361 |
try {
|
362 |
return FW_Cache::get($cache_key);
|
363 |
} catch (FW_Cache_Not_Found_Exception $e) {
|
364 |
-
{
|
365 |
-
$search_paths = array(
|
366 |
-
'framework' => fw_get_framework_directory('/extensions'),
|
367 |
-
'parent' => fw_get_template_customizations_directory('/extensions'),
|
368 |
-
);
|
369 |
-
|
370 |
-
if (is_child_theme()) {
|
371 |
-
$search_paths['child'] = fw_get_stylesheet_customizations_directory('/extensions');
|
372 |
-
}
|
373 |
-
}
|
374 |
-
|
375 |
$extensions = array();
|
376 |
|
377 |
-
foreach (
|
378 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
}
|
380 |
|
381 |
FW_Cache::set($cache_key, $extensions);
|
@@ -386,36 +380,35 @@ final class _FW_Extensions_Manager
|
|
386 |
|
387 |
/**
|
388 |
* used by $this->get_installed_extensions()
|
389 |
-
* @param string $
|
390 |
-
* @param string $path
|
391 |
* @param array $list
|
392 |
* @param null|string $parent_extension_name
|
393 |
*/
|
394 |
-
private function read_extensions($
|
395 |
{
|
396 |
-
$paths = glob($path .'/*', GLOB_ONLYDIR | GLOB_NOSORT);
|
397 |
|
398 |
if (empty($paths)) {
|
399 |
return;
|
400 |
}
|
401 |
|
402 |
-
foreach ($paths as $
|
403 |
$extension_name = basename($extension_path);
|
404 |
|
405 |
if (isset($list[$extension_name])) {
|
406 |
-
// extension already
|
407 |
} elseif (file_exists($extension_path .'/manifest.php')) {
|
408 |
$vars = fw_get_variables_from_file($extension_path .'/manifest.php', array(
|
409 |
'manifest' => array(),
|
410 |
));
|
411 |
|
412 |
$list[$extension_name] = array(
|
413 |
-
'source' => $source,
|
414 |
'path' => $extension_path,
|
415 |
'manifest' => $vars['manifest'],
|
416 |
'children' => array(),
|
417 |
'active' => (bool)fw()->extensions->get($extension_name),
|
418 |
'parent' => $parent_extension_name,
|
|
|
419 |
);
|
420 |
|
421 |
if ($parent_extension_name) {
|
@@ -426,9 +419,11 @@ final class _FW_Extensions_Manager
|
|
426 |
continue;
|
427 |
}
|
428 |
|
|
|
|
|
|
|
429 |
$this->read_extensions(
|
430 |
-
$
|
431 |
-
$extension_path .'/extensions',
|
432 |
$list,
|
433 |
$extension_name
|
434 |
);
|
@@ -1696,7 +1691,7 @@ final class _FW_Extensions_Manager
|
|
1696 |
'is_supported' =>
|
1697 |
fw()->theme->manifest->get('supported_extensions/'. $extension_name, false) !== false
|
1698 |
||
|
1699 |
-
$installed_extensions[$extension_name]['
|
1700 |
), false);
|
1701 |
|
1702 |
unset($installed_extensions);
|
@@ -2806,6 +2801,7 @@ final class _FW_Extensions_Manager
|
|
2806 |
}
|
2807 |
}
|
2808 |
}
|
|
|
2809 |
|
2810 |
// remove all skipped extensions and sub-extension from used extensions
|
2811 |
foreach (array_keys($skip_extensions) as $skip_extension_name) {
|
@@ -2866,7 +2862,7 @@ final class _FW_Extensions_Manager
|
|
2866 |
$db_active_extensions = fw()->extensions->_get_db_active_extensions();
|
2867 |
|
2868 |
foreach ($this->get_installed_extensions() as $extension_name => $extension) {
|
2869 |
-
if ($extension['
|
2870 |
$db_active_extensions[ $extension_name ] = array();
|
2871 |
}
|
2872 |
}
|
347 |
* Scan all directories for extensions
|
348 |
*
|
349 |
* @param bool $reset_cache
|
|
|
350 |
* @return array
|
351 |
*/
|
352 |
private function get_installed_extensions($reset_cache = false)
|
360 |
try {
|
361 |
return FW_Cache::get($cache_key);
|
362 |
} catch (FW_Cache_Not_Found_Exception $e) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
$extensions = array();
|
364 |
|
365 |
+
foreach (fw()->extensions->get_locations() as $location) {
|
366 |
+
// leave only used keys
|
367 |
+
$location = array(
|
368 |
+
'path' => $location['path'],
|
369 |
+
'is' => $location['is'],
|
370 |
+
);
|
371 |
+
|
372 |
+
$this->read_extensions($location, $extensions);
|
373 |
}
|
374 |
|
375 |
FW_Cache::set($cache_key, $extensions);
|
380 |
|
381 |
/**
|
382 |
* used by $this->get_installed_extensions()
|
383 |
+
* @param string $location
|
|
|
384 |
* @param array $list
|
385 |
* @param null|string $parent_extension_name
|
386 |
*/
|
387 |
+
private function read_extensions($location, &$list, $parent_extension_name = null)
|
388 |
{
|
389 |
+
$paths = glob($location['path'] .'/*', GLOB_ONLYDIR | GLOB_NOSORT);
|
390 |
|
391 |
if (empty($paths)) {
|
392 |
return;
|
393 |
}
|
394 |
|
395 |
+
foreach ($paths as $extension_path) {
|
396 |
$extension_name = basename($extension_path);
|
397 |
|
398 |
if (isset($list[$extension_name])) {
|
399 |
+
// extension already found
|
400 |
} elseif (file_exists($extension_path .'/manifest.php')) {
|
401 |
$vars = fw_get_variables_from_file($extension_path .'/manifest.php', array(
|
402 |
'manifest' => array(),
|
403 |
));
|
404 |
|
405 |
$list[$extension_name] = array(
|
|
|
406 |
'path' => $extension_path,
|
407 |
'manifest' => $vars['manifest'],
|
408 |
'children' => array(),
|
409 |
'active' => (bool)fw()->extensions->get($extension_name),
|
410 |
'parent' => $parent_extension_name,
|
411 |
+
'is' => $location['is'],
|
412 |
);
|
413 |
|
414 |
if ($parent_extension_name) {
|
419 |
continue;
|
420 |
}
|
421 |
|
422 |
+
$sub_extension_location = $location;
|
423 |
+
$sub_extension_location['path'] .= '/'. $extension_name .'/extensions';
|
424 |
+
|
425 |
$this->read_extensions(
|
426 |
+
$sub_extension_location,
|
|
|
427 |
$list,
|
428 |
$extension_name
|
429 |
);
|
1691 |
'is_supported' =>
|
1692 |
fw()->theme->manifest->get('supported_extensions/'. $extension_name, false) !== false
|
1693 |
||
|
1694 |
+
$installed_extensions[$extension_name]['is']['theme']
|
1695 |
), false);
|
1696 |
|
1697 |
unset($installed_extensions);
|
2801 |
}
|
2802 |
}
|
2803 |
}
|
2804 |
+
unset($inst_ext_data);
|
2805 |
|
2806 |
// remove all skipped extensions and sub-extension from used extensions
|
2807 |
foreach (array_keys($skip_extensions) as $skip_extension_name) {
|
2862 |
$db_active_extensions = fw()->extensions->_get_db_active_extensions();
|
2863 |
|
2864 |
foreach ($this->get_installed_extensions() as $extension_name => $extension) {
|
2865 |
+
if ($extension['is']['theme']) {
|
2866 |
$db_active_extensions[ $extension_name ] = array();
|
2867 |
}
|
2868 |
}
|
framework/core/components/extensions/manager/views/extension.php
CHANGED
@@ -85,7 +85,7 @@ if (isset($lists['available'][$name])) {
|
|
85 |
if (
|
86 |
isset($lists['supported'][$name]) // is listed in the supported extensions list in theme manifest
|
87 |
||
|
88 |
-
($installed_data && $installed_data['
|
89 |
): ?>
|
90 |
<p><em><strong><span class="dashicons dashicons-yes"></span> <?php _e('Compatible', 'fw') ?></strong> <?php _e('with your current theme', 'fw') ?></em></p>
|
91 |
<?php endif; ?>
|
85 |
if (
|
86 |
isset($lists['supported'][$name]) // is listed in the supported extensions list in theme manifest
|
87 |
||
|
88 |
+
($installed_data && $installed_data['is']['theme']) // is located in the theme
|
89 |
): ?>
|
90 |
<p><em><strong><span class="dashicons dashicons-yes"></span> <?php _e('Compatible', 'fw') ?></strong> <?php _e('with your current theme', 'fw') ?></em></p>
|
91 |
<?php endif; ?>
|
framework/core/components/extensions/manager/views/extensions-page.php
CHANGED
@@ -25,6 +25,7 @@ foreach ($lists['active'] as $name => &$data) {
|
|
25 |
|
26 |
$display_active_extensions[$name] = &$data;
|
27 |
}
|
|
|
28 |
?>
|
29 |
<?php if (empty($display_active_extensions)): ?>
|
30 |
<div class="fw-extensions-no-active">
|
@@ -48,6 +49,7 @@ foreach ($lists['active'] as $name => &$data) {
|
|
48 |
|
49 |
$displayed[$name] = true;
|
50 |
}
|
|
|
51 |
?>
|
52 |
</div>
|
53 |
<?php endif; ?>
|
@@ -62,7 +64,7 @@ foreach ($lists['active'] as $name => &$data) {
|
|
62 |
$theme_extensions = array();
|
63 |
|
64 |
foreach ($lists['disabled'] as $name => &$data) {
|
65 |
-
if (
|
66 |
continue;
|
67 |
}
|
68 |
|
@@ -71,8 +73,9 @@ foreach ($lists['active'] as $name => &$data) {
|
|
71 |
'description' => fw_akg('description', $data['manifest'], '')
|
72 |
);
|
73 |
}
|
|
|
74 |
|
75 |
-
foreach (
|
76 |
if (isset($displayed[$name])) {
|
77 |
continue;
|
78 |
} elseif (isset($lists['installed'][$name])) {
|
@@ -127,6 +130,7 @@ foreach ($lists['active'] as $name => &$data) {
|
|
127 |
|
128 |
$displayed[$name] = $something_displayed = true;
|
129 |
}
|
|
|
130 |
|
131 |
if ($can_install) {
|
132 |
foreach ( $lists['available'] as $name => &$data ) {
|
@@ -161,6 +165,7 @@ foreach ($lists['active'] as $name => &$data) {
|
|
161 |
|
162 |
$something_displayed = true;
|
163 |
}
|
|
|
164 |
}
|
165 |
?>
|
166 |
</div>
|
25 |
|
26 |
$display_active_extensions[$name] = &$data;
|
27 |
}
|
28 |
+
unset($data);
|
29 |
?>
|
30 |
<?php if (empty($display_active_extensions)): ?>
|
31 |
<div class="fw-extensions-no-active">
|
49 |
|
50 |
$displayed[$name] = true;
|
51 |
}
|
52 |
+
unset($data);
|
53 |
?>
|
54 |
</div>
|
55 |
<?php endif; ?>
|
64 |
$theme_extensions = array();
|
65 |
|
66 |
foreach ($lists['disabled'] as $name => &$data) {
|
67 |
+
if (!$data['is']['theme']) {
|
68 |
continue;
|
69 |
}
|
70 |
|
73 |
'description' => fw_akg('description', $data['manifest'], '')
|
74 |
);
|
75 |
}
|
76 |
+
unset($data);
|
77 |
|
78 |
+
foreach ($theme_extensions + $lists['supported'] as $name => $data) {
|
79 |
if (isset($displayed[$name])) {
|
80 |
continue;
|
81 |
} elseif (isset($lists['installed'][$name])) {
|
130 |
|
131 |
$displayed[$name] = $something_displayed = true;
|
132 |
}
|
133 |
+
unset($data);
|
134 |
|
135 |
if ($can_install) {
|
136 |
foreach ( $lists['available'] as $name => &$data ) {
|
165 |
|
166 |
$something_displayed = true;
|
167 |
}
|
168 |
+
unset($data);
|
169 |
}
|
170 |
?>
|
171 |
</div>
|
framework/core/extends/class-fw-extension.php
CHANGED
@@ -274,6 +274,7 @@ abstract class FW_Extension
|
|
274 |
foreach ($active_tree as $extension_name => &$sub_extensions) {
|
275 |
$result[$extension_name] = fw()->extensions->get($extension_name);
|
276 |
}
|
|
|
277 |
|
278 |
return $result;
|
279 |
}
|
274 |
foreach ($active_tree as $extension_name => &$sub_extensions) {
|
275 |
$result[$extension_name] = fw()->extensions->get($extension_name);
|
276 |
}
|
277 |
+
unset($sub_extensions);
|
278 |
|
279 |
return $result;
|
280 |
}
|
framework/helpers/class-fw-form.php
CHANGED
@@ -358,6 +358,63 @@ class FW_Form {
|
|
358 |
unset( $data );
|
359 |
}
|
360 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
361 |
echo '<form '. fw_attr_to_html( $render_data['attr'] ) .' >';
|
362 |
|
363 |
echo fw_html_tag('input', array(
|
@@ -498,7 +555,7 @@ if ( is_admin() ) {
|
|
498 |
* Display form errors in admin side
|
499 |
* @internal
|
500 |
*/
|
501 |
-
function
|
502 |
$form = FW_Form::get_submitted();
|
503 |
|
504 |
if ( ! $form || $form->is_valid() ) {
|
@@ -509,39 +566,20 @@ if ( is_admin() ) {
|
|
509 |
FW_Flash_Messages::add( 'fw-form-admin-' . $input_name, $error_message, 'error' );
|
510 |
}
|
511 |
}
|
512 |
-
add_action( 'wp_loaded', '
|
513 |
} else {
|
514 |
/**
|
515 |
-
*
|
516 |
-
* Do nothing if the theme already displayed the errors
|
517 |
* @internal
|
518 |
*/
|
519 |
-
function
|
520 |
$form = FW_Form::get_submitted();
|
521 |
|
522 |
if ( ! $form || $form->is_valid() ) {
|
523 |
return;
|
524 |
}
|
525 |
|
526 |
-
|
527 |
-
// already displayed
|
528 |
-
return;
|
529 |
-
}
|
530 |
-
|
531 |
-
foreach ($form->get_errors() as $input_name => $error_message) {
|
532 |
-
FW_Flash_Messages::add(
|
533 |
-
'fw-form-error-'. $input_name,
|
534 |
-
$error_message,
|
535 |
-
'error'
|
536 |
-
);
|
537 |
-
}
|
538 |
}
|
539 |
-
add_action( '
|
540 |
-
/**
|
541 |
-
* Use priority later than the default 10.
|
542 |
-
* In docs (to customize the error messages) will be easier to explain
|
543 |
-
* to use just add_action('wp_footer', ...) and not bother about priority
|
544 |
-
*/
|
545 |
-
11
|
546 |
-
);
|
547 |
}
|
358 |
unset( $data );
|
359 |
}
|
360 |
|
361 |
+
// display form errors in frontend
|
362 |
+
do {
|
363 |
+
if (is_admin()) {
|
364 |
+
// errors in admin side are displayed by a script at the end of this file
|
365 |
+
break;
|
366 |
+
}
|
367 |
+
|
368 |
+
$submitted_form = FW_Form::get_submitted();
|
369 |
+
|
370 |
+
if ( ! $submitted_form ) {
|
371 |
+
break;
|
372 |
+
}
|
373 |
+
|
374 |
+
if ( $submitted_form->get_id() !== $this->get_id() ) {
|
375 |
+
// the submitted form is not current form
|
376 |
+
break;
|
377 |
+
}
|
378 |
+
|
379 |
+
unset($submitted_form); // not needed anymore, below will be used only with $this (because it's the same form)
|
380 |
+
|
381 |
+
if ( $this->is_valid() ) {
|
382 |
+
break;
|
383 |
+
}
|
384 |
+
|
385 |
+
/**
|
386 |
+
* Use this action to customize errors display in your theme
|
387 |
+
*/
|
388 |
+
do_action('fw_form_display_errors_frontend', $this);
|
389 |
+
|
390 |
+
if ( $this->errors_accessed() ) {
|
391 |
+
// already displayed, prevent/cancel default display
|
392 |
+
break;
|
393 |
+
}
|
394 |
+
|
395 |
+
$errors = $this->get_errors();
|
396 |
+
|
397 |
+
if (empty($errors)) {
|
398 |
+
break;
|
399 |
+
}
|
400 |
+
|
401 |
+
echo '<ul class="fw-form-errors">';
|
402 |
+
|
403 |
+
foreach ($errors as $input_name => $error_message) {
|
404 |
+
echo fw_html_tag(
|
405 |
+
'li',
|
406 |
+
array(
|
407 |
+
'data-input-name' => $input_name,
|
408 |
+
),
|
409 |
+
$error_message
|
410 |
+
);
|
411 |
+
}
|
412 |
+
|
413 |
+
echo '</ul>';
|
414 |
+
|
415 |
+
unset($errors);
|
416 |
+
} while(false);
|
417 |
+
|
418 |
echo '<form '. fw_attr_to_html( $render_data['attr'] ) .' >';
|
419 |
|
420 |
echo fw_html_tag('input', array(
|
555 |
* Display form errors in admin side
|
556 |
* @internal
|
557 |
*/
|
558 |
+
function _action_fw_form_show_errors_in_admin() {
|
559 |
$form = FW_Form::get_submitted();
|
560 |
|
561 |
if ( ! $form || $form->is_valid() ) {
|
566 |
FW_Flash_Messages::add( 'fw-form-admin-' . $input_name, $error_message, 'error' );
|
567 |
}
|
568 |
}
|
569 |
+
add_action( 'wp_loaded', '_action_fw_form_show_errors_in_admin', 111 );
|
570 |
} else {
|
571 |
/**
|
572 |
+
* to disable this use remove_action('wp_print_styles', '_action_fw_form_frontend_default_styles');
|
|
|
573 |
* @internal
|
574 |
*/
|
575 |
+
function _action_fw_form_frontend_default_styles() {
|
576 |
$form = FW_Form::get_submitted();
|
577 |
|
578 |
if ( ! $form || $form->is_valid() ) {
|
579 |
return;
|
580 |
}
|
581 |
|
582 |
+
echo '<style type="text/css">.fw-form-errors { color: #bf0000; }</style>';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
583 |
}
|
584 |
+
add_action( 'wp_print_styles', '_action_fw_form_frontend_default_styles' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
585 |
}
|
framework/helpers/general.php
CHANGED
@@ -611,6 +611,7 @@ function fw_extract_only_options(array $options, &$_recursion_options = array())
|
|
611 |
$recursion['level']--;
|
612 |
}
|
613 |
}
|
|
|
614 |
|
615 |
if ($recursion['level'] == 0) {
|
616 |
$result =& $recursion['result'];
|
@@ -715,6 +716,7 @@ function fw_collect_first_level_options(&$collected, &$options) {
|
|
715 |
trigger_error('Invalid option: '. $option_id, E_USER_WARNING);
|
716 |
}
|
717 |
}
|
|
|
718 |
}
|
719 |
|
720 |
/**
|
611 |
$recursion['level']--;
|
612 |
}
|
613 |
}
|
614 |
+
unset($option);
|
615 |
|
616 |
if ($recursion['level'] == 0) {
|
617 |
$result =& $recursion['result'];
|
716 |
trigger_error('Invalid option: '. $option_id, E_USER_WARNING);
|
717 |
}
|
718 |
}
|
719 |
+
unset($option);
|
720 |
}
|
721 |
|
722 |
/**
|
framework/includes/option-types.php
CHANGED
@@ -893,3 +893,4 @@ require $dir .'/option-types/popup/class-fw-option-type-popup.php';
|
|
893 |
require $dir .'/option-types/slider/class-fw-option-type-slider.php';
|
894 |
require $dir .'/option-types/range-slider/class-fw-option-type-range-slider.php';
|
895 |
require $dir .'/option-types/rgba-color-picker/class-fw-option-type-rgba-color-picker.php';
|
|
893 |
require $dir .'/option-types/slider/class-fw-option-type-slider.php';
|
894 |
require $dir .'/option-types/range-slider/class-fw-option-type-range-slider.php';
|
895 |
require $dir .'/option-types/rgba-color-picker/class-fw-option-type-rgba-color-picker.php';
|
896 |
+
require $dir .'/option-types/runnable/class-fw-option-type-runnable.php';
|
framework/includes/option-types/addable-box/view.php
CHANGED
@@ -51,7 +51,7 @@ unset($attr['value']);
|
|
51 |
);
|
52 |
?>
|
53 |
</div>
|
54 |
-
<?php endforeach; ?>
|
55 |
</div>
|
56 |
<br class="default-box-template fw-hidden" data-template="<?php
|
57 |
/**
|
@@ -59,13 +59,6 @@ unset($attr['value']);
|
|
59 |
* when this option will be used inside another option template
|
60 |
*/
|
61 |
|
62 |
-
/**
|
63 |
-
* This is a reference.
|
64 |
-
* Unset before replacing with new value
|
65 |
-
* to prevent changing value to what it refers
|
66 |
-
*/
|
67 |
-
unset($values);
|
68 |
-
|
69 |
$values = array();
|
70 |
|
71 |
// must contain characters that will remain the same after htmlspecialchars()
|
51 |
);
|
52 |
?>
|
53 |
</div>
|
54 |
+
<?php endforeach; unset($values); ?>
|
55 |
</div>
|
56 |
<br class="default-box-template fw-hidden" data-template="<?php
|
57 |
/**
|
59 |
* when this option will be used inside another option template
|
60 |
*/
|
61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
$values = array();
|
63 |
|
64 |
// must contain characters that will remain the same after htmlspecialchars()
|
framework/includes/option-types/icon/class-fw-option-type-icon.php
CHANGED
@@ -63,6 +63,8 @@ class FW_Option_Type_Icon extends FW_Option_Type
|
|
63 |
$this->enqueued_font_styles[ $style_hash ] = true;
|
64 |
}
|
65 |
}
|
|
|
|
|
66 |
}
|
67 |
|
68 |
/**
|
63 |
$this->enqueued_font_styles[ $style_hash ] = true;
|
64 |
}
|
65 |
}
|
66 |
+
|
67 |
+
return true;
|
68 |
}
|
69 |
|
70 |
/**
|
framework/includes/option-types/multi-select/class-fw-option-type-multi-select.php
CHANGED
@@ -137,9 +137,9 @@ class FW_Option_Type_Multi_Select extends FW_Option_Type
|
|
137 |
if ( empty( $names ) ) {
|
138 |
$items = $wpdb->get_results(
|
139 |
$wpdb->prepare(
|
140 |
-
"SELECT users.id val, users.
|
141 |
"FROM $wpdb->users as users " .
|
142 |
-
"WHERE users.
|
143 |
"LIMIT 100",
|
144 |
'%'. $wpdb->esc_like($title) .'%'
|
145 |
)
|
@@ -155,9 +155,9 @@ class FW_Option_Type_Multi_Select extends FW_Option_Type
|
|
155 |
array($wpdb, 'prepare'),
|
156 |
array_merge(
|
157 |
array(
|
158 |
-
"SELECT users.id val, users.
|
159 |
"FROM $wpdb->users as users, $wpdb->usermeta as usermeta " .
|
160 |
-
"WHERE users.
|
161 |
"AND ( ".
|
162 |
implode(' OR ', array_fill(1, count($like_user_meta), 'usermeta.meta_value LIKE %s')) .
|
163 |
" ) " .
|
@@ -334,7 +334,7 @@ class FW_Option_Type_Multi_Select extends FW_Option_Type
|
|
334 |
$ids = implode( ', ', array_unique( $ids ) );
|
335 |
|
336 |
$query = $wpdb->get_results(
|
337 |
-
"SELECT users.id, users.
|
338 |
"FROM $wpdb->users as users " .
|
339 |
"WHERE users.ID IN ($ids)"
|
340 |
);
|
137 |
if ( empty( $names ) ) {
|
138 |
$items = $wpdb->get_results(
|
139 |
$wpdb->prepare(
|
140 |
+
"SELECT users.id val, users.user_nicename title " .
|
141 |
"FROM $wpdb->users as users " .
|
142 |
+
"WHERE users.user_nicename LIKE %s " .
|
143 |
"LIMIT 100",
|
144 |
'%'. $wpdb->esc_like($title) .'%'
|
145 |
)
|
155 |
array($wpdb, 'prepare'),
|
156 |
array_merge(
|
157 |
array(
|
158 |
+
"SELECT users.id val, users.user_nicename title " .
|
159 |
"FROM $wpdb->users as users, $wpdb->usermeta as usermeta " .
|
160 |
+
"WHERE users.user_nicename LIKE %s AND usermeta.meta_key = 'wp_capabilities' " .
|
161 |
"AND ( ".
|
162 |
implode(' OR ', array_fill(1, count($like_user_meta), 'usermeta.meta_value LIKE %s')) .
|
163 |
" ) " .
|
334 |
$ids = implode( ', ', array_unique( $ids ) );
|
335 |
|
336 |
$query = $wpdb->get_results(
|
337 |
+
"SELECT users.id, users.user_nicename title " .
|
338 |
"FROM $wpdb->users as users " .
|
339 |
"WHERE users.ID IN ($ids)"
|
340 |
);
|
framework/includes/option-types/runnable/class-fw-option-type-runnable.php
ADDED
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if ( ! defined( 'FW' ) ) {
|
2 |
+
die( 'Forbidden' );
|
3 |
+
}
|
4 |
+
/**
|
5 |
+
* This option type let you run a callback by click on Run button.
|
6 |
+
* example of $option array
|
7 |
+
* array(
|
8 |
+
* 'type' => 'runnable',
|
9 |
+
* 'value' => 'This script have no runs',
|
10 |
+
* 'label' => __('Convert data', 'fw'),
|
11 |
+
* 'desc' => __('There are posts, pages, categories or tags without language set. Do you want to set them all to default language.', 'fw'),
|
12 |
+
* 'help' => __('Help tip', 'fw'),
|
13 |
+
* 'content'=>__('Run this script'),
|
14 |
+
* 'callback'=> array('translation' , 'convert_data_to_default_language')
|
15 |
+
* )
|
16 |
+
*/
|
17 |
+
/**
|
18 |
+
* Class FW_Option_Type_Runnable
|
19 |
+
*/
|
20 |
+
class FW_Option_Type_Runnable extends FW_Option_Type {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Option's unique type, used in option array in 'type' key
|
24 |
+
* @return string
|
25 |
+
*/
|
26 |
+
public function get_type() {
|
27 |
+
return 'runnable';
|
28 |
+
|
29 |
+
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Run callback.
|
34 |
+
*/
|
35 |
+
public function run_callback() {
|
36 |
+
|
37 |
+
$callback = explode( '.', FW_Request::POST( 'callback' ) );
|
38 |
+
$length = count( $callback );
|
39 |
+
|
40 |
+
if ( $length === 1 && is_callable( $callback[0] ) ) {
|
41 |
+
$handler = $callback[0];
|
42 |
+
} elseif ( $length === 2 && is_callable( $callback ) ) {
|
43 |
+
$handler = $callback;
|
44 |
+
} elseif ( $length === 2 && is_callable( $fw_ext_callback = array( fw_ext( $callback[0] ), $callback[1] ) ) ) {
|
45 |
+
$handler = $fw_ext_callback;
|
46 |
+
} else {
|
47 |
+
wp_send_json_error( 'Your callback is not callable' );
|
48 |
+
}
|
49 |
+
|
50 |
+
call_user_func( $handler );
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Generate option's html from option array.
|
55 |
+
*
|
56 |
+
* @param string $id
|
57 |
+
* @param array $option
|
58 |
+
* @param array $data
|
59 |
+
*
|
60 |
+
* @return string HTML
|
61 |
+
* @internal
|
62 |
+
*/
|
63 |
+
protected function _render( $id, $option, $data ) {
|
64 |
+
|
65 |
+
$callback = implode( '.', (array) $option['callback'] );
|
66 |
+
$option['attr']['value'] = (string) $data['value'];
|
67 |
+
|
68 |
+
return '<div class="runnable-wrapper">
|
69 |
+
<button data-callback="' . $callback . '" type="button" class="runnable-button button-primary">' . $option['content'] . '</button>
|
70 |
+
<div class="runnable-last-run">' . $option['attr']['value'] . '</div>
|
71 |
+
<input type="hidden" ' . fw_attr_to_html( $option['attr'] ) . '/>
|
72 |
+
</div>';
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Enqueue static.
|
77 |
+
* @param string $id
|
78 |
+
* @param array $option
|
79 |
+
* @param array $data
|
80 |
+
*/
|
81 |
+
protected function _enqueue_static( $id, $option, $data ) {
|
82 |
+
$js_path = fw_get_framework_directory_uri( '/includes/option-types/runnable/static/js/runnable.js' );
|
83 |
+
$css_path = fw_get_framework_directory_uri( '/includes/option-types/runnable/static/css/runnable.css' );
|
84 |
+
|
85 |
+
wp_enqueue_script(
|
86 |
+
'fw-option-' . $this->get_type() . '-js',
|
87 |
+
$js_path,
|
88 |
+
array( 'jquery', 'fw-moment' ),
|
89 |
+
fw()->manifest->get_version()
|
90 |
+
);
|
91 |
+
|
92 |
+
wp_enqueue_style(
|
93 |
+
'fw-option-' . $this->get_type() . '-css',
|
94 |
+
$css_path,
|
95 |
+
array(),
|
96 |
+
fw()->manifest->get_version()
|
97 |
+
);
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Extract correct value for $option['value'] from input array
|
102 |
+
* If input value is empty, will be returned $option['value']
|
103 |
+
*
|
104 |
+
* @param array $option
|
105 |
+
* @param array|string|null $input_value
|
106 |
+
*
|
107 |
+
* @return string|array|int|bool Correct value
|
108 |
+
* @internal
|
109 |
+
*/
|
110 |
+
protected function _get_value_from_input( $option, $input_value ) {
|
111 |
+
return (string) ( is_null( $input_value ) ? $option['value'] : $input_value );
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Default option array
|
116 |
+
*
|
117 |
+
* This makes possible an option array to have required only one parameter: array('type' => '...')
|
118 |
+
* Other parameters are merged with array returned from this method
|
119 |
+
*
|
120 |
+
* @return array
|
121 |
+
*
|
122 |
+
* array(
|
123 |
+
* 'value' => '',
|
124 |
+
* ...
|
125 |
+
* )
|
126 |
+
* @internal
|
127 |
+
*/
|
128 |
+
protected function _get_defaults() {
|
129 |
+
return array(
|
130 |
+
'value' => '',
|
131 |
+
'content' => 'Run'
|
132 |
+
);
|
133 |
+
}
|
134 |
+
|
135 |
+
}
|
136 |
+
|
137 |
+
FW_Option_Type::register( 'FW_Option_Type_Runnable' );
|
138 |
+
|
139 |
+
add_action( 'wp_ajax_fw_runnable', array( 'FW_Option_Type_Runnable', 'run_callback' ) );
|
framework/includes/option-types/runnable/static/css/runnable.css
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.fw-backend-option-type-runnable .runnable-wrapper .runnable-button {
|
2 |
+
float: left;
|
3 |
+
}
|
4 |
+
|
5 |
+
.fw-backend-option-type-runnable .runnable-wrapper .runnable-last-run {
|
6 |
+
float: left;
|
7 |
+
padding-left: 20px;
|
8 |
+
line-height: 28px
|
9 |
+
}
|
framework/includes/option-types/runnable/static/js/runnable.js
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function ($, fwe) {
|
2 |
+
var init = function () {
|
3 |
+
var $hidden = $(this),
|
4 |
+
$button = $hidden.parent().find('.runnable-button'),
|
5 |
+
$textDiv = $hidden.parent().find('.runnable-last-run');
|
6 |
+
|
7 |
+
var showDate = function ($timestamp) {
|
8 |
+
$textDiv.text('Last run was ' + moment($timestamp, 'X').fromNow());
|
9 |
+
}
|
10 |
+
|
11 |
+
if (moment($hidden.val(), 'X', true).isValid()) {
|
12 |
+
showDate($hidden.val());
|
13 |
+
}
|
14 |
+
|
15 |
+
$button.on('click', function (e) {
|
16 |
+
e.preventDefault();
|
17 |
+
|
18 |
+
$.ajax({
|
19 |
+
type: "post",
|
20 |
+
dataType: "json",
|
21 |
+
url: ajaxurl,
|
22 |
+
data: {action: 'fw_runnable', callback: $(this).data('callback')}
|
23 |
+
}).done(function (data) {
|
24 |
+
if (data.success) {
|
25 |
+
var $timestamp = moment().format('X');
|
26 |
+
$hidden.val($timestamp);
|
27 |
+
showDate($timestamp);
|
28 |
+
}
|
29 |
+
|
30 |
+
fwe.trigger('fw:option-type:runnable:change', {
|
31 |
+
$element: $hidden,
|
32 |
+
response: data
|
33 |
+
});
|
34 |
+
});
|
35 |
+
});
|
36 |
+
};
|
37 |
+
|
38 |
+
fwe.on('fw:options:init', function (data) {
|
39 |
+
data.$elements
|
40 |
+
.find('.fw-option-type-runnable:not(.fw-option-initialized)').each(init)
|
41 |
+
.addClass('fw-option-initialized');
|
42 |
+
});
|
43 |
+
})(jQuery, fwEvents);
|
framework/includes/option-types/typography/view.php
CHANGED
@@ -58,11 +58,11 @@
|
|
58 |
'700italic' => 'Bold/Italic',
|
59 |
)
|
60 |
as $key => $style): ?>
|
61 |
-
<option value="<?php echo esc_attr($key) ?>" <?php if ($data['value']['style']
|
62 |
<?php endforeach; ?>
|
63 |
<?php else: ?>
|
64 |
<?php foreach ($fonts['google'][$data['value']['family']]['variants'] as $variant): ?>
|
65 |
-
<option value="<?php echo esc_attr($variant) ?>" <?php if ($data['value']['style']
|
66 |
<?php endforeach; ?>
|
67 |
<?php endif; ?>
|
68 |
</select>
|
58 |
'700italic' => 'Bold/Italic',
|
59 |
)
|
60 |
as $key => $style): ?>
|
61 |
+
<option value="<?php echo esc_attr($key) ?>" <?php if ($data['value']['style'] === $key): ?>selected="selected"<?php endif; ?>><?php echo fw_htmlspecialchars($style) ?></option>
|
62 |
<?php endforeach; ?>
|
63 |
<?php else: ?>
|
64 |
<?php foreach ($fonts['google'][$data['value']['family']]['variants'] as $variant): ?>
|
65 |
+
<option value="<?php echo esc_attr($variant) ?>" <?php if ($data['value']['style'] === $variant): ?>selected="selected"<?php endif; ?>><?php echo fw_htmlspecialchars(ucfirst($variant)) ?></option>
|
66 |
<?php endforeach; ?>
|
67 |
<?php endif; ?>
|
68 |
</select>
|
framework/manifest.php
CHANGED
@@ -4,4 +4,4 @@ $manifest = array();
|
|
4 |
|
5 |
$manifest['name'] = __('Unyson', 'fw');
|
6 |
|
7 |
-
$manifest['version'] = '2.2.
|
4 |
|
5 |
$manifest['name'] = __('Unyson', 'fw');
|
6 |
|
7 |
+
$manifest['version'] = '2.2.3';
|
framework/static/css/fw.css
CHANGED
@@ -2985,7 +2985,7 @@ body.rtl .fw-options-modal .media-frame-content > form .fw-options-tabs-contents
|
|
2985 |
/* SoleModal */
|
2986 |
|
2987 |
.fw-sole-modal > .media-modal {
|
2988 |
-
z-index:
|
2989 |
margin: auto;
|
2990 |
}
|
2991 |
|
2985 |
/* SoleModal */
|
2986 |
|
2987 |
.fw-sole-modal > .media-modal {
|
2988 |
+
z-index: 500000;
|
2989 |
margin: auto;
|
2990 |
}
|
2991 |
|
framework/views/backend-tabs.php
CHANGED
@@ -10,7 +10,7 @@
|
|
10 |
<ul>
|
11 |
<?php foreach ($tabs as $tab_id => &$tab): ?>
|
12 |
<li><a href="#fw-options-tab-<?php echo esc_attr($tab_id) ?>" class="nav-tab fw-wp-link" ><?php echo htmlspecialchars($tab['title'], ENT_COMPAT, 'UTF-8') ?></a></li>
|
13 |
-
<?php endforeach; ?>
|
14 |
</ul>
|
15 |
<div class="fw-clear"></div>
|
16 |
</div>
|
@@ -33,6 +33,7 @@
|
|
33 |
?><div <?php echo fw_attr_to_html($attr) ?>><?php echo fw()->backend->render_options($tab['options'], $values, $options_data) ?></div><?php
|
34 |
unset($tabs[$tab_id]); // free memory after printed and not needed anymore
|
35 |
endforeach;
|
|
|
36 |
?>
|
37 |
</div>
|
38 |
</div>
|
10 |
<ul>
|
11 |
<?php foreach ($tabs as $tab_id => &$tab): ?>
|
12 |
<li><a href="#fw-options-tab-<?php echo esc_attr($tab_id) ?>" class="nav-tab fw-wp-link" ><?php echo htmlspecialchars($tab['title'], ENT_COMPAT, 'UTF-8') ?></a></li>
|
13 |
+
<?php endforeach; unset($tab); ?>
|
14 |
</ul>
|
15 |
<div class="fw-clear"></div>
|
16 |
</div>
|
33 |
?><div <?php echo fw_attr_to_html($attr) ?>><?php echo fw()->backend->render_options($tab['options'], $values, $options_data) ?></div><?php
|
34 |
unset($tabs[$tab_id]); // free memory after printed and not needed anymore
|
35 |
endforeach;
|
36 |
+
unset($tab);
|
37 |
?>
|
38 |
</div>
|
39 |
</div>
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: unyson, themefusecom
|
|
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.1
|
6 |
-
Stable tag: 2.2.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -86,6 +86,10 @@ Yes; Unyson will work with any theme.
|
|
86 |
|
87 |
== Changelog ==
|
88 |
|
|
|
|
|
|
|
|
|
89 |
= 2.2.2 =
|
90 |
* Added experimental `$option['option_handler']` [636ed56](https://github.com/ThemeFuse/Unyson/commit/636ed56fe499a4e855b5f49198747460833539a3)
|
91 |
* `<input required ... />` works in `fw.OptionsModal` [#274](https://github.com/ThemeFuse/Unyson/issues/274)
|
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.1
|
6 |
+
Stable tag: 2.2.3
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
86 |
|
87 |
== Changelog ==
|
88 |
|
89 |
+
= 2.2.3 =
|
90 |
+
* Fixed [#397](https://github.com/ThemeFuse/Unyson/issues/397), [#394](https://github.com/ThemeFuse/Unyson/issues/394), [#389](https://github.com/ThemeFuse/Unyson/issues/389), [384](https://github.com/ThemeFuse/Unyson/issues/384), [#355](https://github.com/ThemeFuse/Unyson/issues/355)
|
91 |
+
* Added option type `runnable` [code](https://github.com/ThemeFuse/Unyson/blob/master/framework/includes/option-types/runnable/class-fw-option-type-runnable.php)
|
92 |
+
|
93 |
= 2.2.2 =
|
94 |
* Added experimental `$option['option_handler']` [636ed56](https://github.com/ThemeFuse/Unyson/commit/636ed56fe499a4e855b5f49198747460833539a3)
|
95 |
* `<input required ... />` works in `fw.OptionsModal` [#274](https://github.com/ThemeFuse/Unyson/issues/274)
|
unyson.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Unyson
|
4 |
* Plugin URI: http://unyson.themefuse.com/
|
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.2.
|
7 |
* Author: ThemeFuse
|
8 |
* Author URI: http://themefuse.com
|
9 |
* License: GPL2+
|
3 |
* Plugin Name: Unyson
|
4 |
* Plugin URI: http://unyson.themefuse.com/
|
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.2.3
|
7 |
* Author: ThemeFuse
|
8 |
* Author URI: http://themefuse.com
|
9 |
* License: GPL2+
|