Version Description
- Minor fixes and improvements in the extensions installation process
Download this release
Release Info
Developer | Unyson |
Plugin | Unyson |
Version | 2.1.2 |
Comparing to | |
See all releases |
Code changes from version 2.1.1 to 2.1.2
- CONTRIBUTING.md +25 -0
- framework/core/components/extensions/manager/class--fw-extensions-manager.php +22 -15
- framework/core/components/extensions/manager/static/extensions-page.js +1 -1
- framework/core/components/extensions/manager/views/extension.php +19 -1
- framework/core/components/extensions/manager/views/extensions-page.php +37 -20
- framework/core/components/extensions/manager/views/install-form.php +10 -0
- framework/extensions/update/class-fw-extension-update.php +1 -1
- framework/helpers/class-fw-form.php +131 -109
- framework/helpers/class-fw-wp-filesystem.php +20 -16
- framework/helpers/general.php +11 -0
- framework/manifest.php +1 -1
- readme.txt +4 -1
- unyson.php +12 -1
CONTRIBUTING.md
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# How to contribute
|
2 |
+
|
3 |
+
## Getting Started
|
4 |
+
|
5 |
+
* Make sure you have a [GitHub account](https://github.com/signup/free)
|
6 |
+
* Submit a ticket for your issue, assuming one does not already exist.
|
7 |
+
* Clearly describe the issue including steps to reproduce when it is a bug.
|
8 |
+
* Make sure you fill in the earliest version that you know has the issue.
|
9 |
+
|
10 |
+
## Making Changes
|
11 |
+
|
12 |
+
* Fork the repository on GitHub.
|
13 |
+
* Make the changes to your forked repository.
|
14 |
+
* **Ensure you stick to the [WordPress Coding Standards](http://make.wordpress.org/core/handbook/coding-standards/php/).**
|
15 |
+
* Ensure you use LF line endings - no crazy windows line endings. :)
|
16 |
+
* When committing, reference your issue (#1234) and include a note about the fix.
|
17 |
+
* Push the changes to your fork and submit a pull request on the master branch of the Unyson repository. Existing maintenance branches will be maintained of by Unyson developers.
|
18 |
+
|
19 |
+
At this point you're waiting on us to merge your pull request. We'll review all pull requests, and make suggestions and changes if necessary.
|
20 |
+
|
21 |
+
# Additional Resources
|
22 |
+
|
23 |
+
* [General GitHub documentation](http://help.github.com/)
|
24 |
+
* [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
|
25 |
+
* [Unyson Docs](http://unyson-docs.themefuse.com/)
|
framework/core/components/extensions/manager/class--fw-extensions-manager.php
CHANGED
@@ -152,7 +152,7 @@ final class _FW_Extensions_Manager
|
|
152 |
wp_send_json_error();
|
153 |
}
|
154 |
|
155 |
-
if (FW_WP_Filesystem::has_direct_access()) {
|
156 |
wp_send_json_success();
|
157 |
} else {
|
158 |
wp_send_json_error();
|
@@ -205,6 +205,7 @@ final class _FW_Extensions_Manager
|
|
205 |
return;
|
206 |
}
|
207 |
|
|
|
208 |
$tmp_dir = FW_WP_Filesystem::real_path_to_filesystem_path(
|
209 |
fw_fix_path(WP_CONTENT_DIR) .'/tmp/fw-plugin-update-extensions-backup'
|
210 |
);
|
@@ -253,8 +254,9 @@ final class _FW_Extensions_Manager
|
|
253 |
return;
|
254 |
}
|
255 |
|
|
|
256 |
$tmp_dir = FW_WP_Filesystem::real_path_to_filesystem_path(
|
257 |
-
fw_fix_path( WP_CONTENT_DIR ) .
|
258 |
);
|
259 |
$extensions_dir = FW_WP_Filesystem::real_path_to_filesystem_path(
|
260 |
fw_get_framework_directory( '/extensions' )
|
@@ -328,8 +330,8 @@ final class _FW_Extensions_Manager
|
|
328 |
|
329 |
$extensions = array();
|
330 |
|
331 |
-
foreach ($search_paths as $path) {
|
332 |
-
$this->read_extensions($path, $extensions);
|
333 |
}
|
334 |
|
335 |
FW_Cache::set($cache_key, $extensions);
|
@@ -340,11 +342,12 @@ final class _FW_Extensions_Manager
|
|
340 |
|
341 |
/**
|
342 |
* used by $this->get_installed_extensions()
|
|
|
343 |
* @param string $path
|
344 |
* @param array $list
|
345 |
* @param null|string $parent_extension_name
|
346 |
*/
|
347 |
-
private function read_extensions($path, &$list, $parent_extension_name = null)
|
348 |
{
|
349 |
$paths = glob($path .'/*', GLOB_ONLYDIR | GLOB_NOSORT);
|
350 |
|
@@ -363,6 +366,7 @@ final class _FW_Extensions_Manager
|
|
363 |
));
|
364 |
|
365 |
$list[$extension_name] = array(
|
|
|
366 |
'path' => $extension_path,
|
367 |
'manifest' => $vars['manifest'],
|
368 |
'children' => array(),
|
@@ -379,6 +383,7 @@ final class _FW_Extensions_Manager
|
|
379 |
}
|
380 |
|
381 |
$this->read_extensions(
|
|
|
382 |
$extension_path .'/extensions',
|
383 |
$list,
|
384 |
$extension_name
|
@@ -386,11 +391,9 @@ final class _FW_Extensions_Manager
|
|
386 |
}
|
387 |
}
|
388 |
|
389 |
-
private function get_tmp_dir()
|
390 |
{
|
391 |
-
return
|
392 |
-
fw_fix_path(WP_CONTENT_DIR) .'/tmp/fw-extension-download'
|
393 |
-
);
|
394 |
}
|
395 |
|
396 |
/**
|
@@ -733,10 +736,9 @@ final class _FW_Extensions_Manager
|
|
733 |
foreach ($parent_extensions as $parent_extension_name) {
|
734 |
$current_extension_path .= '/extensions/'. $parent_extension_name;
|
735 |
|
736 |
-
$activate_extensions[$parent_extension_name] = array();
|
737 |
-
|
738 |
if (isset($installed_extensions[$parent_extension_name])) {
|
739 |
// skip already installed extensions
|
|
|
740 |
continue;
|
741 |
}
|
742 |
|
@@ -778,6 +780,8 @@ final class _FW_Extensions_Manager
|
|
778 |
)
|
779 |
);
|
780 |
|
|
|
|
|
781 |
/**
|
782 |
* Read again all extensions
|
783 |
* The downloaded extension may contain more sub extensions
|
@@ -880,10 +884,12 @@ final class _FW_Extensions_Manager
|
|
880 |
/** @var WP_Filesystem_Base $wp_filesystem */
|
881 |
global $wp_filesystem;
|
882 |
|
883 |
-
|
884 |
-
|
|
|
|
|
885 |
$skin->error(
|
886 |
-
sprintf( __( 'Cannot remove temporary directory: %s', 'fw' ), $
|
887 |
);
|
888 |
break;
|
889 |
}
|
@@ -900,6 +906,7 @@ final class _FW_Extensions_Manager
|
|
900 |
fw_render_view(dirname(__FILE__) .'/views/install-form.php', array(
|
901 |
'extension_titles' => $install_data['all'],
|
902 |
'list_page_link' => $this->get_link(),
|
|
|
903 |
), false);
|
904 |
|
905 |
echo '</form>';
|
@@ -1587,7 +1594,7 @@ final class _FW_Extensions_Manager
|
|
1587 |
|
1588 |
// create temporary directory
|
1589 |
{
|
1590 |
-
$wp_fs_tmp_dir = $this->get_tmp_dir();
|
1591 |
|
1592 |
if ($wp_filesystem->exists($wp_fs_tmp_dir)) {
|
1593 |
// just in case it already exists, clear everything, it may contain old files
|
152 |
wp_send_json_error();
|
153 |
}
|
154 |
|
155 |
+
if (FW_WP_Filesystem::has_direct_access(fw_get_framework_directory('/extensions'))) {
|
156 |
wp_send_json_success();
|
157 |
} else {
|
158 |
wp_send_json_error();
|
205 |
return;
|
206 |
}
|
207 |
|
208 |
+
// a directory outside the plugin
|
209 |
$tmp_dir = FW_WP_Filesystem::real_path_to_filesystem_path(
|
210 |
fw_fix_path(WP_CONTENT_DIR) .'/tmp/fw-plugin-update-extensions-backup'
|
211 |
);
|
254 |
return;
|
255 |
}
|
256 |
|
257 |
+
// a directory outside the plugin
|
258 |
$tmp_dir = FW_WP_Filesystem::real_path_to_filesystem_path(
|
259 |
+
fw_fix_path( WP_CONTENT_DIR ) .'/tmp/fw-plugin-update-extensions-backup'
|
260 |
);
|
261 |
$extensions_dir = FW_WP_Filesystem::real_path_to_filesystem_path(
|
262 |
fw_get_framework_directory( '/extensions' )
|
330 |
|
331 |
$extensions = array();
|
332 |
|
333 |
+
foreach ($search_paths as $source => $path) {
|
334 |
+
$this->read_extensions($source, $path, $extensions);
|
335 |
}
|
336 |
|
337 |
FW_Cache::set($cache_key, $extensions);
|
342 |
|
343 |
/**
|
344 |
* used by $this->get_installed_extensions()
|
345 |
+
* @param string $source
|
346 |
* @param string $path
|
347 |
* @param array $list
|
348 |
* @param null|string $parent_extension_name
|
349 |
*/
|
350 |
+
private function read_extensions($source, $path, &$list, $parent_extension_name = null)
|
351 |
{
|
352 |
$paths = glob($path .'/*', GLOB_ONLYDIR | GLOB_NOSORT);
|
353 |
|
366 |
));
|
367 |
|
368 |
$list[$extension_name] = array(
|
369 |
+
'source' => $source,
|
370 |
'path' => $extension_path,
|
371 |
'manifest' => $vars['manifest'],
|
372 |
'children' => array(),
|
383 |
}
|
384 |
|
385 |
$this->read_extensions(
|
386 |
+
$source,
|
387 |
$extension_path .'/extensions',
|
388 |
$list,
|
389 |
$extension_name
|
391 |
}
|
392 |
}
|
393 |
|
394 |
+
private function get_tmp_dir($append = '')
|
395 |
{
|
396 |
+
return apply_filters('fw_tmp_dir', fw_fix_path(WP_CONTENT_DIR) .'/tmp') . $append;
|
|
|
|
|
397 |
}
|
398 |
|
399 |
/**
|
736 |
foreach ($parent_extensions as $parent_extension_name) {
|
737 |
$current_extension_path .= '/extensions/'. $parent_extension_name;
|
738 |
|
|
|
|
|
739 |
if (isset($installed_extensions[$parent_extension_name])) {
|
740 |
// skip already installed extensions
|
741 |
+
$activate_extensions[$parent_extension_name] = array();
|
742 |
continue;
|
743 |
}
|
744 |
|
780 |
)
|
781 |
);
|
782 |
|
783 |
+
$activate_extensions[$parent_extension_name] = array();
|
784 |
+
|
785 |
/**
|
786 |
* Read again all extensions
|
787 |
* The downloaded extension may contain more sub extensions
|
884 |
/** @var WP_Filesystem_Base $wp_filesystem */
|
885 |
global $wp_filesystem;
|
886 |
|
887 |
+
$wp_fs_tmp_dir = FW_WP_Filesystem::real_path_to_filesystem_path($this->get_tmp_dir());
|
888 |
+
|
889 |
+
if ($wp_filesystem->exists($wp_fs_tmp_dir)) {
|
890 |
+
if ( ! $wp_filesystem->rmdir( $wp_fs_tmp_dir, true ) ) {
|
891 |
$skin->error(
|
892 |
+
sprintf( __( 'Cannot remove temporary directory: %s', 'fw' ), $wp_fs_tmp_dir )
|
893 |
);
|
894 |
break;
|
895 |
}
|
906 |
fw_render_view(dirname(__FILE__) .'/views/install-form.php', array(
|
907 |
'extension_titles' => $install_data['all'],
|
908 |
'list_page_link' => $this->get_link(),
|
909 |
+
'supported' => $supported
|
910 |
), false);
|
911 |
|
912 |
echo '</form>';
|
1594 |
|
1595 |
// create temporary directory
|
1596 |
{
|
1597 |
+
$wp_fs_tmp_dir = FW_WP_Filesystem::real_path_to_filesystem_path($this->get_tmp_dir());
|
1598 |
|
1599 |
if ($wp_filesystem->exists($wp_fs_tmp_dir)) {
|
1600 |
// just in case it already exists, clear everything, it may contain old files
|
framework/core/components/extensions/manager/static/extensions-page.js
CHANGED
@@ -93,7 +93,7 @@ jQuery(function($){
|
|
93 |
window.location.reload();
|
94 |
} else {
|
95 |
if (true) {
|
96 |
-
var $lastMessage = $content.find('p
|
97 |
|
98 |
if ($lastMessage.find('a').length) {
|
99 |
// this is not message, these are link printed by WP_Upgrader_Skin::after()
|
93 |
window.location.reload();
|
94 |
} else {
|
95 |
if (true) {
|
96 |
+
var $lastMessage = $content.find('> p').last();
|
97 |
|
98 |
if ($lastMessage.find('a').length) {
|
99 |
// this is not message, these are link printed by WP_Upgrader_Skin::after()
|
framework/core/components/extensions/manager/views/extension.php
CHANGED
@@ -77,7 +77,16 @@ if (isset($lists['available'][$name])) {
|
|
77 |
unset( $_links );
|
78 |
}
|
79 |
?>
|
80 |
-
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
<p><em><strong><span class="dashicons dashicons-yes"></span> <?php _e('Compatible', 'fw') ?></strong> <?php _e('with your current theme', 'fw') ?></em></p>
|
82 |
<?php endif; ?>
|
83 |
</td>
|
@@ -93,6 +102,14 @@ if (isset($lists['available'][$name])) {
|
|
93 |
<?php wp_nonce_field($nonces['activate']['action'], $nonces['activate']['name']); ?>
|
94 |
<input class="button" type="submit" value="<?php esc_attr_e('Activate', 'fw'); ?>"/>
|
95 |
</form>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
<form action="<?php echo esc_attr($link) ?>&sub-page=delete&extension=<?php echo esc_attr($name) ?>"
|
97 |
method="post"
|
98 |
class="fw-extension-ajax-form"
|
@@ -102,6 +119,7 @@ if (isset($lists['available'][$name])) {
|
|
102 |
<a href="#" onclick="jQuery(this).closest('form').submit(); return false;" data-remove-extension="<?php echo esc_attr($name) ?>" ><?php _e('Remove', 'fw'); ?></a>
|
103 |
</p>
|
104 |
</form>
|
|
|
105 |
</div>
|
106 |
<?php elseif ($available_data): ?>
|
107 |
<form action="<?php echo esc_attr($link) ?>&sub-page=install&extension=<?php echo esc_attr($name) ?>" method="post" class="fw-extension-ajax-form">
|
77 |
unset( $_links );
|
78 |
}
|
79 |
?>
|
80 |
+
<?php
|
81 |
+
if (
|
82 |
+
!$is_active // do not show the "Compatible" text is extension is already active
|
83 |
+
&&
|
84 |
+
(
|
85 |
+
isset($lists['supported'][$name]) // is listed in the supported extensions list in theme manifest
|
86 |
+
||
|
87 |
+
($installed_data && $installed_data['source'] !== 'framework') // is located in the theme
|
88 |
+
)
|
89 |
+
): ?>
|
90 |
<p><em><strong><span class="dashicons dashicons-yes"></span> <?php _e('Compatible', 'fw') ?></strong> <?php _e('with your current theme', 'fw') ?></em></p>
|
91 |
<?php endif; ?>
|
92 |
</td>
|
102 |
<?php wp_nonce_field($nonces['activate']['action'], $nonces['activate']['name']); ?>
|
103 |
<input class="button" type="submit" value="<?php esc_attr_e('Activate', 'fw'); ?>"/>
|
104 |
</form>
|
105 |
+
<?php
|
106 |
+
/**
|
107 |
+
* Do not show the "Delete extension" button if the extension is not in the available list.
|
108 |
+
* If you delete such extension you will not be able to install it back.
|
109 |
+
* Most often these will be extensions located in the theme.
|
110 |
+
*/
|
111 |
+
if ($available_data):
|
112 |
+
?>
|
113 |
<form action="<?php echo esc_attr($link) ?>&sub-page=delete&extension=<?php echo esc_attr($name) ?>"
|
114 |
method="post"
|
115 |
class="fw-extension-ajax-form"
|
119 |
<a href="#" onclick="jQuery(this).closest('form').submit(); return false;" data-remove-extension="<?php echo esc_attr($name) ?>" ><?php _e('Remove', 'fw'); ?></a>
|
120 |
</p>
|
121 |
</form>
|
122 |
+
<?php endif; ?>
|
123 |
</div>
|
124 |
<?php elseif ($available_data): ?>
|
125 |
<form action="<?php echo esc_attr($link) ?>&sub-page=install&extension=<?php echo esc_attr($name) ?>" method="post" class="fw-extension-ajax-form">
|
framework/core/components/extensions/manager/views/extensions-page.php
CHANGED
@@ -56,31 +56,48 @@ foreach ($lists['active'] as $name => &$data) {
|
|
56 |
<div class="fw-row fw-extensions-list">
|
57 |
<?php $something_displayed = false; ?>
|
58 |
<?php
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
if (
|
64 |
continue;
|
65 |
}
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
}
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
'
|
81 |
-
|
|
|
|
|
|
|
|
|
82 |
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
}
|
85 |
|
86 |
foreach ($lists['disabled'] as $name => &$data) {
|
56 |
<div class="fw-row fw-extensions-list">
|
57 |
<?php $something_displayed = false; ?>
|
58 |
<?php
|
59 |
+
{
|
60 |
+
$theme_extensions = array();
|
61 |
+
|
62 |
+
foreach ($lists['disabled'] as $name => &$data) {
|
63 |
+
if ($data['source'] == 'framework') {
|
64 |
continue;
|
65 |
}
|
66 |
+
|
67 |
+
$theme_extensions[$name] = array(
|
68 |
+
'name' => fw_akg('name', $data['manifest'], fw_id_to_title($name)),
|
69 |
+
'description' => fw_akg('description', $data['manifest'], '')
|
70 |
+
);
|
71 |
}
|
72 |
|
73 |
+
foreach (($theme_extensions + $lists['supported']) as $name => $data) {
|
74 |
+
if (isset($displayed[$name])) {
|
75 |
+
continue;
|
76 |
+
} elseif (isset($lists['installed'][$name])) {
|
77 |
+
if (true !== fw_akg('display', $lists['installed'][$name]['manifest'], $display_default_value)) {
|
78 |
+
continue;
|
79 |
+
}
|
80 |
+
} elseif (!isset($lists['available'][$name])) {
|
81 |
+
/*trigger_error(
|
82 |
+
sprintf(__('Supported extension "%s" is not available.', 'fw'), $name)
|
83 |
+
);*/
|
84 |
+
continue;
|
85 |
+
}
|
86 |
|
87 |
+
fw_render_view($extension_view_path, array(
|
88 |
+
'name' => $name,
|
89 |
+
'title' => $data['name'],
|
90 |
+
'description' => $data['description'],
|
91 |
+
'link' => $link,
|
92 |
+
'lists' => &$lists,
|
93 |
+
'nonces' => $nonces,
|
94 |
+
'default_thumbnail' => $default_thumbnail,
|
95 |
+
), false);
|
96 |
+
|
97 |
+
$displayed[$name] = $something_displayed = true;
|
98 |
+
}
|
99 |
+
|
100 |
+
unset($theme_extensions);
|
101 |
}
|
102 |
|
103 |
foreach ($lists['disabled'] as $name => &$data) {
|
framework/core/components/extensions/manager/views/install-form.php
CHANGED
@@ -2,17 +2,27 @@
|
|
2 |
/**
|
3 |
* @var array $extension_titles
|
4 |
* @var array $list_page_link
|
|
|
5 |
*/
|
6 |
|
7 |
$count = count($extension_titles);
|
8 |
?>
|
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
<p><?php echo _n(
|
11 |
'You are about to install the following extension:',
|
12 |
'You are about to install the following extensions:',
|
13 |
$count,
|
14 |
'fw'
|
15 |
) ?></p>
|
|
|
16 |
|
17 |
<ul class="ul-disc">
|
18 |
<?php foreach ($extension_titles as $extension_title): ?>
|
2 |
/**
|
3 |
* @var array $extension_titles
|
4 |
* @var array $list_page_link
|
5 |
+
* @var bool $supported
|
6 |
*/
|
7 |
|
8 |
$count = count($extension_titles);
|
9 |
?>
|
10 |
|
11 |
+
<?php if ($supported): ?>
|
12 |
+
<p><?php echo _n(
|
13 |
+
'We\'ve detected that your current theme is compatible with the following extension and it is recommended that you install it to fully benefit from your theme.',
|
14 |
+
'We\'ve detected that your current theme is compatible with the following extensions and it is recommended that you install them to fully benefit from your theme.',
|
15 |
+
$count,
|
16 |
+
'fw'
|
17 |
+
) ?></p>
|
18 |
+
<?php else: ?>
|
19 |
<p><?php echo _n(
|
20 |
'You are about to install the following extension:',
|
21 |
'You are about to install the following extensions:',
|
22 |
$count,
|
23 |
'fw'
|
24 |
) ?></p>
|
25 |
+
<?php endif; ?>
|
26 |
|
27 |
<ul class="ul-disc">
|
28 |
<?php foreach ($extension_titles as $extension_title): ?>
|
framework/extensions/update/class-fw-extension-update.php
CHANGED
@@ -62,7 +62,7 @@ class FW_Extension_Update extends FW_Extension
|
|
62 |
private function get_wp_fs_tmp_dir()
|
63 |
{
|
64 |
return FW_WP_Filesystem::real_path_to_filesystem_path(
|
65 |
-
fw_fix_path(WP_CONTENT_DIR) .'/tmp/fw-ext-update'
|
66 |
);
|
67 |
}
|
68 |
|
62 |
private function get_wp_fs_tmp_dir()
|
63 |
{
|
64 |
return FW_WP_Filesystem::real_path_to_filesystem_path(
|
65 |
+
apply_filters('fw_tmp_dir', fw_fix_path(WP_CONTENT_DIR) .'/tmp') .'/fw-ext-update'
|
66 |
);
|
67 |
}
|
68 |
|
framework/helpers/class-fw-form.php
CHANGED
@@ -1,10 +1,11 @@
|
|
1 |
-
<?php if (!defined('FW'))
|
|
|
|
|
2 |
|
3 |
/**
|
4 |
* Dynamic forms
|
5 |
*/
|
6 |
-
class FW_Form
|
7 |
-
{
|
8 |
/**
|
9 |
* Store all form ids created with this class
|
10 |
* @var FW_Form[] {'form_id' => instance}
|
@@ -68,35 +69,34 @@ class FW_Form
|
|
68 |
* 'attr' => array() // Custom <form ...> attributes
|
69 |
* )
|
70 |
*/
|
71 |
-
public function __construct($id, $data = array())
|
72 |
-
|
73 |
-
|
74 |
-
trigger_error(sprintf(__('Form with id "%s" was already defined', 'fw'), $id), E_USER_ERROR);
|
75 |
}
|
76 |
|
77 |
$this->id = $id;
|
78 |
|
79 |
-
self::$forms[$this->id] =& $this;
|
80 |
|
81 |
// prepare $this->attr
|
82 |
{
|
83 |
-
if (!isset($data['attr']) || !is_array($data['attr'])) {
|
84 |
$data['attr'] = array();
|
85 |
}
|
86 |
|
87 |
-
$data['attr']['
|
88 |
|
89 |
-
if (isset($data['attr']['method'])) {
|
90 |
-
$data['attr']['method'] = strtolower($data['attr']['method']);
|
91 |
|
92 |
-
$data['attr']['method'] = in_array($data['attr']['method'], array('get', 'post'))
|
93 |
? $data['attr']['method']
|
94 |
: 'post';
|
95 |
} else {
|
96 |
$data['attr']['method'] = 'post';
|
97 |
}
|
98 |
|
99 |
-
if (!isset($data['attr']['action'])) {
|
100 |
$data['attr']['action'] = '';
|
101 |
}
|
102 |
|
@@ -106,25 +106,25 @@ class FW_Form
|
|
106 |
// prepare $this->callbacks
|
107 |
{
|
108 |
$this->callbacks = array(
|
109 |
-
'render' => empty($data['render'])
|
110 |
-
'validate' => empty($data['validate']) ? false : $data['validate'],
|
111 |
-
'save' => empty($data['save'])
|
112 |
);
|
113 |
}
|
114 |
|
115 |
-
if (did_action('wp_loaded')) {
|
116 |
// in case if form instance was created after action
|
117 |
$this->_validate_and_save();
|
118 |
} else {
|
119 |
// attach to an action before 'send_headers' action, to be able to do redirects
|
120 |
-
add_action('wp_loaded', array($this, '_validate_and_save'), 101);
|
121 |
}
|
122 |
}
|
123 |
|
124 |
-
protected function validate()
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
return;
|
129 |
}
|
130 |
|
@@ -138,10 +138,10 @@ class FW_Form
|
|
138 |
*
|
139 |
* Callback must 'manually' extract input values from $_POST (or $_GET)
|
140 |
*/
|
141 |
-
if ($this->callbacks['validate']) {
|
142 |
-
$errors = call_user_func_array($this->callbacks['validate'], array($errors));
|
143 |
|
144 |
-
if (!is_array($errors)) {
|
145 |
|
146 |
$errors = array();
|
147 |
}
|
@@ -150,19 +150,20 @@ class FW_Form
|
|
150 |
/**
|
151 |
* check nonce
|
152 |
*/
|
153 |
-
if ($this->attr['method'] == 'post') {
|
154 |
-
$nonce_name = '_nonce_'. md5($this->id);
|
155 |
|
156 |
-
if (!isset($_REQUEST[$nonce_name]) || wp_verify_nonce($_REQUEST[$nonce_name],
|
157 |
-
|
|
|
|
|
158 |
}
|
159 |
}
|
160 |
|
161 |
$this->errors = $errors;
|
162 |
}
|
163 |
|
164 |
-
protected function save()
|
165 |
-
{
|
166 |
$save_data = array(
|
167 |
// you can set here a url for redirect after save
|
168 |
'redirect' => null
|
@@ -173,23 +174,31 @@ class FW_Form
|
|
173 |
*
|
174 |
* Callback must 'manually' extract input values from $_POST (or $_GET)
|
175 |
*/
|
176 |
-
if ($this->callbacks['save']) {
|
177 |
-
$data = call_user_func_array($this->callbacks['save'], array($save_data));
|
178 |
|
179 |
-
if (!is_array($data)) {
|
180 |
// fix if returned wrong data from callback
|
181 |
$data = $save_data;
|
182 |
}
|
183 |
|
184 |
$save_data = $data;
|
185 |
|
186 |
-
unset($data);
|
187 |
}
|
188 |
|
189 |
-
if (
|
190 |
-
|
191 |
-
|
|
|
|
|
192 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
}
|
194 |
|
195 |
/**
|
@@ -200,26 +209,38 @@ class FW_Form
|
|
200 |
* @return bool|null
|
201 |
* @internal
|
202 |
*/
|
203 |
-
public function _validate_and_save()
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
return null;
|
208 |
} else {
|
209 |
$this->validate_and_save_called = true;
|
210 |
}
|
211 |
|
212 |
-
if (
|
213 |
-
return;
|
214 |
}
|
215 |
|
216 |
$this->validate();
|
217 |
|
218 |
-
if (
|
219 |
-
|
220 |
-
|
221 |
|
222 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
|
224 |
return true;
|
225 |
}
|
@@ -227,8 +248,7 @@ class FW_Form
|
|
227 |
/**
|
228 |
* @return string
|
229 |
*/
|
230 |
-
public function get_id()
|
231 |
-
{
|
232 |
return $this->id;
|
233 |
}
|
234 |
|
@@ -236,12 +256,12 @@ class FW_Form
|
|
236 |
* Get html attribute(s)
|
237 |
*
|
238 |
* @param null|string $name
|
|
|
239 |
* @return array|string
|
240 |
*/
|
241 |
-
public function attr($name = null)
|
242 |
-
|
243 |
-
|
244 |
-
return isset($this->attr[$name]) ? $this->attr[$name] : null;
|
245 |
} else {
|
246 |
return $this->attr;
|
247 |
}
|
@@ -249,63 +269,65 @@ class FW_Form
|
|
249 |
|
250 |
/**
|
251 |
* Render form's html
|
|
|
|
|
252 |
*/
|
253 |
-
public function render($data = array())
|
254 |
-
|
255 |
-
|
256 |
|
257 |
-
if (!empty($this->attr['action']) && $this->attr['method'] == 'get') {
|
258 |
/**
|
259 |
* Add query vars from action attribute url to hidden inputs to not loose them
|
260 |
* For cases when get_search_link() will return '.../?s=~',
|
261 |
* the 's' will be lost after submit and no search page will be shown
|
262 |
*/
|
263 |
|
264 |
-
parse_str(parse_url($this->attr['action'], PHP_URL_QUERY), $query_vars);
|
265 |
|
266 |
-
if (!empty($query_vars)) {
|
267 |
-
foreach ($query_vars as $var_name => $var_value) {
|
268 |
-
?><input type="hidden" name="<?php print esc_attr($var_name
|
|
|
269 |
}
|
270 |
}
|
271 |
}
|
272 |
|
273 |
?><input type="hidden" name="<?php print self::$id_input_name; ?>" value="<?php print $this->id ?>" /><?php
|
274 |
-
|
275 |
-
|
276 |
-
wp_nonce_field('submit_fwf', '_nonce_'. md5($this->id));
|
277 |
}
|
278 |
|
279 |
$render_data = array(
|
280 |
'submit' => array(
|
281 |
-
'value' => __('Submit', 'fw'),
|
282 |
/**
|
283 |
* you can set here custom submit button html
|
284 |
* and the 'value' parameter will not be used
|
285 |
*/
|
286 |
-
'html'
|
287 |
),
|
288 |
-
'data'
|
289 |
-
'attr'
|
290 |
);
|
291 |
|
292 |
-
unset($data);
|
293 |
|
294 |
-
if ($this->callbacks['render']) {
|
295 |
-
$data = call_user_func_array($this->callbacks['render'], array($render_data));
|
296 |
|
297 |
-
if (empty($data)) {
|
298 |
// fix if returned wrong data from callback
|
299 |
$data = $render_data;
|
300 |
}
|
301 |
|
302 |
$render_data = $data;
|
303 |
|
304 |
-
unset($data);
|
305 |
}
|
306 |
|
307 |
// In filter can be defined custom html for submit button
|
308 |
-
if (isset($render_data['submit']['html'])):
|
309 |
print $render_data['submit']['html'];
|
310 |
else:
|
311 |
?><input type="submit" value="<?php print $render_data['submit']['value'] ?>"><?php
|
@@ -318,22 +340,22 @@ class FW_Form
|
|
318 |
* If now is a submit of this form
|
319 |
* @return bool
|
320 |
*/
|
321 |
-
public function is_submitted()
|
322 |
-
|
323 |
-
|
324 |
-
$method = strtoupper($this->attr('method'));
|
325 |
|
326 |
-
if ($method === 'POST') {
|
327 |
$this->is_submitted = (
|
328 |
-
isset($_POST[self::$id_input_name])
|
329 |
&&
|
330 |
-
FW_Request::POST(self::$id_input_name) === $this->id
|
331 |
);
|
332 |
-
|
|
|
333 |
$this->is_submitted = (
|
334 |
-
isset($_GET[self::$id_input_name])
|
335 |
&&
|
336 |
-
FW_Request::GET(self::$id_input_name) === $this->id
|
337 |
);
|
338 |
} else {
|
339 |
$this->is_submitted = false;
|
@@ -346,25 +368,25 @@ class FW_Form
|
|
346 |
/**
|
347 |
* @return bool
|
348 |
*/
|
349 |
-
public function is_valid()
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
return null;
|
354 |
}
|
355 |
|
356 |
-
return empty($this->errors);
|
357 |
}
|
358 |
|
359 |
/**
|
360 |
* Get validation errors
|
361 |
* @return array
|
362 |
*/
|
363 |
-
public function get_errors()
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
return array('~' => true);
|
368 |
}
|
369 |
|
370 |
return $this->errors;
|
@@ -374,23 +396,22 @@ class FW_Form
|
|
374 |
* Get submitted form instance (or false if no form is currently submitted)
|
375 |
* @return FW_Form|false
|
376 |
*/
|
377 |
-
public static function get_submitted()
|
378 |
-
|
379 |
-
if (is_null(self::$submitted_id)) {
|
380 |
// method called first time, search for submitted form
|
381 |
do {
|
382 |
-
foreach (self::$forms as $form) {
|
383 |
-
if ($form->is_submitted()) {
|
384 |
self::$submitted_id = $form->get_id();
|
385 |
break 2;
|
386 |
}
|
387 |
}
|
388 |
|
389 |
self::$submitted_id = false;
|
390 |
-
} while(false);
|
391 |
}
|
392 |
|
393 |
-
if (is_string(self::$submitted_id)) {
|
394 |
return self::$forms[ self::$submitted_id ];
|
395 |
} else {
|
396 |
return false;
|
@@ -398,20 +419,21 @@ class FW_Form
|
|
398 |
}
|
399 |
}
|
400 |
|
401 |
-
if (is_admin()) {
|
402 |
/**
|
403 |
* Display form errors in admin side
|
404 |
*/
|
405 |
function _action_show_fw_form_errors_in_admin() {
|
406 |
$form = FW_Form::get_submitted();
|
407 |
|
408 |
-
if (
|
409 |
return;
|
410 |
}
|
411 |
|
412 |
-
foreach ($form->get_errors() as $input_name => $error_message) {
|
413 |
-
FW_Flash_Messages::add('fw-form-admin-'. $input_name, $error_message, 'error');
|
414 |
}
|
415 |
}
|
416 |
-
|
417 |
-
|
|
1 |
+
<?php if ( ! defined( 'FW' ) ) {
|
2 |
+
die( 'Forbidden' );
|
3 |
+
}
|
4 |
|
5 |
/**
|
6 |
* Dynamic forms
|
7 |
*/
|
8 |
+
class FW_Form {
|
|
|
9 |
/**
|
10 |
* Store all form ids created with this class
|
11 |
* @var FW_Form[] {'form_id' => instance}
|
69 |
* 'attr' => array() // Custom <form ...> attributes
|
70 |
* )
|
71 |
*/
|
72 |
+
public function __construct( $id, $data = array() ) {
|
73 |
+
if ( isset( self::$forms[ $id ] ) ) {
|
74 |
+
trigger_error( sprintf( __( 'Form with id "%s" was already defined', 'fw' ), $id ), E_USER_ERROR );
|
|
|
75 |
}
|
76 |
|
77 |
$this->id = $id;
|
78 |
|
79 |
+
self::$forms[ $this->id ] =& $this;
|
80 |
|
81 |
// prepare $this->attr
|
82 |
{
|
83 |
+
if ( ! isset( $data['attr'] ) || ! is_array( $data['attr'] ) ) {
|
84 |
$data['attr'] = array();
|
85 |
}
|
86 |
|
87 |
+
$data['attr']['class'] = 'fw_form_' . $this->id;
|
88 |
|
89 |
+
if ( isset( $data['attr']['method'] ) ) {
|
90 |
+
$data['attr']['method'] = strtolower( $data['attr']['method'] );
|
91 |
|
92 |
+
$data['attr']['method'] = in_array( $data['attr']['method'], array( 'get', 'post' ) )
|
93 |
? $data['attr']['method']
|
94 |
: 'post';
|
95 |
} else {
|
96 |
$data['attr']['method'] = 'post';
|
97 |
}
|
98 |
|
99 |
+
if ( ! isset( $data['attr']['action'] ) ) {
|
100 |
$data['attr']['action'] = '';
|
101 |
}
|
102 |
|
106 |
// prepare $this->callbacks
|
107 |
{
|
108 |
$this->callbacks = array(
|
109 |
+
'render' => empty( $data['render'] ) ? false : $data['render'],
|
110 |
+
'validate' => empty( $data['validate'] ) ? false : $data['validate'],
|
111 |
+
'save' => empty( $data['save'] ) ? false : $data['save'],
|
112 |
);
|
113 |
}
|
114 |
|
115 |
+
if ( did_action( 'wp_loaded' ) ) {
|
116 |
// in case if form instance was created after action
|
117 |
$this->_validate_and_save();
|
118 |
} else {
|
119 |
// attach to an action before 'send_headers' action, to be able to do redirects
|
120 |
+
add_action( 'wp_loaded', array( $this, '_validate_and_save' ), 101 );
|
121 |
}
|
122 |
}
|
123 |
|
124 |
+
protected function validate() {
|
125 |
+
if ( is_array( $this->errors ) ) {
|
126 |
+
trigger_error( __METHOD__ . ' already called', E_USER_WARNING );
|
127 |
+
|
128 |
return;
|
129 |
}
|
130 |
|
138 |
*
|
139 |
* Callback must 'manually' extract input values from $_POST (or $_GET)
|
140 |
*/
|
141 |
+
if ( $this->callbacks['validate'] ) {
|
142 |
+
$errors = call_user_func_array( $this->callbacks['validate'], array( $errors ) );
|
143 |
|
144 |
+
if ( ! is_array( $errors ) ) {
|
145 |
|
146 |
$errors = array();
|
147 |
}
|
150 |
/**
|
151 |
* check nonce
|
152 |
*/
|
153 |
+
if ( $this->attr['method'] == 'post' ) {
|
154 |
+
$nonce_name = '_nonce_' . md5( $this->id );
|
155 |
|
156 |
+
if ( ! isset( $_REQUEST[ $nonce_name ] ) || wp_verify_nonce( $_REQUEST[ $nonce_name ],
|
157 |
+
'submit_fwf' ) === false
|
158 |
+
) {
|
159 |
+
$errors[ $nonce_name ] = __( 'Nonce verification failed', 'fw' );
|
160 |
}
|
161 |
}
|
162 |
|
163 |
$this->errors = $errors;
|
164 |
}
|
165 |
|
166 |
+
protected function save() {
|
|
|
167 |
$save_data = array(
|
168 |
// you can set here a url for redirect after save
|
169 |
'redirect' => null
|
174 |
*
|
175 |
* Callback must 'manually' extract input values from $_POST (or $_GET)
|
176 |
*/
|
177 |
+
if ( $this->callbacks['save'] ) {
|
178 |
+
$data = call_user_func_array( $this->callbacks['save'], array( $save_data ) );
|
179 |
|
180 |
+
if ( ! is_array( $data ) ) {
|
181 |
// fix if returned wrong data from callback
|
182 |
$data = $save_data;
|
183 |
}
|
184 |
|
185 |
$save_data = $data;
|
186 |
|
187 |
+
unset( $data );
|
188 |
}
|
189 |
|
190 |
+
if ( ! $this->is_ajax() ) {
|
191 |
+
if ( isset( $save_data['redirect'] ) ) {
|
192 |
+
wp_redirect( $save_data['redirect'] );
|
193 |
+
exit;
|
194 |
+
}
|
195 |
}
|
196 |
+
|
197 |
+
return $save_data;
|
198 |
+
}
|
199 |
+
|
200 |
+
protected function is_ajax() {
|
201 |
+
return defined( 'DOING_AJAX' ) && DOING_AJAX;
|
202 |
}
|
203 |
|
204 |
/**
|
209 |
* @return bool|null
|
210 |
* @internal
|
211 |
*/
|
212 |
+
public function _validate_and_save() {
|
213 |
+
if ( $this->validate_and_save_called ) {
|
214 |
+
trigger_error( __METHOD__ . ' already called', E_USER_WARNING );
|
215 |
+
|
216 |
return null;
|
217 |
} else {
|
218 |
$this->validate_and_save_called = true;
|
219 |
}
|
220 |
|
221 |
+
if ( ! $this->is_submitted() ) {
|
222 |
+
return null;
|
223 |
}
|
224 |
|
225 |
$this->validate();
|
226 |
|
227 |
+
if ( $this->is_ajax() ) {
|
228 |
+
if ( $this->is_valid() ) {
|
229 |
+
$this->save();
|
230 |
|
231 |
+
wp_send_json_success();
|
232 |
+
} else {
|
233 |
+
wp_send_json_error( array(
|
234 |
+
'errors' => $this->get_errors()
|
235 |
+
) );
|
236 |
+
}
|
237 |
+
} else {
|
238 |
+
if ( ! $this->is_valid() ) {
|
239 |
+
return false;
|
240 |
+
}
|
241 |
+
|
242 |
+
$this->save();
|
243 |
+
}
|
244 |
|
245 |
return true;
|
246 |
}
|
248 |
/**
|
249 |
* @return string
|
250 |
*/
|
251 |
+
public function get_id() {
|
|
|
252 |
return $this->id;
|
253 |
}
|
254 |
|
256 |
* Get html attribute(s)
|
257 |
*
|
258 |
* @param null|string $name
|
259 |
+
*
|
260 |
* @return array|string
|
261 |
*/
|
262 |
+
public function attr( $name = null ) {
|
263 |
+
if ( $name ) {
|
264 |
+
return isset( $this->attr[ $name ] ) ? $this->attr[ $name ] : null;
|
|
|
265 |
} else {
|
266 |
return $this->attr;
|
267 |
}
|
269 |
|
270 |
/**
|
271 |
* Render form's html
|
272 |
+
*
|
273 |
+
* @param array $data
|
274 |
*/
|
275 |
+
public function render( $data = array() ) {
|
276 |
+
?>
|
277 |
+
<form <?php echo fw_attr_to_html( $this->attr ) ?> ><?php
|
278 |
|
279 |
+
if ( ! empty( $this->attr['action'] ) && $this->attr['method'] == 'get' ) {
|
280 |
/**
|
281 |
* Add query vars from action attribute url to hidden inputs to not loose them
|
282 |
* For cases when get_search_link() will return '.../?s=~',
|
283 |
* the 's' will be lost after submit and no search page will be shown
|
284 |
*/
|
285 |
|
286 |
+
parse_str( parse_url( $this->attr['action'], PHP_URL_QUERY ), $query_vars );
|
287 |
|
288 |
+
if ( ! empty( $query_vars ) ) {
|
289 |
+
foreach ( $query_vars as $var_name => $var_value ) {
|
290 |
+
?><input type="hidden" name="<?php print esc_attr( $var_name ) ?>"
|
291 |
+
value="<?php print fw_htmlspecialchars( $var_value ) ?>" /><?php
|
292 |
}
|
293 |
}
|
294 |
}
|
295 |
|
296 |
?><input type="hidden" name="<?php print self::$id_input_name; ?>" value="<?php print $this->id ?>" /><?php
|
297 |
+
if ( $this->attr['method'] == 'post' ) {
|
298 |
+
wp_nonce_field( 'submit_fwf', '_nonce_' . md5( $this->id ) );
|
|
|
299 |
}
|
300 |
|
301 |
$render_data = array(
|
302 |
'submit' => array(
|
303 |
+
'value' => __( 'Submit', 'fw' ),
|
304 |
/**
|
305 |
* you can set here custom submit button html
|
306 |
* and the 'value' parameter will not be used
|
307 |
*/
|
308 |
+
'html' => null,
|
309 |
),
|
310 |
+
'data' => $data,
|
311 |
+
'attr' => $this->attr,
|
312 |
);
|
313 |
|
314 |
+
unset( $data );
|
315 |
|
316 |
+
if ( $this->callbacks['render'] ) {
|
317 |
+
$data = call_user_func_array( $this->callbacks['render'], array( $render_data ) );
|
318 |
|
319 |
+
if ( empty( $data ) ) {
|
320 |
// fix if returned wrong data from callback
|
321 |
$data = $render_data;
|
322 |
}
|
323 |
|
324 |
$render_data = $data;
|
325 |
|
326 |
+
unset( $data );
|
327 |
}
|
328 |
|
329 |
// In filter can be defined custom html for submit button
|
330 |
+
if ( isset( $render_data['submit']['html'] ) ):
|
331 |
print $render_data['submit']['html'];
|
332 |
else:
|
333 |
?><input type="submit" value="<?php print $render_data['submit']['value'] ?>"><?php
|
340 |
* If now is a submit of this form
|
341 |
* @return bool
|
342 |
*/
|
343 |
+
public function is_submitted() {
|
344 |
+
if ( is_null( $this->is_submitted ) ) {
|
345 |
+
$method = strtoupper( $this->attr( 'method' ) );
|
|
|
346 |
|
347 |
+
if ( $method === 'POST' ) {
|
348 |
$this->is_submitted = (
|
349 |
+
isset( $_POST[ self::$id_input_name ] )
|
350 |
&&
|
351 |
+
FW_Request::POST( self::$id_input_name ) === $this->id
|
352 |
);
|
353 |
+
|
354 |
+
} elseif ( $method === 'GET' ) {
|
355 |
$this->is_submitted = (
|
356 |
+
isset( $_GET[ self::$id_input_name ] )
|
357 |
&&
|
358 |
+
FW_Request::GET( self::$id_input_name ) === $this->id
|
359 |
);
|
360 |
} else {
|
361 |
$this->is_submitted = false;
|
368 |
/**
|
369 |
* @return bool
|
370 |
*/
|
371 |
+
public function is_valid() {
|
372 |
+
if ( ! $this->validate_and_save_called ) {
|
373 |
+
trigger_error( __METHOD__ . ' called before validation', E_USER_WARNING );
|
374 |
+
|
375 |
return null;
|
376 |
}
|
377 |
|
378 |
+
return empty( $this->errors );
|
379 |
}
|
380 |
|
381 |
/**
|
382 |
* Get validation errors
|
383 |
* @return array
|
384 |
*/
|
385 |
+
public function get_errors() {
|
386 |
+
if ( ! $this->validate_and_save_called ) {
|
387 |
+
trigger_error( __METHOD__ . ' called before validation', E_USER_WARNING );
|
388 |
+
|
389 |
+
return array( '~' => true );
|
390 |
}
|
391 |
|
392 |
return $this->errors;
|
396 |
* Get submitted form instance (or false if no form is currently submitted)
|
397 |
* @return FW_Form|false
|
398 |
*/
|
399 |
+
public static function get_submitted() {
|
400 |
+
if ( is_null( self::$submitted_id ) ) {
|
|
|
401 |
// method called first time, search for submitted form
|
402 |
do {
|
403 |
+
foreach ( self::$forms as $form ) {
|
404 |
+
if ( $form->is_submitted() ) {
|
405 |
self::$submitted_id = $form->get_id();
|
406 |
break 2;
|
407 |
}
|
408 |
}
|
409 |
|
410 |
self::$submitted_id = false;
|
411 |
+
} while ( false );
|
412 |
}
|
413 |
|
414 |
+
if ( is_string( self::$submitted_id ) ) {
|
415 |
return self::$forms[ self::$submitted_id ];
|
416 |
} else {
|
417 |
return false;
|
419 |
}
|
420 |
}
|
421 |
|
422 |
+
if ( is_admin() ) {
|
423 |
/**
|
424 |
* Display form errors in admin side
|
425 |
*/
|
426 |
function _action_show_fw_form_errors_in_admin() {
|
427 |
$form = FW_Form::get_submitted();
|
428 |
|
429 |
+
if ( ! $form || $form->is_valid() ) {
|
430 |
return;
|
431 |
}
|
432 |
|
433 |
+
foreach ( $form->get_errors() as $input_name => $error_message ) {
|
434 |
+
FW_Flash_Messages::add( 'fw-form-admin-' . $input_name, $error_message, 'error' );
|
435 |
}
|
436 |
}
|
437 |
+
|
438 |
+
add_action( 'wp_loaded', '_action_show_fw_form_errors_in_admin', 111 );
|
439 |
+
}
|
framework/helpers/class-fw-wp-filesystem.php
CHANGED
@@ -83,10 +83,10 @@ class FW_WP_Filesystem
|
|
83 |
|
84 |
/**
|
85 |
* Convert real file path to WP Filesystem path
|
86 |
-
* @param string $
|
87 |
* @return string
|
88 |
*/
|
89 |
-
final public static function real_path_to_filesystem_path($
|
90 |
/** @var WP_Filesystem_Base $wp_filesystem */
|
91 |
global $wp_filesystem;
|
92 |
|
@@ -94,11 +94,11 @@ class FW_WP_Filesystem
|
|
94 |
trigger_error('Filesystem is not available', E_USER_ERROR);
|
95 |
}
|
96 |
|
97 |
-
$
|
98 |
-
|
99 |
$real_abspath = fw_fix_path(ABSPATH);
|
100 |
$wp_filesystem_abspath = fw_fix_path($wp_filesystem->abspath());
|
101 |
-
|
|
|
102 |
|
103 |
return $wp_filesystem_abspath . $relative_path;
|
104 |
}
|
@@ -117,9 +117,9 @@ class FW_WP_Filesystem
|
|
117 |
}
|
118 |
|
119 |
$wp_filesystem_path = fw_fix_path($wp_filesystem_path);
|
120 |
-
|
121 |
-
$real_abspath = fw_fix_path(ABSPATH);
|
122 |
$wp_filesystem_abspath = fw_fix_path($wp_filesystem->abspath());
|
|
|
|
|
123 |
$relative_path = preg_replace('/^'. preg_quote($wp_filesystem_abspath, '/') .'/', '', $wp_filesystem_path);
|
124 |
|
125 |
return $real_abspath . $relative_path;
|
@@ -127,9 +127,10 @@ class FW_WP_Filesystem
|
|
127 |
|
128 |
/**
|
129 |
* Check if there is direct filesystem access, so we can make changes without asking the credentials via form
|
|
|
130 |
* @return bool
|
131 |
*/
|
132 |
-
final public static function has_direct_access()
|
133 |
{
|
134 |
/** @var WP_Filesystem_Base $wp_filesystem */
|
135 |
global $wp_filesystem;
|
@@ -138,10 +139,10 @@ class FW_WP_Filesystem
|
|
138 |
return $wp_filesystem->method === 'direct';
|
139 |
}
|
140 |
|
141 |
-
if (get_filesystem_method() === 'direct') {
|
142 |
ob_start();
|
143 |
{
|
144 |
-
$creds = request_filesystem_credentials(
|
145 |
}
|
146 |
ob_end_clean();
|
147 |
|
@@ -170,24 +171,27 @@ class FW_WP_Filesystem
|
|
170 |
|
171 |
$path = '';
|
172 |
$check_if_exists = true;
|
173 |
-
$
|
174 |
foreach (explode('/', $wp_filesystem_dir_path) as $dir_name) {
|
175 |
if (empty($dir_name)) {
|
176 |
-
if ($
|
177 |
/**
|
178 |
-
* It's a unix style path staring with '/'
|
179 |
-
*
|
180 |
*/
|
181 |
$path = '/';
|
182 |
} else {
|
183 |
trigger_error('Invalid path: '. $wp_filesystem_dir_path, E_USER_WARNING);
|
184 |
return false;
|
185 |
}
|
|
|
|
|
|
|
186 |
}
|
187 |
|
188 |
-
$path .= ($
|
189 |
|
190 |
-
$
|
191 |
|
192 |
if ($check_if_exists) {
|
193 |
if ($wp_filesystem->is_dir($path)) {
|
83 |
|
84 |
/**
|
85 |
* Convert real file path to WP Filesystem path
|
86 |
+
* @param string $real_path
|
87 |
* @return string
|
88 |
*/
|
89 |
+
final public static function real_path_to_filesystem_path($real_path) {
|
90 |
/** @var WP_Filesystem_Base $wp_filesystem */
|
91 |
global $wp_filesystem;
|
92 |
|
94 |
trigger_error('Filesystem is not available', E_USER_ERROR);
|
95 |
}
|
96 |
|
97 |
+
$real_path = fw_fix_path($real_path);
|
|
|
98 |
$real_abspath = fw_fix_path(ABSPATH);
|
99 |
$wp_filesystem_abspath = fw_fix_path($wp_filesystem->abspath());
|
100 |
+
|
101 |
+
$relative_path = preg_replace('/^'. preg_quote($real_abspath, '/') .'/', '', $real_path);
|
102 |
|
103 |
return $wp_filesystem_abspath . $relative_path;
|
104 |
}
|
117 |
}
|
118 |
|
119 |
$wp_filesystem_path = fw_fix_path($wp_filesystem_path);
|
|
|
|
|
120 |
$wp_filesystem_abspath = fw_fix_path($wp_filesystem->abspath());
|
121 |
+
$real_abspath = fw_fix_path(ABSPATH);
|
122 |
+
|
123 |
$relative_path = preg_replace('/^'. preg_quote($wp_filesystem_abspath, '/') .'/', '', $wp_filesystem_path);
|
124 |
|
125 |
return $real_abspath . $relative_path;
|
127 |
|
128 |
/**
|
129 |
* Check if there is direct filesystem access, so we can make changes without asking the credentials via form
|
130 |
+
* @param string|null $context
|
131 |
* @return bool
|
132 |
*/
|
133 |
+
final public static function has_direct_access($context = null)
|
134 |
{
|
135 |
/** @var WP_Filesystem_Base $wp_filesystem */
|
136 |
global $wp_filesystem;
|
139 |
return $wp_filesystem->method === 'direct';
|
140 |
}
|
141 |
|
142 |
+
if (get_filesystem_method(array(), $context) === 'direct') {
|
143 |
ob_start();
|
144 |
{
|
145 |
+
$creds = request_filesystem_credentials(admin_url(), '', false, $context, null);
|
146 |
}
|
147 |
ob_end_clean();
|
148 |
|
171 |
|
172 |
$path = '';
|
173 |
$check_if_exists = true;
|
174 |
+
$loop_counter = 1;
|
175 |
foreach (explode('/', $wp_filesystem_dir_path) as $dir_name) {
|
176 |
if (empty($dir_name)) {
|
177 |
+
if ($loop_counter === 1) {
|
178 |
/**
|
179 |
+
* It's a unix style path staring with '/' -> ''
|
180 |
+
* On windows it starts with 'C:/' -> 'C:'
|
181 |
*/
|
182 |
$path = '/';
|
183 |
} else {
|
184 |
trigger_error('Invalid path: '. $wp_filesystem_dir_path, E_USER_WARNING);
|
185 |
return false;
|
186 |
}
|
187 |
+
} elseif ($loop_counter === 2 && $path === '/') {
|
188 |
+
// prevent multiple slash prefix '//var/www'
|
189 |
+
$path = '';
|
190 |
}
|
191 |
|
192 |
+
$path .= ($loop_counter === 1 ? '' : '/') . $dir_name;
|
193 |
|
194 |
+
$loop_counter++;
|
195 |
|
196 |
if ($check_if_exists) {
|
197 |
if ($wp_filesystem->is_dir($path)) {
|
framework/helpers/general.php
CHANGED
@@ -211,6 +211,15 @@ function fw_print($value) {
|
|
211 |
line-height: 16px;
|
212 |
text-align: left;
|
213 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
214 |
</style>';
|
215 |
echo str_replace(array(' ', "\n"), '', ob_get_clean());
|
216 |
|
@@ -222,9 +231,11 @@ function fw_print($value) {
|
|
222 |
echo fw_htmlspecialchars(FW_Dumper::dump($value));
|
223 |
echo '</pre></div>';
|
224 |
} else {
|
|
|
225 |
foreach (func_get_args() as $param) {
|
226 |
fw_print($param);
|
227 |
}
|
|
|
228 |
}
|
229 |
}
|
230 |
|
211 |
line-height: 16px;
|
212 |
text-align: left;
|
213 |
}
|
214 |
+
|
215 |
+
div.fw_print_r_group {
|
216 |
+
background: #111;
|
217 |
+
margin: 10px 30px;
|
218 |
+
padding: 1px;
|
219 |
+
}
|
220 |
+
div.fw_print_r_group div.fw_print_r {
|
221 |
+
margin: 9px;
|
222 |
+
}
|
223 |
</style>';
|
224 |
echo str_replace(array(' ', "\n"), '', ob_get_clean());
|
225 |
|
231 |
echo fw_htmlspecialchars(FW_Dumper::dump($value));
|
232 |
echo '</pre></div>';
|
233 |
} else {
|
234 |
+
echo '<div class="fw_print_r_group">';
|
235 |
foreach (func_get_args() as $param) {
|
236 |
fw_print($param);
|
237 |
}
|
238 |
+
echo '</div>';
|
239 |
}
|
240 |
}
|
241 |
|
framework/manifest.php
CHANGED
@@ -4,4 +4,4 @@ $manifest = array();
|
|
4 |
|
5 |
$manifest['name'] = __('Unyson', 'fw');
|
6 |
|
7 |
-
$manifest['version'] = '2.1.
|
4 |
|
5 |
$manifest['name'] = __('Unyson', 'fw');
|
6 |
|
7 |
+
$manifest['version'] = '2.1.2';
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: unyson, themefusecom
|
|
3 |
Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio
|
4 |
Requires at least: 4.0.0
|
5 |
Tested up to: 4.0.1
|
6 |
-
Stable tag: 2.1.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -82,6 +82,9 @@ Yes; Unyson will work with any theme.
|
|
82 |
|
83 |
== Changelog ==
|
84 |
|
|
|
|
|
|
|
85 |
= 2.1.1 =
|
86 |
* Added the `FW_Extension::(get|set)_db_(settings_option|data)()` methods
|
87 |
* Added README.md for Github
|
3 |
Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio
|
4 |
Requires at least: 4.0.0
|
5 |
Tested up to: 4.0.1
|
6 |
+
Stable tag: 2.1.2
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
82 |
|
83 |
== Changelog ==
|
84 |
|
85 |
+
= 2.1.2 =
|
86 |
+
* Minor fixes and improvements in the extensions installation process
|
87 |
+
|
88 |
= 2.1.1 =
|
89 |
* Added the `FW_Extension::(get|set)_db_(settings_option|data)()` methods
|
90 |
* Added README.md for Github
|
unyson.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Unyson
|
4 |
* Plugin URI: http://unyson.themefuse.com/
|
5 |
* Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
|
6 |
-
* Version: 2.1.
|
7 |
* Author: ThemeFuse
|
8 |
* Author URI: http://themefuse.com
|
9 |
* License: GPL2+
|
@@ -83,4 +83,15 @@ require dirname( __FILE__ ) . '/framework/bootstrap.php';
|
|
83 |
load_plugin_textdomain( 'fw', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
|
84 |
}
|
85 |
add_action( 'plugins_loaded', '_action_fw_textdomain' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
}
|
3 |
* Plugin Name: Unyson
|
4 |
* Plugin URI: http://unyson.themefuse.com/
|
5 |
* Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
|
6 |
+
* Version: 2.1.2
|
7 |
* Author: ThemeFuse
|
8 |
* Author URI: http://themefuse.com
|
9 |
* License: GPL2+
|
83 |
load_plugin_textdomain( 'fw', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
|
84 |
}
|
85 |
add_action( 'plugins_loaded', '_action_fw_textdomain' );
|
86 |
+
|
87 |
+
/** @internal */
|
88 |
+
function _filter_fw_tmp_dir($dir) {
|
89 |
+
/**
|
90 |
+
* Some users force WP_Filesystem to use the 'direct' method <?php define( 'FS_METHOD', 'direct' ); ?> and set chmod 777 to the unyson/ plugin.
|
91 |
+
* By default tmp dir is WP_CONTENT_DIR.'/tmp' and WP_Filesystem can't create it with 'direct' method, then users can't download and install extensions.
|
92 |
+
* In order to prevent this situation, create the temporary directory inside the plugin folder.
|
93 |
+
*/
|
94 |
+
return dirname(__FILE__) . '/tmp';
|
95 |
+
}
|
96 |
+
add_filter('fw_tmp_dir', '_filter_fw_tmp_dir');
|
97 |
}
|