Version Description
- Fixed infinite loop when php memory limit is
-1
- Minor changes
Download this release
Release Info
Developer | Unyson |
Plugin | Unyson |
Version | 2.6.14 |
Comparing to | |
See all releases |
Code changes from version 2.6.13 to 2.6.14
- framework/autoload.php +1 -0
- framework/core/components/backend.php +23 -8
- framework/core/components/extensions/manager/class--fw-extensions-manager.php +8 -0
- framework/core/components/extensions/manager/static/extensions-page.css +14 -0
- framework/core/components/extensions/manager/views/extension.php +1 -0
- framework/core/extends/class-fw-option-type.php +14 -2
- framework/helpers/class-fw-cache.php +4 -0
- framework/helpers/class-fw-callback.php +117 -0
- framework/helpers/class-fw-db-options-model.php +22 -4
- framework/helpers/class-fw-flash-messages.php +10 -1
- framework/helpers/class-fw-form.php +47 -41
- framework/helpers/general.php +600 -486
- framework/includes/option-storage/type/class-fw-option-storage-type-wp-option.php +6 -1
- framework/includes/option-types/simple.php +2 -2
- framework/includes/option-types/typography-v2/class-fw-option-type-typography-v2.php +4 -1
- framework/includes/option-types/typography-v2/static/css/styles.css +1 -0
- framework/includes/option-types/typography-v2/static/js/scripts.js +6 -10
- framework/includes/option-types/typography-v2/view.php +15 -6
- framework/manifest.php +1 -1
- framework/static/js/fw.js +74 -1
- readme.txt +5 -1
- unyson.php +1 -1
framework/autoload.php
CHANGED
@@ -103,6 +103,7 @@ function _fw_autoload_helper_classes($class) {
|
|
103 |
static $class_to_file = array(
|
104 |
'FW_Dumper' => 'class-fw-dumper',
|
105 |
'FW_Cache' => 'class-fw-cache',
|
|
|
106 |
'FW_Access_Key' => 'class-fw-access-key',
|
107 |
'FW_WP_Filesystem' => 'class-fw-wp-filesystem',
|
108 |
'FW_Form' => 'class-fw-form',
|
103 |
static $class_to_file = array(
|
104 |
'FW_Dumper' => 'class-fw-dumper',
|
105 |
'FW_Cache' => 'class-fw-cache',
|
106 |
+
'FW_Callback' => 'class-fw-callback',
|
107 |
'FW_Access_Key' => 'class-fw-access-key',
|
108 |
'FW_WP_Filesystem' => 'class-fw-wp-filesystem',
|
109 |
'FW_Form' => 'class-fw-form',
|
framework/core/components/backend.php
CHANGED
@@ -347,14 +347,21 @@ final class _FW_Component_Backend {
|
|
347 |
'FW_URI' => fw_get_framework_directory_uri(),
|
348 |
'SITE_URI' => site_url(),
|
349 |
'LOADER_URI' => apply_filters( 'fw_loader_image', fw_get_framework_directory_uri() . '/static/img/logo.svg' ),
|
350 |
-
'l10n' =>
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
358 |
),
|
359 |
'options_modal' => array(
|
360 |
/** @since 2.6.13 */
|
@@ -577,6 +584,14 @@ final class _FW_Component_Backend {
|
|
577 |
* @param WP_Post $post
|
578 |
*/
|
579 |
public function _action_create_post_meta_boxes( $post_type, $post ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
580 |
$options = fw()->theme->get_post_options( $post_type );
|
581 |
|
582 |
if ( empty( $options ) ) {
|
347 |
'FW_URI' => fw_get_framework_directory_uri(),
|
348 |
'SITE_URI' => site_url(),
|
349 |
'LOADER_URI' => apply_filters( 'fw_loader_image', fw_get_framework_directory_uri() . '/static/img/logo.svg' ),
|
350 |
+
'l10n' => array_merge(
|
351 |
+
$l10n = array(
|
352 |
+
'modal_save_btn' => __( 'Save', 'fw' ),
|
353 |
+
'done' => __( 'Done', 'fw' ),
|
354 |
+
'ah_sorry' => __( 'Ah, Sorry', 'fw' ),
|
355 |
+
'reset' => __( 'Reset', 'fw' ),
|
356 |
+
'apply' => __( 'Apply', 'fw' ),
|
357 |
+
'cancel' => __( 'Cancel', 'fw' ),
|
358 |
+
'ok' => __( 'Ok', 'fw' )
|
359 |
+
),
|
360 |
+
/**
|
361 |
+
* fixes https://github.com/ThemeFuse/Unyson/issues/2381
|
362 |
+
* @since 2.6.14
|
363 |
+
*/
|
364 |
+
apply_filters('fw_js_l10n', $l10n)
|
365 |
),
|
366 |
'options_modal' => array(
|
367 |
/** @since 2.6.13 */
|
584 |
* @param WP_Post $post
|
585 |
*/
|
586 |
public function _action_create_post_meta_boxes( $post_type, $post ) {
|
587 |
+
if ('comment' === $post_type) {
|
588 |
+
/**
|
589 |
+
* This is wrong, comment is not a post(type)
|
590 |
+
* it is stored in a separate db table and has a separate meta (wp_comments and wp_commentmeta)
|
591 |
+
*/
|
592 |
+
return;
|
593 |
+
}
|
594 |
+
|
595 |
$options = fw()->theme->get_post_options( $post_type );
|
596 |
|
597 |
if ( empty( $options ) ) {
|
framework/core/components/extensions/manager/class--fw-extensions-manager.php
CHANGED
@@ -1021,6 +1021,14 @@ final class _FW_Extensions_Manager
|
|
1021 |
$skin->after(array(
|
1022 |
'extensions_page_link' => $this->get_link()
|
1023 |
));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1024 |
} else {
|
1025 |
echo '<form method="post">';
|
1026 |
|
1021 |
$skin->after(array(
|
1022 |
'extensions_page_link' => $this->get_link()
|
1023 |
));
|
1024 |
+
|
1025 |
+
if ($supported && $install_result === true) {
|
1026 |
+
/**
|
1027 |
+
* @since 2.6.14
|
1028 |
+
* Fixes https://github.com/ThemeFuse/Unyson/issues/2330
|
1029 |
+
*/
|
1030 |
+
do_action( 'fw_after_supported_extensions_install_success' );
|
1031 |
+
}
|
1032 |
} else {
|
1033 |
echo '<form method="post">';
|
1034 |
|
framework/core/components/extensions/manager/static/extensions-page.css
CHANGED
@@ -245,3 +245,17 @@
|
|
245 |
}
|
246 |
|
247 |
/* end: form ajax loading */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
}
|
246 |
|
247 |
/* end: form ajax loading */
|
248 |
+
|
249 |
+
|
250 |
+
/* anchor */
|
251 |
+
|
252 |
+
.fw-extensions-list .fw-extensions-list-item a.fw-ext-anchor {
|
253 |
+
position: absolute;
|
254 |
+
top: -15px;
|
255 |
+
}
|
256 |
+
|
257 |
+
body.admin-bar .fw-extensions-list .fw-extensions-list-item a.fw-ext-anchor {
|
258 |
+
top: -50px;
|
259 |
+
}
|
260 |
+
|
261 |
+
/* end: anchor */
|
framework/core/components/extensions/manager/views/extension.php
CHANGED
@@ -64,6 +64,7 @@ if (!$installed_data && !$is_compatible) {
|
|
64 |
}
|
65 |
?>
|
66 |
<div class="<?php echo esc_attr($wrapper_class) ?>" id="fw-ext-<?php echo esc_attr($name) ?>">
|
|
|
67 |
<div class="inner">
|
68 |
<div class="fw-extension-list-item-table">
|
69 |
<div class="fw-extension-list-item-table-row">
|
64 |
}
|
65 |
?>
|
66 |
<div class="<?php echo esc_attr($wrapper_class) ?>" id="fw-ext-<?php echo esc_attr($name) ?>">
|
67 |
+
<a class="fw-ext-anchor" name="ext-<?php echo esc_attr($name) ?>"></a>
|
68 |
<div class="inner">
|
69 |
<div class="fw-extension-list-item-table">
|
70 |
<div class="fw-extension-list-item-table-row">
|
framework/core/extends/class-fw-option-type.php
CHANGED
@@ -111,6 +111,10 @@ abstract class FW_Option_Type
|
|
111 |
}
|
112 |
}
|
113 |
|
|
|
|
|
|
|
|
|
114 |
/**
|
115 |
* Fixes and prepare defaults
|
116 |
*
|
@@ -184,7 +188,7 @@ abstract class FW_Option_Type
|
|
184 |
|
185 |
$this->enqueue_static($id, $option, $data);
|
186 |
|
187 |
-
return $this->_render($id, $option, $data);
|
188 |
}
|
189 |
|
190 |
/**
|
@@ -264,7 +268,7 @@ abstract class FW_Option_Type
|
|
264 |
)
|
265 |
);
|
266 |
|
267 |
-
return $this->_get_value_from_input($option, $input_value);
|
268 |
}
|
269 |
|
270 |
/**
|
@@ -403,4 +407,12 @@ abstract class FW_Option_Type
|
|
403 |
|
404 |
return self::$access_key;
|
405 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
406 |
}
|
111 |
}
|
112 |
}
|
113 |
|
114 |
+
public function __construct() {
|
115 |
+
|
116 |
+
}
|
117 |
+
|
118 |
/**
|
119 |
* Fixes and prepare defaults
|
120 |
*
|
188 |
|
189 |
$this->enqueue_static($id, $option, $data);
|
190 |
|
191 |
+
return $this->_render( $id, $this->load_callbacks( $option ), $data );
|
192 |
}
|
193 |
|
194 |
/**
|
268 |
)
|
269 |
);
|
270 |
|
271 |
+
return $this->_get_value_from_input( $this->load_callbacks( $option ), $input_value);
|
272 |
}
|
273 |
|
274 |
/**
|
407 |
|
408 |
return self::$access_key;
|
409 |
}
|
410 |
+
|
411 |
+
protected function load_callbacks( $data ) {
|
412 |
+
if ( ! is_array( $data ) ) {
|
413 |
+
return $data;
|
414 |
+
}
|
415 |
+
|
416 |
+
return array_map( 'fw_call', $data );
|
417 |
+
}
|
418 |
}
|
framework/helpers/class-fw-cache.php
CHANGED
@@ -65,6 +65,10 @@ class FW_Cache
|
|
65 |
{
|
66 |
$memory_limit = ini_get('memory_limit');
|
67 |
|
|
|
|
|
|
|
|
|
68 |
switch (substr($memory_limit, -1)) {
|
69 |
case 'M': return intval($memory_limit) * 1024 * 1024;
|
70 |
case 'K': return intval($memory_limit) * 1024;
|
65 |
{
|
66 |
$memory_limit = ini_get('memory_limit');
|
67 |
|
68 |
+
if ($memory_limit === '-1') { // This happens in WP CLI
|
69 |
+
return 256 * 1024 * 1024;
|
70 |
+
}
|
71 |
+
|
72 |
switch (substr($memory_limit, -1)) {
|
73 |
case 'M': return intval($memory_limit) * 1024 * 1024;
|
74 |
case 'K': return intval($memory_limit) * 1024;
|
framework/helpers/class-fw-callback.php
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if ( ! defined( 'FW' ) ) {
|
2 |
+
die( 'Forbidden' );
|
3 |
+
}
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class FW_Callback
|
7 |
+
*
|
8 |
+
* @since 2.6.14
|
9 |
+
*/
|
10 |
+
class FW_Callback {
|
11 |
+
/**
|
12 |
+
* @var $callback string|array
|
13 |
+
*/
|
14 |
+
private $callback;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var array $args
|
18 |
+
*/
|
19 |
+
private $args;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var bool
|
23 |
+
*/
|
24 |
+
private $cache;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
private $id;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* FW_Callback constructor.
|
33 |
+
*
|
34 |
+
* @param string|array $callback Callback function
|
35 |
+
* @param array $args Callback arguments
|
36 |
+
* @param bool $cache Whenever you want to cache the function value after it's first call or not
|
37 |
+
* Recommend when the function call may require many resources or time (database requests) , or the value is small
|
38 |
+
* Not recommended using on very large values
|
39 |
+
*
|
40 |
+
*/
|
41 |
+
public function __construct( $callback, array $args = array(), $cache = true ) {
|
42 |
+
$this->callback = $callback;
|
43 |
+
$this->args = $args;
|
44 |
+
$this->cache = (bool) $cache;
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Return callback function
|
49 |
+
* @return array|string
|
50 |
+
*/
|
51 |
+
public function get_callback() {
|
52 |
+
return $this->callback;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Return callback function arguments
|
57 |
+
* @return array
|
58 |
+
*/
|
59 |
+
public function get_args() {
|
60 |
+
return $this->args;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Execute callback function
|
65 |
+
* @return mixed
|
66 |
+
*/
|
67 |
+
public function execute() {
|
68 |
+
if ( $this->cache ) {
|
69 |
+
try {
|
70 |
+
return FW_Cache::get( $this->get_id() );
|
71 |
+
} catch ( FW_Cache_Not_Found_Exception $e ) {
|
72 |
+
FW_Cache::set(
|
73 |
+
$this->get_id(),
|
74 |
+
$value = $this->get_value()
|
75 |
+
);
|
76 |
+
|
77 |
+
return $value;
|
78 |
+
}
|
79 |
+
} else {
|
80 |
+
return $this->get_value();
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Whenever you want to clear the cached value or the function
|
86 |
+
*/
|
87 |
+
public function clear_cache() {
|
88 |
+
FW_Cache::del( $this->get_id() );
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Get raw callback value, ignoring the cache
|
93 |
+
* @return mixed
|
94 |
+
*/
|
95 |
+
protected function get_value() {
|
96 |
+
return call_user_func_array( $this->callback, $this->args );
|
97 |
+
}
|
98 |
+
|
99 |
+
protected function get_id() {
|
100 |
+
if ( ! is_string( $this->id ) ) {
|
101 |
+
$this->id = 'fw-callback-' . md5( $this->serialize_callback() . serialize( $this->args ) );
|
102 |
+
}
|
103 |
+
|
104 |
+
return $this->id;
|
105 |
+
}
|
106 |
+
|
107 |
+
protected function serialize_callback() {
|
108 |
+
//Closures cannot be serialized and at the moment do not have a solution
|
109 |
+
//So the Closures will be replaced with a unique Id
|
110 |
+
return ( $this->callback instanceof Closure )
|
111 |
+
? uniqid( 'fw-callback-' )
|
112 |
+
: (
|
113 |
+
is_string( $this->callback )
|
114 |
+
? $this->callback
|
115 |
+
: serialize( $this->callback ) );
|
116 |
+
}
|
117 |
+
}
|
framework/helpers/class-fw-db-options-model.php
CHANGED
@@ -172,10 +172,28 @@ abstract class FW_Db_Options_Model {
|
|
172 |
FW_Cache::set($cache_key_values_processed, true);
|
173 |
|
174 |
// Complete missing db values with default values from options array
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
|
180 |
foreach ($options as $id => $option) {
|
181 |
$values[$id] = fw()->backend->option_type($option['type'])->storage_load(
|
172 |
FW_Cache::set($cache_key_values_processed, true);
|
173 |
|
174 |
// Complete missing db values with default values from options array
|
175 |
+
{
|
176 |
+
try {
|
177 |
+
$skip_types_process = FW_Cache::get($cache_key = 'fw:options-default-values:skip-types');
|
178 |
+
} catch (FW_Cache_Not_Found_Exception $e) {
|
179 |
+
FW_Cache::set(
|
180 |
+
$cache_key,
|
181 |
+
$skip_types_process = apply_filters('fw:options-default-values:skip-types', array(
|
182 |
+
// 'type' => true
|
183 |
+
))
|
184 |
+
);
|
185 |
+
}
|
186 |
+
|
187 |
+
foreach (array_diff_key(fw_extract_only_options( $options ), $values) as $id => $option) {
|
188 |
+
$values[ $id ] = isset($skip_types_process[ $option['type'] ])
|
189 |
+
? (
|
190 |
+
isset($option['value'])
|
191 |
+
? $option['value']
|
192 |
+
: fw()->backend->option_type( $option['type'] )->get_defaults( 'value' )
|
193 |
+
)
|
194 |
+
: fw()->backend->option_type($option['type'])->get_value_from_input($option, null);
|
195 |
+
}
|
196 |
+
}
|
197 |
|
198 |
foreach ($options as $id => $option) {
|
199 |
$values[$id] = fw()->backend->option_type($option['type'])->storage_load(
|
framework/helpers/class-fw-flash-messages.php
CHANGED
@@ -201,9 +201,18 @@ class FW_Flash_Messages
|
|
201 |
$messages = self::get_messages();
|
202 |
|
203 |
if ($clear) {
|
204 |
-
self::
|
205 |
}
|
206 |
|
207 |
return $messages;
|
208 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
}
|
201 |
$messages = self::get_messages();
|
202 |
|
203 |
if ($clear) {
|
204 |
+
self::_clear();
|
205 |
}
|
206 |
|
207 |
return $messages;
|
208 |
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Clear the FW_Flash_Messages messages
|
212 |
+
*
|
213 |
+
* @since 2.6.14
|
214 |
+
*/
|
215 |
+
public static function _clear() {
|
216 |
+
self::set_messages(array());
|
217 |
+
}
|
218 |
}
|
framework/helpers/class-fw-form.php
CHANGED
@@ -178,12 +178,14 @@ class FW_Form {
|
|
178 |
* Some forms (like Forms extension frontend form) uses the same FW_Form instance for all sub-forms
|
179 |
* and they must be differentiated somehow.
|
180 |
* Fixes https://github.com/ThemeFuse/Unyson/issues/2033
|
|
|
181 |
* @param array $render_data
|
|
|
182 |
* @return string
|
183 |
* @since 2.6.6
|
184 |
*/
|
185 |
-
private function get_nonce_name($render_data = array()) {
|
186 |
-
return '_nonce_' . md5( $this->id . apply_filters('fw:form:nonce-name-data', '', $this, $render_data) );
|
187 |
}
|
188 |
|
189 |
protected function save() {
|
@@ -221,7 +223,9 @@ class FW_Form {
|
|
221 |
}
|
222 |
|
223 |
protected function is_ajax() {
|
224 |
-
return defined( 'DOING_AJAX' ) && DOING_AJAX
|
|
|
|
|
225 |
}
|
226 |
|
227 |
/**
|
@@ -265,11 +269,11 @@ class FW_Form {
|
|
265 |
{
|
266 |
$flash_messages = array();
|
267 |
|
268 |
-
foreach (FW_Flash_Messages::_get_messages(true) as $type => $messages) {
|
269 |
-
$flash_messages[$type] = array();
|
270 |
|
271 |
-
foreach ($messages as $id => $message_data) {
|
272 |
-
$flash_messages[$type][$id] = $message_data['message'];
|
273 |
}
|
274 |
}
|
275 |
|
@@ -297,9 +301,9 @@ class FW_Form {
|
|
297 |
*/
|
298 |
|
299 |
if ( $this->is_valid() ) {
|
300 |
-
wp_send_json_success($json_data);
|
301 |
} else {
|
302 |
-
wp_send_json_error($json_data);
|
303 |
}
|
304 |
} else {
|
305 |
if ( ! $this->is_valid() ) {
|
@@ -349,8 +353,8 @@ class FW_Form {
|
|
349 |
*/
|
350 |
'html' => null,
|
351 |
),
|
352 |
-
'data'
|
353 |
-
'attr'
|
354 |
);
|
355 |
|
356 |
unset( $data );
|
@@ -374,7 +378,7 @@ class FW_Form {
|
|
374 |
|
375 |
// display form errors in frontend
|
376 |
do {
|
377 |
-
if (is_admin()) {
|
378 |
// errors in admin side are displayed by a script at the end of this file
|
379 |
break;
|
380 |
}
|
@@ -390,9 +394,9 @@ class FW_Form {
|
|
390 |
break;
|
391 |
}
|
392 |
|
393 |
-
unset($submitted_form); // not needed anymore, below will be used only with $this (because it's the same form)
|
394 |
|
395 |
-
if ( ! isset( $_POST[ $this->get_nonce_name($render_data) ] )) {
|
396 |
break;
|
397 |
}
|
398 |
|
@@ -403,7 +407,7 @@ class FW_Form {
|
|
403 |
/**
|
404 |
* Use this action to customize errors display in your theme
|
405 |
*/
|
406 |
-
do_action('fw_form_display_errors_frontend', $this);
|
407 |
|
408 |
if ( $this->errors_accessed() ) {
|
409 |
// already displayed, prevent/cancel default display
|
@@ -412,13 +416,13 @@ class FW_Form {
|
|
412 |
|
413 |
$errors = $this->get_errors();
|
414 |
|
415 |
-
if (empty($errors)) {
|
416 |
break;
|
417 |
}
|
418 |
|
419 |
echo '<ul class="fw-form-errors">';
|
420 |
|
421 |
-
foreach ($errors as $input_name => $error_message) {
|
422 |
echo fw_html_tag(
|
423 |
'li',
|
424 |
array(
|
@@ -430,21 +434,22 @@ class FW_Form {
|
|
430 |
|
431 |
echo '</ul>';
|
432 |
|
433 |
-
unset($errors);
|
434 |
-
} while(false);
|
435 |
|
436 |
-
echo '<form '. fw_attr_to_html( $render_data['attr'] ) .' >';
|
437 |
|
438 |
-
do_action('fw_form_display:before', $this);
|
439 |
|
440 |
-
echo fw_html_tag('input',
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
|
|
445 |
|
446 |
if ( $render_data['attr']['method'] == 'post' ) {
|
447 |
-
wp_nonce_field( 'submit_fwf', $this->get_nonce_name($render_data) );
|
448 |
}
|
449 |
|
450 |
if ( ! empty( $render_data['attr']['action'] ) && $render_data['attr']['method'] == 'get' ) {
|
@@ -456,11 +461,12 @@ class FW_Form {
|
|
456 |
|
457 |
if ( ! empty( $query_vars ) ) {
|
458 |
foreach ( $query_vars as $var_name => $var_value ) {
|
459 |
-
echo fw_html_tag('input',
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
|
|
464 |
}
|
465 |
}
|
466 |
}
|
@@ -471,13 +477,14 @@ class FW_Form {
|
|
471 |
if ( isset( $render_data['submit']['html'] ) ) {
|
472 |
echo $render_data['submit']['html'];
|
473 |
} else {
|
474 |
-
echo fw_html_tag('input',
|
475 |
-
|
476 |
-
|
477 |
-
|
|
|
478 |
}
|
479 |
|
480 |
-
do_action('fw_form_display:after', $this);
|
481 |
|
482 |
echo '</form>';
|
483 |
}
|
@@ -487,8 +494,8 @@ class FW_Form {
|
|
487 |
* @return bool
|
488 |
*/
|
489 |
public function is_submitted() {
|
490 |
-
if (is_null($this->is_submitted)) {
|
491 |
-
switch (strtoupper( $this->attr( 'method' ) )) {
|
492 |
case 'POST':
|
493 |
$this->is_submitted = (
|
494 |
isset( $_POST[ self::$id_input_name ] )
|
@@ -540,8 +547,7 @@ class FW_Form {
|
|
540 |
return $this->errors;
|
541 |
}
|
542 |
|
543 |
-
public function errors_accessed()
|
544 |
-
{
|
545 |
return $this->errors_accessed;
|
546 |
}
|
547 |
|
178 |
* Some forms (like Forms extension frontend form) uses the same FW_Form instance for all sub-forms
|
179 |
* and they must be differentiated somehow.
|
180 |
* Fixes https://github.com/ThemeFuse/Unyson/issues/2033
|
181 |
+
*
|
182 |
* @param array $render_data
|
183 |
+
*
|
184 |
* @return string
|
185 |
* @since 2.6.6
|
186 |
*/
|
187 |
+
private function get_nonce_name( $render_data = array() ) {
|
188 |
+
return '_nonce_' . md5( $this->id . apply_filters( 'fw:form:nonce-name-data', '', $this, $render_data ) );
|
189 |
}
|
190 |
|
191 |
protected function save() {
|
223 |
}
|
224 |
|
225 |
protected function is_ajax() {
|
226 |
+
return ( defined( 'DOING_AJAX' ) && DOING_AJAX )
|
227 |
+
||
|
228 |
+
strtolower( fw_akg( 'HTTP_X_REQUESTED_WITH', $_SERVER ) ) == 'xmlhttprequest';
|
229 |
}
|
230 |
|
231 |
/**
|
269 |
{
|
270 |
$flash_messages = array();
|
271 |
|
272 |
+
foreach ( FW_Flash_Messages::_get_messages( true ) as $type => $messages ) {
|
273 |
+
$flash_messages[ $type ] = array();
|
274 |
|
275 |
+
foreach ( $messages as $id => $message_data ) {
|
276 |
+
$flash_messages[ $type ][ $id ] = $message_data['message'];
|
277 |
}
|
278 |
}
|
279 |
|
301 |
*/
|
302 |
|
303 |
if ( $this->is_valid() ) {
|
304 |
+
wp_send_json_success( $json_data );
|
305 |
} else {
|
306 |
+
wp_send_json_error( $json_data );
|
307 |
}
|
308 |
} else {
|
309 |
if ( ! $this->is_valid() ) {
|
353 |
*/
|
354 |
'html' => null,
|
355 |
),
|
356 |
+
'data' => $data,
|
357 |
+
'attr' => $this->attr,
|
358 |
);
|
359 |
|
360 |
unset( $data );
|
378 |
|
379 |
// display form errors in frontend
|
380 |
do {
|
381 |
+
if ( is_admin() ) {
|
382 |
// errors in admin side are displayed by a script at the end of this file
|
383 |
break;
|
384 |
}
|
394 |
break;
|
395 |
}
|
396 |
|
397 |
+
unset( $submitted_form ); // not needed anymore, below will be used only with $this (because it's the same form)
|
398 |
|
399 |
+
if ( ! isset( $_POST[ $this->get_nonce_name( $render_data ) ] ) ) {
|
400 |
break;
|
401 |
}
|
402 |
|
407 |
/**
|
408 |
* Use this action to customize errors display in your theme
|
409 |
*/
|
410 |
+
do_action( 'fw_form_display_errors_frontend', $this );
|
411 |
|
412 |
if ( $this->errors_accessed() ) {
|
413 |
// already displayed, prevent/cancel default display
|
416 |
|
417 |
$errors = $this->get_errors();
|
418 |
|
419 |
+
if ( empty( $errors ) ) {
|
420 |
break;
|
421 |
}
|
422 |
|
423 |
echo '<ul class="fw-form-errors">';
|
424 |
|
425 |
+
foreach ( $errors as $input_name => $error_message ) {
|
426 |
echo fw_html_tag(
|
427 |
'li',
|
428 |
array(
|
434 |
|
435 |
echo '</ul>';
|
436 |
|
437 |
+
unset( $errors );
|
438 |
+
} while ( false );
|
439 |
|
440 |
+
echo '<form ' . fw_attr_to_html( $render_data['attr'] ) . ' >';
|
441 |
|
442 |
+
do_action( 'fw_form_display:before', $this );
|
443 |
|
444 |
+
echo fw_html_tag( 'input',
|
445 |
+
array(
|
446 |
+
'type' => 'hidden',
|
447 |
+
'name' => self::$id_input_name,
|
448 |
+
'value' => $this->id,
|
449 |
+
) );
|
450 |
|
451 |
if ( $render_data['attr']['method'] == 'post' ) {
|
452 |
+
wp_nonce_field( 'submit_fwf', $this->get_nonce_name( $render_data ) );
|
453 |
}
|
454 |
|
455 |
if ( ! empty( $render_data['attr']['action'] ) && $render_data['attr']['method'] == 'get' ) {
|
461 |
|
462 |
if ( ! empty( $query_vars ) ) {
|
463 |
foreach ( $query_vars as $var_name => $var_value ) {
|
464 |
+
echo fw_html_tag( 'input',
|
465 |
+
array(
|
466 |
+
'type' => 'hidden',
|
467 |
+
'name' => $var_name,
|
468 |
+
'value' => $var_value,
|
469 |
+
) );
|
470 |
}
|
471 |
}
|
472 |
}
|
477 |
if ( isset( $render_data['submit']['html'] ) ) {
|
478 |
echo $render_data['submit']['html'];
|
479 |
} else {
|
480 |
+
echo fw_html_tag( 'input',
|
481 |
+
array(
|
482 |
+
'type' => 'submit',
|
483 |
+
'value' => $render_data['submit']['value']
|
484 |
+
) );
|
485 |
}
|
486 |
|
487 |
+
do_action( 'fw_form_display:after', $this );
|
488 |
|
489 |
echo '</form>';
|
490 |
}
|
494 |
* @return bool
|
495 |
*/
|
496 |
public function is_submitted() {
|
497 |
+
if ( is_null( $this->is_submitted ) ) {
|
498 |
+
switch ( strtoupper( $this->attr( 'method' ) ) ) {
|
499 |
case 'POST':
|
500 |
$this->is_submitted = (
|
501 |
isset( $_POST[ self::$id_input_name ] )
|
547 |
return $this->errors;
|
548 |
}
|
549 |
|
550 |
+
public function errors_accessed() {
|
|
|
551 |
return $this->errors_accessed;
|
552 |
}
|
553 |
|
framework/helpers/general.php
CHANGED
@@ -1,19 +1,23 @@
|
|
1 |
-
<?php if (!defined('FW'))
|
|
|
|
|
2 |
// Useful functions
|
3 |
|
4 |
/**
|
5 |
* Convert to Unix style directory separators
|
6 |
*/
|
7 |
-
function fw_fix_path($path) {
|
8 |
-
$windows_network_path = isset($_SERVER['windir']) && in_array(substr($path, 0, 2
|
9 |
-
|
|
|
|
|
10 |
|
11 |
-
if (empty($fixed_path) && !empty($path)) {
|
12 |
$fixed_path = '/';
|
13 |
}
|
14 |
|
15 |
-
if ($windows_network_path) {
|
16 |
-
$fixed_path = '//'. ltrim($fixed_path, '/');
|
17 |
}
|
18 |
|
19 |
return $fixed_path;
|
@@ -21,16 +25,18 @@ function fw_fix_path($path) {
|
|
21 |
|
22 |
/**
|
23 |
* Relative path of the framework customizations directory
|
|
|
24 |
* @param string $append
|
|
|
25 |
* @return string
|
26 |
*/
|
27 |
-
function fw_get_framework_customizations_dir_rel_path($append = '') {
|
28 |
try {
|
29 |
-
$dir = FW_Cache::get($cache_key = 'fw_customizations_dir_rel_path');
|
30 |
-
} catch (FW_Cache_Not_Found_Exception $e) {
|
31 |
FW_Cache::set(
|
32 |
$cache_key,
|
33 |
-
$dir = apply_filters('fw_framework_customizations_dir_rel_path', '/framework-customizations')
|
34 |
);
|
35 |
}
|
36 |
|
@@ -41,12 +47,14 @@ function fw_get_framework_customizations_dir_rel_path($append = '') {
|
|
41 |
{
|
42 |
/**
|
43 |
* Full path to the child-theme framework customizations directory
|
|
|
44 |
* @param string $rel_path
|
|
|
45 |
* @return null|string
|
46 |
*/
|
47 |
-
function fw_get_stylesheet_customizations_directory($rel_path = '') {
|
48 |
-
if (is_child_theme()) {
|
49 |
-
return get_stylesheet_directory() . fw_get_framework_customizations_dir_rel_path($rel_path);
|
50 |
} else {
|
51 |
// check is_child_theme() before using this function
|
52 |
return null;
|
@@ -55,12 +63,14 @@ function fw_get_framework_customizations_dir_rel_path($append = '') {
|
|
55 |
|
56 |
/**
|
57 |
* URI to the child-theme framework customizations directory
|
|
|
58 |
* @param string $rel_path
|
|
|
59 |
* @return null|string
|
60 |
*/
|
61 |
-
function fw_get_stylesheet_customizations_directory_uri($rel_path = '') {
|
62 |
-
if (is_child_theme()) {
|
63 |
-
return get_stylesheet_directory_uri() . fw_get_framework_customizations_dir_rel_path($rel_path);
|
64 |
} else {
|
65 |
// check is_child_theme() before using this function
|
66 |
return null;
|
@@ -72,13 +82,15 @@ function fw_get_framework_customizations_dir_rel_path($append = '') {
|
|
72 |
{
|
73 |
/**
|
74 |
* Full path to the parent-theme framework customizations directory
|
|
|
75 |
* @param string $rel_path
|
|
|
76 |
* @return string
|
77 |
*/
|
78 |
-
function fw_get_template_customizations_directory($rel_path = '') {
|
79 |
try {
|
80 |
-
$dir = FW_Cache::get($cache_key = 'fw_template_customizations_dir');
|
81 |
-
} catch (FW_Cache_Not_Found_Exception $e) {
|
82 |
FW_Cache::set(
|
83 |
$cache_key,
|
84 |
$dir = get_template_directory() . fw_get_framework_customizations_dir_rel_path()
|
@@ -90,13 +102,15 @@ function fw_get_framework_customizations_dir_rel_path($append = '') {
|
|
90 |
|
91 |
/**
|
92 |
* URI to the parent-theme framework customizations directory
|
|
|
93 |
* @param string $rel_path
|
|
|
94 |
* @return string
|
95 |
*/
|
96 |
-
function fw_get_template_customizations_directory_uri($rel_path = '') {
|
97 |
try {
|
98 |
-
$dir = FW_Cache::get($cache_key = 'fw_template_customizations_dir_uri');
|
99 |
-
} catch (FW_Cache_Not_Found_Exception $e) {
|
100 |
FW_Cache::set(
|
101 |
$cache_key,
|
102 |
$dir = get_template_directory_uri() . fw_get_framework_customizations_dir_rel_path()
|
@@ -111,18 +125,20 @@ function fw_get_framework_customizations_dir_rel_path($append = '') {
|
|
111 |
{
|
112 |
/**
|
113 |
* Full path to the parent-theme/framework directory
|
|
|
114 |
* @param string $rel_path
|
|
|
115 |
* @return string
|
116 |
*/
|
117 |
-
function fw_get_framework_directory($rel_path = '') {
|
118 |
try {
|
119 |
-
$dir = FW_Cache::get($cache_key = 'fw_framework_dir');
|
120 |
-
} catch (FW_Cache_Not_Found_Exception $e) {
|
121 |
FW_Cache::set(
|
122 |
$cache_key,
|
123 |
$dir = apply_filters(
|
124 |
'fw_framework_directory',
|
125 |
-
fw_fix_path(dirname(dirname(__FILE__))) // double dirname() to remove '/helpers', use parent dir
|
126 |
)
|
127 |
);
|
128 |
}
|
@@ -132,18 +148,20 @@ function fw_get_framework_customizations_dir_rel_path($append = '') {
|
|
132 |
|
133 |
/**
|
134 |
* URI to the parent-theme/framework directory
|
|
|
135 |
* @param string $rel_path
|
|
|
136 |
* @return string
|
137 |
*/
|
138 |
-
function fw_get_framework_directory_uri($rel_path = '') {
|
139 |
try {
|
140 |
-
$uri = FW_Cache::get($cache_key = 'fw_framework_dir_uri');
|
141 |
-
} catch (FW_Cache_Not_Found_Exception $e) {
|
142 |
FW_Cache::set(
|
143 |
$cache_key,
|
144 |
$uri = apply_filters(
|
145 |
'fw_framework_directory_uri',
|
146 |
-
($uri = fw_get_path_url(fw_get_framework_directory()))
|
147 |
? $uri
|
148 |
: get_template_directory_uri() . '/framework'
|
149 |
)
|
@@ -161,41 +179,44 @@ function fw_get_framework_customizations_dir_rel_path($append = '') {
|
|
161 |
* @param array|object $array_or_object
|
162 |
* @param null|mixed $default_value
|
163 |
* @param string $keys_delimiter
|
|
|
164 |
* @return null|mixed
|
165 |
*/
|
166 |
-
function fw_akg($keys, $array_or_object, $default_value = null, $keys_delimiter = '/') {
|
167 |
-
if (!is_array($keys)) {
|
168 |
$keys = explode( $keys_delimiter, (string) $keys );
|
169 |
}
|
170 |
|
171 |
-
$
|
172 |
-
|
|
|
|
|
173 |
return $default_value;
|
174 |
}
|
175 |
|
176 |
-
$is_object = is_object($array_or_object);
|
177 |
|
178 |
-
if ($is_object) {
|
179 |
-
if (!property_exists($array_or_object, $key_or_property)) {
|
180 |
return $default_value;
|
181 |
}
|
182 |
} else {
|
183 |
-
if (!is_array($array_or_object) || !array_key_exists($key_or_property, $array_or_object)) {
|
184 |
return $default_value;
|
185 |
}
|
186 |
}
|
187 |
|
188 |
-
if (isset($keys[0])) { // not used count() for performance reasons
|
189 |
-
if ($is_object) {
|
190 |
-
return fw_akg($keys, $array_or_object->{$key_or_property}, $default_value);
|
191 |
} else {
|
192 |
-
return fw_akg($keys, $array_or_object[$key_or_property], $default_value);
|
193 |
}
|
194 |
} else {
|
195 |
-
if ($is_object) {
|
196 |
return $array_or_object->{$key_or_property};
|
197 |
} else {
|
198 |
-
return $array_or_object[$key_or_property];
|
199 |
}
|
200 |
}
|
201 |
}
|
@@ -208,59 +229,61 @@ function fw_akg($keys, $array_or_object, $default_value = null, $keys_delimiter
|
|
208 |
* @param array|object $array_or_object
|
209 |
* @param string $keys_delimiter
|
210 |
*/
|
211 |
-
function fw_aks($keys, $value, &$array_or_object, $keys_delimiter = '/') {
|
212 |
-
if (!is_array($keys)) {
|
213 |
-
$keys = explode($keys_delimiter, (string)$keys);
|
214 |
}
|
215 |
|
216 |
-
$key_or_property = array_shift($keys);
|
217 |
-
if ($key_or_property === null) {
|
218 |
return;
|
219 |
}
|
220 |
|
221 |
-
$is_object = is_object($array_or_object);
|
222 |
|
223 |
-
if ($is_object) {
|
224 |
-
if (!property_exists($array_or_object, $key_or_property)
|
225 |
-
|
226 |
) {
|
227 |
-
if ($key_or_property === '') {
|
228 |
// this happens when use 'empty keys' like: abc/d/e////i/j//foo/
|
229 |
-
trigger_error('Cannot push value to object like in array ($arr[] = $val)', E_USER_WARNING);
|
230 |
} else {
|
231 |
$array_or_object->{$key_or_property} = array();
|
232 |
}
|
233 |
}
|
234 |
} else {
|
235 |
-
if (!is_array($array_or_object)) {
|
236 |
$array_or_object = array();
|
237 |
}
|
238 |
|
239 |
-
if (!array_key_exists($key_or_property,
|
240 |
-
|
|
|
|
|
241 |
// this happens when use 'empty keys' like: abc.d.e....i.j..foo.
|
242 |
$array_or_object[] = array();
|
243 |
|
244 |
// get auto created key (last)
|
245 |
-
end($array_or_object);
|
246 |
-
$key_or_property = key($array_or_object);
|
247 |
} else {
|
248 |
-
$array_or_object[$key_or_property] = array();
|
249 |
}
|
250 |
}
|
251 |
}
|
252 |
|
253 |
-
if (isset($keys[0])) { // not used count() for performance reasons
|
254 |
-
if ($is_object) {
|
255 |
-
fw_aks($keys, $value, $array_or_object->{$key_or_property});
|
256 |
} else {
|
257 |
-
fw_aks($keys, $value, $array_or_object[$key_or_property]);
|
258 |
}
|
259 |
} else {
|
260 |
-
if ($is_object) {
|
261 |
$array_or_object->{$key_or_property} = $value;
|
262 |
} else {
|
263 |
-
$array_or_object[$key_or_property] = $value;
|
264 |
}
|
265 |
}
|
266 |
}
|
@@ -272,39 +295,39 @@ function fw_aks($keys, $value, &$array_or_object, $keys_delimiter = '/') {
|
|
272 |
* @param array|object $array_or_object
|
273 |
* @param string $keys_delimiter
|
274 |
*/
|
275 |
-
function fw_aku($keys, &$array_or_object, $keys_delimiter = '/') {
|
276 |
-
if (!is_array($keys)) {
|
277 |
-
$keys = explode($keys_delimiter, (string)$keys);
|
278 |
}
|
279 |
|
280 |
-
$key_or_property = array_shift($keys);
|
281 |
-
if ($key_or_property === null || $key_or_property === '') {
|
282 |
return;
|
283 |
}
|
284 |
|
285 |
-
$is_object = is_object($array_or_object);
|
286 |
|
287 |
-
if ($is_object) {
|
288 |
-
if (!property_exists($array_or_object, $key_or_property)) {
|
289 |
return;
|
290 |
}
|
291 |
} else {
|
292 |
-
if (!is_array($array_or_object) || !array_key_exists($key_or_property, $array_or_object)) {
|
293 |
return;
|
294 |
}
|
295 |
}
|
296 |
|
297 |
-
if (isset($keys[0])) { // not used count() for performance reasons
|
298 |
-
if ($is_object) {
|
299 |
-
fw_aku($keys, $array_or_object->{$key_or_property});
|
300 |
} else {
|
301 |
-
fw_aku($keys, $array_or_object[$key_or_property]);
|
302 |
}
|
303 |
} else {
|
304 |
-
if ($is_object) {
|
305 |
-
unset($array_or_object->{$key_or_property});
|
306 |
} else {
|
307 |
-
unset($array_or_object[$key_or_property]);
|
308 |
}
|
309 |
|
310 |
return;
|
@@ -315,12 +338,13 @@ function fw_aku($keys, &$array_or_object, $keys_delimiter = '/') {
|
|
315 |
* Generate random unique md5
|
316 |
*/
|
317 |
function fw_rand_md5() {
|
318 |
-
return md5(time() .'-'. uniqid(rand(), true) .'-'. mt_rand(1, 1000));
|
319 |
}
|
320 |
|
321 |
function fw_unique_increment() {
|
322 |
static $i = 0;
|
323 |
-
|
|
|
324 |
}
|
325 |
|
326 |
/**
|
@@ -328,10 +352,10 @@ function fw_unique_increment() {
|
|
328 |
*
|
329 |
* @param mixed $value Value to debug
|
330 |
*/
|
331 |
-
function fw_print($value) {
|
332 |
static $first_time = true;
|
333 |
|
334 |
-
if ($first_time) {
|
335 |
ob_start();
|
336 |
echo '<style type="text/css">
|
337 |
div.fw_print_r {
|
@@ -372,19 +396,19 @@ function fw_print($value) {
|
|
372 |
border-width: 0;
|
373 |
}
|
374 |
</style>';
|
375 |
-
echo str_replace(array(' ', "\n"), '', ob_get_clean());
|
376 |
|
377 |
$first_time = false;
|
378 |
}
|
379 |
|
380 |
-
if (func_num_args() == 1) {
|
381 |
echo '<div class="fw_print_r"><pre>';
|
382 |
-
echo fw_htmlspecialchars(FW_Dumper::dump($value));
|
383 |
echo '</pre></div>';
|
384 |
} else {
|
385 |
echo '<div class="fw_print_r_group">';
|
386 |
-
foreach (func_get_args() as $param) {
|
387 |
-
fw_print($param);
|
388 |
}
|
389 |
echo '</div>';
|
390 |
}
|
@@ -396,20 +420,21 @@ function fw_print($value) {
|
|
396 |
* @param string $tag Tag name
|
397 |
* @param array $attr Tag attributes
|
398 |
* @param bool|string $end Append closing tag. Also accepts body content
|
|
|
399 |
* @return string The tag's html
|
400 |
*/
|
401 |
-
function fw_html_tag($tag, $attr = array(), $end = false) {
|
402 |
-
$html = '<'. $tag .' '. fw_attr_to_html($attr);
|
403 |
|
404 |
-
if ($end === true) {
|
405 |
# <script></script>
|
406 |
-
$html .= '></'. $tag .'>';
|
407 |
-
} else if ($end === false) {
|
408 |
# <br/>
|
409 |
$html .= '/>';
|
410 |
} else {
|
411 |
# <div>content</div>
|
412 |
-
$html .= '>'. $end .'</'. $tag .'>';
|
413 |
}
|
414 |
|
415 |
return $html;
|
@@ -417,18 +442,20 @@ function fw_html_tag($tag, $attr = array(), $end = false) {
|
|
417 |
|
418 |
/**
|
419 |
* Generate attributes string for html tag
|
|
|
420 |
* @param array $attr_array array('href' => '/', 'title' => 'Test')
|
|
|
421 |
* @return string 'href="/" title="Test"'
|
422 |
*/
|
423 |
-
function fw_attr_to_html(array $attr_array) {
|
424 |
$html_attr = '';
|
425 |
|
426 |
-
foreach ($attr_array as $attr_name => $attr_val) {
|
427 |
-
if ($attr_val === false) {
|
428 |
continue;
|
429 |
}
|
430 |
|
431 |
-
$html_attr .= $attr_name .'="'. fw_htmlspecialchars($attr_val) .'" ';
|
432 |
}
|
433 |
|
434 |
return $html_attr;
|
@@ -437,30 +464,30 @@ function fw_attr_to_html(array $attr_array) {
|
|
437 |
/**
|
438 |
* Strip slashes from values, and from keys if magic_quotes_gpc = On
|
439 |
*/
|
440 |
-
function fw_stripslashes_deep_keys($value) {
|
441 |
static $magic_quotes = null;
|
442 |
-
if ($magic_quotes === null) {
|
443 |
$magic_quotes = get_magic_quotes_gpc();
|
444 |
}
|
445 |
|
446 |
-
if (is_array($value)) {
|
447 |
-
if ($magic_quotes) {
|
448 |
$new_value = array();
|
449 |
-
foreach ($value as $key => $val) {
|
450 |
-
$new_value[ is_string($key) ? stripslashes($key) : $key ] = fw_stripslashes_deep_keys($val);
|
451 |
}
|
452 |
$value = $new_value;
|
453 |
-
unset($new_value);
|
454 |
} else {
|
455 |
-
$value = array_map('fw_stripslashes_deep_keys', $value);
|
456 |
}
|
457 |
-
} elseif (is_object($value)) {
|
458 |
-
$vars = get_object_vars($value);
|
459 |
-
foreach ($vars as $key
|
460 |
-
$value->{$key} = fw_stripslashes_deep_keys($data);
|
461 |
}
|
462 |
-
} elseif (is_string($value)) {
|
463 |
-
$value = stripslashes($value);
|
464 |
}
|
465 |
|
466 |
return $value;
|
@@ -469,30 +496,30 @@ function fw_stripslashes_deep_keys($value) {
|
|
469 |
/**
|
470 |
* Add slashes to values, and to keys if magic_quotes_gpc = On
|
471 |
*/
|
472 |
-
function fw_addslashes_deep_keys($value) {
|
473 |
static $magic_quotes = null;
|
474 |
-
if ($magic_quotes === null) {
|
475 |
$magic_quotes = get_magic_quotes_gpc();
|
476 |
}
|
477 |
|
478 |
-
if (is_array($value)) {
|
479 |
-
if ($magic_quotes) {
|
480 |
$new_value = array();
|
481 |
-
foreach ($value as $key
|
482 |
-
$new_value[ is_string($key) ? addslashes($key) : $key ] = fw_addslashes_deep_keys($value);
|
483 |
}
|
484 |
$value = $new_value;
|
485 |
-
unset($new_value);
|
486 |
} else {
|
487 |
-
$value = array_map('fw_addslashes_deep_keys', $value);
|
488 |
}
|
489 |
-
} elseif (is_object($value)) {
|
490 |
-
$vars = get_object_vars($value);
|
491 |
-
foreach ($vars as $key
|
492 |
-
$value->{$key} = fw_addslashes_deep_keys($data);
|
493 |
}
|
494 |
-
} elseif (is_string($value)) {
|
495 |
-
$value = addslashes($value);
|
496 |
}
|
497 |
|
498 |
return $value;
|
@@ -500,10 +527,12 @@ function fw_addslashes_deep_keys($value) {
|
|
500 |
|
501 |
/**
|
502 |
* Check if current screen pass/match give rules
|
|
|
503 |
* @param array $rules Rules for current screen
|
|
|
504 |
* @return bool
|
505 |
*/
|
506 |
-
function fw_current_screen_match(array $rules) {
|
507 |
$available_options = array(
|
508 |
'action' => true,
|
509 |
'base' => true,
|
@@ -516,7 +545,7 @@ function fw_current_screen_match(array $rules) {
|
|
516 |
'taxonomy' => true,
|
517 |
);
|
518 |
|
519 |
-
if (empty($rules)) {
|
520 |
return true;
|
521 |
}
|
522 |
|
@@ -528,13 +557,13 @@ function fw_current_screen_match(array $rules) {
|
|
528 |
$rules
|
529 |
);
|
530 |
|
531 |
-
if (empty($rules['exclude']) && empty($rules['only'])) {
|
532 |
return true;
|
533 |
}
|
534 |
|
535 |
global $current_screen;
|
536 |
|
537 |
-
if (gettype($current_screen) != 'object') {
|
538 |
return false;
|
539 |
}
|
540 |
|
@@ -542,93 +571,93 @@ function fw_current_screen_match(array $rules) {
|
|
542 |
do {
|
543 |
$only = $rules['only'];
|
544 |
|
545 |
-
if (empty($only)) {
|
546 |
break;
|
547 |
}
|
548 |
|
549 |
-
if (!isset($only[0])) { // if not array of arrays
|
550 |
-
$only = array($only);
|
551 |
}
|
552 |
|
553 |
$found_one = false;
|
554 |
-
$counter
|
555 |
-
foreach ($only as $rule) {
|
556 |
-
if (!count($rule)) {
|
557 |
continue;
|
558 |
}
|
559 |
|
560 |
$match = true;
|
561 |
|
562 |
-
foreach ($rule as $r_key => $r_val) {
|
563 |
-
if (!isset($available_options[$r_key])) {
|
564 |
continue;
|
565 |
}
|
566 |
|
567 |
-
if (gettype($r_val) != 'array') {
|
568 |
-
$r_val = array($r_val);
|
569 |
}
|
570 |
|
571 |
-
$counter++;
|
572 |
|
573 |
-
if (!in_array($current_screen->{$r_key}, $r_val)) {
|
574 |
$match = false;
|
575 |
break;
|
576 |
}
|
577 |
}
|
578 |
|
579 |
-
if ($match) {
|
580 |
$found_one = true;
|
581 |
break;
|
582 |
}
|
583 |
}
|
584 |
|
585 |
-
if (
|
586 |
return false;
|
587 |
}
|
588 |
-
} while(false);
|
589 |
|
590 |
// check if current screen passes the "exclude" rules
|
591 |
do {
|
592 |
$exclude = $rules['exclude'];
|
593 |
|
594 |
-
if (empty($exclude)) {
|
595 |
break;
|
596 |
}
|
597 |
|
598 |
-
if (!isset($exclude[0])) { // if not array of arrays
|
599 |
-
$exclude = array($exclude);
|
600 |
}
|
601 |
|
602 |
-
foreach ($exclude as $rule) {
|
603 |
-
if (!count($rule)) {
|
604 |
continue;
|
605 |
}
|
606 |
|
607 |
$match = true;
|
608 |
$counter = 0;
|
609 |
|
610 |
-
foreach ($rule as $r_key => $r_val) {
|
611 |
-
if (!isset($available_options[$r_key])) {
|
612 |
continue;
|
613 |
}
|
614 |
|
615 |
-
if (gettype($r_val) != 'array') {
|
616 |
-
$r_val = array($r_val);
|
617 |
}
|
618 |
|
619 |
-
$counter++;
|
620 |
|
621 |
-
if (!in_array($current_screen->{$r_key}, $r_val)) {
|
622 |
$match = false;
|
623 |
break;
|
624 |
}
|
625 |
}
|
626 |
|
627 |
-
if ($match && $counter) {
|
628 |
return false;
|
629 |
}
|
630 |
}
|
631 |
-
} while(false);
|
632 |
|
633 |
return true;
|
634 |
}
|
@@ -637,15 +666,16 @@ function fw_current_screen_match(array $rules) {
|
|
637 |
* Search relative path in child then in parent theme directory and return URI
|
638 |
*
|
639 |
* @param string $rel_path '/some/path_to_dir' or '/some/path_to_file.php'
|
|
|
640 |
* @return string URI
|
641 |
*/
|
642 |
-
function fw_locate_theme_path_uri($rel_path) {
|
643 |
-
if (is_child_theme() && file_exists(get_stylesheet_directory() . $rel_path)) {
|
644 |
return get_stylesheet_directory_uri() . $rel_path;
|
645 |
-
} elseif (file_exists(get_template_directory() . $rel_path)) {
|
646 |
return get_template_directory_uri() . $rel_path;
|
647 |
} else {
|
648 |
-
return 'about:blank#theme-file-not-found:'. $rel_path;
|
649 |
}
|
650 |
}
|
651 |
|
@@ -653,12 +683,13 @@ function fw_locate_theme_path_uri($rel_path) {
|
|
653 |
* Search relative path in child then in parent theme directory and return full path
|
654 |
*
|
655 |
* @param string $rel_path '/some/path_to_dir' or '/some/path_to_file.php'
|
|
|
656 |
* @return string URI
|
657 |
*/
|
658 |
-
function fw_locate_theme_path($rel_path) {
|
659 |
-
if (is_child_theme() && file_exists(get_stylesheet_directory() . $rel_path)) {
|
660 |
return get_stylesheet_directory() . $rel_path;
|
661 |
-
} elseif (file_exists(get_template_directory() . $rel_path)) {
|
662 |
return get_template_directory() . $rel_path;
|
663 |
} else {
|
664 |
return false;
|
@@ -671,47 +702,52 @@ function fw_locate_theme_path($rel_path) {
|
|
671 |
* https://github.com/ThemeFuse/Unyson/commit/07be8b1f4b50eaf0f1f7e85ea1c6912a0415d241#diff-cf866bf08b8f747e3120221a6b1b07cfR48
|
672 |
* it throws fatal error because this function here is defined after that
|
673 |
*/
|
674 |
-
if (!function_exists('fw_render_view')):
|
675 |
-
/**
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
|
|
|
|
687 |
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
|
|
|
|
694 |
}
|
695 |
-
}
|
696 |
endif;
|
697 |
|
698 |
/**
|
699 |
* Safe load variables from an file
|
700 |
* Use this function to not include files directly and to not give access to current context variables (like $this)
|
|
|
701 |
* @param string $file_path
|
702 |
* @param array $_extract_variables Extract these from file array('variable_name' => 'default_value')
|
703 |
* @param array $_set_variables Set these to be available in file (like variables in view)
|
|
|
704 |
* @return array
|
705 |
*/
|
706 |
-
function fw_get_variables_from_file($file_path, array $_extract_variables, array $_set_variables = array()) {
|
707 |
-
extract($_set_variables, EXTR_REFS);
|
708 |
-
unset($_set_variables);
|
709 |
|
710 |
require $file_path;
|
711 |
|
712 |
-
foreach ($_extract_variables as $variable_name => $default_value) {
|
713 |
-
if (isset($$variable_name)) {
|
714 |
-
$_extract_variables[$variable_name] = $$variable_name;
|
715 |
}
|
716 |
}
|
717 |
|
@@ -720,17 +756,20 @@ function fw_get_variables_from_file($file_path, array $_extract_variables, array
|
|
720 |
|
721 |
/**
|
722 |
* Use this function to not include files directly and to not give access to current context variables (like $this)
|
|
|
723 |
* @param string $file_path
|
724 |
* @param bool $once
|
|
|
725 |
* @return bool If was included or not
|
726 |
*/
|
727 |
-
function fw_include_file_isolated($file_path, $once = false) {
|
728 |
-
if (file_exists($file_path)) {
|
729 |
if ( (bool) $once ) {
|
730 |
include_once $file_path;
|
731 |
} else {
|
732 |
include $file_path;
|
733 |
}
|
|
|
734 |
return true;
|
735 |
} else {
|
736 |
return false;
|
@@ -739,19 +778,22 @@ function fw_include_file_isolated($file_path, $once = false) {
|
|
739 |
|
740 |
/**
|
741 |
* Extract only input options (without containers)
|
|
|
742 |
* @param array $options
|
|
|
743 |
* @return array {option_id => option}
|
744 |
*/
|
745 |
-
function fw_extract_only_options(array $options) {
|
746 |
$collected = array();
|
747 |
|
748 |
-
fw_collect_options($collected, $options);
|
749 |
|
750 |
return $collected;
|
751 |
}
|
752 |
|
753 |
/**
|
754 |
* Collect correct options from the first level of the array and group them
|
|
|
755 |
* @param array $collected Will be filled with found correct options
|
756 |
* @param array $options
|
757 |
*
|
@@ -760,12 +802,12 @@ function fw_extract_only_options(array $options) {
|
|
760 |
* but this function is hardcoded only for tab,box,group.
|
761 |
* Use fw_collect_options()
|
762 |
*/
|
763 |
-
function fw_collect_first_level_options(&$collected, &$options) {
|
764 |
-
if (empty($options)) {
|
765 |
return;
|
766 |
}
|
767 |
|
768 |
-
if (empty($collected)) {
|
769 |
$collected['tabs'] =
|
770 |
$collected['boxes'] =
|
771 |
$collected['groups'] =
|
@@ -774,41 +816,41 @@ function fw_collect_first_level_options(&$collected, &$options) {
|
|
774 |
$collected['all'] = array();
|
775 |
}
|
776 |
|
777 |
-
foreach ($options as $option_id => &$option) {
|
778 |
-
if (isset($option['options'])) {
|
779 |
// this is container for other options
|
780 |
|
781 |
-
switch ($option['type']) {
|
782 |
case 'tab':
|
783 |
-
$collected['tabs'][$option_id] =& $option;
|
784 |
break;
|
785 |
case 'box':
|
786 |
-
$collected['boxes'][$option_id] =& $option;
|
787 |
break;
|
788 |
case 'group':
|
789 |
-
$collected['groups'][$option_id]
|
790 |
-
$collected['groups_and_options'][$option_id] =& $option;
|
791 |
break;
|
792 |
default:
|
793 |
-
trigger_error('Invalid option container type: '. $option['type'], E_USER_WARNING);
|
794 |
continue 2;
|
795 |
}
|
796 |
|
797 |
-
$collected['all'][ $option['type'] .':~:'. $option_id ] = array(
|
798 |
'type' => $option['type'],
|
799 |
'id' => $option_id,
|
800 |
'option' => &$option,
|
801 |
);
|
802 |
} elseif (
|
803 |
-
is_int($option_id)
|
804 |
&&
|
805 |
-
is_array($option)
|
806 |
&&
|
807 |
/**
|
808 |
* make sure the array key was generated automatically
|
809 |
* and it's not an associative array with numeric keys created like this: $options[1] = array();
|
810 |
*/
|
811 |
-
isset($options[0])
|
812 |
) {
|
813 |
/**
|
814 |
* Array "without key" containing options.
|
@@ -834,22 +876,22 @@ function fw_collect_first_level_options(&$collected, &$options) {
|
|
834 |
* ),
|
835 |
* )
|
836 |
*/
|
837 |
-
fw_collect_first_level_options($collected, $option);
|
838 |
-
} elseif (isset($option['type'])) {
|
839 |
// simple option, last possible level in options array
|
840 |
-
$collected['options'][$option_id]
|
841 |
-
$collected['groups_and_options'][$option_id] =& $option;
|
842 |
|
843 |
-
$collected['all'][ 'option' .':~:'. $option_id ] = array(
|
844 |
'type' => 'option',
|
845 |
'id' => $option_id,
|
846 |
'option' => &$option,
|
847 |
);
|
848 |
} else {
|
849 |
-
trigger_error('Invalid option: '. $option_id, E_USER_WARNING);
|
850 |
}
|
851 |
}
|
852 |
-
unset($option);
|
853 |
}
|
854 |
|
855 |
/**
|
@@ -858,7 +900,7 @@ function fw_collect_first_level_options(&$collected, &$options) {
|
|
858 |
* @param array $settings
|
859 |
* @param array $_recursion_data (private) for internal use
|
860 |
*/
|
861 |
-
function fw_collect_options(&$result, &$options, $settings = array(), $_recursion_data = array()) {
|
862 |
static $default_settings = array(
|
863 |
/**
|
864 |
* @type bool Wrap the result/collected options in arrays will useful info
|
@@ -879,15 +921,15 @@ function fw_collect_options(&$result, &$options, $settings = array(), $_recursio
|
|
879 |
* // Warning: There can be options and containers with the same id (array key will be replaced)
|
880 |
* )
|
881 |
*/
|
882 |
-
'info_wrapper'
|
883 |
/**
|
884 |
* @type int Nested options level limit. For e.g. use 1 to collect only first level. 0 is for unlimited.
|
885 |
*/
|
886 |
-
'limit_level'
|
887 |
/**
|
888 |
* @type false|array('option-type', ...) Empty array will skip all types
|
889 |
*/
|
890 |
-
'limit_option_types'
|
891 |
/**
|
892 |
* @type false|array('container-type', ...) Empty array will skip all types
|
893 |
*/
|
@@ -895,40 +937,41 @@ function fw_collect_options(&$result, &$options, $settings = array(), $_recursio
|
|
895 |
/**
|
896 |
* @type int Limit the number of options that will be collected
|
897 |
*/
|
898 |
-
'limit'
|
899 |
/**
|
900 |
* @type callable Executed on each collected option
|
901 |
* @since 2.6.0
|
902 |
*/
|
903 |
-
'callback'
|
904 |
);
|
905 |
|
906 |
static $access_key = null;
|
907 |
|
908 |
-
if (empty($options)) {
|
909 |
return;
|
910 |
}
|
911 |
|
912 |
-
if (empty($_recursion_data)) {
|
913 |
-
if (is_null($access_key)) {
|
914 |
-
$access_key = new FW_Access_Key('fw_collect_options');
|
915 |
}
|
916 |
|
917 |
-
$settings = array_merge($default_settings, $settings);
|
918 |
|
919 |
$_recursion_data = array(
|
920 |
-
'level'
|
921 |
'access_key' => $access_key,
|
922 |
// todo: maybe add 'parent' => array('id' => '{id}', 'type' => 'container|option') ?
|
923 |
);
|
924 |
-
} elseif (!(
|
925 |
-
isset($_recursion_data['access_key'])
|
926 |
&&
|
927 |
-
($_recursion_data['access_key'] instanceof FW_Access_Key)
|
928 |
&&
|
929 |
-
($_recursion_data['access_key']->get_key() === 'fw_collect_options')
|
930 |
-
)
|
931 |
-
|
|
|
932 |
}
|
933 |
|
934 |
if (
|
@@ -939,17 +982,17 @@ function fw_collect_options(&$result, &$options, $settings = array(), $_recursio
|
|
939 |
return;
|
940 |
}
|
941 |
|
942 |
-
foreach ($options as $option_id => &$option) {
|
943 |
-
if (isset($option['options'])) { // this is a container
|
944 |
do {
|
945 |
if (
|
946 |
-
is_array($settings['limit_container_types'])
|
947 |
&&
|
948 |
(
|
949 |
// Customizer options can contain options with not existing or empty $option['type']
|
950 |
-
empty($option['type'])
|
951 |
||
|
952 |
-
!in_array($option['type'], $settings['limit_container_types'])
|
953 |
)
|
954 |
) {
|
955 |
break;
|
@@ -958,47 +1001,50 @@ function fw_collect_options(&$result, &$options, $settings = array(), $_recursio
|
|
958 |
if (
|
959 |
$settings['limit']
|
960 |
&&
|
961 |
-
count($result) >= $settings['limit']
|
962 |
) {
|
963 |
return;
|
964 |
}
|
965 |
|
966 |
-
if ($settings['info_wrapper']) {
|
967 |
-
$result['container:'. $option_id] = array(
|
968 |
'group' => 'container',
|
969 |
'id' => $option_id,
|
970 |
'option' => &$option,
|
971 |
'level' => $_recursion_data['level'],
|
972 |
);
|
973 |
} else {
|
974 |
-
$result[$option_id] = &$option;
|
975 |
}
|
976 |
|
977 |
-
if ($settings['callback']) {
|
978 |
-
call_user_func_array($settings['callback'],
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
|
|
|
|
|
|
983 |
}
|
984 |
-
} while(false);
|
985 |
|
986 |
fw_collect_options(
|
987 |
$result,
|
988 |
$option['options'],
|
989 |
$settings,
|
990 |
-
array_merge($_recursion_data, array('level' => $_recursion_data['level'] + 1))
|
991 |
);
|
992 |
} elseif (
|
993 |
-
is_int($option_id)
|
994 |
&&
|
995 |
-
is_array($option)
|
996 |
&&
|
997 |
/**
|
998 |
* make sure the array key was generated automatically
|
999 |
* and it's not an associative array with numeric keys created like this: $options[1] = array();
|
1000 |
*/
|
1001 |
-
isset($options[0])
|
1002 |
) {
|
1003 |
/**
|
1004 |
* Array "without key" containing options.
|
@@ -1024,12 +1070,12 @@ function fw_collect_options(&$result, &$options, $settings = array(), $_recursio
|
|
1024 |
* ),
|
1025 |
* )
|
1026 |
*/
|
1027 |
-
fw_collect_options($result, $option, $settings, $_recursion_data);
|
1028 |
-
} elseif (isset($option['type'])) { // option
|
1029 |
if (
|
1030 |
-
is_array($settings['limit_option_types'])
|
1031 |
&&
|
1032 |
-
!in_array($option['type'], $settings['limit_option_types'])
|
1033 |
) {
|
1034 |
continue;
|
1035 |
}
|
@@ -1037,31 +1083,34 @@ function fw_collect_options(&$result, &$options, $settings = array(), $_recursio
|
|
1037 |
if (
|
1038 |
$settings['limit']
|
1039 |
&&
|
1040 |
-
count($result) >= $settings['limit']
|
1041 |
) {
|
1042 |
return;
|
1043 |
}
|
1044 |
|
1045 |
-
if ($settings['info_wrapper']) {
|
1046 |
-
$result['option:'. $option_id] = array(
|
1047 |
'group' => 'option',
|
1048 |
'id' => $option_id,
|
1049 |
'option' => &$option,
|
1050 |
'level' => $_recursion_data['level'],
|
1051 |
);
|
1052 |
} else {
|
1053 |
-
$result[$option_id] = &$option;
|
1054 |
}
|
1055 |
|
1056 |
-
if ($settings['callback']) {
|
1057 |
-
call_user_func_array($settings['callback'],
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
|
|
|
|
|
|
1062 |
}
|
1063 |
} else {
|
1064 |
-
trigger_error('Invalid option: '. $option_id, E_USER_WARNING);
|
1065 |
}
|
1066 |
}
|
1067 |
}
|
@@ -1069,26 +1118,28 @@ function fw_collect_options(&$result, &$options, $settings = array(), $_recursio
|
|
1069 |
/**
|
1070 |
* Get correct values from input (POST) for given options
|
1071 |
* This values can be saved in db then replaced with $option['value'] for each option
|
|
|
1072 |
* @param array $options
|
1073 |
* @param array $input_array
|
|
|
1074 |
* @return array Values
|
1075 |
*/
|
1076 |
-
function fw_get_options_values_from_input(array $options, $input_array = null) {
|
1077 |
-
if (!is_array($input_array)) {
|
1078 |
-
$input_array = FW_Request::POST(fw()->backend->get_options_name_attr_prefix());
|
1079 |
}
|
1080 |
|
1081 |
$values = array();
|
1082 |
|
1083 |
-
foreach (fw_extract_only_options($options) as $id => $option) {
|
1084 |
-
$values[$id] = fw()->backend->option_type($option['type'])->get_value_from_input(
|
1085 |
$option,
|
1086 |
-
isset($input_array[$id]) ? $input_array[$id] : null
|
1087 |
);
|
1088 |
|
1089 |
-
if (is_null($values[$id])) {
|
1090 |
// do not save null values
|
1091 |
-
unset($values[$id]);
|
1092 |
}
|
1093 |
}
|
1094 |
|
@@ -1098,28 +1149,29 @@ function fw_get_options_values_from_input(array $options, $input_array = null) {
|
|
1098 |
/**
|
1099 |
* @param $attr_name
|
1100 |
* @param bool $set_mode
|
|
|
1101 |
* @return mixed
|
1102 |
*/
|
1103 |
-
function fw_html_attr_name_to_array_multi_key($attr_name, $set_mode = false) {
|
1104 |
-
if ($set_mode) {
|
1105 |
/**
|
1106 |
* The key will be used to set value in array
|
1107 |
* 'hello[world][]' -> 'hello/world/'
|
1108 |
* $array['hello']['world'][] = $value;
|
1109 |
*/
|
1110 |
-
$attr_name = str_replace('[]', '/', $attr_name);
|
1111 |
} else {
|
1112 |
/**
|
1113 |
* The key will be used to get value from array
|
1114 |
* 'hello[world][]' -> 'hello/world'
|
1115 |
* $value = $array['hello']['world'];
|
1116 |
*/
|
1117 |
-
$attr_name = str_replace('[]', '', $attr_name);
|
1118 |
}
|
1119 |
|
1120 |
-
$attr_name = str_replace('][', '/', $attr_name);
|
1121 |
-
$attr_name = str_replace('[',
|
1122 |
-
$attr_name = str_replace(']',
|
1123 |
|
1124 |
return $attr_name;
|
1125 |
}
|
@@ -1128,16 +1180,18 @@ function fw_html_attr_name_to_array_multi_key($attr_name, $set_mode = false) {
|
|
1128 |
* Used when getting some option value from serialized array saved in a custom place
|
1129 |
* and that option is unreachable for standard WordPress filters by other plugins
|
1130 |
* For e.g. that option cannot be translated by plugins, so we pass its value through this function and do the fixes
|
|
|
1131 |
* @param $value
|
|
|
1132 |
* @return array
|
1133 |
*/
|
1134 |
-
function fw_prepare_option_value($value) {
|
1135 |
-
if (empty($value)) {
|
1136 |
return $value;
|
1137 |
}
|
1138 |
|
1139 |
-
if (function_exists('qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage')) {
|
1140 |
-
$value = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage($value);
|
1141 |
}
|
1142 |
|
1143 |
return $value;
|
@@ -1150,6 +1204,7 @@ function fw_prepare_option_value($value) {
|
|
1150 |
* not a revision, auto-save or something else
|
1151 |
*
|
1152 |
* @param $post_id
|
|
|
1153 |
* @return bool
|
1154 |
*
|
1155 |
* @deprecated
|
@@ -1158,14 +1213,14 @@ function fw_prepare_option_value($value) {
|
|
1158 |
* the developers should study and understand better how it works
|
1159 |
* and handle different save cases in their scripts using wp functions
|
1160 |
*/
|
1161 |
-
function fw_is_real_post_save($post_id) {
|
1162 |
-
return !(
|
1163 |
-
wp_is_post_revision($post_id)
|
1164 |
-
|| wp_is_post_autosave($post_id)
|
1165 |
-
|| (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
|
1166 |
-
|| (defined('DOING_AJAX') && DOING_AJAX)
|
1167 |
-
|| empty($_POST)
|
1168 |
-
|| empty($_POST['post_ID'])
|
1169 |
|| $_POST['post_ID'] != $post_id
|
1170 |
);
|
1171 |
}
|
@@ -1177,25 +1232,25 @@ function fw_get_google_fonts() {
|
|
1177 |
$cache_key = 'fw_google_fonts';
|
1178 |
|
1179 |
try {
|
1180 |
-
return FW_Cache::get($cache_key);
|
1181 |
-
} catch (FW_Cache_Not_Found_Exception $e) {
|
1182 |
-
$g_fonts
|
1183 |
-
$old_fonts = include(dirname(__FILE__) .'/fw-google-fonts.json.php');
|
1184 |
-
$fonts
|
1185 |
|
1186 |
foreach ( $g_fonts['items'] as $font ) {
|
1187 |
$fonts[ $font['family'] ] = array(
|
1188 |
-
'family'
|
1189 |
'variants' => $font['variants'],
|
1190 |
-
'position' => isset($old_fonts[$font['family']])
|
1191 |
-
? $old_fonts[$font['family']]['position']
|
1192 |
: 99999
|
1193 |
);
|
1194 |
}
|
1195 |
|
1196 |
-
$fonts = apply_filters('fw_google_fonts', $fonts);
|
1197 |
|
1198 |
-
FW_Cache::set($cache_key, $fonts);
|
1199 |
|
1200 |
return $fonts;
|
1201 |
}
|
@@ -1206,14 +1261,15 @@ function fw_get_google_fonts() {
|
|
1206 |
*/
|
1207 |
function fw_get_google_fonts_v2() {
|
1208 |
$saved_data = get_option( 'fw_google_fonts', false );
|
1209 |
-
$ttl
|
1210 |
|
1211 |
if (
|
1212 |
false === $saved_data
|
1213 |
||
|
1214 |
( $saved_data['last_update'] + $ttl < time() )
|
1215 |
) {
|
1216 |
-
$response = wp_remote_get( apply_filters( 'fw_googleapis_webfonts_url',
|
|
|
1217 |
$body = wp_remote_retrieve_body( $response );
|
1218 |
|
1219 |
if (
|
@@ -1221,10 +1277,12 @@ function fw_get_google_fonts_v2() {
|
|
1221 |
&&
|
1222 |
! is_wp_error( $body ) && ! empty( $body )
|
1223 |
) {
|
1224 |
-
update_option( 'fw_google_fonts',
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
|
|
|
|
1228 |
|
1229 |
return $body;
|
1230 |
} else {
|
@@ -1232,10 +1290,12 @@ function fw_get_google_fonts_v2() {
|
|
1232 |
$saved_data['fonts'] = json_encode( array( 'items' => array() ) );
|
1233 |
}
|
1234 |
|
1235 |
-
update_option( 'fw_google_fonts',
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
|
|
|
|
1239 |
}
|
1240 |
}
|
1241 |
|
@@ -1248,31 +1308,31 @@ function fw_get_google_fonts_v2() {
|
|
1248 |
function fw_current_url() {
|
1249 |
static $url = null;
|
1250 |
|
1251 |
-
if ($url === null) {
|
1252 |
$url = 'http://';
|
1253 |
|
1254 |
-
if ($_SERVER['SERVER_NAME'] === '_') { // https://github.com/ThemeFuse/Unyson/issues/126
|
1255 |
$url .= $_SERVER['HTTP_HOST'];
|
1256 |
} else {
|
1257 |
$url .= $_SERVER['SERVER_NAME'];
|
1258 |
}
|
1259 |
|
1260 |
-
if (!in_array(intval($_SERVER['SERVER_PORT']), array(80, 443))) {
|
1261 |
-
$url .= ':'. $_SERVER['SERVER_PORT'];
|
1262 |
}
|
1263 |
|
1264 |
$url .= $_SERVER['REQUEST_URI'];
|
1265 |
|
1266 |
-
$url = set_url_scheme($url); // https fix
|
1267 |
|
1268 |
if ( is_multisite() ) {
|
1269 |
if ( defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL ) {
|
1270 |
-
$site_url = parse_url($url);
|
1271 |
|
1272 |
-
if ( isset($site_url['query']) ) {
|
1273 |
-
$url = home_url($site_url['path'] . '?' . $site_url['query']);
|
1274 |
} else {
|
1275 |
-
$url = home_url($site_url['path']);
|
1276 |
}
|
1277 |
}
|
1278 |
}
|
@@ -1281,10 +1341,10 @@ function fw_current_url() {
|
|
1281 |
return $url;
|
1282 |
}
|
1283 |
|
1284 |
-
function fw_is_valid_domain_name($domain_name) {
|
1285 |
-
return (preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name) // valid chars check
|
1286 |
-
|
1287 |
-
|
1288 |
}
|
1289 |
|
1290 |
/**
|
@@ -1292,10 +1352,11 @@ function fw_is_valid_domain_name($domain_name) {
|
|
1292 |
* Info: Cannot use default parameters because in php 5.2 encoding is not UTF-8 by default
|
1293 |
*
|
1294 |
* @param string $string
|
|
|
1295 |
* @return string
|
1296 |
*/
|
1297 |
-
function fw_htmlspecialchars($string) {
|
1298 |
-
return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
|
1299 |
}
|
1300 |
|
1301 |
/**
|
@@ -1303,21 +1364,22 @@ function fw_htmlspecialchars($string) {
|
|
1303 |
*
|
1304 |
* @param array $capabilities list of capabilities to check
|
1305 |
* @param mixed $default_value
|
|
|
1306 |
* @return string|bool|mixed
|
1307 |
* Return first capability that user can.
|
1308 |
* Else, return default value if it is not null, else return first capability from list.
|
1309 |
* Use default value false to check if user can some of the capabilities
|
1310 |
*/
|
1311 |
-
function fw_current_user_can($capabilities, $default_value = null)
|
1312 |
-
{
|
1313 |
-
|
1314 |
-
|
1315 |
-
if (current_user_can($capability))
|
1316 |
return $capability;
|
|
|
1317 |
}
|
1318 |
}
|
1319 |
|
1320 |
-
return ($default_value !== null ? $default_value : array_shift($capabilities));
|
1321 |
}
|
1322 |
|
1323 |
/**
|
@@ -1327,52 +1389,54 @@ function fw_current_user_can($capabilities, $default_value = null)
|
|
1327 |
* then you can use this string how you want, for e.g. append ' ago' => '2 minutes ago'
|
1328 |
*
|
1329 |
* @param int $seconds
|
|
|
1330 |
* @return string
|
1331 |
*/
|
1332 |
-
function fw_human_time($seconds)
|
1333 |
static $translations = null;
|
1334 |
-
if ($translations === null) {
|
1335 |
$translations = array(
|
1336 |
-
'year'
|
1337 |
-
'years'
|
1338 |
|
1339 |
-
'month'
|
1340 |
-
'months'
|
1341 |
|
1342 |
-
'week'
|
1343 |
-
'weeks'
|
1344 |
|
1345 |
-
'day'
|
1346 |
-
'days'
|
1347 |
|
1348 |
-
'hour'
|
1349 |
-
'hours'
|
1350 |
|
1351 |
-
'minute'
|
1352 |
-
'minutes'
|
1353 |
|
1354 |
-
'second'
|
1355 |
-
'seconds'
|
1356 |
);
|
1357 |
}
|
1358 |
|
1359 |
-
$tokens = array
|
1360 |
31536000 => 'year',
|
1361 |
-
2592000
|
1362 |
-
604800
|
1363 |
-
86400
|
1364 |
-
3600
|
1365 |
-
60
|
1366 |
-
1
|
1367 |
);
|
1368 |
|
1369 |
-
foreach ($tokens as $unit => $translation_key) {
|
1370 |
-
if ($seconds < $unit)
|
1371 |
continue;
|
|
|
1372 |
|
1373 |
-
$number_of_units = floor($seconds / $unit);
|
1374 |
|
1375 |
-
return $number_of_units .' '. $translations[ $translation_key . ($number_of_units != 1 ? 's' : '') ];
|
1376 |
}
|
1377 |
}
|
1378 |
|
@@ -1381,39 +1445,40 @@ function fw_human_time($seconds) {
|
|
1381 |
*
|
1382 |
* @param integer $bytes Size in bytes to convert
|
1383 |
* @param integer $precision
|
|
|
1384 |
* @return string
|
1385 |
* @since 2.4.17
|
1386 |
*/
|
1387 |
-
function fw_human_bytes($bytes, $precision = 2) {
|
1388 |
$kilobyte = 1024;
|
1389 |
$megabyte = $kilobyte * 1024;
|
1390 |
$gigabyte = $megabyte * 1024;
|
1391 |
$terabyte = $gigabyte * 1024;
|
1392 |
|
1393 |
-
if (($bytes >= 0) && ($bytes < $kilobyte)) {
|
1394 |
return $bytes . ' B';
|
1395 |
|
1396 |
-
} elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
|
1397 |
-
return round($bytes / $kilobyte, $precision) . ' KB';
|
1398 |
|
1399 |
-
} elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
|
1400 |
-
return round($bytes / $megabyte, $precision) . ' MB';
|
1401 |
|
1402 |
-
} elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
|
1403 |
-
return round($bytes / $gigabyte, $precision) . ' GB';
|
1404 |
|
1405 |
-
} elseif ($bytes >= $terabyte) {
|
1406 |
-
return round($bytes / $terabyte, $precision) . ' TB';
|
1407 |
} else {
|
1408 |
return $bytes . ' B';
|
1409 |
}
|
1410 |
}
|
1411 |
|
1412 |
-
function fw_strlen($string) {
|
1413 |
-
if (function_exists('mb_strlen')) {
|
1414 |
-
return mb_strlen($string, 'UTF-8');
|
1415 |
} else {
|
1416 |
-
return strlen($string);
|
1417 |
}
|
1418 |
}
|
1419 |
|
@@ -1424,31 +1489,31 @@ function fw_strlen($string) {
|
|
1424 |
function fw_is_post_edit() {
|
1425 |
static $result = null;
|
1426 |
|
1427 |
-
if ($result === null) {
|
1428 |
$result = false;
|
1429 |
|
1430 |
-
if (is_admin()) {
|
1431 |
if (
|
1432 |
-
empty($_POST)
|
1433 |
&&
|
1434 |
-
isset($_GET['action'])
|
1435 |
&&
|
1436 |
$_GET['action'] === 'edit'
|
1437 |
&&
|
1438 |
-
isset($_GET['post'])
|
1439 |
) {
|
1440 |
// Display Edit Post page
|
1441 |
$result = true;
|
1442 |
} elseif (
|
1443 |
-
isset($_POST['action'])
|
1444 |
&&
|
1445 |
$_POST['action'] === 'editpost'
|
1446 |
&&
|
1447 |
-
isset($_POST['post_type'])
|
1448 |
&&
|
1449 |
-
isset($_POST['post_ID'])
|
1450 |
&&
|
1451 |
-
strpos(wp_get_referer(), 'action=edit') !== false
|
1452 |
) {
|
1453 |
// Submit Edit Post page
|
1454 |
$result = true;
|
@@ -1461,12 +1526,13 @@ function fw_is_post_edit() {
|
|
1461 |
|
1462 |
/**
|
1463 |
* @param string $dirname 'foo-bar'
|
|
|
1464 |
* @return string 'Foo_Bar'
|
1465 |
*/
|
1466 |
-
function fw_dirname_to_classname($dirname) {
|
1467 |
-
$class_name = explode('-', $dirname);
|
1468 |
-
$class_name = array_map('ucfirst', $class_name);
|
1469 |
-
$class_name = implode('_', $class_name);
|
1470 |
|
1471 |
return $class_name;
|
1472 |
}
|
@@ -1476,20 +1542,21 @@ function fw_dirname_to_classname($dirname) {
|
|
1476 |
*
|
1477 |
* @param $url
|
1478 |
* @param array $args
|
|
|
1479 |
* @return bool|string
|
1480 |
*/
|
1481 |
-
function fw_oembed_get($url, $args = array()) {
|
1482 |
-
$html = wp_oembed_get($url, $args);
|
1483 |
|
1484 |
-
if (!empty($args['width']) and !empty($args['height']) and class_exists('DOMDocument') and !empty($html)) {
|
1485 |
$dom_element = new DOMDocument();
|
1486 |
-
@$dom_element->loadHTML($html);
|
1487 |
|
1488 |
-
if ($obj = $dom_element->getElementsByTagName('iframe')->item(0)) {
|
1489 |
-
$obj->setAttribute('width', $args['width']);
|
1490 |
-
$obj->setAttribute('height', $args['height']);
|
1491 |
//saveXml instead of SaveHTML for php version compatibility
|
1492 |
-
$html = $dom_element->saveXML($obj, LIBXML_NOEMPTYTAG);
|
1493 |
}
|
1494 |
}
|
1495 |
|
@@ -1506,32 +1573,32 @@ function fw_oembed_get($url, $args = array()) {
|
|
1506 |
* http://www.zimuel.it/en/strong-cryptography-in-php/
|
1507 |
* > Don't use rand() or mt_rand()
|
1508 |
*/
|
1509 |
-
function fw_secure_rand($length) {
|
1510 |
-
if (function_exists('openssl_random_pseudo_bytes')) {
|
1511 |
-
$rnd = openssl_random_pseudo_bytes($length, $strong);
|
1512 |
-
if ($strong) {
|
1513 |
return $rnd;
|
1514 |
}
|
1515 |
}
|
1516 |
|
1517 |
-
$sha ='';
|
1518 |
-
$rnd ='';
|
1519 |
|
1520 |
-
if (file_exists('/dev/urandom')) {
|
1521 |
-
$fp = fopen('/dev/urandom', 'rb');
|
1522 |
-
if ($fp) {
|
1523 |
-
if (function_exists('stream_set_read_buffer')) {
|
1524 |
-
stream_set_read_buffer($fp, 0);
|
1525 |
}
|
1526 |
-
$sha = fread($fp, $length);
|
1527 |
-
fclose($fp);
|
1528 |
}
|
1529 |
}
|
1530 |
|
1531 |
-
for ($i = 0; $i < $length; $i++) {
|
1532 |
-
$sha
|
1533 |
-
$char = mt_rand(0, 62);
|
1534 |
-
$rnd .= chr(hexdec($sha[$char]
|
1535 |
}
|
1536 |
|
1537 |
return $rnd;
|
@@ -1539,27 +1606,34 @@ function fw_secure_rand($length) {
|
|
1539 |
|
1540 |
/**
|
1541 |
* Try to make user friendly title from an id
|
|
|
1542 |
* @param string $id 'hello-world'
|
|
|
1543 |
* @return string 'Hello world'
|
1544 |
*/
|
1545 |
-
function fw_id_to_title($id) {
|
1546 |
// mb_ucfirst()
|
1547 |
-
if (function_exists('mb_strtoupper') && function_exists('mb_substr') && function_exists('mb_strlen')) {
|
1548 |
-
$id = mb_strtoupper(mb_substr($id, 0, 1, 'UTF-8'), 'UTF-8') . mb_substr(
|
|
|
|
|
|
|
1549 |
} else {
|
1550 |
-
$id = strtoupper(substr($id, 0, 1)) . substr($id, 1, strlen($id));
|
1551 |
}
|
1552 |
|
1553 |
-
return str_replace(array('_', '-'), ' ', $id);
|
1554 |
}
|
1555 |
|
1556 |
/**
|
1557 |
* Alias
|
|
|
1558 |
* @param string $extension_name
|
|
|
1559 |
* @return FW_Extension|null
|
1560 |
*/
|
1561 |
-
function fw_ext($extension_name) {
|
1562 |
-
return fw()->extensions->get($extension_name);
|
1563 |
}
|
1564 |
|
1565 |
/*
|
@@ -1571,33 +1645,35 @@ function fw_get_url_without_scheme( $url ) {
|
|
1571 |
|
1572 |
/**
|
1573 |
* Try to find file path by its uri and read the file contents
|
|
|
1574 |
* @param string $file_uri
|
|
|
1575 |
* @return bool|string false or string - the file contents
|
1576 |
*/
|
1577 |
-
function fw_read_file_by_uri($file_uri) {
|
1578 |
static $base = null;
|
1579 |
|
1580 |
-
if ($base === null) {
|
1581 |
-
$base
|
1582 |
-
$base['dir']
|
1583 |
-
$base['uri']
|
1584 |
-
$base['uri_prefix_regex'] = '/^'. preg_quote($base['uri'], '/') .'/';
|
1585 |
}
|
1586 |
|
1587 |
-
$file_rel_path = preg_replace($base['uri_prefix_regex'], '', $file_uri);
|
1588 |
|
1589 |
-
if ($base['uri'] === $file_rel_path) {
|
1590 |
// the file is not inside base dir
|
1591 |
return false;
|
1592 |
}
|
1593 |
|
1594 |
-
$file_path = $base['dir'] .'/'. $file_rel_path;
|
1595 |
|
1596 |
-
if (!file_exists($file_path)) {
|
1597 |
return false;
|
1598 |
}
|
1599 |
|
1600 |
-
return file_get_contents($file_path);
|
1601 |
}
|
1602 |
|
1603 |
/**
|
@@ -1606,18 +1682,19 @@ function fw_read_file_by_uri($file_uri) {
|
|
1606 |
*
|
1607 |
* @param string $href 'http://.../style.css'
|
1608 |
* @param null|string $contents If not specified, will try to read from $href
|
|
|
1609 |
* @return bool|string false - on failure; string - stylesheet contents
|
1610 |
*/
|
1611 |
-
function fw_make_stylesheet_portable($href, $contents = null) {
|
1612 |
-
if (is_null($contents)) {
|
1613 |
-
$contents = fw_read_file_by_uri($href);
|
1614 |
|
1615 |
-
if ($contents === false) {
|
1616 |
return false;
|
1617 |
}
|
1618 |
}
|
1619 |
|
1620 |
-
$dir_uri = dirname($href);
|
1621 |
|
1622 |
/**
|
1623 |
* Replace relative 'url(img/bg.png)'
|
@@ -1632,7 +1709,7 @@ function fw_make_stylesheet_portable($href, $contents = null) {
|
|
1632 |
*/
|
1633 |
$contents = preg_replace(
|
1634 |
'/url\s*\((?!\s*[\'"]?(?:\/|data\:|\#|(?:https?:)?\/\/))\s*([\'"])?/',
|
1635 |
-
'url($1'. $dir_uri .'/',
|
1636 |
$contents
|
1637 |
);
|
1638 |
|
@@ -1643,6 +1720,7 @@ function fw_make_stylesheet_portable($href, $contents = null) {
|
|
1643 |
* Return all images sizes register by add_image_size() merged with
|
1644 |
* WordPress default image sizes.
|
1645 |
* @link https://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes
|
|
|
1646 |
* @param string $size
|
1647 |
*
|
1648 |
* @return array|bool
|
@@ -1650,27 +1728,27 @@ function fw_make_stylesheet_portable($href, $contents = null) {
|
|
1650 |
function fw_get_image_sizes( $size = '' ) {
|
1651 |
global $_wp_additional_image_sizes;
|
1652 |
|
1653 |
-
$sizes
|
1654 |
$get_intermediate_image_sizes = get_intermediate_image_sizes();
|
1655 |
|
1656 |
// Create the full array with sizes and crop info
|
1657 |
-
foreach( $get_intermediate_image_sizes as $_size ) {
|
1658 |
if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
|
1659 |
-
$sizes[ $_size ]['width']
|
1660 |
$sizes[ $_size ]['height'] = get_option( $_size . '_size_h' );
|
1661 |
-
$sizes[ $_size ]['crop']
|
1662 |
} elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
|
1663 |
$sizes[ $_size ] = array(
|
1664 |
-
'width'
|
1665 |
'height' => $_wp_additional_image_sizes[ $_size ]['height'],
|
1666 |
-
'crop'
|
1667 |
);
|
1668 |
}
|
1669 |
}
|
1670 |
|
1671 |
// Get only 1 size if found
|
1672 |
if ( $size ) {
|
1673 |
-
if( isset( $sizes[ $size ] ) ) {
|
1674 |
return $sizes[ $size ];
|
1675 |
} else {
|
1676 |
return false;
|
@@ -1683,44 +1761,45 @@ function fw_get_image_sizes( $size = '' ) {
|
|
1683 |
/**
|
1684 |
* @param string $icon A string that is meant to be an icon (an image, a font icon class, or something else)
|
1685 |
* @param array Additional attributes
|
|
|
1686 |
* @return string
|
1687 |
*/
|
1688 |
-
function fw_string_to_icon_html($icon, array $attributes = array()) {
|
1689 |
if (
|
1690 |
-
preg_match('/\.(png|jpg|jpeg|gif|svg|webp)$/', $icon)
|
1691 |
||
|
1692 |
-
preg_match('/^data:image\//', $icon)
|
1693 |
) {
|
1694 |
// http://.../image.png
|
1695 |
-
$tag
|
1696 |
$attr = array(
|
1697 |
'src' => $icon,
|
1698 |
'alt' => 'icon',
|
1699 |
);
|
1700 |
-
} elseif (preg_match('/^[a-zA-Z0-9\-_ ]+$/', $icon)) {
|
1701 |
// 'font-icon font-icon-class'
|
1702 |
-
$tag
|
1703 |
$attr = array(
|
1704 |
-
'class' => trim($icon),
|
1705 |
);
|
1706 |
} else {
|
1707 |
// can't detect. maybe it's raw html '<span ...'
|
1708 |
return $icon;
|
1709 |
}
|
1710 |
|
1711 |
-
foreach ($attributes as $attr_name => $attr_val) {
|
1712 |
-
if (isset($attr[$attr_name])) {
|
1713 |
-
if ($attr_name === 'class') {
|
1714 |
-
$attr[$attr_name] .= ' '. $attr_val;
|
1715 |
} else {
|
1716 |
// ignore. do not overwrite already set attributes
|
1717 |
}
|
1718 |
} else {
|
1719 |
-
$attr[$attr_name] = (string)$attr_val;
|
1720 |
}
|
1721 |
}
|
1722 |
|
1723 |
-
return fw_html_tag($tag, $attr);
|
1724 |
}
|
1725 |
|
1726 |
/**
|
@@ -1728,27 +1807,27 @@ function fw_string_to_icon_html($icon, array $attributes = array()) {
|
|
1728 |
* @since 2.4.10
|
1729 |
*/
|
1730 |
function fw_get_json_last_error_message() {
|
1731 |
-
switch (function_exists('json_last_error') ? json_last_error() : -1) {
|
1732 |
case JSON_ERROR_NONE:
|
1733 |
return null; // __('No errors', 'fw');
|
1734 |
break;
|
1735 |
case JSON_ERROR_DEPTH:
|
1736 |
-
return __('Maximum stack depth exceeded', 'fw');
|
1737 |
break;
|
1738 |
case JSON_ERROR_STATE_MISMATCH:
|
1739 |
-
return __('Underflow or the modes mismatch', 'fw');
|
1740 |
break;
|
1741 |
case JSON_ERROR_CTRL_CHAR:
|
1742 |
-
return __('Unexpected control character found', 'fw');
|
1743 |
break;
|
1744 |
case JSON_ERROR_SYNTAX:
|
1745 |
-
return __('Syntax error, malformed JSON', 'fw');
|
1746 |
break;
|
1747 |
case JSON_ERROR_UTF8:
|
1748 |
-
return __('Malformed UTF-8 characters, possibly incorrectly encoded', 'fw');
|
1749 |
break;
|
1750 |
default:
|
1751 |
-
return __('Unknown error', 'fw');
|
1752 |
break;
|
1753 |
}
|
1754 |
}
|
@@ -1807,36 +1886,71 @@ if ( ! function_exists( 'fw_resize' ) ) {
|
|
1807 |
|
1808 |
/**
|
1809 |
* fw_get_path_url( dirname(__FILE__) .'/test.css' ) --> http://site.url/path/to/test.css
|
|
|
1810 |
* @param string $path
|
|
|
1811 |
* @return string|null
|
1812 |
* @since 2.6.11
|
1813 |
*/
|
1814 |
-
function fw_get_path_url($path) {
|
1815 |
try {
|
1816 |
-
$paths_to_urls = FW_Cache::get($cache_key = 'fw:paths_to_urls');
|
1817 |
-
} catch (FW_Cache_Not_Found_Exception $e) {
|
1818 |
$wp_upload_dir = wp_upload_dir();
|
1819 |
|
1820 |
$paths_to_urls = array(
|
1821 |
-
fw_fix_path(WP_PLUGIN_DIR)
|
1822 |
-
fw_fix_path(get_theme_root())
|
1823 |
-
fw_fix_path($wp_upload_dir['basedir']) => $wp_upload_dir['baseurl'],
|
1824 |
);
|
1825 |
|
1826 |
-
if (is_multisite() && WPMU_PLUGIN_DIR) {
|
1827 |
-
$paths_to_urls[ fw_fix_path(WPMU_PLUGIN_DIR) ] = WPMU_PLUGIN_URL;
|
1828 |
}
|
1829 |
|
1830 |
-
FW_Cache::set($cache_key, $paths_to_urls);
|
1831 |
}
|
1832 |
|
1833 |
-
$path = fw_fix_path($path);
|
1834 |
|
1835 |
-
foreach ($paths_to_urls as $_path => $_url) {
|
1836 |
-
if (preg_match($regex = '/^'. preg_quote($_path, '/') .'($|\/)/', $path)) {
|
1837 |
-
return $_url .'/'. preg_replace($regex, '', $path);
|
1838 |
}
|
1839 |
}
|
1840 |
|
1841 |
return null;
|
1842 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if ( ! defined( 'FW' ) ) {
|
2 |
+
die( 'Forbidden' );
|
3 |
+
}
|
4 |
// Useful functions
|
5 |
|
6 |
/**
|
7 |
* Convert to Unix style directory separators
|
8 |
*/
|
9 |
+
function fw_fix_path( $path ) {
|
10 |
+
$windows_network_path = isset( $_SERVER['windir'] ) && in_array( substr( $path, 0, 2 ),
|
11 |
+
array( '//', '\\\\' ),
|
12 |
+
true );
|
13 |
+
$fixed_path = untrailingslashit( str_replace( array( '//', '\\' ), array( '/', '/' ), $path ) );
|
14 |
|
15 |
+
if ( empty( $fixed_path ) && ! empty( $path ) ) {
|
16 |
$fixed_path = '/';
|
17 |
}
|
18 |
|
19 |
+
if ( $windows_network_path ) {
|
20 |
+
$fixed_path = '//' . ltrim( $fixed_path, '/' );
|
21 |
}
|
22 |
|
23 |
return $fixed_path;
|
25 |
|
26 |
/**
|
27 |
* Relative path of the framework customizations directory
|
28 |
+
*
|
29 |
* @param string $append
|
30 |
+
*
|
31 |
* @return string
|
32 |
*/
|
33 |
+
function fw_get_framework_customizations_dir_rel_path( $append = '' ) {
|
34 |
try {
|
35 |
+
$dir = FW_Cache::get( $cache_key = 'fw_customizations_dir_rel_path' );
|
36 |
+
} catch ( FW_Cache_Not_Found_Exception $e ) {
|
37 |
FW_Cache::set(
|
38 |
$cache_key,
|
39 |
+
$dir = apply_filters( 'fw_framework_customizations_dir_rel_path', '/framework-customizations' )
|
40 |
);
|
41 |
}
|
42 |
|
47 |
{
|
48 |
/**
|
49 |
* Full path to the child-theme framework customizations directory
|
50 |
+
*
|
51 |
* @param string $rel_path
|
52 |
+
*
|
53 |
* @return null|string
|
54 |
*/
|
55 |
+
function fw_get_stylesheet_customizations_directory( $rel_path = '' ) {
|
56 |
+
if ( is_child_theme() ) {
|
57 |
+
return get_stylesheet_directory() . fw_get_framework_customizations_dir_rel_path( $rel_path );
|
58 |
} else {
|
59 |
// check is_child_theme() before using this function
|
60 |
return null;
|
63 |
|
64 |
/**
|
65 |
* URI to the child-theme framework customizations directory
|
66 |
+
*
|
67 |
* @param string $rel_path
|
68 |
+
*
|
69 |
* @return null|string
|
70 |
*/
|
71 |
+
function fw_get_stylesheet_customizations_directory_uri( $rel_path = '' ) {
|
72 |
+
if ( is_child_theme() ) {
|
73 |
+
return get_stylesheet_directory_uri() . fw_get_framework_customizations_dir_rel_path( $rel_path );
|
74 |
} else {
|
75 |
// check is_child_theme() before using this function
|
76 |
return null;
|
82 |
{
|
83 |
/**
|
84 |
* Full path to the parent-theme framework customizations directory
|
85 |
+
*
|
86 |
* @param string $rel_path
|
87 |
+
*
|
88 |
* @return string
|
89 |
*/
|
90 |
+
function fw_get_template_customizations_directory( $rel_path = '' ) {
|
91 |
try {
|
92 |
+
$dir = FW_Cache::get( $cache_key = 'fw_template_customizations_dir' );
|
93 |
+
} catch ( FW_Cache_Not_Found_Exception $e ) {
|
94 |
FW_Cache::set(
|
95 |
$cache_key,
|
96 |
$dir = get_template_directory() . fw_get_framework_customizations_dir_rel_path()
|
102 |
|
103 |
/**
|
104 |
* URI to the parent-theme framework customizations directory
|
105 |
+
*
|
106 |
* @param string $rel_path
|
107 |
+
*
|
108 |
* @return string
|
109 |
*/
|
110 |
+
function fw_get_template_customizations_directory_uri( $rel_path = '' ) {
|
111 |
try {
|
112 |
+
$dir = FW_Cache::get( $cache_key = 'fw_template_customizations_dir_uri' );
|
113 |
+
} catch ( FW_Cache_Not_Found_Exception $e ) {
|
114 |
FW_Cache::set(
|
115 |
$cache_key,
|
116 |
$dir = get_template_directory_uri() . fw_get_framework_customizations_dir_rel_path()
|
125 |
{
|
126 |
/**
|
127 |
* Full path to the parent-theme/framework directory
|
128 |
+
*
|
129 |
* @param string $rel_path
|
130 |
+
*
|
131 |
* @return string
|
132 |
*/
|
133 |
+
function fw_get_framework_directory( $rel_path = '' ) {
|
134 |
try {
|
135 |
+
$dir = FW_Cache::get( $cache_key = 'fw_framework_dir' );
|
136 |
+
} catch ( FW_Cache_Not_Found_Exception $e ) {
|
137 |
FW_Cache::set(
|
138 |
$cache_key,
|
139 |
$dir = apply_filters(
|
140 |
'fw_framework_directory',
|
141 |
+
fw_fix_path( dirname( dirname( __FILE__ ) ) ) // double dirname() to remove '/helpers', use parent dir
|
142 |
)
|
143 |
);
|
144 |
}
|
148 |
|
149 |
/**
|
150 |
* URI to the parent-theme/framework directory
|
151 |
+
*
|
152 |
* @param string $rel_path
|
153 |
+
*
|
154 |
* @return string
|
155 |
*/
|
156 |
+
function fw_get_framework_directory_uri( $rel_path = '' ) {
|
157 |
try {
|
158 |
+
$uri = FW_Cache::get( $cache_key = 'fw_framework_dir_uri' );
|
159 |
+
} catch ( FW_Cache_Not_Found_Exception $e ) {
|
160 |
FW_Cache::set(
|
161 |
$cache_key,
|
162 |
$uri = apply_filters(
|
163 |
'fw_framework_directory_uri',
|
164 |
+
( $uri = fw_get_path_url( fw_get_framework_directory() ) )
|
165 |
? $uri
|
166 |
: get_template_directory_uri() . '/framework'
|
167 |
)
|
179 |
* @param array|object $array_or_object
|
180 |
* @param null|mixed $default_value
|
181 |
* @param string $keys_delimiter
|
182 |
+
*
|
183 |
* @return null|mixed
|
184 |
*/
|
185 |
+
function fw_akg( $keys, $array_or_object, $default_value = null, $keys_delimiter = '/' ) {
|
186 |
+
if ( ! is_array( $keys ) ) {
|
187 |
$keys = explode( $keys_delimiter, (string) $keys );
|
188 |
}
|
189 |
|
190 |
+
$array_or_object = fw_call( $array_or_object );
|
191 |
+
|
192 |
+
$key_or_property = array_shift( $keys );
|
193 |
+
if ( $key_or_property === null ) {
|
194 |
return $default_value;
|
195 |
}
|
196 |
|
197 |
+
$is_object = is_object( $array_or_object );
|
198 |
|
199 |
+
if ( $is_object ) {
|
200 |
+
if ( ! property_exists( $array_or_object, $key_or_property ) ) {
|
201 |
return $default_value;
|
202 |
}
|
203 |
} else {
|
204 |
+
if ( ! is_array( $array_or_object ) || ! array_key_exists( $key_or_property, $array_or_object ) ) {
|
205 |
return $default_value;
|
206 |
}
|
207 |
}
|
208 |
|
209 |
+
if ( isset( $keys[0] ) ) { // not used count() for performance reasons
|
210 |
+
if ( $is_object ) {
|
211 |
+
return fw_akg( $keys, $array_or_object->{$key_or_property}, $default_value );
|
212 |
} else {
|
213 |
+
return fw_akg( $keys, $array_or_object[ $key_or_property ], $default_value );
|
214 |
}
|
215 |
} else {
|
216 |
+
if ( $is_object ) {
|
217 |
return $array_or_object->{$key_or_property};
|
218 |
} else {
|
219 |
+
return $array_or_object[ $key_or_property ];
|
220 |
}
|
221 |
}
|
222 |
}
|
229 |
* @param array|object $array_or_object
|
230 |
* @param string $keys_delimiter
|
231 |
*/
|
232 |
+
function fw_aks( $keys, $value, &$array_or_object, $keys_delimiter = '/' ) {
|
233 |
+
if ( ! is_array( $keys ) ) {
|
234 |
+
$keys = explode( $keys_delimiter, (string) $keys );
|
235 |
}
|
236 |
|
237 |
+
$key_or_property = array_shift( $keys );
|
238 |
+
if ( $key_or_property === null ) {
|
239 |
return;
|
240 |
}
|
241 |
|
242 |
+
$is_object = is_object( $array_or_object );
|
243 |
|
244 |
+
if ( $is_object ) {
|
245 |
+
if ( ! property_exists( $array_or_object, $key_or_property )
|
246 |
+
|| ! ( is_array( $array_or_object->{$key_or_property} ) || is_object( $array_or_object->{$key_or_property} ) )
|
247 |
) {
|
248 |
+
if ( $key_or_property === '' ) {
|
249 |
// this happens when use 'empty keys' like: abc/d/e////i/j//foo/
|
250 |
+
trigger_error( 'Cannot push value to object like in array ($arr[] = $val)', E_USER_WARNING );
|
251 |
} else {
|
252 |
$array_or_object->{$key_or_property} = array();
|
253 |
}
|
254 |
}
|
255 |
} else {
|
256 |
+
if ( ! is_array( $array_or_object ) ) {
|
257 |
$array_or_object = array();
|
258 |
}
|
259 |
|
260 |
+
if ( ! array_key_exists( $key_or_property,
|
261 |
+
$array_or_object ) || ! is_array( $array_or_object[ $key_or_property ] )
|
262 |
+
) {
|
263 |
+
if ( $key_or_property === '' ) {
|
264 |
// this happens when use 'empty keys' like: abc.d.e....i.j..foo.
|
265 |
$array_or_object[] = array();
|
266 |
|
267 |
// get auto created key (last)
|
268 |
+
end( $array_or_object );
|
269 |
+
$key_or_property = key( $array_or_object );
|
270 |
} else {
|
271 |
+
$array_or_object[ $key_or_property ] = array();
|
272 |
}
|
273 |
}
|
274 |
}
|
275 |
|
276 |
+
if ( isset( $keys[0] ) ) { // not used count() for performance reasons
|
277 |
+
if ( $is_object ) {
|
278 |
+
fw_aks( $keys, $value, $array_or_object->{$key_or_property} );
|
279 |
} else {
|
280 |
+
fw_aks( $keys, $value, $array_or_object[ $key_or_property ] );
|
281 |
}
|
282 |
} else {
|
283 |
+
if ( $is_object ) {
|
284 |
$array_or_object->{$key_or_property} = $value;
|
285 |
} else {
|
286 |
+
$array_or_object[ $key_or_property ] = $value;
|
287 |
}
|
288 |
}
|
289 |
}
|
295 |
* @param array|object $array_or_object
|
296 |
* @param string $keys_delimiter
|
297 |
*/
|
298 |
+
function fw_aku( $keys, &$array_or_object, $keys_delimiter = '/' ) {
|
299 |
+
if ( ! is_array( $keys ) ) {
|
300 |
+
$keys = explode( $keys_delimiter, (string) $keys );
|
301 |
}
|
302 |
|
303 |
+
$key_or_property = array_shift( $keys );
|
304 |
+
if ( $key_or_property === null || $key_or_property === '' ) {
|
305 |
return;
|
306 |
}
|
307 |
|
308 |
+
$is_object = is_object( $array_or_object );
|
309 |
|
310 |
+
if ( $is_object ) {
|
311 |
+
if ( ! property_exists( $array_or_object, $key_or_property ) ) {
|
312 |
return;
|
313 |
}
|
314 |
} else {
|
315 |
+
if ( ! is_array( $array_or_object ) || ! array_key_exists( $key_or_property, $array_or_object ) ) {
|
316 |
return;
|
317 |
}
|
318 |
}
|
319 |
|
320 |
+
if ( isset( $keys[0] ) ) { // not used count() for performance reasons
|
321 |
+
if ( $is_object ) {
|
322 |
+
fw_aku( $keys, $array_or_object->{$key_or_property} );
|
323 |
} else {
|
324 |
+
fw_aku( $keys, $array_or_object[ $key_or_property ] );
|
325 |
}
|
326 |
} else {
|
327 |
+
if ( $is_object ) {
|
328 |
+
unset( $array_or_object->{$key_or_property} );
|
329 |
} else {
|
330 |
+
unset( $array_or_object[ $key_or_property ] );
|
331 |
}
|
332 |
|
333 |
return;
|
338 |
* Generate random unique md5
|
339 |
*/
|
340 |
function fw_rand_md5() {
|
341 |
+
return md5( time() . '-' . uniqid( rand(), true ) . '-' . mt_rand( 1, 1000 ) );
|
342 |
}
|
343 |
|
344 |
function fw_unique_increment() {
|
345 |
static $i = 0;
|
346 |
+
|
347 |
+
return ++ $i;
|
348 |
}
|
349 |
|
350 |
/**
|
352 |
*
|
353 |
* @param mixed $value Value to debug
|
354 |
*/
|
355 |
+
function fw_print( $value ) {
|
356 |
static $first_time = true;
|
357 |
|
358 |
+
if ( $first_time ) {
|
359 |
ob_start();
|
360 |
echo '<style type="text/css">
|
361 |
div.fw_print_r {
|
396 |
border-width: 0;
|
397 |
}
|
398 |
</style>';
|
399 |
+
echo str_replace( array( ' ', "\n" ), '', ob_get_clean() );
|
400 |
|
401 |
$first_time = false;
|
402 |
}
|
403 |
|
404 |
+
if ( func_num_args() == 1 ) {
|
405 |
echo '<div class="fw_print_r"><pre>';
|
406 |
+
echo fw_htmlspecialchars( FW_Dumper::dump( $value ) );
|
407 |
echo '</pre></div>';
|
408 |
} else {
|
409 |
echo '<div class="fw_print_r_group">';
|
410 |
+
foreach ( func_get_args() as $param ) {
|
411 |
+
fw_print( $param );
|
412 |
}
|
413 |
echo '</div>';
|
414 |
}
|
420 |
* @param string $tag Tag name
|
421 |
* @param array $attr Tag attributes
|
422 |
* @param bool|string $end Append closing tag. Also accepts body content
|
423 |
+
*
|
424 |
* @return string The tag's html
|
425 |
*/
|
426 |
+
function fw_html_tag( $tag, $attr = array(), $end = false ) {
|
427 |
+
$html = '<' . $tag . ' ' . fw_attr_to_html( $attr );
|
428 |
|
429 |
+
if ( $end === true ) {
|
430 |
# <script></script>
|
431 |
+
$html .= '></' . $tag . '>';
|
432 |
+
} else if ( $end === false ) {
|
433 |
# <br/>
|
434 |
$html .= '/>';
|
435 |
} else {
|
436 |
# <div>content</div>
|
437 |
+
$html .= '>' . $end . '</' . $tag . '>';
|
438 |
}
|
439 |
|
440 |
return $html;
|
442 |
|
443 |
/**
|
444 |
* Generate attributes string for html tag
|
445 |
+
*
|
446 |
* @param array $attr_array array('href' => '/', 'title' => 'Test')
|
447 |
+
*
|
448 |
* @return string 'href="/" title="Test"'
|
449 |
*/
|
450 |
+
function fw_attr_to_html( array $attr_array ) {
|
451 |
$html_attr = '';
|
452 |
|
453 |
+
foreach ( $attr_array as $attr_name => $attr_val ) {
|
454 |
+
if ( $attr_val === false ) {
|
455 |
continue;
|
456 |
}
|
457 |
|
458 |
+
$html_attr .= $attr_name . '="' . fw_htmlspecialchars( $attr_val ) . '" ';
|
459 |
}
|
460 |
|
461 |
return $html_attr;
|
464 |
/**
|
465 |
* Strip slashes from values, and from keys if magic_quotes_gpc = On
|
466 |
*/
|
467 |
+
function fw_stripslashes_deep_keys( $value ) {
|
468 |
static $magic_quotes = null;
|
469 |
+
if ( $magic_quotes === null ) {
|
470 |
$magic_quotes = get_magic_quotes_gpc();
|
471 |
}
|
472 |
|
473 |
+
if ( is_array( $value ) ) {
|
474 |
+
if ( $magic_quotes ) {
|
475 |
$new_value = array();
|
476 |
+
foreach ( $value as $key => $val ) {
|
477 |
+
$new_value[ is_string( $key ) ? stripslashes( $key ) : $key ] = fw_stripslashes_deep_keys( $val );
|
478 |
}
|
479 |
$value = $new_value;
|
480 |
+
unset( $new_value );
|
481 |
} else {
|
482 |
+
$value = array_map( 'fw_stripslashes_deep_keys', $value );
|
483 |
}
|
484 |
+
} elseif ( is_object( $value ) ) {
|
485 |
+
$vars = get_object_vars( $value );
|
486 |
+
foreach ( $vars as $key => $data ) {
|
487 |
+
$value->{$key} = fw_stripslashes_deep_keys( $data );
|
488 |
}
|
489 |
+
} elseif ( is_string( $value ) ) {
|
490 |
+
$value = stripslashes( $value );
|
491 |
}
|
492 |
|
493 |
return $value;
|
496 |
/**
|
497 |
* Add slashes to values, and to keys if magic_quotes_gpc = On
|
498 |
*/
|
499 |
+
function fw_addslashes_deep_keys( $value ) {
|
500 |
static $magic_quotes = null;
|
501 |
+
if ( $magic_quotes === null ) {
|
502 |
$magic_quotes = get_magic_quotes_gpc();
|
503 |
}
|
504 |
|
505 |
+
if ( is_array( $value ) ) {
|
506 |
+
if ( $magic_quotes ) {
|
507 |
$new_value = array();
|
508 |
+
foreach ( $value as $key => $value ) {
|
509 |
+
$new_value[ is_string( $key ) ? addslashes( $key ) : $key ] = fw_addslashes_deep_keys( $value );
|
510 |
}
|
511 |
$value = $new_value;
|
512 |
+
unset( $new_value );
|
513 |
} else {
|
514 |
+
$value = array_map( 'fw_addslashes_deep_keys', $value );
|
515 |
}
|
516 |
+
} elseif ( is_object( $value ) ) {
|
517 |
+
$vars = get_object_vars( $value );
|
518 |
+
foreach ( $vars as $key => $data ) {
|
519 |
+
$value->{$key} = fw_addslashes_deep_keys( $data );
|
520 |
}
|
521 |
+
} elseif ( is_string( $value ) ) {
|
522 |
+
$value = addslashes( $value );
|
523 |
}
|
524 |
|
525 |
return $value;
|
527 |
|
528 |
/**
|
529 |
* Check if current screen pass/match give rules
|
530 |
+
*
|
531 |
* @param array $rules Rules for current screen
|
532 |
+
*
|
533 |
* @return bool
|
534 |
*/
|
535 |
+
function fw_current_screen_match( array $rules ) {
|
536 |
$available_options = array(
|
537 |
'action' => true,
|
538 |
'base' => true,
|
545 |
'taxonomy' => true,
|
546 |
);
|
547 |
|
548 |
+
if ( empty( $rules ) ) {
|
549 |
return true;
|
550 |
}
|
551 |
|
557 |
$rules
|
558 |
);
|
559 |
|
560 |
+
if ( empty( $rules['exclude'] ) && empty( $rules['only'] ) ) {
|
561 |
return true;
|
562 |
}
|
563 |
|
564 |
global $current_screen;
|
565 |
|
566 |
+
if ( gettype( $current_screen ) != 'object' ) {
|
567 |
return false;
|
568 |
}
|
569 |
|
571 |
do {
|
572 |
$only = $rules['only'];
|
573 |
|
574 |
+
if ( empty( $only ) ) {
|
575 |
break;
|
576 |
}
|
577 |
|
578 |
+
if ( ! isset( $only[0] ) ) { // if not array of arrays
|
579 |
+
$only = array( $only );
|
580 |
}
|
581 |
|
582 |
$found_one = false;
|
583 |
+
$counter = 0;
|
584 |
+
foreach ( $only as $rule ) {
|
585 |
+
if ( ! count( $rule ) ) {
|
586 |
continue;
|
587 |
}
|
588 |
|
589 |
$match = true;
|
590 |
|
591 |
+
foreach ( $rule as $r_key => $r_val ) {
|
592 |
+
if ( ! isset( $available_options[ $r_key ] ) ) {
|
593 |
continue;
|
594 |
}
|
595 |
|
596 |
+
if ( gettype( $r_val ) != 'array' ) {
|
597 |
+
$r_val = array( $r_val );
|
598 |
}
|
599 |
|
600 |
+
$counter ++;
|
601 |
|
602 |
+
if ( ! in_array( $current_screen->{$r_key}, $r_val ) ) {
|
603 |
$match = false;
|
604 |
break;
|
605 |
}
|
606 |
}
|
607 |
|
608 |
+
if ( $match ) {
|
609 |
$found_one = true;
|
610 |
break;
|
611 |
}
|
612 |
}
|
613 |
|
614 |
+
if ( ! $found_one && $counter ) {
|
615 |
return false;
|
616 |
}
|
617 |
+
} while ( false );
|
618 |
|
619 |
// check if current screen passes the "exclude" rules
|
620 |
do {
|
621 |
$exclude = $rules['exclude'];
|
622 |
|
623 |
+
if ( empty( $exclude ) ) {
|
624 |
break;
|
625 |
}
|
626 |
|
627 |
+
if ( ! isset( $exclude[0] ) ) { // if not array of arrays
|
628 |
+
$exclude = array( $exclude );
|
629 |
}
|
630 |
|
631 |
+
foreach ( $exclude as $rule ) {
|
632 |
+
if ( ! count( $rule ) ) {
|
633 |
continue;
|
634 |
}
|
635 |
|
636 |
$match = true;
|
637 |
$counter = 0;
|
638 |
|
639 |
+
foreach ( $rule as $r_key => $r_val ) {
|
640 |
+
if ( ! isset( $available_options[ $r_key ] ) ) {
|
641 |
continue;
|
642 |
}
|
643 |
|
644 |
+
if ( gettype( $r_val ) != 'array' ) {
|
645 |
+
$r_val = array( $r_val );
|
646 |
}
|
647 |
|
648 |
+
$counter ++;
|
649 |
|
650 |
+
if ( ! in_array( $current_screen->{$r_key}, $r_val ) ) {
|
651 |
$match = false;
|
652 |
break;
|
653 |
}
|
654 |
}
|
655 |
|
656 |
+
if ( $match && $counter ) {
|
657 |
return false;
|
658 |
}
|
659 |
}
|
660 |
+
} while ( false );
|
661 |
|
662 |
return true;
|
663 |
}
|
666 |
* Search relative path in child then in parent theme directory and return URI
|
667 |
*
|
668 |
* @param string $rel_path '/some/path_to_dir' or '/some/path_to_file.php'
|
669 |
+
*
|
670 |
* @return string URI
|
671 |
*/
|
672 |
+
function fw_locate_theme_path_uri( $rel_path ) {
|
673 |
+
if ( is_child_theme() && file_exists( get_stylesheet_directory() . $rel_path ) ) {
|
674 |
return get_stylesheet_directory_uri() . $rel_path;
|
675 |
+
} elseif ( file_exists( get_template_directory() . $rel_path ) ) {
|
676 |
return get_template_directory_uri() . $rel_path;
|
677 |
} else {
|
678 |
+
return 'about:blank#theme-file-not-found:' . $rel_path;
|
679 |
}
|
680 |
}
|
681 |
|
683 |
* Search relative path in child then in parent theme directory and return full path
|
684 |
*
|
685 |
* @param string $rel_path '/some/path_to_dir' or '/some/path_to_file.php'
|
686 |
+
*
|
687 |
* @return string URI
|
688 |
*/
|
689 |
+
function fw_locate_theme_path( $rel_path ) {
|
690 |
+
if ( is_child_theme() && file_exists( get_stylesheet_directory() . $rel_path ) ) {
|
691 |
return get_stylesheet_directory() . $rel_path;
|
692 |
+
} elseif ( file_exists( get_template_directory() . $rel_path ) ) {
|
693 |
return get_template_directory() . $rel_path;
|
694 |
} else {
|
695 |
return false;
|
702 |
* https://github.com/ThemeFuse/Unyson/commit/07be8b1f4b50eaf0f1f7e85ea1c6912a0415d241#diff-cf866bf08b8f747e3120221a6b1b07cfR48
|
703 |
* it throws fatal error because this function here is defined after that
|
704 |
*/
|
705 |
+
if ( ! function_exists( 'fw_render_view' ) ):
|
706 |
+
/**
|
707 |
+
* Safe render a view and return html
|
708 |
+
* In view will be accessible only passed variables
|
709 |
+
* Use this function to not include files directly and to not give access to current context variables (like $this)
|
710 |
+
*
|
711 |
+
* @param string $file_path
|
712 |
+
* @param array $view_variables
|
713 |
+
* @param bool $return In some cases, for memory saving reasons, you can disable the use of output buffering
|
714 |
+
*
|
715 |
+
* @return string HTML
|
716 |
+
*/
|
717 |
+
function fw_render_view( $file_path, $view_variables = array(), $return = true ) {
|
718 |
+
extract( $view_variables, EXTR_REFS );
|
719 |
+
unset( $view_variables );
|
720 |
|
721 |
+
if ( $return ) {
|
722 |
+
ob_start();
|
723 |
+
require $file_path;
|
724 |
+
|
725 |
+
return ob_get_clean();
|
726 |
+
} else {
|
727 |
+
require $file_path;
|
728 |
+
}
|
729 |
}
|
|
|
730 |
endif;
|
731 |
|
732 |
/**
|
733 |
* Safe load variables from an file
|
734 |
* Use this function to not include files directly and to not give access to current context variables (like $this)
|
735 |
+
*
|
736 |
* @param string $file_path
|
737 |
* @param array $_extract_variables Extract these from file array('variable_name' => 'default_value')
|
738 |
* @param array $_set_variables Set these to be available in file (like variables in view)
|
739 |
+
*
|
740 |
* @return array
|
741 |
*/
|
742 |
+
function fw_get_variables_from_file( $file_path, array $_extract_variables, array $_set_variables = array() ) {
|
743 |
+
extract( $_set_variables, EXTR_REFS );
|
744 |
+
unset( $_set_variables );
|
745 |
|
746 |
require $file_path;
|
747 |
|
748 |
+
foreach ( $_extract_variables as $variable_name => $default_value ) {
|
749 |
+
if ( isset( $$variable_name ) ) {
|
750 |
+
$_extract_variables[ $variable_name ] = $$variable_name;
|
751 |
}
|
752 |
}
|
753 |
|
756 |
|
757 |
/**
|
758 |
* Use this function to not include files directly and to not give access to current context variables (like $this)
|
759 |
+
*
|
760 |
* @param string $file_path
|
761 |
* @param bool $once
|
762 |
+
*
|
763 |
* @return bool If was included or not
|
764 |
*/
|
765 |
+
function fw_include_file_isolated( $file_path, $once = false ) {
|
766 |
+
if ( file_exists( $file_path ) ) {
|
767 |
if ( (bool) $once ) {
|
768 |
include_once $file_path;
|
769 |
} else {
|
770 |
include $file_path;
|
771 |
}
|
772 |
+
|
773 |
return true;
|
774 |
} else {
|
775 |
return false;
|
778 |
|
779 |
/**
|
780 |
* Extract only input options (without containers)
|
781 |
+
*
|
782 |
* @param array $options
|
783 |
+
*
|
784 |
* @return array {option_id => option}
|
785 |
*/
|
786 |
+
function fw_extract_only_options( array $options ) {
|
787 |
$collected = array();
|
788 |
|
789 |
+
fw_collect_options( $collected, $options );
|
790 |
|
791 |
return $collected;
|
792 |
}
|
793 |
|
794 |
/**
|
795 |
* Collect correct options from the first level of the array and group them
|
796 |
+
*
|
797 |
* @param array $collected Will be filled with found correct options
|
798 |
* @param array $options
|
799 |
*
|
802 |
* but this function is hardcoded only for tab,box,group.
|
803 |
* Use fw_collect_options()
|
804 |
*/
|
805 |
+
function fw_collect_first_level_options( &$collected, &$options ) {
|
806 |
+
if ( empty( $options ) ) {
|
807 |
return;
|
808 |
}
|
809 |
|
810 |
+
if ( empty( $collected ) ) {
|
811 |
$collected['tabs'] =
|
812 |
$collected['boxes'] =
|
813 |
$collected['groups'] =
|
816 |
$collected['all'] = array();
|
817 |
}
|
818 |
|
819 |
+
foreach ( $options as $option_id => &$option ) {
|
820 |
+
if ( isset( $option['options'] ) ) {
|
821 |
// this is container for other options
|
822 |
|
823 |
+
switch ( $option['type'] ) {
|
824 |
case 'tab':
|
825 |
+
$collected['tabs'][ $option_id ] =& $option;
|
826 |
break;
|
827 |
case 'box':
|
828 |
+
$collected['boxes'][ $option_id ] =& $option;
|
829 |
break;
|
830 |
case 'group':
|
831 |
+
$collected['groups'][ $option_id ] =& $option;
|
832 |
+
$collected['groups_and_options'][ $option_id ] =& $option;
|
833 |
break;
|
834 |
default:
|
835 |
+
trigger_error( 'Invalid option container type: ' . $option['type'], E_USER_WARNING );
|
836 |
continue 2;
|
837 |
}
|
838 |
|
839 |
+
$collected['all'][ $option['type'] . ':~:' . $option_id ] = array(
|
840 |
'type' => $option['type'],
|
841 |
'id' => $option_id,
|
842 |
'option' => &$option,
|
843 |
);
|
844 |
} elseif (
|
845 |
+
is_int( $option_id )
|
846 |
&&
|
847 |
+
is_array( $option )
|
848 |
&&
|
849 |
/**
|
850 |
* make sure the array key was generated automatically
|
851 |
* and it's not an associative array with numeric keys created like this: $options[1] = array();
|
852 |
*/
|
853 |
+
isset( $options[0] )
|
854 |
) {
|
855 |
/**
|
856 |
* Array "without key" containing options.
|
876 |
* ),
|
877 |
* )
|
878 |
*/
|
879 |
+
fw_collect_first_level_options( $collected, $option );
|
880 |
+
} elseif ( isset( $option['type'] ) ) {
|
881 |
// simple option, last possible level in options array
|
882 |
+
$collected['options'][ $option_id ] =& $option;
|
883 |
+
$collected['groups_and_options'][ $option_id ] =& $option;
|
884 |
|
885 |
+
$collected['all'][ 'option' . ':~:' . $option_id ] = array(
|
886 |
'type' => 'option',
|
887 |
'id' => $option_id,
|
888 |
'option' => &$option,
|
889 |
);
|
890 |
} else {
|
891 |
+
trigger_error( 'Invalid option: ' . $option_id, E_USER_WARNING );
|
892 |
}
|
893 |
}
|
894 |
+
unset( $option );
|
895 |
}
|
896 |
|
897 |
/**
|
900 |
* @param array $settings
|
901 |
* @param array $_recursion_data (private) for internal use
|
902 |
*/
|
903 |
+
function fw_collect_options( &$result, &$options, $settings = array(), $_recursion_data = array() ) {
|
904 |
static $default_settings = array(
|
905 |
/**
|
906 |
* @type bool Wrap the result/collected options in arrays will useful info
|
921 |
* // Warning: There can be options and containers with the same id (array key will be replaced)
|
922 |
* )
|
923 |
*/
|
924 |
+
'info_wrapper' => false,
|
925 |
/**
|
926 |
* @type int Nested options level limit. For e.g. use 1 to collect only first level. 0 is for unlimited.
|
927 |
*/
|
928 |
+
'limit_level' => 0,
|
929 |
/**
|
930 |
* @type false|array('option-type', ...) Empty array will skip all types
|
931 |
*/
|
932 |
+
'limit_option_types' => false,
|
933 |
/**
|
934 |
* @type false|array('container-type', ...) Empty array will skip all types
|
935 |
*/
|
937 |
/**
|
938 |
* @type int Limit the number of options that will be collected
|
939 |
*/
|
940 |
+
'limit' => 0,
|
941 |
/**
|
942 |
* @type callable Executed on each collected option
|
943 |
* @since 2.6.0
|
944 |
*/
|
945 |
+
'callback' => null,
|
946 |
);
|
947 |
|
948 |
static $access_key = null;
|
949 |
|
950 |
+
if ( empty( $options ) ) {
|
951 |
return;
|
952 |
}
|
953 |
|
954 |
+
if ( empty( $_recursion_data ) ) {
|
955 |
+
if ( is_null( $access_key ) ) {
|
956 |
+
$access_key = new FW_Access_Key( 'fw_collect_options' );
|
957 |
}
|
958 |
|
959 |
+
$settings = array_merge( $default_settings, $settings );
|
960 |
|
961 |
$_recursion_data = array(
|
962 |
+
'level' => 1,
|
963 |
'access_key' => $access_key,
|
964 |
// todo: maybe add 'parent' => array('id' => '{id}', 'type' => 'container|option') ?
|
965 |
);
|
966 |
+
} elseif ( ! (
|
967 |
+
isset( $_recursion_data['access_key'] )
|
968 |
&&
|
969 |
+
( $_recursion_data['access_key'] instanceof FW_Access_Key )
|
970 |
&&
|
971 |
+
( $_recursion_data['access_key']->get_key() === 'fw_collect_options' )
|
972 |
+
)
|
973 |
+
) {
|
974 |
+
trigger_error( 'Call not allowed', E_USER_ERROR );
|
975 |
}
|
976 |
|
977 |
if (
|
982 |
return;
|
983 |
}
|
984 |
|
985 |
+
foreach ( $options as $option_id => &$option ) {
|
986 |
+
if ( isset( $option['options'] ) ) { // this is a container
|
987 |
do {
|
988 |
if (
|
989 |
+
is_array( $settings['limit_container_types'] )
|
990 |
&&
|
991 |
(
|
992 |
// Customizer options can contain options with not existing or empty $option['type']
|
993 |
+
empty( $option['type'] )
|
994 |
||
|
995 |
+
! in_array( $option['type'], $settings['limit_container_types'] )
|
996 |
)
|
997 |
) {
|
998 |
break;
|
1001 |
if (
|
1002 |
$settings['limit']
|
1003 |
&&
|
1004 |
+
count( $result ) >= $settings['limit']
|
1005 |
) {
|
1006 |
return;
|
1007 |
}
|
1008 |
|
1009 |
+
if ( $settings['info_wrapper'] ) {
|
1010 |
+
$result[ 'container:' . $option_id ] = array(
|
1011 |
'group' => 'container',
|
1012 |
'id' => $option_id,
|
1013 |
'option' => &$option,
|
1014 |
'level' => $_recursion_data['level'],
|
1015 |
);
|
1016 |
} else {
|
1017 |
+
$result[ $option_id ] = &$option;
|
1018 |
}
|
1019 |
|
1020 |
+
if ( $settings['callback'] ) {
|
1021 |
+
call_user_func_array( $settings['callback'],
|
1022 |
+
array(
|
1023 |
+
array(
|
1024 |
+
'group' => 'container',
|
1025 |
+
'id' => $option_id,
|
1026 |
+
'option' => &$option,
|
1027 |
+
)
|
1028 |
+
) );
|
1029 |
}
|
1030 |
+
} while ( false );
|
1031 |
|
1032 |
fw_collect_options(
|
1033 |
$result,
|
1034 |
$option['options'],
|
1035 |
$settings,
|
1036 |
+
array_merge( $_recursion_data, array( 'level' => $_recursion_data['level'] + 1 ) )
|
1037 |
);
|
1038 |
} elseif (
|
1039 |
+
is_int( $option_id )
|
1040 |
&&
|
1041 |
+
is_array( $option )
|
1042 |
&&
|
1043 |
/**
|
1044 |
* make sure the array key was generated automatically
|
1045 |
* and it's not an associative array with numeric keys created like this: $options[1] = array();
|
1046 |
*/
|
1047 |
+
isset( $options[0] )
|
1048 |
) {
|
1049 |
/**
|
1050 |
* Array "without key" containing options.
|
1070 |
* ),
|
1071 |
* )
|
1072 |
*/
|
1073 |
+
fw_collect_options( $result, $option, $settings, $_recursion_data );
|
1074 |
+
} elseif ( isset( $option['type'] ) ) { // option
|
1075 |
if (
|
1076 |
+
is_array( $settings['limit_option_types'] )
|
1077 |
&&
|
1078 |
+
! in_array( $option['type'], $settings['limit_option_types'] )
|
1079 |
) {
|
1080 |
continue;
|
1081 |
}
|
1083 |
if (
|
1084 |
$settings['limit']
|
1085 |
&&
|
1086 |
+
count( $result ) >= $settings['limit']
|
1087 |
) {
|
1088 |
return;
|
1089 |
}
|
1090 |
|
1091 |
+
if ( $settings['info_wrapper'] ) {
|
1092 |
+
$result[ 'option:' . $option_id ] = array(
|
1093 |
'group' => 'option',
|
1094 |
'id' => $option_id,
|
1095 |
'option' => &$option,
|
1096 |
'level' => $_recursion_data['level'],
|
1097 |
);
|
1098 |
} else {
|
1099 |
+
$result[ $option_id ] = &$option;
|
1100 |
}
|
1101 |
|
1102 |
+
if ( $settings['callback'] ) {
|
1103 |
+
call_user_func_array( $settings['callback'],
|
1104 |
+
array(
|
1105 |
+
array(
|
1106 |
+
'group' => 'option',
|
1107 |
+
'id' => $option_id,
|
1108 |
+
'option' => &$option,
|
1109 |
+
)
|
1110 |
+
) );
|
1111 |
}
|
1112 |
} else {
|
1113 |
+
trigger_error( 'Invalid option: ' . $option_id, E_USER_WARNING );
|
1114 |
}
|
1115 |
}
|
1116 |
}
|
1118 |
/**
|
1119 |
* Get correct values from input (POST) for given options
|
1120 |
* This values can be saved in db then replaced with $option['value'] for each option
|
1121 |
+
*
|
1122 |
* @param array $options
|
1123 |
* @param array $input_array
|
1124 |
+
*
|
1125 |
* @return array Values
|
1126 |
*/
|
1127 |
+
function fw_get_options_values_from_input( array $options, $input_array = null ) {
|
1128 |
+
if ( ! is_array( $input_array ) ) {
|
1129 |
+
$input_array = FW_Request::POST( fw()->backend->get_options_name_attr_prefix() );
|
1130 |
}
|
1131 |
|
1132 |
$values = array();
|
1133 |
|
1134 |
+
foreach ( fw_extract_only_options( $options ) as $id => $option ) {
|
1135 |
+
$values[ $id ] = fw()->backend->option_type( $option['type'] )->get_value_from_input(
|
1136 |
$option,
|
1137 |
+
isset( $input_array[ $id ] ) ? $input_array[ $id ] : null
|
1138 |
);
|
1139 |
|
1140 |
+
if ( is_null( $values[ $id ] ) ) {
|
1141 |
// do not save null values
|
1142 |
+
unset( $values[ $id ] );
|
1143 |
}
|
1144 |
}
|
1145 |
|
1149 |
/**
|
1150 |
* @param $attr_name
|
1151 |
* @param bool $set_mode
|
1152 |
+
*
|
1153 |
* @return mixed
|
1154 |
*/
|
1155 |
+
function fw_html_attr_name_to_array_multi_key( $attr_name, $set_mode = false ) {
|
1156 |
+
if ( $set_mode ) {
|
1157 |
/**
|
1158 |
* The key will be used to set value in array
|
1159 |
* 'hello[world][]' -> 'hello/world/'
|
1160 |
* $array['hello']['world'][] = $value;
|
1161 |
*/
|
1162 |
+
$attr_name = str_replace( '[]', '/', $attr_name );
|
1163 |
} else {
|
1164 |
/**
|
1165 |
* The key will be used to get value from array
|
1166 |
* 'hello[world][]' -> 'hello/world'
|
1167 |
* $value = $array['hello']['world'];
|
1168 |
*/
|
1169 |
+
$attr_name = str_replace( '[]', '', $attr_name );
|
1170 |
}
|
1171 |
|
1172 |
+
$attr_name = str_replace( '][', '/', $attr_name );
|
1173 |
+
$attr_name = str_replace( '[', '/', $attr_name );
|
1174 |
+
$attr_name = str_replace( ']', '', $attr_name );
|
1175 |
|
1176 |
return $attr_name;
|
1177 |
}
|
1180 |
* Used when getting some option value from serialized array saved in a custom place
|
1181 |
* and that option is unreachable for standard WordPress filters by other plugins
|
1182 |
* For e.g. that option cannot be translated by plugins, so we pass its value through this function and do the fixes
|
1183 |
+
*
|
1184 |
* @param $value
|
1185 |
+
*
|
1186 |
* @return array
|
1187 |
*/
|
1188 |
+
function fw_prepare_option_value( $value ) {
|
1189 |
+
if ( empty( $value ) ) {
|
1190 |
return $value;
|
1191 |
}
|
1192 |
|
1193 |
+
if ( function_exists( 'qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) ) {
|
1194 |
+
$value = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $value );
|
1195 |
}
|
1196 |
|
1197 |
return $value;
|
1204 |
* not a revision, auto-save or something else
|
1205 |
*
|
1206 |
* @param $post_id
|
1207 |
+
*
|
1208 |
* @return bool
|
1209 |
*
|
1210 |
* @deprecated
|
1213 |
* the developers should study and understand better how it works
|
1214 |
* and handle different save cases in their scripts using wp functions
|
1215 |
*/
|
1216 |
+
function fw_is_real_post_save( $post_id ) {
|
1217 |
+
return ! (
|
1218 |
+
wp_is_post_revision( $post_id )
|
1219 |
+
|| wp_is_post_autosave( $post_id )
|
1220 |
+
|| ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
|
1221 |
+
|| ( defined( 'DOING_AJAX' ) && DOING_AJAX )
|
1222 |
+
|| empty( $_POST )
|
1223 |
+
|| empty( $_POST['post_ID'] )
|
1224 |
|| $_POST['post_ID'] != $post_id
|
1225 |
);
|
1226 |
}
|
1232 |
$cache_key = 'fw_google_fonts';
|
1233 |
|
1234 |
try {
|
1235 |
+
return FW_Cache::get( $cache_key );
|
1236 |
+
} catch ( FW_Cache_Not_Found_Exception $e ) {
|
1237 |
+
$g_fonts = json_decode( fw_get_google_fonts_v2(), true );
|
1238 |
+
$old_fonts = include( dirname( __FILE__ ) . '/fw-google-fonts.json.php' );
|
1239 |
+
$fonts = array();
|
1240 |
|
1241 |
foreach ( $g_fonts['items'] as $font ) {
|
1242 |
$fonts[ $font['family'] ] = array(
|
1243 |
+
'family' => $font['family'],
|
1244 |
'variants' => $font['variants'],
|
1245 |
+
'position' => isset( $old_fonts[ $font['family'] ] )
|
1246 |
+
? $old_fonts[ $font['family'] ]['position']
|
1247 |
: 99999
|
1248 |
);
|
1249 |
}
|
1250 |
|
1251 |
+
$fonts = apply_filters( 'fw_google_fonts', $fonts );
|
1252 |
|
1253 |
+
FW_Cache::set( $cache_key, $fonts );
|
1254 |
|
1255 |
return $fonts;
|
1256 |
}
|
1261 |
*/
|
1262 |
function fw_get_google_fonts_v2() {
|
1263 |
$saved_data = get_option( 'fw_google_fonts', false );
|
1264 |
+
$ttl = 7 * DAY_IN_SECONDS;
|
1265 |
|
1266 |
if (
|
1267 |
false === $saved_data
|
1268 |
||
|
1269 |
( $saved_data['last_update'] + $ttl < time() )
|
1270 |
) {
|
1271 |
+
$response = wp_remote_get( apply_filters( 'fw_googleapis_webfonts_url',
|
1272 |
+
'http://google-webfonts-cache.unyson.io/v1/webfonts' ) );
|
1273 |
$body = wp_remote_retrieve_body( $response );
|
1274 |
|
1275 |
if (
|
1277 |
&&
|
1278 |
! is_wp_error( $body ) && ! empty( $body )
|
1279 |
) {
|
1280 |
+
update_option( 'fw_google_fonts',
|
1281 |
+
array(
|
1282 |
+
'last_update' => time(),
|
1283 |
+
'fonts' => $body
|
1284 |
+
),
|
1285 |
+
false );
|
1286 |
|
1287 |
return $body;
|
1288 |
} else {
|
1290 |
$saved_data['fonts'] = json_encode( array( 'items' => array() ) );
|
1291 |
}
|
1292 |
|
1293 |
+
update_option( 'fw_google_fonts',
|
1294 |
+
array(
|
1295 |
+
'last_update' => time() - $ttl + MINUTE_IN_SECONDS,
|
1296 |
+
'fonts' => $saved_data['fonts']
|
1297 |
+
),
|
1298 |
+
false );
|
1299 |
}
|
1300 |
}
|
1301 |
|
1308 |
function fw_current_url() {
|
1309 |
static $url = null;
|
1310 |
|
1311 |
+
if ( $url === null ) {
|
1312 |
$url = 'http://';
|
1313 |
|
1314 |
+
if ( $_SERVER['SERVER_NAME'] === '_' ) { // https://github.com/ThemeFuse/Unyson/issues/126
|
1315 |
$url .= $_SERVER['HTTP_HOST'];
|
1316 |
} else {
|
1317 |
$url .= $_SERVER['SERVER_NAME'];
|
1318 |
}
|
1319 |
|
1320 |
+
if ( ! in_array( intval( $_SERVER['SERVER_PORT'] ), array( 80, 443 ) ) ) {
|
1321 |
+
$url .= ':' . $_SERVER['SERVER_PORT'];
|
1322 |
}
|
1323 |
|
1324 |
$url .= $_SERVER['REQUEST_URI'];
|
1325 |
|
1326 |
+
$url = set_url_scheme( $url ); // https fix
|
1327 |
|
1328 |
if ( is_multisite() ) {
|
1329 |
if ( defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL ) {
|
1330 |
+
$site_url = parse_url( $url );
|
1331 |
|
1332 |
+
if ( isset( $site_url['query'] ) ) {
|
1333 |
+
$url = home_url( $site_url['path'] . '?' . $site_url['query'] );
|
1334 |
} else {
|
1335 |
+
$url = home_url( $site_url['path'] );
|
1336 |
}
|
1337 |
}
|
1338 |
}
|
1341 |
return $url;
|
1342 |
}
|
1343 |
|
1344 |
+
function fw_is_valid_domain_name( $domain_name ) {
|
1345 |
+
return ( preg_match( "/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name ) // valid chars check
|
1346 |
+
&& preg_match( "/^.{1,253}$/", $domain_name ) // overall length check
|
1347 |
+
&& preg_match( "/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name ) ); // length of each label
|
1348 |
}
|
1349 |
|
1350 |
/**
|
1352 |
* Info: Cannot use default parameters because in php 5.2 encoding is not UTF-8 by default
|
1353 |
*
|
1354 |
* @param string $string
|
1355 |
+
*
|
1356 |
* @return string
|
1357 |
*/
|
1358 |
+
function fw_htmlspecialchars( $string ) {
|
1359 |
+
return htmlspecialchars( $string, ENT_QUOTES, 'UTF-8' );
|
1360 |
}
|
1361 |
|
1362 |
/**
|
1364 |
*
|
1365 |
* @param array $capabilities list of capabilities to check
|
1366 |
* @param mixed $default_value
|
1367 |
+
*
|
1368 |
* @return string|bool|mixed
|
1369 |
* Return first capability that user can.
|
1370 |
* Else, return default value if it is not null, else return first capability from list.
|
1371 |
* Use default value false to check if user can some of the capabilities
|
1372 |
*/
|
1373 |
+
function fw_current_user_can( $capabilities, $default_value = null ) {
|
1374 |
+
if ( is_user_logged_in() ) {
|
1375 |
+
foreach ( $capabilities as $capability ) {
|
1376 |
+
if ( current_user_can( $capability ) ) {
|
|
|
1377 |
return $capability;
|
1378 |
+
}
|
1379 |
}
|
1380 |
}
|
1381 |
|
1382 |
+
return ( $default_value !== null ? $default_value : array_shift( $capabilities ) );
|
1383 |
}
|
1384 |
|
1385 |
/**
|
1389 |
* then you can use this string how you want, for e.g. append ' ago' => '2 minutes ago'
|
1390 |
*
|
1391 |
* @param int $seconds
|
1392 |
+
*
|
1393 |
* @return string
|
1394 |
*/
|
1395 |
+
function fw_human_time( $seconds ) {
|
1396 |
static $translations = null;
|
1397 |
+
if ( $translations === null ) {
|
1398 |
$translations = array(
|
1399 |
+
'year' => __( 'year', 'fw' ),
|
1400 |
+
'years' => __( 'years', 'fw' ),
|
1401 |
|
1402 |
+
'month' => __( 'month', 'fw' ),
|
1403 |
+
'months' => __( 'months', 'fw' ),
|
1404 |
|
1405 |
+
'week' => __( 'week', 'fw' ),
|
1406 |
+
'weeks' => __( 'weeks', 'fw' ),
|
1407 |
|
1408 |
+
'day' => __( 'day', 'fw' ),
|
1409 |
+
'days' => __( 'days', 'fw' ),
|
1410 |
|
1411 |
+
'hour' => __( 'hour', 'fw' ),
|
1412 |
+
'hours' => __( 'hours', 'fw' ),
|
1413 |
|
1414 |
+
'minute' => __( 'minute', 'fw' ),
|
1415 |
+
'minutes' => __( 'minutes', 'fw' ),
|
1416 |
|
1417 |
+
'second' => __( 'second', 'fw' ),
|
1418 |
+
'seconds' => __( 'seconds', 'fw' ),
|
1419 |
);
|
1420 |
}
|
1421 |
|
1422 |
+
$tokens = array(
|
1423 |
31536000 => 'year',
|
1424 |
+
2592000 => 'month',
|
1425 |
+
604800 => 'week',
|
1426 |
+
86400 => 'day',
|
1427 |
+
3600 => 'hour',
|
1428 |
+
60 => 'minute',
|
1429 |
+
1 => 'second'
|
1430 |
);
|
1431 |
|
1432 |
+
foreach ( $tokens as $unit => $translation_key ) {
|
1433 |
+
if ( $seconds < $unit ) {
|
1434 |
continue;
|
1435 |
+
}
|
1436 |
|
1437 |
+
$number_of_units = floor( $seconds / $unit );
|
1438 |
|
1439 |
+
return $number_of_units . ' ' . $translations[ $translation_key . ( $number_of_units != 1 ? 's' : '' ) ];
|
1440 |
}
|
1441 |
}
|
1442 |
|
1445 |
*
|
1446 |
* @param integer $bytes Size in bytes to convert
|
1447 |
* @param integer $precision
|
1448 |
+
*
|
1449 |
* @return string
|
1450 |
* @since 2.4.17
|
1451 |
*/
|
1452 |
+
function fw_human_bytes( $bytes, $precision = 2 ) {
|
1453 |
$kilobyte = 1024;
|
1454 |
$megabyte = $kilobyte * 1024;
|
1455 |
$gigabyte = $megabyte * 1024;
|
1456 |
$terabyte = $gigabyte * 1024;
|
1457 |
|
1458 |
+
if ( ( $bytes >= 0 ) && ( $bytes < $kilobyte ) ) {
|
1459 |
return $bytes . ' B';
|
1460 |
|
1461 |
+
} elseif ( ( $bytes >= $kilobyte ) && ( $bytes < $megabyte ) ) {
|
1462 |
+
return round( $bytes / $kilobyte, $precision ) . ' KB';
|
1463 |
|
1464 |
+
} elseif ( ( $bytes >= $megabyte ) && ( $bytes < $gigabyte ) ) {
|
1465 |
+
return round( $bytes / $megabyte, $precision ) . ' MB';
|
1466 |
|
1467 |
+
} elseif ( ( $bytes >= $gigabyte ) && ( $bytes < $terabyte ) ) {
|
1468 |
+
return round( $bytes / $gigabyte, $precision ) . ' GB';
|
1469 |
|
1470 |
+
} elseif ( $bytes >= $terabyte ) {
|
1471 |
+
return round( $bytes / $terabyte, $precision ) . ' TB';
|
1472 |
} else {
|
1473 |
return $bytes . ' B';
|
1474 |
}
|
1475 |
}
|
1476 |
|
1477 |
+
function fw_strlen( $string ) {
|
1478 |
+
if ( function_exists( 'mb_strlen' ) ) {
|
1479 |
+
return mb_strlen( $string, 'UTF-8' );
|
1480 |
} else {
|
1481 |
+
return strlen( $string );
|
1482 |
}
|
1483 |
}
|
1484 |
|
1489 |
function fw_is_post_edit() {
|
1490 |
static $result = null;
|
1491 |
|
1492 |
+
if ( $result === null ) {
|
1493 |
$result = false;
|
1494 |
|
1495 |
+
if ( is_admin() ) {
|
1496 |
if (
|
1497 |
+
empty( $_POST )
|
1498 |
&&
|
1499 |
+
isset( $_GET['action'] )
|
1500 |
&&
|
1501 |
$_GET['action'] === 'edit'
|
1502 |
&&
|
1503 |
+
isset( $_GET['post'] )
|
1504 |
) {
|
1505 |
// Display Edit Post page
|
1506 |
$result = true;
|
1507 |
} elseif (
|
1508 |
+
isset( $_POST['action'] )
|
1509 |
&&
|
1510 |
$_POST['action'] === 'editpost'
|
1511 |
&&
|
1512 |
+
isset( $_POST['post_type'] )
|
1513 |
&&
|
1514 |
+
isset( $_POST['post_ID'] )
|
1515 |
&&
|
1516 |
+
strpos( wp_get_referer(), 'action=edit' ) !== false
|
1517 |
) {
|
1518 |
// Submit Edit Post page
|
1519 |
$result = true;
|
1526 |
|
1527 |
/**
|
1528 |
* @param string $dirname 'foo-bar'
|
1529 |
+
*
|
1530 |
* @return string 'Foo_Bar'
|
1531 |
*/
|
1532 |
+
function fw_dirname_to_classname( $dirname ) {
|
1533 |
+
$class_name = explode( '-', $dirname );
|
1534 |
+
$class_name = array_map( 'ucfirst', $class_name );
|
1535 |
+
$class_name = implode( '_', $class_name );
|
1536 |
|
1537 |
return $class_name;
|
1538 |
}
|
1542 |
*
|
1543 |
* @param $url
|
1544 |
* @param array $args
|
1545 |
+
*
|
1546 |
* @return bool|string
|
1547 |
*/
|
1548 |
+
function fw_oembed_get( $url, $args = array() ) {
|
1549 |
+
$html = wp_oembed_get( $url, $args );
|
1550 |
|
1551 |
+
if ( ! empty( $args['width'] ) and ! empty( $args['height'] ) and class_exists( 'DOMDocument' ) and ! empty( $html ) ) {
|
1552 |
$dom_element = new DOMDocument();
|
1553 |
+
@$dom_element->loadHTML( $html );
|
1554 |
|
1555 |
+
if ( $obj = $dom_element->getElementsByTagName( 'iframe' )->item( 0 ) ) {
|
1556 |
+
$obj->setAttribute( 'width', $args['width'] );
|
1557 |
+
$obj->setAttribute( 'height', $args['height'] );
|
1558 |
//saveXml instead of SaveHTML for php version compatibility
|
1559 |
+
$html = $dom_element->saveXML( $obj, LIBXML_NOEMPTYTAG );
|
1560 |
}
|
1561 |
}
|
1562 |
|
1573 |
* http://www.zimuel.it/en/strong-cryptography-in-php/
|
1574 |
* > Don't use rand() or mt_rand()
|
1575 |
*/
|
1576 |
+
function fw_secure_rand( $length ) {
|
1577 |
+
if ( function_exists( 'openssl_random_pseudo_bytes' ) ) {
|
1578 |
+
$rnd = openssl_random_pseudo_bytes( $length, $strong );
|
1579 |
+
if ( $strong ) {
|
1580 |
return $rnd;
|
1581 |
}
|
1582 |
}
|
1583 |
|
1584 |
+
$sha = '';
|
1585 |
+
$rnd = '';
|
1586 |
|
1587 |
+
if ( file_exists( '/dev/urandom' ) ) {
|
1588 |
+
$fp = fopen( '/dev/urandom', 'rb' );
|
1589 |
+
if ( $fp ) {
|
1590 |
+
if ( function_exists( 'stream_set_read_buffer' ) ) {
|
1591 |
+
stream_set_read_buffer( $fp, 0 );
|
1592 |
}
|
1593 |
+
$sha = fread( $fp, $length );
|
1594 |
+
fclose( $fp );
|
1595 |
}
|
1596 |
}
|
1597 |
|
1598 |
+
for ( $i = 0; $i < $length; $i ++ ) {
|
1599 |
+
$sha = hash( 'sha256', $sha . mt_rand() );
|
1600 |
+
$char = mt_rand( 0, 62 );
|
1601 |
+
$rnd .= chr( hexdec( $sha[ $char ] . $sha[ $char + 1 ] ) );
|
1602 |
}
|
1603 |
|
1604 |
return $rnd;
|
1606 |
|
1607 |
/**
|
1608 |
* Try to make user friendly title from an id
|
1609 |
+
*
|
1610 |
* @param string $id 'hello-world'
|
1611 |
+
*
|
1612 |
* @return string 'Hello world'
|
1613 |
*/
|
1614 |
+
function fw_id_to_title( $id ) {
|
1615 |
// mb_ucfirst()
|
1616 |
+
if ( function_exists( 'mb_strtoupper' ) && function_exists( 'mb_substr' ) && function_exists( 'mb_strlen' ) ) {
|
1617 |
+
$id = mb_strtoupper( mb_substr( $id, 0, 1, 'UTF-8' ), 'UTF-8' ) . mb_substr( $id,
|
1618 |
+
1,
|
1619 |
+
mb_strlen( $id, 'UTF-8' ),
|
1620 |
+
'UTF-8' );
|
1621 |
} else {
|
1622 |
+
$id = strtoupper( substr( $id, 0, 1 ) ) . substr( $id, 1, strlen( $id ) );
|
1623 |
}
|
1624 |
|
1625 |
+
return str_replace( array( '_', '-' ), ' ', $id );
|
1626 |
}
|
1627 |
|
1628 |
/**
|
1629 |
* Alias
|
1630 |
+
*
|
1631 |
* @param string $extension_name
|
1632 |
+
*
|
1633 |
* @return FW_Extension|null
|
1634 |
*/
|
1635 |
+
function fw_ext( $extension_name ) {
|
1636 |
+
return fw()->extensions->get( $extension_name );
|
1637 |
}
|
1638 |
|
1639 |
/*
|
1645 |
|
1646 |
/**
|
1647 |
* Try to find file path by its uri and read the file contents
|
1648 |
+
*
|
1649 |
* @param string $file_uri
|
1650 |
+
*
|
1651 |
* @return bool|string false or string - the file contents
|
1652 |
*/
|
1653 |
+
function fw_read_file_by_uri( $file_uri ) {
|
1654 |
static $base = null;
|
1655 |
|
1656 |
+
if ( $base === null ) {
|
1657 |
+
$base = array();
|
1658 |
+
$base['dir'] = WP_CONTENT_DIR;
|
1659 |
+
$base['uri'] = ltrim( content_url(), '/' );
|
1660 |
+
$base['uri_prefix_regex'] = '/^' . preg_quote( $base['uri'], '/' ) . '/';
|
1661 |
}
|
1662 |
|
1663 |
+
$file_rel_path = preg_replace( $base['uri_prefix_regex'], '', $file_uri );
|
1664 |
|
1665 |
+
if ( $base['uri'] === $file_rel_path ) {
|
1666 |
// the file is not inside base dir
|
1667 |
return false;
|
1668 |
}
|
1669 |
|
1670 |
+
$file_path = $base['dir'] . '/' . $file_rel_path;
|
1671 |
|
1672 |
+
if ( ! file_exists( $file_path ) ) {
|
1673 |
return false;
|
1674 |
}
|
1675 |
|
1676 |
+
return file_get_contents( $file_path );
|
1677 |
}
|
1678 |
|
1679 |
/**
|
1682 |
*
|
1683 |
* @param string $href 'http://.../style.css'
|
1684 |
* @param null|string $contents If not specified, will try to read from $href
|
1685 |
+
*
|
1686 |
* @return bool|string false - on failure; string - stylesheet contents
|
1687 |
*/
|
1688 |
+
function fw_make_stylesheet_portable( $href, $contents = null ) {
|
1689 |
+
if ( is_null( $contents ) ) {
|
1690 |
+
$contents = fw_read_file_by_uri( $href );
|
1691 |
|
1692 |
+
if ( $contents === false ) {
|
1693 |
return false;
|
1694 |
}
|
1695 |
}
|
1696 |
|
1697 |
+
$dir_uri = dirname( $href );
|
1698 |
|
1699 |
/**
|
1700 |
* Replace relative 'url(img/bg.png)'
|
1709 |
*/
|
1710 |
$contents = preg_replace(
|
1711 |
'/url\s*\((?!\s*[\'"]?(?:\/|data\:|\#|(?:https?:)?\/\/))\s*([\'"])?/',
|
1712 |
+
'url($1' . $dir_uri . '/',
|
1713 |
$contents
|
1714 |
);
|
1715 |
|
1720 |
* Return all images sizes register by add_image_size() merged with
|
1721 |
* WordPress default image sizes.
|
1722 |
* @link https://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes
|
1723 |
+
*
|
1724 |
* @param string $size
|
1725 |
*
|
1726 |
* @return array|bool
|
1728 |
function fw_get_image_sizes( $size = '' ) {
|
1729 |
global $_wp_additional_image_sizes;
|
1730 |
|
1731 |
+
$sizes = array();
|
1732 |
$get_intermediate_image_sizes = get_intermediate_image_sizes();
|
1733 |
|
1734 |
// Create the full array with sizes and crop info
|
1735 |
+
foreach ( $get_intermediate_image_sizes as $_size ) {
|
1736 |
if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
|
1737 |
+
$sizes[ $_size ]['width'] = get_option( $_size . '_size_w' );
|
1738 |
$sizes[ $_size ]['height'] = get_option( $_size . '_size_h' );
|
1739 |
+
$sizes[ $_size ]['crop'] = (bool) get_option( $_size . '_crop' );
|
1740 |
} elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
|
1741 |
$sizes[ $_size ] = array(
|
1742 |
+
'width' => $_wp_additional_image_sizes[ $_size ]['width'],
|
1743 |
'height' => $_wp_additional_image_sizes[ $_size ]['height'],
|
1744 |
+
'crop' => $_wp_additional_image_sizes[ $_size ]['crop']
|
1745 |
);
|
1746 |
}
|
1747 |
}
|
1748 |
|
1749 |
// Get only 1 size if found
|
1750 |
if ( $size ) {
|
1751 |
+
if ( isset( $sizes[ $size ] ) ) {
|
1752 |
return $sizes[ $size ];
|
1753 |
} else {
|
1754 |
return false;
|
1761 |
/**
|
1762 |
* @param string $icon A string that is meant to be an icon (an image, a font icon class, or something else)
|
1763 |
* @param array Additional attributes
|
1764 |
+
*
|
1765 |
* @return string
|
1766 |
*/
|
1767 |
+
function fw_string_to_icon_html( $icon, array $attributes = array() ) {
|
1768 |
if (
|
1769 |
+
preg_match( '/\.(png|jpg|jpeg|gif|svg|webp)$/', $icon )
|
1770 |
||
|
1771 |
+
preg_match( '/^data:image\//', $icon )
|
1772 |
) {
|
1773 |
// http://.../image.png
|
1774 |
+
$tag = 'img';
|
1775 |
$attr = array(
|
1776 |
'src' => $icon,
|
1777 |
'alt' => 'icon',
|
1778 |
);
|
1779 |
+
} elseif ( preg_match( '/^[a-zA-Z0-9\-_ ]+$/', $icon ) ) {
|
1780 |
// 'font-icon font-icon-class'
|
1781 |
+
$tag = 'span';
|
1782 |
$attr = array(
|
1783 |
+
'class' => trim( $icon ),
|
1784 |
);
|
1785 |
} else {
|
1786 |
// can't detect. maybe it's raw html '<span ...'
|
1787 |
return $icon;
|
1788 |
}
|
1789 |
|
1790 |
+
foreach ( $attributes as $attr_name => $attr_val ) {
|
1791 |
+
if ( isset( $attr[ $attr_name ] ) ) {
|
1792 |
+
if ( $attr_name === 'class' ) {
|
1793 |
+
$attr[ $attr_name ] .= ' ' . $attr_val;
|
1794 |
} else {
|
1795 |
// ignore. do not overwrite already set attributes
|
1796 |
}
|
1797 |
} else {
|
1798 |
+
$attr[ $attr_name ] = (string) $attr_val;
|
1799 |
}
|
1800 |
}
|
1801 |
|
1802 |
+
return fw_html_tag( $tag, $attr );
|
1803 |
}
|
1804 |
|
1805 |
/**
|
1807 |
* @since 2.4.10
|
1808 |
*/
|
1809 |
function fw_get_json_last_error_message() {
|
1810 |
+
switch ( function_exists( 'json_last_error' ) ? json_last_error() : - 1 ) {
|
1811 |
case JSON_ERROR_NONE:
|
1812 |
return null; // __('No errors', 'fw');
|
1813 |
break;
|
1814 |
case JSON_ERROR_DEPTH:
|
1815 |
+
return __( 'Maximum stack depth exceeded', 'fw' );
|
1816 |
break;
|
1817 |
case JSON_ERROR_STATE_MISMATCH:
|
1818 |
+
return __( 'Underflow or the modes mismatch', 'fw' );
|
1819 |
break;
|
1820 |
case JSON_ERROR_CTRL_CHAR:
|
1821 |
+
return __( 'Unexpected control character found', 'fw' );
|
1822 |
break;
|
1823 |
case JSON_ERROR_SYNTAX:
|
1824 |
+
return __( 'Syntax error, malformed JSON', 'fw' );
|
1825 |
break;
|
1826 |
case JSON_ERROR_UTF8:
|
1827 |
+
return __( 'Malformed UTF-8 characters, possibly incorrectly encoded', 'fw' );
|
1828 |
break;
|
1829 |
default:
|
1830 |
+
return __( 'Unknown error', 'fw' );
|
1831 |
break;
|
1832 |
}
|
1833 |
}
|
1886 |
|
1887 |
/**
|
1888 |
* fw_get_path_url( dirname(__FILE__) .'/test.css' ) --> http://site.url/path/to/test.css
|
1889 |
+
*
|
1890 |
* @param string $path
|
1891 |
+
*
|
1892 |
* @return string|null
|
1893 |
* @since 2.6.11
|
1894 |
*/
|
1895 |
+
function fw_get_path_url( $path ) {
|
1896 |
try {
|
1897 |
+
$paths_to_urls = FW_Cache::get( $cache_key = 'fw:paths_to_urls' );
|
1898 |
+
} catch ( FW_Cache_Not_Found_Exception $e ) {
|
1899 |
$wp_upload_dir = wp_upload_dir();
|
1900 |
|
1901 |
$paths_to_urls = array(
|
1902 |
+
fw_fix_path( WP_PLUGIN_DIR ) => plugins_url(),
|
1903 |
+
fw_fix_path( get_theme_root() ) => get_theme_root_uri(),
|
1904 |
+
fw_fix_path( $wp_upload_dir['basedir'] ) => $wp_upload_dir['baseurl'],
|
1905 |
);
|
1906 |
|
1907 |
+
if ( is_multisite() && WPMU_PLUGIN_DIR ) {
|
1908 |
+
$paths_to_urls[ fw_fix_path( WPMU_PLUGIN_DIR ) ] = WPMU_PLUGIN_URL;
|
1909 |
}
|
1910 |
|
1911 |
+
FW_Cache::set( $cache_key, $paths_to_urls );
|
1912 |
}
|
1913 |
|
1914 |
+
$path = fw_fix_path( $path );
|
1915 |
|
1916 |
+
foreach ( $paths_to_urls as $_path => $_url ) {
|
1917 |
+
if ( preg_match( $regex = '/^' . preg_quote( $_path, '/' ) . '($|\/)/', $path ) ) {
|
1918 |
+
return $_url . '/' . preg_replace( $regex, '', $path );
|
1919 |
}
|
1920 |
}
|
1921 |
|
1922 |
return null;
|
1923 |
}
|
1924 |
+
|
1925 |
+
/**
|
1926 |
+
* @param string|array $callback Callback function
|
1927 |
+
* @param array $args Callback arguments
|
1928 |
+
* @param bool $cache Whenever you want to cache the function value after it's first call or not
|
1929 |
+
* Recommend when the function call may require many resources or time (database requests) , or the value is small
|
1930 |
+
* Not recommended using on very large values
|
1931 |
+
*
|
1932 |
+
* @return FW_Callback
|
1933 |
+
*
|
1934 |
+
* @since 2.6.14
|
1935 |
+
*/
|
1936 |
+
function fw_callback( $callback, array $args = array(), $cache = true ) {
|
1937 |
+
return new FW_Callback( $callback, $args, $cache );
|
1938 |
+
}
|
1939 |
+
|
1940 |
+
/**
|
1941 |
+
* In the value is instance of FW_Callback class then it is executed and returns the callback value
|
1942 |
+
* In other case function returns the provided value
|
1943 |
+
*
|
1944 |
+
* @param mixed|FW_Callback $value
|
1945 |
+
*
|
1946 |
+
* @return mixed
|
1947 |
+
*
|
1948 |
+
* @since 2.6.14
|
1949 |
+
*/
|
1950 |
+
function fw_call( $value ) {
|
1951 |
+
if ( $value instanceof FW_Callback ) {
|
1952 |
+
return $value->execute();
|
1953 |
+
}
|
1954 |
+
|
1955 |
+
return $value;
|
1956 |
+
}
|
framework/includes/option-storage/type/class-fw-option-storage-type-wp-option.php
CHANGED
@@ -25,7 +25,12 @@ class FW_Option_Storage_Type_WP_Option extends FW_Option_Storage_Type {
|
|
25 |
|
26 |
unset($wp_option_value);
|
27 |
} else {
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
29 |
}
|
30 |
|
31 |
return fw()->backend->option_type($option['type'])->get_value_from_input(
|
25 |
|
26 |
unset($wp_option_value);
|
27 |
} else {
|
28 |
+
if (empty($value)) {
|
29 |
+
delete_option($wp_option);
|
30 |
+
return $value; // Preserve value (don't return default below) because it can be false|0|array()
|
31 |
+
} else {
|
32 |
+
update_option($wp_option, $value, false);
|
33 |
+
}
|
34 |
}
|
35 |
|
36 |
return fw()->backend->option_type($option['type'])->get_value_from_input(
|
framework/includes/option-types/simple.php
CHANGED
@@ -791,7 +791,7 @@ class FW_Option_Type_Select extends FW_Option_Type {
|
|
791 |
return $result;
|
792 |
}
|
793 |
|
794 |
-
protected function render_choices(
|
795 |
if ( empty( $choices ) || ! is_array( $choices ) ) {
|
796 |
return '';
|
797 |
}
|
@@ -946,7 +946,7 @@ class FW_Option_Type_Select_Multiple extends FW_Option_Type_Select {
|
|
946 |
return $input_value;
|
947 |
}
|
948 |
|
949 |
-
protected function render_choices(
|
950 |
if ( empty( $choices ) || ! is_array( $choices ) ) {
|
951 |
return '';
|
952 |
}
|
791 |
return $result;
|
792 |
}
|
793 |
|
794 |
+
protected function render_choices( $choices, $value ) {
|
795 |
if ( empty( $choices ) || ! is_array( $choices ) ) {
|
796 |
return '';
|
797 |
}
|
946 |
return $input_value;
|
947 |
}
|
948 |
|
949 |
+
protected function render_choices( $choices, $value ) {
|
950 |
if ( empty( $choices ) || ! is_array( $choices ) ) {
|
951 |
return '';
|
952 |
}
|
framework/includes/option-types/typography-v2/class-fw-option-type-typography-v2.php
CHANGED
@@ -173,7 +173,10 @@ class FW_Option_Type_Typography_v2 extends FW_Option_Type {
|
|
173 |
'size' => true,
|
174 |
'line-height' => true,
|
175 |
'letter-spacing' => true,
|
176 |
-
'color' => true
|
|
|
|
|
|
|
177 |
)
|
178 |
);
|
179 |
}
|
173 |
'size' => true,
|
174 |
'line-height' => true,
|
175 |
'letter-spacing' => true,
|
176 |
+
'color' => true,
|
177 |
+
'weight' => true,
|
178 |
+
'style' => true,
|
179 |
+
'variation' => true,
|
180 |
)
|
181 |
);
|
182 |
}
|
framework/includes/option-types/typography-v2/static/css/styles.css
CHANGED
@@ -68,6 +68,7 @@ body.rtl .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-opt
|
|
68 |
display: inline-block;
|
69 |
margin: 0;
|
70 |
width: 100%;
|
|
|
71 |
}
|
72 |
|
73 |
|
68 |
display: inline-block;
|
69 |
margin: 0;
|
70 |
width: 100%;
|
71 |
+
padding: 5px 4px;
|
72 |
}
|
73 |
|
74 |
|
framework/includes/option-types/typography-v2/static/js/scripts.js
CHANGED
@@ -118,18 +118,14 @@
|
|
118 |
.html(getFontsOptionHTML($fontFamilySelect.attr('data-value')))
|
119 |
.selectize({
|
120 |
onChange: function (selected) {
|
121 |
-
var results = $.grep(googleFonts['items'], function (font) {
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
var $style = this.$dropdown.closest(optionTypeClass).find('.fw-option-typography-v2-option-style');
|
128 |
-
var $weight = this.$dropdown.closest(optionTypeClass).find('.fw-option-typography-v2-option-weight');
|
129 |
|
130 |
if (results.length === 1) {
|
131 |
-
var variations = '';
|
132 |
-
var subsets = '';
|
133 |
_.each(results[0]['variants'], function (variation) {
|
134 |
variations += '<option value="' + variation + '">' + variation + '</option>';
|
135 |
});
|
118 |
.html(getFontsOptionHTML($fontFamilySelect.attr('data-value')))
|
119 |
.selectize({
|
120 |
onChange: function (selected) {
|
121 |
+
var results = $.grep(googleFonts['items'], function (font) { return font['family'] === selected; }),
|
122 |
+
$variations = $option.find('.fw-option-typography-v2-option-variation'),
|
123 |
+
$subsets = $option.find('.fw-option-typography-v2-option-subset'),
|
124 |
+
$style = $option.find('.fw-option-typography-v2-option-style'),
|
125 |
+
$weight = $option.find('.fw-option-typography-v2-option-weight');
|
|
|
|
|
|
|
126 |
|
127 |
if (results.length === 1) {
|
128 |
+
var variations = '', subsets = '';
|
|
|
129 |
_.each(results[0]['variants'], function (variation) {
|
130 |
variations += '<option value="' + variation + '">' + variation + '</option>';
|
131 |
});
|
framework/includes/option-types/typography-v2/view.php
CHANGED
@@ -25,7 +25,9 @@
|
|
25 |
|
26 |
}
|
27 |
|
28 |
-
$components = (isset($option['components']) && is_array($option['components']))
|
|
|
|
|
29 |
?>
|
30 |
<div <?php echo fw_attr_to_html( $wrapper_attr ) ?>>
|
31 |
<?php if ( $components['family'] ) : ?>
|
@@ -38,6 +40,7 @@ $components = (isset($option['components']) && is_array($option['components']))
|
|
38 |
<div class="fw-inner"><?php _e('Font face', 'fw'); ?></div>
|
39 |
</div>
|
40 |
|
|
|
41 |
<div class="fw-option-typography-v2-option fw-option-typography-v2-option-style fw-border-box-sizing fw-col-sm-3"
|
42 |
style="display: <?php echo ( $google_font ) ? 'none' : 'inline-block'; ?>;">
|
43 |
<select data-type="style" name="<?php echo esc_attr( $option['attr']['name'] ) ?>[style]"
|
@@ -57,7 +60,9 @@ $components = (isset($option['components']) && is_array($option['components']))
|
|
57 |
|
58 |
<div class="fw-inner"><?php _e( 'Style', 'fw' ); ?></div>
|
59 |
</div>
|
|
|
60 |
|
|
|
61 |
<div class="fw-option-typography-v2-option fw-option-typography-v2-option-weight fw-border-box-sizing fw-col-sm-3"
|
62 |
style="display: <?php echo ( $google_font ) ? 'none' : 'inline-block'; ?>;">
|
63 |
<select data-type="weight" name="<?php echo esc_attr( $option['attr']['name'] ) ?>[weight]"
|
@@ -83,6 +88,7 @@ $components = (isset($option['components']) && is_array($option['components']))
|
|
83 |
|
84 |
<div class="fw-inner"><?php _e( 'Weight', 'fw' ); ?></div>
|
85 |
</div>
|
|
|
86 |
|
87 |
<div class="fw-option-typography-v2-option fw-option-typography-v2-option-subset fw-border-box-sizing fw-col-sm-2"
|
88 |
style="display: <?php echo ( $google_font ) ? 'inline-block' : 'none'; ?>;">
|
@@ -100,6 +106,8 @@ $components = (isset($option['components']) && is_array($option['components']))
|
|
100 |
<div class="fw-inner"><?php _e( 'Script', 'fw' ); ?></div>
|
101 |
</div>
|
102 |
|
|
|
|
|
103 |
<div
|
104 |
class="fw-option-typography-v2-option fw-option-typography-v2-option-variation fw-border-box-sizing fw-col-sm-2"
|
105 |
style="display: <?php echo ( $google_font ) ? 'inline-block' : 'none'; ?>;">
|
@@ -114,8 +122,9 @@ $components = (isset($option['components']) && is_array($option['components']))
|
|
114 |
?>
|
115 |
</select>
|
116 |
|
117 |
-
<div class="fw-inner"><?php
|
118 |
</div>
|
|
|
119 |
<?php endif; ?>
|
120 |
|
121 |
<?php if ( $components['size'] ) : ?>
|
@@ -124,7 +133,7 @@ $components = (isset($option['components']) && is_array($option['components']))
|
|
124 |
class="fw-option-typography-v2-option-size-input" type="text"
|
125 |
value="<?php echo esc_attr($data['value']['size']); ?>">
|
126 |
|
127 |
-
<div class="fw-inner"><?php
|
128 |
</div>
|
129 |
<?php endif; ?>
|
130 |
|
@@ -135,7 +144,7 @@ $components = (isset($option['components']) && is_array($option['components']))
|
|
135 |
value="<?php echo esc_attr($data['value']['line-height']); ?>"
|
136 |
class="fw-option-typography-v2-option-line-height-input" type="text">
|
137 |
|
138 |
-
<div class="fw-inner"><?php
|
139 |
</div>
|
140 |
<?php endif; ?>
|
141 |
|
@@ -146,7 +155,7 @@ $components = (isset($option['components']) && is_array($option['components']))
|
|
146 |
value="<?php echo esc_attr($data['value']['letter-spacing']); ?>"
|
147 |
class="fw-option-typography-v2-option-letter-spacing-input" type="text">
|
148 |
|
149 |
-
<div class="fw-inner"><?php
|
150 |
</div>
|
151 |
<?php endif; ?>
|
152 |
|
@@ -169,7 +178,7 @@ $components = (isset($option['components']) && is_array($option['components']))
|
|
169 |
)
|
170 |
)
|
171 |
?>
|
172 |
-
<div class="fw-inner"><?php
|
173 |
</div>
|
174 |
<?php endif; ?>
|
175 |
|
25 |
|
26 |
}
|
27 |
|
28 |
+
$components = (isset($option['components']) && is_array($option['components']))
|
29 |
+
? array_merge($defaults['components'], $option['components'])
|
30 |
+
: $defaults['components'];
|
31 |
?>
|
32 |
<div <?php echo fw_attr_to_html( $wrapper_attr ) ?>>
|
33 |
<?php if ( $components['family'] ) : ?>
|
40 |
<div class="fw-inner"><?php _e('Font face', 'fw'); ?></div>
|
41 |
</div>
|
42 |
|
43 |
+
<?php if ( $components['style'] ) : ?>
|
44 |
<div class="fw-option-typography-v2-option fw-option-typography-v2-option-style fw-border-box-sizing fw-col-sm-3"
|
45 |
style="display: <?php echo ( $google_font ) ? 'none' : 'inline-block'; ?>;">
|
46 |
<select data-type="style" name="<?php echo esc_attr( $option['attr']['name'] ) ?>[style]"
|
60 |
|
61 |
<div class="fw-inner"><?php _e( 'Style', 'fw' ); ?></div>
|
62 |
</div>
|
63 |
+
<?php endif; ?>
|
64 |
|
65 |
+
<?php if ( $components['weight'] ) : ?>
|
66 |
<div class="fw-option-typography-v2-option fw-option-typography-v2-option-weight fw-border-box-sizing fw-col-sm-3"
|
67 |
style="display: <?php echo ( $google_font ) ? 'none' : 'inline-block'; ?>;">
|
68 |
<select data-type="weight" name="<?php echo esc_attr( $option['attr']['name'] ) ?>[weight]"
|
88 |
|
89 |
<div class="fw-inner"><?php _e( 'Weight', 'fw' ); ?></div>
|
90 |
</div>
|
91 |
+
<?php endif; ?>
|
92 |
|
93 |
<div class="fw-option-typography-v2-option fw-option-typography-v2-option-subset fw-border-box-sizing fw-col-sm-2"
|
94 |
style="display: <?php echo ( $google_font ) ? 'inline-block' : 'none'; ?>;">
|
106 |
<div class="fw-inner"><?php _e( 'Script', 'fw' ); ?></div>
|
107 |
</div>
|
108 |
|
109 |
+
|
110 |
+
<?php if ( $components['variation'] ) : ?>
|
111 |
<div
|
112 |
class="fw-option-typography-v2-option fw-option-typography-v2-option-variation fw-border-box-sizing fw-col-sm-2"
|
113 |
style="display: <?php echo ( $google_font ) ? 'inline-block' : 'none'; ?>;">
|
122 |
?>
|
123 |
</select>
|
124 |
|
125 |
+
<div class="fw-inner"><?php esc_html_e( 'Style', 'fw' ); ?></div>
|
126 |
</div>
|
127 |
+
<?php endif; ?>
|
128 |
<?php endif; ?>
|
129 |
|
130 |
<?php if ( $components['size'] ) : ?>
|
133 |
class="fw-option-typography-v2-option-size-input" type="text"
|
134 |
value="<?php echo esc_attr($data['value']['size']); ?>">
|
135 |
|
136 |
+
<div class="fw-inner"><?php esc_html_e( 'Size', 'fw' ); ?></div>
|
137 |
</div>
|
138 |
<?php endif; ?>
|
139 |
|
144 |
value="<?php echo esc_attr($data['value']['line-height']); ?>"
|
145 |
class="fw-option-typography-v2-option-line-height-input" type="text">
|
146 |
|
147 |
+
<div class="fw-inner"><?php esc_html_e( 'Line height', 'fw' ); ?></div>
|
148 |
</div>
|
149 |
<?php endif; ?>
|
150 |
|
155 |
value="<?php echo esc_attr($data['value']['letter-spacing']); ?>"
|
156 |
class="fw-option-typography-v2-option-letter-spacing-input" type="text">
|
157 |
|
158 |
+
<div class="fw-inner"><?php esc_html_e( 'Spacing', 'fw' ); ?></div>
|
159 |
</div>
|
160 |
<?php endif; ?>
|
161 |
|
178 |
)
|
179 |
)
|
180 |
?>
|
181 |
+
<div class="fw-inner"><?php esc_html_e( 'Color', 'fw' ); ?></div>
|
182 |
</div>
|
183 |
<?php endif; ?>
|
184 |
|
framework/manifest.php
CHANGED
@@ -4,4 +4,4 @@ $manifest = array();
|
|
4 |
|
5 |
$manifest['name'] = __('Unyson', 'fw');
|
6 |
|
7 |
-
$manifest['version'] = '2.6.
|
4 |
|
5 |
$manifest['name'] = __('Unyson', 'fw');
|
6 |
|
7 |
+
$manifest['version'] = '2.6.14';
|
framework/static/js/fw.js
CHANGED
@@ -730,6 +730,8 @@ fw.getQueryString = function(name) {
|
|
730 |
uploader: false
|
731 |
});
|
732 |
|
|
|
|
|
733 |
var modal = this;
|
734 |
|
735 |
this.frame.once('ready', function(){
|
@@ -977,6 +979,65 @@ fw.getQueryString = function(name) {
|
|
977 |
$frame.css('overflow-y', 'hidden');
|
978 |
}
|
979 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
980 |
})();
|
981 |
|
982 |
/**
|
@@ -1196,6 +1257,18 @@ fw.getValuesFromServer = function (data) {
|
|
1196 |
silentReceiveOfDefaultValues: true
|
1197 |
}
|
1198 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1199 |
initializeFrame: function(settings) {
|
1200 |
fw.Modal.prototype.initializeFrame.call(this, settings);
|
1201 |
|
@@ -1205,7 +1278,7 @@ fw.getValuesFromServer = function (data) {
|
|
1205 |
buttons = [
|
1206 |
{
|
1207 |
style: 'primary',
|
1208 |
-
text: settings.saveText || _fw_localized.l10n.
|
1209 |
priority: 40,
|
1210 |
click: function () {
|
1211 |
if (settings.shouldSaveWithoutClose) {
|
730 |
uploader: false
|
731 |
});
|
732 |
|
733 |
+
patchMediaFramesModalToDoTheFocusCorrectly( this.frame );
|
734 |
+
|
735 |
var modal = this;
|
736 |
|
737 |
this.frame.once('ready', function(){
|
979 |
$frame.css('overflow-y', 'hidden');
|
980 |
}
|
981 |
});
|
982 |
+
|
983 |
+
// https://github.com/WordPress/WordPress/blob/4ca4ff999aba05892c05d26cddf3af540f47b93b/wp-includes/js/media-views.js#L6800
|
984 |
+
// When you execute frame.modal.open() - the modal tries to switch focus
|
985 |
+
// to its $el. Actually, this switches the scrollTop property for window.
|
986 |
+
//
|
987 |
+
// In order to prevent that we'll have to monkey patch the frame.modal.open
|
988 |
+
// method and do the focus properly - that's what this function does
|
989 |
+
function patchMediaFramesModalToDoTheFocusCorrectly (frame) {
|
990 |
+
if (! frame.modal) return;
|
991 |
+
|
992 |
+
frame.modal.open = function () {
|
993 |
+
var $el = this.$el,
|
994 |
+
options = this.options,
|
995 |
+
mceEditor;
|
996 |
+
|
997 |
+
if ( $el.is(':visible') ) {
|
998 |
+
return this;
|
999 |
+
}
|
1000 |
+
|
1001 |
+
this.clickedOpenerEl = document.activeElement;
|
1002 |
+
|
1003 |
+
if ( ! this.views.attached ) {
|
1004 |
+
this.attach();
|
1005 |
+
}
|
1006 |
+
|
1007 |
+
// If the `freeze` option is set, record the window's scroll position.
|
1008 |
+
if ( options.freeze ) {
|
1009 |
+
this._freeze = {
|
1010 |
+
scrollTop: jQuery( window ).scrollTop()
|
1011 |
+
};
|
1012 |
+
}
|
1013 |
+
|
1014 |
+
// Disable page scrolling.
|
1015 |
+
jQuery( 'body' ).addClass( 'modal-open' );
|
1016 |
+
|
1017 |
+
$el.show();
|
1018 |
+
|
1019 |
+
// Try to close the onscreen keyboard
|
1020 |
+
if ( 'ontouchend' in document ) {
|
1021 |
+
if ( ( mceEditor = window.tinymce && window.tinymce.activeEditor ) && ! mceEditor.isHidden() && mceEditor.iframeElement ) {
|
1022 |
+
mceEditor.iframeElement.focus();
|
1023 |
+
mceEditor.iframeElement.blur();
|
1024 |
+
|
1025 |
+
setTimeout( function() {
|
1026 |
+
mceEditor.iframeElement.blur();
|
1027 |
+
}, 100 );
|
1028 |
+
}
|
1029 |
+
}
|
1030 |
+
|
1031 |
+
// this part is changed from the original method
|
1032 |
+
// this.$el.focus();
|
1033 |
+
// http://stackoverflow.com/a/11676673/3220977
|
1034 |
+
var initialX = window.scrollX, initialY = window.scrollY;
|
1035 |
+
this.$el.focus();
|
1036 |
+
window.scrollTo(initialX, initialY);
|
1037 |
+
|
1038 |
+
return this.propagate('open');
|
1039 |
+
}
|
1040 |
+
}
|
1041 |
})();
|
1042 |
|
1043 |
/**
|
1257 |
silentReceiveOfDefaultValues: true
|
1258 |
}
|
1259 |
),
|
1260 |
+
initialize: function () {
|
1261 |
+
fw.Modal.prototype.initialize.call(this);
|
1262 |
+
|
1263 |
+
// Forward events to fwEvents
|
1264 |
+
{
|
1265 |
+
/** @since 2.6.14 */
|
1266 |
+
this.on('open', function () { fwEvents.trigger('fw:options-modal:open', {modal: this}); });
|
1267 |
+
|
1268 |
+
/** @since 2.6.14 */
|
1269 |
+
this.on('close', function () { fwEvents.trigger('fw:options-modal:close', {modal: this}); });
|
1270 |
+
}
|
1271 |
+
},
|
1272 |
initializeFrame: function(settings) {
|
1273 |
fw.Modal.prototype.initializeFrame.call(this, settings);
|
1274 |
|
1278 |
buttons = [
|
1279 |
{
|
1280 |
style: 'primary',
|
1281 |
+
text: settings.saveText || _fw_localized.l10n.modal_save_btn,
|
1282 |
priority: 40,
|
1283 |
click: function () {
|
1284 |
if (settings.shouldSaveWithoutClose) {
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: unyson
|
|
3 |
Tags: page builder, shortcodes, backup, seo, breadcrumbs, portfolio, framework
|
4 |
Requires at least: 4.4
|
5 |
Tested up to: 4.7
|
6 |
-
Stable tag: 2.6.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -85,6 +85,10 @@ Yes; Unyson will work with any theme.
|
|
85 |
|
86 |
== Changelog ==
|
87 |
|
|
|
|
|
|
|
|
|
88 |
= 2.6.13 =
|
89 |
* Fixed [#2310](https://github.com/ThemeFuse/Unyson/issues/2310), [#2308](https://github.com/ThemeFuse/Unyson/issues/2308), [#961](https://github.com/ThemeFuse/Unyson/issues/961), [#2073](https://github.com/ThemeFuse/Unyson/issues/2073)
|
90 |
|
3 |
Tags: page builder, shortcodes, backup, seo, breadcrumbs, portfolio, framework
|
4 |
Requires at least: 4.4
|
5 |
Tested up to: 4.7
|
6 |
+
Stable tag: 2.6.14
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
85 |
|
86 |
== Changelog ==
|
87 |
|
88 |
+
= 2.6.14 =
|
89 |
+
* Fixed infinite loop when php memory limit is `-1`
|
90 |
+
* Minor changes
|
91 |
+
|
92 |
= 2.6.13 =
|
93 |
* Fixed [#2310](https://github.com/ThemeFuse/Unyson/issues/2310), [#2308](https://github.com/ThemeFuse/Unyson/issues/2308), [#961](https://github.com/ThemeFuse/Unyson/issues/961), [#2073](https://github.com/ThemeFuse/Unyson/issues/2073)
|
94 |
|
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.6.
|
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.6.14
|
7 |
* Author: ThemeFuse
|
8 |
* Author URI: http://themefuse.com
|
9 |
* License: GPL2+
|