Version Description
- Fixed #453
- Improved option type
multi-picker
html render #442 - Option type
rgba-color-picker
optimizations #442 -
fw_resize()
improvements #447 - Fixed #445, #161, #484, #456
- Added the possibility to prevent box auto-close #466
- Fixed the
_get_value_from_input()
method in some option types #275 - Added the
limit
parameter for option typeaddable-popup
#478 - Fixed popup position in IE #483
- Created
fw_post_options_update
action - Improved post save: Options are saved in revision and autosave. Restore from revision works.
Download this release
Release Info
Developer | Unyson |
Plugin | Unyson |
Version | 2.2.8 |
Comparing to | |
See all releases |
Code changes from version 2.2.7 to 2.2.8
- framework/core/components/backend.php +168 -33
- framework/helpers/class-fw-resize.php +19 -3
- framework/helpers/class-fw-wp-meta.php +8 -5
- framework/helpers/class-fw-wp-option.php +5 -5
- framework/helpers/database.php +34 -0
- framework/helpers/general.php +12 -8
- framework/includes/option-types/addable-popup/class-fw-option-type-addable-popup.php +8 -0
- framework/includes/option-types/addable-popup/static/js/addable-popup.js +14 -3
- framework/includes/option-types/icon/class-fw-option-type-icon.php +6 -2
- framework/includes/option-types/image-picker/class-fw-option-type-image-picker.php +4 -0
- framework/includes/option-types/multi-picker/class-fw-option-type-multi-picker.php +57 -12
- framework/includes/option-types/multi-picker/static/js/multi-picker.js +17 -0
- framework/includes/option-types/multi-select/class-fw-option-type-multi-select.php +419 -351
- framework/includes/option-types/multi-upload/views/images-only.php +11 -11
- framework/includes/option-types/popup/class-fw-option-type-popup.php +7 -4
- framework/includes/option-types/radio-text/class-fw-option-type-radio-text.php +4 -0
- framework/includes/option-types/rgba-color-picker/class-fw-option-type-rgba-color-picker.php +5 -3
- framework/includes/option-types/rgba-color-picker/static/js/scripts.js +129 -93
- framework/includes/option-types/switch/class-fw-option-type-switch.php +0 -1
- framework/includes/option-types/upload/class-fw-option-type-upload.php +1 -2
- framework/includes/option-types/upload/views/images-only.php +8 -7
- framework/manifest.php +1 -1
- framework/static/css/fw.css +1 -0
- framework/static/js/backend-options.js +1 -1
- readme.txt +15 -2
- unyson.php +1 -1
framework/core/components/backend.php
CHANGED
@@ -6,6 +6,7 @@
|
|
6 |
* Backend functionality
|
7 |
*/
|
8 |
final class _FW_Component_Backend {
|
|
|
9 |
/** @var callable */
|
10 |
private $print_meta_box_content_callback;
|
11 |
|
@@ -128,10 +129,14 @@ final class _FW_Component_Backend {
|
|
128 |
private function add_actions() {
|
129 |
add_action( 'admin_menu', array( $this, '_action_admin_menu' ) );
|
130 |
add_action( 'add_meta_boxes', array( $this, '_action_create_post_meta_boxes' ), 10, 2 );
|
131 |
-
add_action( 'save_post', array( $this, '_action_save_post' ), 10, 2 );
|
132 |
add_action( 'init', array( $this, '_action_init' ), 20 );
|
133 |
add_action( 'admin_enqueue_scripts', array( $this, '_action_admin_enqueue_scripts' ), 8 );
|
134 |
|
|
|
|
|
|
|
|
|
|
|
135 |
// render and submit options from javascript
|
136 |
{
|
137 |
add_action( 'wp_ajax_fw_backend_options_render', array( $this, '_action_ajax_options_render' ) );
|
@@ -592,58 +597,183 @@ final class _FW_Component_Backend {
|
|
592 |
}
|
593 |
|
594 |
/**
|
595 |
-
*
|
596 |
-
* @param
|
|
|
|
|
597 |
*/
|
598 |
-
|
599 |
-
|
600 |
-
&& ! wp_is_post_revision( $post_id )
|
601 |
-
&& ! wp_is_post_autosave( $post_id )
|
602 |
-
) {
|
603 |
-
return;
|
604 |
-
}
|
605 |
-
|
606 |
-
if ( wp_is_post_autosave( $post_id ) ) {
|
607 |
-
$original_id = wp_is_post_autosave( $post_id );
|
608 |
-
$original_post = get_post( $original_id );
|
609 |
-
} else if ( wp_is_post_revision( $post_id ) ) {
|
610 |
-
$original_id = wp_is_post_revision( $post_id );
|
611 |
-
$original_post = get_post( $original_id );
|
612 |
-
} else {
|
613 |
-
$original_id = $post_id;
|
614 |
-
$original_post = $post;
|
615 |
-
}
|
616 |
-
|
617 |
-
$old_values = (array) fw_get_db_post_option( $original_id );
|
618 |
-
|
619 |
$handled_values = array();
|
620 |
-
$all_options = fw_extract_only_options(fw()->theme->get_post_options($original_post->post_type));
|
621 |
-
$options_values = fw_get_options_values_from_input( fw()->theme->get_post_options($original_post->post_type) );
|
622 |
|
623 |
-
foreach (
|
|
|
|
|
|
|
624 |
if (
|
625 |
-
isset($option['option_handler'])
|
|
|
626 |
$option['option_handler'] instanceof FW_Option_Handler
|
627 |
) {
|
628 |
-
|
629 |
/*
|
630 |
* if the option has a custom option_handler
|
631 |
* the saving is delegated to the handler,
|
632 |
* so it does not go to the post_meta
|
633 |
*/
|
634 |
-
$option['option_handler']->save_option_value($option_id, $option, $
|
635 |
|
636 |
-
$handled_values[$option_id] =
|
637 |
}
|
638 |
}
|
639 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
640 |
fw_set_db_post_option(
|
641 |
$post_id,
|
642 |
null,
|
643 |
-
|
644 |
);
|
|
|
645 |
|
646 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
647 |
}
|
648 |
|
649 |
/**
|
@@ -732,6 +862,11 @@ final class _FW_Component_Backend {
|
|
732 |
return; // this is not real term form submit, abort save
|
733 |
}
|
734 |
|
|
|
|
|
|
|
|
|
|
|
735 |
$old_values = (array) fw_get_db_term_option( $term_id, $taxonomy );
|
736 |
|
737 |
fw_set_db_term_option(
|
6 |
* Backend functionality
|
7 |
*/
|
8 |
final class _FW_Component_Backend {
|
9 |
+
|
10 |
/** @var callable */
|
11 |
private $print_meta_box_content_callback;
|
12 |
|
129 |
private function add_actions() {
|
130 |
add_action( 'admin_menu', array( $this, '_action_admin_menu' ) );
|
131 |
add_action( 'add_meta_boxes', array( $this, '_action_create_post_meta_boxes' ), 10, 2 );
|
|
|
132 |
add_action( 'init', array( $this, '_action_init' ), 20 );
|
133 |
add_action( 'admin_enqueue_scripts', array( $this, '_action_admin_enqueue_scripts' ), 8 );
|
134 |
|
135 |
+
add_action( 'save_post', array( $this, '_action_save_post' ), 7, 3 );
|
136 |
+
add_action( 'wp_restore_post_revision', array( $this, '_action_restore_post_revision' ), 10, 2 );
|
137 |
+
add_action( '_wp_put_post_revision', array( $this, '_action__wp_put_post_revision' ) );
|
138 |
+
add_action( 'wp_creating_autosave', array( $this, '_action_trigger_wp_create_autosave') );
|
139 |
+
|
140 |
// render and submit options from javascript
|
141 |
{
|
142 |
add_action( 'wp_ajax_fw_backend_options_render', array( $this, '_action_ajax_options_render' ) );
|
597 |
}
|
598 |
|
599 |
/**
|
600 |
+
* Experimental custom options save
|
601 |
+
* @param array $options
|
602 |
+
* @param array $values
|
603 |
+
* @return array
|
604 |
*/
|
605 |
+
private function process_options_handlers($options, $values)
|
606 |
+
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
607 |
$handled_values = array();
|
|
|
|
|
608 |
|
609 |
+
foreach (
|
610 |
+
fw_extract_only_options($options)
|
611 |
+
as $option_id => $option
|
612 |
+
) {
|
613 |
if (
|
614 |
+
isset($option['option_handler'])
|
615 |
+
&&
|
616 |
$option['option_handler'] instanceof FW_Option_Handler
|
617 |
) {
|
|
|
618 |
/*
|
619 |
* if the option has a custom option_handler
|
620 |
* the saving is delegated to the handler,
|
621 |
* so it does not go to the post_meta
|
622 |
*/
|
623 |
+
$option['option_handler']->save_option_value($option_id, $option, $values[$option_id]);
|
624 |
|
625 |
+
$handled_values[$option_id] = true;
|
626 |
}
|
627 |
}
|
628 |
|
629 |
+
return $handled_values;
|
630 |
+
}
|
631 |
+
|
632 |
+
/**
|
633 |
+
* @param int $post_id
|
634 |
+
* @param WP_Post $post
|
635 |
+
* @param bool $update
|
636 |
+
*/
|
637 |
+
public function _action_save_post( $post_id, $post, $update ) {
|
638 |
+
if (intval(FW_Request::POST('post_ID')) == $post_id) {
|
639 |
+
/**
|
640 |
+
* This happens on regular post form submit
|
641 |
+
* All data from $_POST belongs this $post
|
642 |
+
* so we save them in its post meta
|
643 |
+
*/
|
644 |
+
|
645 |
+
static $post_options_save_happened = false;
|
646 |
+
if ($post_options_save_happened) {
|
647 |
+
/**
|
648 |
+
* Prevent multiple options save for same post
|
649 |
+
* It can happen from a recursion or wp_update_post() for same post id
|
650 |
+
*/
|
651 |
+
return;
|
652 |
+
} else {
|
653 |
+
$post_options_save_happened = true;
|
654 |
+
}
|
655 |
+
|
656 |
+
$old_values = (array)fw_get_db_post_option($post_id);
|
657 |
+
$current_values = fw_get_options_values_from_input(
|
658 |
+
fw()->theme->get_post_options($post->post_type)
|
659 |
+
);
|
660 |
+
|
661 |
+
fw_set_db_post_option(
|
662 |
+
$post_id,
|
663 |
+
null,
|
664 |
+
array_diff_key( // remove handled values
|
665 |
+
$current_values,
|
666 |
+
$this->process_options_handlers(
|
667 |
+
fw()->theme->get_post_options($post->post_type),
|
668 |
+
$current_values
|
669 |
+
)
|
670 |
+
)
|
671 |
+
);
|
672 |
+
|
673 |
+
/**
|
674 |
+
* @deprecated
|
675 |
+
* Use the 'fw_post_options_update' action
|
676 |
+
*/
|
677 |
+
do_action( 'fw_save_post_options', $post_id, $post, $old_values );
|
678 |
+
} elseif ($original_post_id = wp_is_post_revision( $post_id )) {
|
679 |
+
/**
|
680 |
+
* Do nothing, the
|
681 |
+
* - '_wp_put_post_revision'
|
682 |
+
* - 'wp_restore_post_revision'
|
683 |
+
* - 'wp_creating_autosave'
|
684 |
+
* actions will handle this
|
685 |
+
*/
|
686 |
+
} elseif ($original_post_id = wp_is_post_autosave( $post_id )) {
|
687 |
+
// fixme: I don't know how to test this. The execution never entered here
|
688 |
+
FW_Flash_Messages::add(fw_rand_md5(), 'Unhandled auto-save');
|
689 |
+
} else {
|
690 |
+
/**
|
691 |
+
* This happens on:
|
692 |
+
* - post add (auto-draft): do nothing
|
693 |
+
* - revision restore: do nothing, that is handled by the 'wp_restore_post_revision' action
|
694 |
+
*/
|
695 |
+
}
|
696 |
+
}
|
697 |
+
|
698 |
+
/**
|
699 |
+
* @param array $autosave
|
700 |
+
*
|
701 |
+
* @internal
|
702 |
+
**/
|
703 |
+
public function _action_trigger_wp_create_autosave( $autosave ) {
|
704 |
+
add_action( 'save_post', array( $this, '_action_update_autosave_options' ), 10, 2 );
|
705 |
+
}
|
706 |
+
|
707 |
+
/**
|
708 |
+
* Happens on post Preview
|
709 |
+
*
|
710 |
+
* @param int $post_id
|
711 |
+
* @param WP_Post $post
|
712 |
+
*
|
713 |
+
* @internal
|
714 |
+
**/
|
715 |
+
public function _action_update_autosave_options( $post_id, $post ) {
|
716 |
+
remove_action( 'save_post', array( $this, '_action_update_autosave_options' ) );
|
717 |
+
remove_action( 'save_post', array( $this, '_action_save_post' ) );
|
718 |
+
|
719 |
+
$parent = get_post($post->post_parent);
|
720 |
+
|
721 |
+
if ( ! $parent instanceof WP_Post ) {
|
722 |
+
return;
|
723 |
+
}
|
724 |
+
|
725 |
+
$current_values = fw_get_options_values_from_input(
|
726 |
+
fw()->theme->get_post_options($parent->post_type)
|
727 |
+
);
|
728 |
+
|
729 |
+
fw_set_db_post_option(
|
730 |
+
$post->ID,
|
731 |
+
null,
|
732 |
+
array_diff_key( // remove handled values
|
733 |
+
$current_values,
|
734 |
+
$this->process_options_handlers(
|
735 |
+
fw()->theme->get_post_options($parent->post_type),
|
736 |
+
$current_values
|
737 |
+
)
|
738 |
+
)
|
739 |
+
);
|
740 |
+
|
741 |
+
add_action( 'save_post', array( $this, '_action_save_post' ), 7, 3 );
|
742 |
+
}
|
743 |
+
|
744 |
+
/**
|
745 |
+
* @param $post_id
|
746 |
+
* @param $revision_id
|
747 |
+
*/
|
748 |
+
public function _action_restore_post_revision($post_id, $revision_id)
|
749 |
+
{
|
750 |
+
/**
|
751 |
+
* Copy options meta from revision to post
|
752 |
+
*/
|
753 |
fw_set_db_post_option(
|
754 |
$post_id,
|
755 |
null,
|
756 |
+
(array)fw_get_db_post_option($revision_id, null, array())
|
757 |
);
|
758 |
+
}
|
759 |
|
760 |
+
/**
|
761 |
+
* @param $revision_id
|
762 |
+
*/
|
763 |
+
public function _action__wp_put_post_revision($revision_id)
|
764 |
+
{
|
765 |
+
/**
|
766 |
+
* Copy options meta from post to revision
|
767 |
+
*/
|
768 |
+
fw_set_db_post_option(
|
769 |
+
$revision_id,
|
770 |
+
null,
|
771 |
+
(array)fw_get_db_post_option(
|
772 |
+
wp_is_post_revision($revision_id),
|
773 |
+
null,
|
774 |
+
array()
|
775 |
+
)
|
776 |
+
);
|
777 |
}
|
778 |
|
779 |
/**
|
862 |
return; // this is not real term form submit, abort save
|
863 |
}
|
864 |
|
865 |
+
if (intval(FW_Request::POST('tag_ID')) != $term_id) {
|
866 |
+
// the $_POST values belongs to another term, do not save them into this one
|
867 |
+
return;
|
868 |
+
}
|
869 |
+
|
870 |
$old_values = (array) fw_get_db_term_option( $term_id, $taxonomy );
|
871 |
|
872 |
fw_set_db_term_option(
|
framework/helpers/class-fw-resize.php
CHANGED
@@ -57,7 +57,7 @@ if ( ! class_exists( 'FW_Resize' ) ) {
|
|
57 |
}
|
58 |
}
|
59 |
|
60 |
-
public function process( $attachment, $width, $height, $crop = false ) {
|
61 |
|
62 |
$attachment_info = $this->get_attachment_info( $attachment );
|
63 |
|
@@ -73,6 +73,22 @@ if ( ! class_exists( 'FW_Resize' ) ) {
|
|
73 |
$name = wp_basename( $file_path, ".$ext" );
|
74 |
$name = preg_replace( '/(.+)(\-\d+x\d+)$/', '$1', $name );
|
75 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
// Suffix applied to filename
|
77 |
$suffix = "{$width}x{$height}";
|
78 |
|
@@ -81,7 +97,7 @@ if ( ! class_exists( 'FW_Resize' ) ) {
|
|
81 |
// No need to resize & create a new image if it already exists
|
82 |
if ( ! file_exists( $destination_file_name ) ) {
|
83 |
//Image Resize
|
84 |
-
$editor = wp_get_image_editor( $file_path );
|
85 |
|
86 |
if ( is_wp_error( $editor ) ) {
|
87 |
return new WP_Error( 'wp_image_editor', 'WP Image editor can\'t resize this attachment', $attachment );
|
@@ -137,7 +153,7 @@ if ( ! class_exists( 'FW_Resize' ) ) {
|
|
137 |
}
|
138 |
|
139 |
if ( ! function_exists( 'fw_resize' ) ) {
|
140 |
-
function fw_resize( $url, $width, $height, $crop = false ) {
|
141 |
$fw_resize = FW_Resize::getInstance();
|
142 |
$response = $fw_resize->process( $url, $width, $height, $crop );
|
143 |
|
57 |
}
|
58 |
}
|
59 |
|
60 |
+
public function process( $attachment, $width = false, $height = false, $crop = false ) {
|
61 |
|
62 |
$attachment_info = $this->get_attachment_info( $attachment );
|
63 |
|
73 |
$name = wp_basename( $file_path, ".$ext" );
|
74 |
$name = preg_replace( '/(.+)(\-\d+x\d+)$/', '$1', $name );
|
75 |
|
76 |
+
{
|
77 |
+
if ( ! $width || ! $height ) {
|
78 |
+
$editor = wp_get_image_editor( $file_path );
|
79 |
+
$size = $editor->get_size();
|
80 |
+
$orig_width = $size['width'];
|
81 |
+
$orig_height = $size['height'];
|
82 |
+
if ( ! $height && $width ) {
|
83 |
+
$height = round( ( $orig_height * $width ) / $orig_width );
|
84 |
+
} elseif ( ! $width && $height ) {
|
85 |
+
$width = round( ( $orig_width * $height ) / $orig_height );
|
86 |
+
} else {
|
87 |
+
return $attachment;
|
88 |
+
}
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
// Suffix applied to filename
|
93 |
$suffix = "{$width}x{$height}";
|
94 |
|
97 |
// No need to resize & create a new image if it already exists
|
98 |
if ( ! file_exists( $destination_file_name ) ) {
|
99 |
//Image Resize
|
100 |
+
$editor = (isset($editor)) ? $editor : wp_get_image_editor( $file_path );
|
101 |
|
102 |
if ( is_wp_error( $editor ) ) {
|
103 |
return new WP_Error( 'wp_image_editor', 'WP Image editor can\'t resize this attachment', $attachment );
|
153 |
}
|
154 |
|
155 |
if ( ! function_exists( 'fw_resize' ) ) {
|
156 |
+
function fw_resize( $url, $width = false, $height = false, $crop = false ) {
|
157 |
$fw_resize = FW_Resize::getInstance();
|
158 |
$response = $fw_resize->process( $url, $width, $height, $crop );
|
159 |
|
framework/helpers/class-fw-wp-meta.php
CHANGED
@@ -33,10 +33,13 @@ class FW_WP_Meta {
|
|
33 |
$key = array_shift( $multi_key );
|
34 |
$multi_key = implode( '/', $multi_key );
|
35 |
|
|
|
36 |
// Make sure meta is added to the post, not a revision.
|
|
|
37 |
if ( $meta_type === 'post' && $the_post = wp_is_post_revision( $object_id ) ) {
|
38 |
$object_id = $the_post;
|
39 |
}
|
|
|
40 |
|
41 |
$cache_key = self::$cache_key . '/' . $meta_type . '/' . $object_id . '/' . $key;
|
42 |
|
@@ -101,10 +104,10 @@ class FW_WP_Meta {
|
|
101 |
FW_Cache::set( $cache_key, $values );
|
102 |
}
|
103 |
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
}
|
110 |
}
|
33 |
$key = array_shift( $multi_key );
|
34 |
$multi_key = implode( '/', $multi_key );
|
35 |
|
36 |
+
/*
|
37 |
// Make sure meta is added to the post, not a revision.
|
38 |
+
// fixme: why make sure? but I want to set post meta for a revision, how to do that?
|
39 |
if ( $meta_type === 'post' && $the_post = wp_is_post_revision( $object_id ) ) {
|
40 |
$object_id = $the_post;
|
41 |
}
|
42 |
+
*/
|
43 |
|
44 |
$cache_key = self::$cache_key . '/' . $meta_type . '/' . $object_id . '/' . $key;
|
45 |
|
104 |
FW_Cache::set( $cache_key, $values );
|
105 |
}
|
106 |
|
107 |
+
return fw_akg(
|
108 |
+
($get_original_value ? 'original' : 'prepared') . (empty($multi_key) ? '' : '/'. $multi_key),
|
109 |
+
$values,
|
110 |
+
$default_value
|
111 |
+
);
|
112 |
}
|
113 |
}
|
framework/helpers/class-fw-wp-option.php
CHANGED
@@ -42,11 +42,11 @@ class FW_WP_Option
|
|
42 |
FW_Cache::set($cache_key, $values);
|
43 |
}
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
}
|
51 |
|
52 |
/**
|
42 |
FW_Cache::set($cache_key, $values);
|
43 |
}
|
44 |
|
45 |
+
return fw_akg(
|
46 |
+
($get_original_value ? 'original' : 'prepared') . (empty($specific_multi_key) ? '' : '/'. $specific_multi_key),
|
47 |
+
$values,
|
48 |
+
$default_value
|
49 |
+
);
|
50 |
}
|
51 |
|
52 |
/**
|
framework/helpers/database.php
CHANGED
@@ -105,6 +105,8 @@
|
|
105 |
* @param $value
|
106 |
*/
|
107 |
function fw_set_db_post_option( $post_id = null, $option_id = null, $value ) {
|
|
|
|
|
108 |
if ( ! $post_id ) {
|
109 |
/** @var WP_Post $post */
|
110 |
global $post;
|
@@ -116,11 +118,43 @@
|
|
116 |
}
|
117 |
}
|
118 |
|
|
|
|
|
|
|
119 |
$option_id = 'fw_options' . ( $option_id !== null ? '/' . $option_id : '' );
|
120 |
|
121 |
FW_WP_Meta::set( 'post', $post_id, $option_id, $value );
|
122 |
|
123 |
fw()->backend->_sync_post_separate_meta($post_id);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
}
|
125 |
}
|
126 |
|
105 |
* @param $value
|
106 |
*/
|
107 |
function fw_set_db_post_option( $post_id = null, $option_id = null, $value ) {
|
108 |
+
$post_id = intval($post_id);
|
109 |
+
|
110 |
if ( ! $post_id ) {
|
111 |
/** @var WP_Post $post */
|
112 |
global $post;
|
118 |
}
|
119 |
}
|
120 |
|
121 |
+
$sub_keys = explode('/', $option_id);
|
122 |
+
$base_key = array_shift($sub_keys);
|
123 |
+
|
124 |
$option_id = 'fw_options' . ( $option_id !== null ? '/' . $option_id : '' );
|
125 |
|
126 |
FW_WP_Meta::set( 'post', $post_id, $option_id, $value );
|
127 |
|
128 |
fw()->backend->_sync_post_separate_meta($post_id);
|
129 |
+
|
130 |
+
/**
|
131 |
+
* @since 2.2.8
|
132 |
+
*/
|
133 |
+
do_action('fw_post_options_update',
|
134 |
+
$post_id,
|
135 |
+
/**
|
136 |
+
* Option id
|
137 |
+
* First level multi-key
|
138 |
+
*
|
139 |
+
* For e.g.
|
140 |
+
*
|
141 |
+
* if $option_id is 'hello/world/7'
|
142 |
+
* this will be 'hello'
|
143 |
+
*/
|
144 |
+
$base_key,
|
145 |
+
/**
|
146 |
+
* The remaining sub-keys
|
147 |
+
*
|
148 |
+
* For e.g.
|
149 |
+
*
|
150 |
+
* if $option_id is 'hello/world/7'
|
151 |
+
* $option_id_keys will be array('world', '7')
|
152 |
+
*
|
153 |
+
* if $option_id is 'hello'
|
154 |
+
* $option_id_keys will be array()
|
155 |
+
*/
|
156 |
+
$sub_keys
|
157 |
+
);
|
158 |
}
|
159 |
}
|
160 |
|
framework/helpers/general.php
CHANGED
@@ -193,15 +193,16 @@ function fw_print($value) {
|
|
193 |
div.fw_print_r {
|
194 |
max-height: 500px;
|
195 |
overflow-y: scroll;
|
196 |
-
background: #
|
197 |
margin: 10px 30px;
|
198 |
padding: 0;
|
199 |
border: 1px solid #F5F5F5;
|
|
|
200 |
}
|
201 |
|
202 |
div.fw_print_r pre {
|
203 |
-
color: #
|
204 |
-
background: #
|
205 |
text-shadow: 1px 1px 0 #000;
|
206 |
font-family: Consolas, monospace;
|
207 |
font-size: 12px;
|
@@ -213,9 +214,10 @@ function fw_print($value) {
|
|
213 |
}
|
214 |
|
215 |
div.fw_print_r_group {
|
216 |
-
background: #
|
217 |
margin: 10px 30px;
|
218 |
padding: 1px;
|
|
|
219 |
}
|
220 |
div.fw_print_r_group div.fw_print_r {
|
221 |
margin: 9px;
|
@@ -786,14 +788,16 @@ function fw_prepare_option_value($value) {
|
|
786 |
* Used to check if current post save is a regular "Save" button press
|
787 |
* not a revision, auto-save or something else
|
788 |
*
|
789 |
-
* todo: make sure it is correct to ignore revision and auto-save.
|
790 |
-
* todo: maybe we use wrong (too simplified) the 'save_post' action, maybe we should do something like this http://bit.ly/1xkbmml ?
|
791 |
-
*
|
792 |
* @param $post_id
|
793 |
* @return bool
|
|
|
|
|
|
|
|
|
|
|
|
|
794 |
*/
|
795 |
function fw_is_real_post_save($post_id) {
|
796 |
-
|
797 |
return !(
|
798 |
wp_is_post_revision($post_id)
|
799 |
|| wp_is_post_autosave($post_id)
|
193 |
div.fw_print_r {
|
194 |
max-height: 500px;
|
195 |
overflow-y: scroll;
|
196 |
+
background: #23282d;
|
197 |
margin: 10px 30px;
|
198 |
padding: 0;
|
199 |
border: 1px solid #F5F5F5;
|
200 |
+
border-radius: 3px;
|
201 |
}
|
202 |
|
203 |
div.fw_print_r pre {
|
204 |
+
color: #78FF5B;
|
205 |
+
background: #23282d;
|
206 |
text-shadow: 1px 1px 0 #000;
|
207 |
font-family: Consolas, monospace;
|
208 |
font-size: 12px;
|
214 |
}
|
215 |
|
216 |
div.fw_print_r_group {
|
217 |
+
background: #f1f1f1;
|
218 |
margin: 10px 30px;
|
219 |
padding: 1px;
|
220 |
+
border-radius: 5px;
|
221 |
}
|
222 |
div.fw_print_r_group div.fw_print_r {
|
223 |
margin: 9px;
|
788 |
* Used to check if current post save is a regular "Save" button press
|
789 |
* not a revision, auto-save or something else
|
790 |
*
|
|
|
|
|
|
|
791 |
* @param $post_id
|
792 |
* @return bool
|
793 |
+
*
|
794 |
+
* @deprecated
|
795 |
+
* save_post action happens also happens on Preview, Revision, Auto-save Restore, ...
|
796 |
+
* the verifications in this function simplifies too much the save process,
|
797 |
+
* the developers should study and understand better how it works
|
798 |
+
* and handle different save cases in their scripts using wp functions
|
799 |
*/
|
800 |
function fw_is_real_post_save($post_id) {
|
|
|
801 |
return !(
|
802 |
wp_is_post_revision($post_id)
|
803 |
|| wp_is_post_autosave($post_id)
|
framework/includes/option-types/addable-popup/class-fw-option-type-addable-popup.php
CHANGED
@@ -50,6 +50,7 @@ class FW_Option_Type_Addable_Popup extends FW_Option_Type
|
|
50 |
'options' => $this->transform_options($option['popup-options']),
|
51 |
'template' => $option['template'],
|
52 |
'size' => $option['size'],
|
|
|
53 |
));
|
54 |
|
55 |
$sortable_image = fw_get_framework_directory_uri('/static/img/sort-vertically.png');
|
@@ -105,8 +106,14 @@ class FW_Option_Type_Addable_Popup extends FW_Option_Type
|
|
105 |
return $option['value'];
|
106 |
}
|
107 |
|
|
|
|
|
108 |
$values = array_map('json_decode', $input_value, array_fill(0, count($input_value), true));
|
109 |
|
|
|
|
|
|
|
|
|
110 |
return $values;
|
111 |
}
|
112 |
|
@@ -133,6 +140,7 @@ class FW_Option_Type_Addable_Popup extends FW_Option_Type
|
|
133 |
),
|
134 |
'template' => '',
|
135 |
'popup-title' => null,
|
|
|
136 |
'size' => 'small' // small, medium, large
|
137 |
);
|
138 |
}
|
50 |
'options' => $this->transform_options($option['popup-options']),
|
51 |
'template' => $option['template'],
|
52 |
'size' => $option['size'],
|
53 |
+
'limit' => $option['limit']
|
54 |
));
|
55 |
|
56 |
$sortable_image = fw_get_framework_directory_uri('/static/img/sort-vertically.png');
|
106 |
return $option['value'];
|
107 |
}
|
108 |
|
109 |
+
$option['limit'] = intval($option['limit']);
|
110 |
+
|
111 |
$values = array_map('json_decode', $input_value, array_fill(0, count($input_value), true));
|
112 |
|
113 |
+
if($option['limit']){
|
114 |
+
$values= array_slice($values, 0 , $option['limit']);
|
115 |
+
}
|
116 |
+
|
117 |
return $values;
|
118 |
}
|
119 |
|
140 |
),
|
141 |
'template' => '',
|
142 |
'popup-title' => null,
|
143 |
+
'limit' => 0,
|
144 |
'size' => 'small' // small, medium, large
|
145 |
);
|
146 |
}
|
framework/includes/option-types/addable-popup/static/js/addable-popup.js
CHANGED
@@ -23,6 +23,10 @@
|
|
23 |
removeDefaultItem: function () {
|
24 |
nodes.$itemsWrapper.find('.item.default').remove();
|
25 |
},
|
|
|
|
|
|
|
|
|
26 |
toogleItemsWrapper: function () {
|
27 |
|
28 |
if (utils.countItems() === 0) {
|
@@ -31,9 +35,16 @@
|
|
31 |
nodes.$itemsWrapper.show();
|
32 |
}
|
33 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
init: function () {
|
35 |
utils.initItemsTemplates();
|
36 |
-
utils.
|
37 |
utils.removeDefaultItem();
|
38 |
utils.initSortable();
|
39 |
},
|
@@ -101,7 +112,7 @@
|
|
101 |
e.stopPropagation();
|
102 |
e.preventDefault();
|
103 |
$(this).closest('.item').remove();
|
104 |
-
utils.
|
105 |
});
|
106 |
|
107 |
nodes.$itemsWrapper.on('click', '.item', function (e) {
|
@@ -129,7 +140,7 @@
|
|
129 |
utils.modal.on('change:values', function (modal, values) {
|
130 |
if (!modal.get('edit')) {
|
131 |
utils.addNewItem(values);
|
132 |
-
utils.
|
133 |
} else {
|
134 |
utils.editItem(utils.modal.get('itemRef'), values);
|
135 |
}
|
23 |
removeDefaultItem: function () {
|
24 |
nodes.$itemsWrapper.find('.item.default').remove();
|
25 |
},
|
26 |
+
toogleNodes : function(){
|
27 |
+
utils.toogleItemsWrapper();
|
28 |
+
utils.toogleAddButton();
|
29 |
+
},
|
30 |
toogleItemsWrapper: function () {
|
31 |
|
32 |
if (utils.countItems() === 0) {
|
35 |
nodes.$itemsWrapper.show();
|
36 |
}
|
37 |
},
|
38 |
+
toogleAddButton: function(){
|
39 |
+
if(data.limit !== 0 ){
|
40 |
+
(utils.countItems() >= data.limit ) ?
|
41 |
+
nodes.$addButton.hide() :
|
42 |
+
nodes.$addButton.show();
|
43 |
+
}
|
44 |
+
},
|
45 |
init: function () {
|
46 |
utils.initItemsTemplates();
|
47 |
+
utils.toogleNodes();
|
48 |
utils.removeDefaultItem();
|
49 |
utils.initSortable();
|
50 |
},
|
112 |
e.stopPropagation();
|
113 |
e.preventDefault();
|
114 |
$(this).closest('.item').remove();
|
115 |
+
utils.toogleNodes();
|
116 |
});
|
117 |
|
118 |
nodes.$itemsWrapper.on('click', '.item', function (e) {
|
140 |
utils.modal.on('change:values', function (modal, values) {
|
141 |
if (!modal.get('edit')) {
|
142 |
utils.addNewItem(values);
|
143 |
+
utils.toogleNodes();
|
144 |
} else {
|
145 |
utils.editItem(utils.modal.get('itemRef'), values);
|
146 |
}
|
framework/includes/option-types/icon/class-fw-option-type-icon.php
CHANGED
@@ -92,6 +92,10 @@ class FW_Option_Type_Icon extends FW_Option_Type
|
|
92 |
*/
|
93 |
protected function _get_value_from_input($option, $input_value)
|
94 |
{
|
|
|
|
|
|
|
|
|
95 |
$sets = $this->get_sets();
|
96 |
|
97 |
if (isset($sets[ $option['set'] ])) {
|
@@ -102,7 +106,7 @@ class FW_Option_Type_Icon extends FW_Option_Type
|
|
102 |
|
103 |
unset($sets);
|
104 |
|
105 |
-
if (
|
106 |
$input_value = $option['value'];
|
107 |
}
|
108 |
|
@@ -141,7 +145,7 @@ class FW_Option_Type_Icon extends FW_Option_Type
|
|
141 |
private function generate_unknown_set($icon)
|
142 |
{
|
143 |
return array(
|
144 |
-
'font-style-src' => 'data:text/css;charset=utf-8;base64,LyoqLw==',
|
145 |
'container-class' => '',
|
146 |
'groups' => array(
|
147 |
'unknown' => __('Unknown Set', 'fw'),
|
92 |
*/
|
93 |
protected function _get_value_from_input($option, $input_value)
|
94 |
{
|
95 |
+
if (is_null($input_value)) {
|
96 |
+
return $option['value'];
|
97 |
+
}
|
98 |
+
|
99 |
$sets = $this->get_sets();
|
100 |
|
101 |
if (isset($sets[ $option['set'] ])) {
|
106 |
|
107 |
unset($sets);
|
108 |
|
109 |
+
if (!isset($set['icons'][ $input_value ])) {
|
110 |
$input_value = $option['value'];
|
111 |
}
|
112 |
|
145 |
private function generate_unknown_set($icon)
|
146 |
{
|
147 |
return array(
|
148 |
+
'font-style-src' => 'data:text/css;charset=utf-8;base64,LyoqLw==', // fixme: WP will transform this to `http://domain.com/data:text/css;...`
|
149 |
'container-class' => '',
|
150 |
'groups' => array(
|
151 |
'unknown' => __('Unknown Set', 'fw'),
|
framework/includes/option-types/image-picker/class-fw-option-type-image-picker.php
CHANGED
@@ -171,6 +171,10 @@ class Fw_Option_Type_Image_Picker extends FW_Option_Type
|
|
171 |
*/
|
172 |
protected function _get_value_from_input($option, $input_value)
|
173 |
{
|
|
|
|
|
|
|
|
|
174 |
if (!isset($option['choices'][$input_value])) {
|
175 |
if (
|
176 |
empty($option['choices']) ||
|
171 |
*/
|
172 |
protected function _get_value_from_input($option, $input_value)
|
173 |
{
|
174 |
+
if (is_null($input_value)) {
|
175 |
+
return $option['value'];
|
176 |
+
}
|
177 |
+
|
178 |
if (!isset($option['choices'][$input_value])) {
|
179 |
if (
|
180 |
empty($option['choices']) ||
|
framework/includes/option-types/multi-picker/class-fw-option-type-multi-picker.php
CHANGED
@@ -74,6 +74,45 @@ class FW_Option_Type_Multi_Picker extends FW_Option_Type
|
|
74 |
$option['attr']['class'] .= ' fw-option-type-multi-picker-without-borders';
|
75 |
}
|
76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
return '<div ' . fw_attr_to_html($option['attr']) . '>' .
|
78 |
fw()->backend->render_options($options_array, $data['value'], array(
|
79 |
'id_prefix' => $data['id_prefix'] . $id . '-',
|
@@ -170,7 +209,7 @@ class FW_Option_Type_Multi_Picker extends FW_Option_Type
|
|
170 |
'type' => 'group',
|
171 |
'attr' => array('class' => 'choice-group choice-' . $key),
|
172 |
'options' => array(
|
173 |
-
$key
|
174 |
'type' => 'multi',
|
175 |
'attr' => array('class' => $show_borders),
|
176 |
'label' => false,
|
@@ -209,10 +248,14 @@ class FW_Option_Type_Multi_Picker extends FW_Option_Type
|
|
209 |
|
210 |
$value = array();
|
211 |
|
212 |
-
$value[$picker_key]
|
213 |
-
$
|
214 |
-
|
215 |
-
|
|
|
|
|
|
|
|
|
216 |
|
217 |
// choices
|
218 |
switch($picker_type) {
|
@@ -241,14 +284,16 @@ class FW_Option_Type_Multi_Picker extends FW_Option_Type
|
|
241 |
}
|
242 |
|
243 |
foreach ($choices as $choice_id => $options) {
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
|
|
|
|
|
|
250 |
}
|
251 |
-
|
252 |
}
|
253 |
|
254 |
return $value;
|
74 |
$option['attr']['class'] .= ' fw-option-type-multi-picker-without-borders';
|
75 |
}
|
76 |
|
77 |
+
/**
|
78 |
+
* Leave only select choice options to be rendered in the browser
|
79 |
+
* the rest move to attr[data-options-template] to be rendered on choice change.
|
80 |
+
* This should improve page loading speed.
|
81 |
+
*/
|
82 |
+
{
|
83 |
+
{
|
84 |
+
reset($option['picker']);
|
85 |
+
$picker_key = key($option['picker']);
|
86 |
+
$picker_type = $option['picker'][$picker_key]['type'];
|
87 |
+
$picker = $option['picker'][$picker_key];
|
88 |
+
$picker_value = fw()->backend->option_type($picker_type)->get_value_from_input(
|
89 |
+
$picker,
|
90 |
+
isset($data['value'][$picker_key]) ? $data['value'][$picker_key] : null
|
91 |
+
);
|
92 |
+
}
|
93 |
+
|
94 |
+
$skip_first = true;
|
95 |
+
foreach ($options_array as $group_id => &$group) {
|
96 |
+
if ($skip_first) {
|
97 |
+
// first is picker
|
98 |
+
$skip_first = false;
|
99 |
+
continue;
|
100 |
+
}
|
101 |
+
|
102 |
+
if ($group_id === $id .'-'. $picker_value) {
|
103 |
+
// skip selected choice options
|
104 |
+
continue;
|
105 |
+
}
|
106 |
+
|
107 |
+
$options_array[$group_id]['attr']['data-options-template'] = fw()->backend->render_options(
|
108 |
+
$options_array[$group_id]['options'], $data['value'], array(
|
109 |
+
'id_prefix' => $data['id_prefix'] . $id . '-',
|
110 |
+
'name_prefix' => $data['name_prefix'] . '[' . $id . ']',
|
111 |
+
));
|
112 |
+
$options_array[$group_id]['options'] = array();
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
return '<div ' . fw_attr_to_html($option['attr']) . '>' .
|
117 |
fw()->backend->render_options($options_array, $data['value'], array(
|
118 |
'id_prefix' => $data['id_prefix'] . $id . '-',
|
209 |
'type' => 'group',
|
210 |
'attr' => array('class' => 'choice-group choice-' . $key),
|
211 |
'options' => array(
|
212 |
+
$key => array(
|
213 |
'type' => 'multi',
|
214 |
'attr' => array('class' => $show_borders),
|
215 |
'label' => false,
|
248 |
|
249 |
$value = array();
|
250 |
|
251 |
+
if (is_null($input_value) && isset($option['value'][$picker_key])) {
|
252 |
+
$value[$picker_key] = $option['value'][$picker_key];
|
253 |
+
} else {
|
254 |
+
$value[$picker_key] = fw()->backend->option_type($picker_type)->get_value_from_input(
|
255 |
+
$picker,
|
256 |
+
isset($input_value[$picker_key]) ? $input_value[$picker_key] : null
|
257 |
+
);
|
258 |
+
}
|
259 |
|
260 |
// choices
|
261 |
switch($picker_type) {
|
284 |
}
|
285 |
|
286 |
foreach ($choices as $choice_id => $options) {
|
287 |
+
if (is_null($input_value) && isset($option['value'][$choice_id])) {
|
288 |
+
$value[$choice_id] = $option['value'][$choice_id];
|
289 |
+
} else {
|
290 |
+
foreach (fw_extract_only_options($options) as $option_id => $option) {
|
291 |
+
$value[$choice_id][$option_id] = fw()->backend->option_type($option['type'])->get_value_from_input(
|
292 |
+
$option,
|
293 |
+
isset($input_value[$choice_id][$option_id]) ? $input_value[$choice_id][$option_id] : null
|
294 |
+
);
|
295 |
+
}
|
296 |
}
|
|
|
297 |
}
|
298 |
|
299 |
return $value;
|
framework/includes/option-types/multi-picker/static/js/multi-picker.js
CHANGED
@@ -7,6 +7,23 @@
|
|
7 |
},
|
8 |
chooseGroup = function(groupId) {
|
9 |
var $choicesToReveal = elements.$choicesGroups.filter('.choice-' + groupId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
elements.$choicesGroups.removeClass('chosen');
|
11 |
$choicesToReveal.addClass('chosen');
|
12 |
|
7 |
},
|
8 |
chooseGroup = function(groupId) {
|
9 |
var $choicesToReveal = elements.$choicesGroups.filter('.choice-' + groupId);
|
10 |
+
|
11 |
+
/**
|
12 |
+
* The group options html was rendered in an attribute to make page load faster.
|
13 |
+
* Move the html from attribute in group and init options with js.
|
14 |
+
*/
|
15 |
+
if ($choicesToReveal.attr('data-options-template')) {
|
16 |
+
$choicesToReveal.html(
|
17 |
+
$choicesToReveal.attr('data-options-template')
|
18 |
+
);
|
19 |
+
|
20 |
+
$choicesToReveal.removeAttr('data-options-template');
|
21 |
+
|
22 |
+
fwEvents.trigger('fw:options:init', {
|
23 |
+
$elements: $choicesToReveal
|
24 |
+
});
|
25 |
+
}
|
26 |
+
|
27 |
elements.$choicesGroups.removeClass('chosen');
|
28 |
$choicesToReveal.addClass('chosen');
|
29 |
|
framework/includes/option-types/multi-select/class-fw-option-type-multi-select.php
CHANGED
@@ -2,169 +2,131 @@
|
|
2 |
die( 'Forbidden' );
|
3 |
}
|
4 |
|
5 |
-
if (!class_exists('FW_Option_Type_Multi_Select')):
|
6 |
|
7 |
-
/**
|
8 |
-
* Select multiple choices from different sources: posts, taxonomies, users or custom array
|
9 |
-
*/
|
10 |
-
class FW_Option_Type_Multi_Select extends FW_Option_Type
|
11 |
-
{
|
12 |
/**
|
13 |
-
*
|
14 |
*/
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
|
50 |
-
|
51 |
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
|
67 |
-
/**
|
68 |
-
* @internal
|
69 |
-
*/
|
70 |
-
public static function _admin_action_get_ajax_response() {
|
71 |
/**
|
72 |
-
* @
|
73 |
*/
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
array(
|
89 |
-
"SELECT ID val, post_title title " .
|
90 |
-
"FROM $wpdb->posts " .
|
91 |
-
"WHERE post_title LIKE %s " .
|
92 |
-
"AND post_status = 'publish' " .
|
93 |
-
"AND NULLIF(post_password, '') IS NULL " .
|
94 |
-
"AND post_type IN ( ".
|
95 |
-
implode(', ', array_fill(1, count($names), '%s')) .
|
96 |
-
" ) " .
|
97 |
-
"LIMIT 100",
|
98 |
-
'%'. $wpdb->esc_like($title) .'%'
|
99 |
-
),
|
100 |
-
/**
|
101 |
-
* These strings may contain '%abc'
|
102 |
-
* so we cannot use them directly in sql
|
103 |
-
* because $wpdb->prepare() will return false
|
104 |
-
* also you can test that with sprintf()
|
105 |
-
*/
|
106 |
-
$names
|
107 |
-
)
|
108 |
-
)
|
109 |
-
);
|
110 |
-
break;
|
111 |
-
case 'taxonomy':
|
112 |
-
$items = $wpdb->get_results(
|
113 |
-
call_user_func_array(
|
114 |
-
array($wpdb, 'prepare'),
|
115 |
-
array_merge(
|
116 |
-
array(
|
117 |
-
"SELECT terms.term_id val, terms.name title " .
|
118 |
-
"FROM $wpdb->terms as terms, $wpdb->term_taxonomy as taxonomies " .
|
119 |
-
"WHERE terms.name LIKE %s AND taxonomies.taxonomy IN ( ".
|
120 |
-
implode(', ', array_fill(1, count($names), '%s')) .
|
121 |
-
" ) " .
|
122 |
-
"AND terms.term_id = taxonomies.term_id " .
|
123 |
-
"AND taxonomies.term_id = taxonomies.term_taxonomy_id " .
|
124 |
-
"LIMIT 100",
|
125 |
-
'%'. $wpdb->esc_like($title) .'%'
|
126 |
-
),
|
127 |
-
/**
|
128 |
-
* These strings may contain '%abc'
|
129 |
-
* so we cannot use them directly in sql
|
130 |
-
* because $wpdb->prepare() will return false
|
131 |
-
* also you can test that with sprintf()
|
132 |
-
*/
|
133 |
-
$names
|
134 |
-
)
|
135 |
-
)
|
136 |
-
);
|
137 |
-
break;
|
138 |
-
case 'users':
|
139 |
-
if ( empty( $names ) ) {
|
140 |
$items = $wpdb->get_results(
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
)
|
148 |
);
|
149 |
-
|
150 |
-
|
151 |
-
foreach ($names as $name) {
|
152 |
-
$like_user_meta[] = '%'. $wpdb->esc_like($name) .'%';
|
153 |
-
}
|
154 |
-
|
155 |
$items = $wpdb->get_results(
|
156 |
call_user_func_array(
|
157 |
-
array($wpdb, 'prepare'),
|
158 |
array_merge(
|
159 |
array(
|
160 |
-
"SELECT
|
161 |
-
"FROM $wpdb->
|
162 |
-
"WHERE
|
163 |
-
|
164 |
-
implode(' OR ', array_fill(1, count($like_user_meta), 'usermeta.meta_value LIKE %s')) .
|
165 |
" ) " .
|
166 |
-
"AND
|
167 |
-
|
|
|
|
|
168 |
),
|
169 |
/**
|
170 |
* These strings may contain '%abc'
|
@@ -172,111 +134,276 @@ class FW_Option_Type_Multi_Select extends FW_Option_Type
|
|
172 |
* because $wpdb->prepare() will return false
|
173 |
* also you can test that with sprintf()
|
174 |
*/
|
175 |
-
$
|
176 |
)
|
177 |
)
|
178 |
);
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
|
|
|
|
|
|
|
|
192 |
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
}
|
207 |
break;
|
208 |
-
|
209 |
-
if ( isset( $option['source'] ) ) {
|
210 |
-
/**
|
211 |
-
* @var WPDB $wpdb
|
212 |
-
*/
|
213 |
-
global $wpdb;
|
214 |
|
215 |
-
|
216 |
-
|
217 |
|
218 |
-
|
219 |
-
|
220 |
-
|
|
|
|
|
|
|
221 |
|
222 |
-
|
223 |
-
|
224 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
}
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
|
236 |
-
if ( is_wp_error( $query ) ) {
|
237 |
-
break;
|
238 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
239 |
|
240 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
}
|
246 |
-
break;
|
247 |
-
case 'taxonomy' :
|
248 |
-
if ( isset( $option['source'] ) ) {
|
249 |
-
$population = 'taxonomy';
|
250 |
-
$source = is_array($option['source']) ? $option['source'] : array($option['source']);
|
251 |
|
252 |
-
|
253 |
-
break;
|
254 |
-
}
|
255 |
|
|
|
|
|
|
|
|
|
|
|
|
|
256 |
/**
|
257 |
* @var WPDB $wpdb
|
258 |
*/
|
259 |
global $wpdb;
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
264 |
}
|
265 |
-
$ids = implode( ', ', array_unique( $ids ) );
|
266 |
|
267 |
-
$
|
268 |
-
|
269 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
270 |
}
|
271 |
-
$in_sources = implode(', ', $in_sources);
|
272 |
-
|
273 |
-
$query = $wpdb->get_results(
|
274 |
-
"SELECT terms.term_id id, terms.name title " .
|
275 |
-
"FROM $wpdb->terms as terms, $wpdb->term_taxonomy as taxonomies " .
|
276 |
-
"WHERE terms.term_id IN ( $ids ) AND taxonomies.taxonomy IN ( $in_sources ) " .
|
277 |
-
"AND terms.term_id = taxonomies.term_id " .
|
278 |
-
"AND taxonomies.term_id = taxonomies.term_taxonomy_id"
|
279 |
-
);
|
280 |
|
281 |
if ( is_wp_error( $query ) || empty( $query ) ) {
|
282 |
break;
|
@@ -287,145 +414,86 @@ class FW_Option_Type_Multi_Select extends FW_Option_Type
|
|
287 |
foreach ( $query as $term ) {
|
288 |
$items[ $term->id ] = $term->title;
|
289 |
}
|
290 |
-
}
|
291 |
-
break;
|
292 |
-
case 'users' :
|
293 |
-
/**
|
294 |
-
* @var WPDB $wpdb
|
295 |
-
*/
|
296 |
-
global $wpdb;
|
297 |
-
$population = 'users';
|
298 |
-
|
299 |
-
if ( isset( $option['source'] ) && ! empty( $option['source'] ) ) {
|
300 |
-
$source = is_array($option['source']) ? $option['source'] : array($option['source']);
|
301 |
-
|
302 |
-
if ( empty( $data['value'] ) ) {
|
303 |
-
break;
|
304 |
-
}
|
305 |
-
|
306 |
-
$ids = $data['value'];
|
307 |
-
foreach ( $ids as $post_id ) {
|
308 |
-
$ids[] = intval( $post_id );
|
309 |
-
}
|
310 |
-
$ids = implode( ', ', array_unique( $ids ) );
|
311 |
-
|
312 |
-
$in_sources = array();
|
313 |
-
foreach ($source as $_source) {
|
314 |
-
$in_sources[] = $wpdb->prepare('usermeta.meta_value LIKE %s', '%'. $wpdb->esc_like($_source) .'%');
|
315 |
-
}
|
316 |
-
$in_sources = implode(' OR ', $in_sources);
|
317 |
-
|
318 |
-
$query = $wpdb->get_results(
|
319 |
-
"SELECT users.id, users.display_name title " .
|
320 |
-
"FROM $wpdb->users as users, $wpdb->usermeta usermeta " .
|
321 |
-
"WHERE users.ID IN ($ids) AND usermeta.meta_key = 'wp_capabilities' AND ( $in_sources ) " .
|
322 |
-
"AND usermeta.user_id = users.ID"
|
323 |
-
);
|
324 |
-
|
325 |
-
} else {
|
326 |
-
$source = array();
|
327 |
-
|
328 |
-
if ( empty( $data['value'] ) ) {
|
329 |
-
break;
|
330 |
-
}
|
331 |
-
|
332 |
-
$ids = $data['value'];
|
333 |
-
foreach ( $ids as $post_id ) {
|
334 |
-
$ids[] = intval( $post_id );
|
335 |
-
}
|
336 |
-
$ids = implode( ', ', array_unique( $ids ) );
|
337 |
|
338 |
-
$query = $wpdb->get_results(
|
339 |
-
"SELECT users.id, users.user_nicename title " .
|
340 |
-
"FROM $wpdb->users as users " .
|
341 |
-
"WHERE users.ID IN ($ids)"
|
342 |
-
);
|
343 |
-
}
|
344 |
-
|
345 |
-
if ( is_wp_error( $query ) || empty( $query ) ) {
|
346 |
break;
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
foreach ( $query as $term ) {
|
352 |
-
$items[ $term->id ] = $term->title;
|
353 |
-
}
|
354 |
|
355 |
-
|
356 |
-
|
357 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
358 |
}
|
359 |
|
360 |
-
|
361 |
-
$option['attr']['data-population'] = $population;
|
362 |
-
$option['attr']['data-source'] = json_encode( $source );
|
363 |
-
$option['attr']['data-limit'] = ( intval( $option['limit'] ) > 0 ) ? $option['limit'] : 0;
|
364 |
-
} else {
|
365 |
-
return '';
|
366 |
}
|
367 |
-
if ( ! empty( $data['value'] ) ) {
|
368 |
-
$data['value'] = implode( '/*/', $data['value'] );
|
369 |
-
} else {
|
370 |
-
$data['value'] = '';
|
371 |
-
}
|
372 |
-
|
373 |
-
return fw()->backend->option_type( 'text' )->render( $id, $option, $data );
|
374 |
-
}
|
375 |
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
fw()->backend->option_type( 'text' )->enqueue_static();
|
396 |
-
}
|
397 |
|
398 |
-
|
399 |
-
* @internal
|
400 |
-
*/
|
401 |
-
private function convert_array( $array = array() ) {
|
402 |
-
if ( ! is_array( $array ) || empty( $array ) ) {
|
403 |
-
return array();
|
404 |
}
|
405 |
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
412 |
}
|
413 |
|
414 |
-
|
415 |
-
|
|
|
|
|
|
|
|
|
|
|
416 |
|
417 |
-
|
418 |
-
* @internal
|
419 |
-
*/
|
420 |
-
protected function _get_value_from_input( $option, $input_value ) {
|
421 |
-
$value = explode( '/*/', $input_value );
|
422 |
|
423 |
-
|
|
|
424 |
}
|
425 |
-
}
|
426 |
|
427 |
-
FW_Option_Type::register( 'FW_Option_Type_Multi_Select' );
|
428 |
|
429 |
-
add_action( 'wp_ajax_admin_action_get_ajax_response',
|
|
|
430 |
|
431 |
endif;
|
2 |
die( 'Forbidden' );
|
3 |
}
|
4 |
|
5 |
+
if ( ! class_exists( 'FW_Option_Type_Multi_Select' ) ):
|
6 |
|
|
|
|
|
|
|
|
|
|
|
7 |
/**
|
8 |
+
* Select multiple choices from different sources: posts, taxonomies, users or custom array
|
9 |
*/
|
10 |
+
class FW_Option_Type_Multi_Select extends FW_Option_Type {
|
11 |
+
/**
|
12 |
+
* @internal
|
13 |
+
*/
|
14 |
+
protected function _get_defaults() {
|
15 |
+
return array(
|
16 |
+
'value' => array(),
|
17 |
+
/**
|
18 |
+
* Available options: array, posts, taxonomy, users
|
19 |
+
*/
|
20 |
+
'population' => 'array',
|
21 |
+
/**
|
22 |
+
* Set post types, taxonomies, user roles to search for
|
23 |
+
*
|
24 |
+
* 'population' => 'posts'
|
25 |
+
* 'source' => 'page',
|
26 |
+
*
|
27 |
+
* 'population' => 'taxonomy'
|
28 |
+
* 'source' => 'category',
|
29 |
+
*
|
30 |
+
* 'population' => 'users'
|
31 |
+
* 'source' => array( 'editor', 'subscriber', 'author' ),
|
32 |
+
*
|
33 |
+
* 'population' => 'array'
|
34 |
+
* 'source' => '' // will populate with 'choices' array
|
35 |
+
*/
|
36 |
+
'source' => '',
|
37 |
+
/**
|
38 |
+
* Set the number of posts/users/taxonomies that multi-select will be prepopulated
|
39 |
+
* Or set the value to false in order to disable this functionality.
|
40 |
+
*/
|
41 |
+
'prepopulate' => 10,
|
42 |
+
/**
|
43 |
+
* An array with the available choices
|
44 |
+
* Used only when 'population' => 'array'
|
45 |
+
*/
|
46 |
+
'choices' => array( /* 'value' => 'Title' */ ),
|
47 |
+
/**
|
48 |
+
* Set maximum items number that can be selected
|
49 |
+
*/
|
50 |
+
'limit' => 100,
|
51 |
+
);
|
52 |
+
}
|
53 |
|
54 |
+
private $internal_options = array();
|
55 |
|
56 |
+
public function get_type() {
|
57 |
+
return 'multi-select';
|
58 |
+
}
|
59 |
|
60 |
+
/**
|
61 |
+
* @internal
|
62 |
+
*/
|
63 |
+
public function _init() {
|
64 |
+
$this->internal_options = array(
|
65 |
+
'label' => false,
|
66 |
+
'type' => 'text',
|
67 |
+
'value' => '',
|
68 |
+
);
|
69 |
+
}
|
70 |
|
|
|
|
|
|
|
|
|
71 |
/**
|
72 |
+
* @internal
|
73 |
*/
|
74 |
+
public static function _admin_action_get_ajax_response() {
|
75 |
+
/**
|
76 |
+
* @var WPDB $wpdb
|
77 |
+
*/
|
78 |
+
global $wpdb;
|
79 |
+
|
80 |
+
$type = FW_Request::POST( 'data/type' );
|
81 |
+
$names = json_decode( FW_Request::POST( 'data/names' ), true );
|
82 |
+
$title = FW_Request::POST( 'data/string' );
|
83 |
+
|
84 |
+
$items = array();
|
85 |
+
|
86 |
+
switch ( $type ) {
|
87 |
+
case 'posts':
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
$items = $wpdb->get_results(
|
89 |
+
call_user_func_array(
|
90 |
+
array( $wpdb, 'prepare' ),
|
91 |
+
array_merge(
|
92 |
+
array(
|
93 |
+
"SELECT ID val, post_title title " .
|
94 |
+
"FROM $wpdb->posts " .
|
95 |
+
"WHERE post_title LIKE %s " .
|
96 |
+
"AND post_status = 'publish' " .
|
97 |
+
"AND NULLIF(post_password, '') IS NULL " .
|
98 |
+
"AND post_type IN ( " .
|
99 |
+
implode( ', ', array_fill( 1, count( $names ), '%s' ) ) .
|
100 |
+
" ) " .
|
101 |
+
"LIMIT 100",
|
102 |
+
'%' . $wpdb->esc_like( $title ) . '%'
|
103 |
+
),
|
104 |
+
/**
|
105 |
+
* These strings may contain '%abc'
|
106 |
+
* so we cannot use them directly in sql
|
107 |
+
* because $wpdb->prepare() will return false
|
108 |
+
* also you can test that with sprintf()
|
109 |
+
*/
|
110 |
+
$names
|
111 |
+
)
|
112 |
)
|
113 |
);
|
114 |
+
break;
|
115 |
+
case 'taxonomy':
|
|
|
|
|
|
|
|
|
116 |
$items = $wpdb->get_results(
|
117 |
call_user_func_array(
|
118 |
+
array( $wpdb, 'prepare' ),
|
119 |
array_merge(
|
120 |
array(
|
121 |
+
"SELECT terms.term_id val, terms.name title " .
|
122 |
+
"FROM $wpdb->terms as terms, $wpdb->term_taxonomy as taxonomies " .
|
123 |
+
"WHERE terms.name LIKE %s AND taxonomies.taxonomy IN ( " .
|
124 |
+
implode( ', ', array_fill( 1, count( $names ), '%s' ) ) .
|
|
|
125 |
" ) " .
|
126 |
+
"AND terms.term_id = taxonomies.term_id " .
|
127 |
+
"AND taxonomies.term_id = taxonomies.term_taxonomy_id " .
|
128 |
+
"LIMIT 100",
|
129 |
+
'%' . $wpdb->esc_like( $title ) . '%'
|
130 |
),
|
131 |
/**
|
132 |
* These strings may contain '%abc'
|
134 |
* because $wpdb->prepare() will return false
|
135 |
* also you can test that with sprintf()
|
136 |
*/
|
137 |
+
$names
|
138 |
)
|
139 |
)
|
140 |
);
|
141 |
+
break;
|
142 |
+
case 'users':
|
143 |
+
if ( empty( $names ) ) {
|
144 |
+
$items = $wpdb->get_results(
|
145 |
+
$wpdb->prepare(
|
146 |
+
"SELECT users.id val, users.user_nicename title " .
|
147 |
+
"FROM $wpdb->users as users " .
|
148 |
+
"WHERE users.user_nicename LIKE %s " .
|
149 |
+
"LIMIT 100",
|
150 |
+
'%' . $wpdb->esc_like( $title ) . '%'
|
151 |
+
)
|
152 |
+
);
|
153 |
+
} else {
|
154 |
+
$like_user_meta = array();
|
155 |
+
foreach ( $names as $name ) {
|
156 |
+
$like_user_meta[] = '%' . $wpdb->esc_like( $name ) . '%';
|
157 |
+
}
|
158 |
|
159 |
+
$items = $wpdb->get_results(
|
160 |
+
call_user_func_array(
|
161 |
+
array( $wpdb, 'prepare' ),
|
162 |
+
array_merge(
|
163 |
+
array(
|
164 |
+
"SELECT users.id val, users.user_nicename title " .
|
165 |
+
"FROM $wpdb->users as users, $wpdb->usermeta as usermeta " .
|
166 |
+
"WHERE users.user_nicename LIKE %s AND usermeta.meta_key = 'wp_capabilities' " .
|
167 |
+
"AND ( " .
|
168 |
+
implode( ' OR ',
|
169 |
+
array_fill( 1, count( $like_user_meta ), 'usermeta.meta_value LIKE %s' ) ) .
|
170 |
+
" ) " .
|
171 |
+
"AND usermeta.user_id = users.ID",
|
172 |
+
'%' . $wpdb->esc_like( $title ) . '%'
|
173 |
+
),
|
174 |
+
/**
|
175 |
+
* These strings may contain '%abc'
|
176 |
+
* so we cannot use them directly in sql
|
177 |
+
* because $wpdb->prepare() will return false
|
178 |
+
* also you can test that with sprintf()
|
179 |
+
*/
|
180 |
+
$like_user_meta
|
181 |
+
)
|
182 |
+
)
|
183 |
+
);
|
184 |
}
|
185 |
break;
|
186 |
+
}
|
|
|
|
|
|
|
|
|
|
|
187 |
|
188 |
+
wp_send_json_success( $items );
|
189 |
+
}
|
190 |
|
191 |
+
/**
|
192 |
+
* @internal
|
193 |
+
*/
|
194 |
+
public function _get_backend_width_type() {
|
195 |
+
return 'fixed';
|
196 |
+
}
|
197 |
|
198 |
+
/**
|
199 |
+
* @internal
|
200 |
+
*/
|
201 |
+
protected function _render( $id, $option, $data ) {
|
202 |
+
$items = '';
|
203 |
+
$population = 'array';
|
204 |
+
$source = array();
|
205 |
+
|
206 |
+
if ( isset( $option['population'] ) ) {
|
207 |
+
switch ( $option['population'] ) {
|
208 |
+
case 'array' :
|
209 |
+
if ( isset( $option['choices'] ) && is_array( $option['choices'] ) ) {
|
210 |
+
$items = $option['choices'];
|
211 |
}
|
212 |
+
break;
|
213 |
+
case 'posts' :
|
214 |
+
if ( isset( $option['source'] ) ) {
|
215 |
+
/**
|
216 |
+
* @var WPDB $wpdb
|
217 |
+
*/
|
218 |
+
global $wpdb;
|
219 |
+
|
220 |
+
$source = is_array( $option['source'] ) ? $option['source'] : array( $option['source'] );
|
221 |
+
$population = 'posts';
|
222 |
+
|
223 |
+
if ( isset( $option['prepopulate'] )
|
224 |
+
&& ( $number = (int) ( $option['prepopulate'] ) ) > 0
|
225 |
+
&& ! empty( $source )
|
226 |
+
) {
|
227 |
+
|
228 |
+
$posts = $wpdb->get_results(
|
229 |
+
"SELECT posts.ID, posts.post_title " .
|
230 |
+
"FROM $wpdb->posts as posts " .
|
231 |
+
"WHERE post_type IN ('" . implode( "', ", $source ) . "') " .
|
232 |
+
"ORDER BY post_date DESC LIMIT $number"
|
233 |
+
);
|
234 |
+
|
235 |
+
if ( ! empty( $posts ) || ! is_wp_error( $posts ) ) {
|
236 |
+
$items = wp_list_pluck( $posts, 'post_title', 'ID' );
|
237 |
+
}
|
238 |
+
unset( $posts );
|
239 |
+
}
|
240 |
+
|
241 |
+
if ( empty( $data['value'] ) ) {
|
242 |
+
break;
|
243 |
+
}
|
244 |
+
|
245 |
+
$ids = $data['value'];
|
246 |
+
foreach ( $ids as $post_id ) {
|
247 |
+
$ids[] = intval( $post_id );
|
248 |
+
}
|
249 |
+
$ids = implode( ', ', array_unique( $ids ) );
|
250 |
+
|
251 |
+
//$query = new WP_Query( array( 'post__in' => $ids ) );
|
252 |
+
|
253 |
+
$query = $wpdb->get_results(
|
254 |
+
"SELECT posts.ID, posts.post_title " .
|
255 |
+
"FROM $wpdb->posts as posts " .
|
256 |
+
"WHERE posts.ID IN ( $ids )"
|
257 |
+
);
|
258 |
+
|
259 |
+
if ( is_wp_error( $query ) ) {
|
260 |
+
break;
|
261 |
+
}
|
262 |
+
|
263 |
+
foreach ( $query as $post ) {
|
264 |
+
$items[ $post->ID ] = $post->post_title;
|
265 |
+
}
|
266 |
|
|
|
|
|
267 |
}
|
268 |
+
break;
|
269 |
+
case 'taxonomy' :
|
270 |
+
if ( isset( $option['source'] ) ) {
|
271 |
+
/**
|
272 |
+
* @var WPDB $wpdb
|
273 |
+
*/
|
274 |
+
global $wpdb;
|
275 |
+
$population = 'taxonomy';
|
276 |
+
$source = is_array( $option['source'] ) ? $option['source'] : array( $option['source'] );
|
277 |
+
|
278 |
+
if ( isset( $option['prepopulate'] ) && ! empty( $source )
|
279 |
+
&& ( $number = (int) ( $option['prepopulate'] ) ) > 0
|
280 |
+
) {
|
281 |
+
$terms = $wpdb->get_results(
|
282 |
+
"SELECT terms.term_id, terms.name " .
|
283 |
+
"FROM $wpdb->terms as terms, $wpdb->term_taxonomy as taxonomies " .
|
284 |
+
"WHERE taxonomies.taxonomy IN ('" . implode( "', ", $source ) . "') " .
|
285 |
+
"AND terms.term_id = taxonomies.term_id " .
|
286 |
+
"AND taxonomies.term_id = taxonomies.term_taxonomy_id"
|
287 |
+
);
|
288 |
+
|
289 |
+
if ( ! empty( $terms ) || ! is_wp_error( $terms ) ) {
|
290 |
+
$items = wp_list_pluck( $terms, 'name', 'term_id' );
|
291 |
+
}
|
292 |
+
unset( $terms );
|
293 |
+
}
|
294 |
+
|
295 |
+
if ( empty( $data['value'] ) ) {
|
296 |
+
break;
|
297 |
+
}
|
298 |
|
299 |
+
/**
|
300 |
+
* @var WPDB $wpdb
|
301 |
+
*/
|
302 |
+
global $wpdb;
|
303 |
+
|
304 |
+
$ids = $data['value'];
|
305 |
+
foreach ( $ids as $post_id ) {
|
306 |
+
$ids[] = intval( $post_id );
|
307 |
+
}
|
308 |
+
$ids = implode( ', ', array_unique( $ids ) );
|
309 |
+
|
310 |
+
$in_sources = array();
|
311 |
+
foreach ( $source as $_source ) {
|
312 |
+
$in_sources[] = $wpdb->prepare( '%s', $_source );
|
313 |
+
}
|
314 |
+
$in_sources = implode( ', ', $in_sources );
|
315 |
+
|
316 |
+
$query = $wpdb->get_results(
|
317 |
+
"SELECT terms.term_id id, terms.name title " .
|
318 |
+
"FROM $wpdb->terms as terms, $wpdb->term_taxonomy as taxonomies " .
|
319 |
+
"WHERE terms.term_id IN ( $ids ) AND taxonomies.taxonomy IN ( $in_sources ) " .
|
320 |
+
"AND terms.term_id = taxonomies.term_id " .
|
321 |
+
"AND taxonomies.term_id = taxonomies.term_taxonomy_id"
|
322 |
+
);
|
323 |
|
324 |
+
if ( is_wp_error( $query ) || empty( $query ) ) {
|
325 |
+
break;
|
326 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
327 |
|
328 |
+
$items = array();
|
|
|
|
|
329 |
|
330 |
+
foreach ( $query as $term ) {
|
331 |
+
$items[ $term->id ] = $term->title;
|
332 |
+
}
|
333 |
+
}
|
334 |
+
break;
|
335 |
+
case 'users' :
|
336 |
/**
|
337 |
* @var WPDB $wpdb
|
338 |
*/
|
339 |
global $wpdb;
|
340 |
+
$population = 'users';
|
341 |
+
|
342 |
+
if ( isset( $option['prepopulate'] )
|
343 |
+
&& ( $number = (int) ( $option['prepopulate'] ) ) > 0
|
344 |
+
) {
|
345 |
+
$users = $wpdb->get_results(
|
346 |
+
"SELECT DISTINCT users.ID, users.user_nicename " .
|
347 |
+
"FROM $wpdb->users as users, $wpdb->usermeta usermeta " .
|
348 |
+
( ! empty( $source )
|
349 |
+
? "WHERE usermeta.meta_key = 'wp_capabilities'" .
|
350 |
+
" AND usermeta.meta_value IN ('" . implode( "', ", $source ) . "')" .
|
351 |
+
" AND usermeta.user_id = users.ID"
|
352 |
+
: '' ) . " LIMIT $number"
|
353 |
+
);
|
354 |
+
|
355 |
+
if ( ! empty( $users ) || ! is_wp_error( $users ) ) {
|
356 |
+
$items = wp_list_pluck( $users, 'user_nicename', 'ID' );
|
357 |
+
}
|
358 |
+
unset( $users );
|
359 |
}
|
|
|
360 |
|
361 |
+
if ( isset( $option['source'] ) && ! empty( $option['source'] ) ) {
|
362 |
+
$source = is_array( $option['source'] ) ? $option['source'] : array( $option['source'] );
|
363 |
+
|
364 |
+
if ( empty( $data['value'] ) ) {
|
365 |
+
break;
|
366 |
+
}
|
367 |
+
|
368 |
+
$ids = $data['value'];
|
369 |
+
foreach ( $ids as $post_id ) {
|
370 |
+
$ids[] = intval( $post_id );
|
371 |
+
}
|
372 |
+
$ids = implode( ', ', array_unique( $ids ) );
|
373 |
+
|
374 |
+
$in_sources = array();
|
375 |
+
foreach ( $source as $_source ) {
|
376 |
+
$in_sources[] = $wpdb->prepare( 'usermeta.meta_value LIKE %s',
|
377 |
+
'%' . $wpdb->esc_like( $_source ) . '%' );
|
378 |
+
}
|
379 |
+
$in_sources = implode( ' OR ', $in_sources );
|
380 |
+
|
381 |
+
$query = $wpdb->get_results(
|
382 |
+
"SELECT users.id, users.user_nicename title " .
|
383 |
+
"FROM $wpdb->users as users, $wpdb->usermeta usermeta " .
|
384 |
+
"WHERE users.ID IN ($ids) AND usermeta.meta_key = 'wp_capabilities' AND ( $in_sources ) " .
|
385 |
+
"AND usermeta.user_id = users.ID"
|
386 |
+
);
|
387 |
+
|
388 |
+
} else {
|
389 |
+
$source = array();
|
390 |
+
|
391 |
+
if ( empty( $data['value'] ) ) {
|
392 |
+
break;
|
393 |
+
}
|
394 |
+
|
395 |
+
$ids = $data['value'];
|
396 |
+
foreach ( $ids as $post_id ) {
|
397 |
+
$ids[] = intval( $post_id );
|
398 |
+
}
|
399 |
+
$ids = implode( ', ', array_unique( $ids ) );
|
400 |
+
|
401 |
+
$query = $wpdb->get_results(
|
402 |
+
"SELECT users.id, users.user_nicename title " .
|
403 |
+
"FROM $wpdb->users as users " .
|
404 |
+
"WHERE users.ID IN ($ids)"
|
405 |
+
);
|
406 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
407 |
|
408 |
if ( is_wp_error( $query ) || empty( $query ) ) {
|
409 |
break;
|
414 |
foreach ( $query as $term ) {
|
415 |
$items[ $term->id ] = $term->title;
|
416 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
417 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
418 |
break;
|
419 |
+
default :
|
420 |
+
$items = '';
|
421 |
+
}
|
|
|
|
|
|
|
|
|
422 |
|
423 |
+
$option['attr']['data-options'] = json_encode( $this->convert_array( $items ) );
|
424 |
+
$option['attr']['data-population'] = $population;
|
425 |
+
$option['attr']['data-source'] = json_encode( $source );
|
426 |
+
$option['attr']['data-limit'] = ( intval( $option['limit'] ) > 0 ) ? $option['limit'] : 0;
|
427 |
+
} else {
|
428 |
+
return '';
|
429 |
+
}
|
430 |
+
if ( ! empty( $data['value'] ) ) {
|
431 |
+
$data['value'] = implode( '/*/', $data['value'] );
|
432 |
+
} else {
|
433 |
+
$data['value'] = '';
|
434 |
}
|
435 |
|
436 |
+
return fw()->backend->option_type( 'text' )->render( $id, $option, $data );
|
|
|
|
|
|
|
|
|
|
|
437 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
438 |
|
439 |
+
/**
|
440 |
+
* @internal
|
441 |
+
* {@inheritdoc}
|
442 |
+
*/
|
443 |
+
protected function _enqueue_static( $id, $option, $data ) {
|
444 |
+
wp_enqueue_style(
|
445 |
+
$this->get_type() . '-styles',
|
446 |
+
fw_get_framework_directory_uri( '/includes/option-types/' . $this->get_type() . '/static/css/style.css' ),
|
447 |
+
array( 'fw-selectize' ),
|
448 |
+
fw()->manifest->get_version()
|
449 |
+
);
|
450 |
+
wp_enqueue_script(
|
451 |
+
$this->get_type() . '-styles',
|
452 |
+
fw_get_framework_directory_uri( '/includes/option-types/' . $this->get_type() . '/static/js/scripts.js' ),
|
453 |
+
array( 'jquery', 'fw-events', 'fw-selectize' ),
|
454 |
+
fw()->manifest->get_version(),
|
455 |
+
true
|
456 |
+
);
|
|
|
|
|
|
|
457 |
|
458 |
+
fw()->backend->option_type( 'text' )->enqueue_static();
|
|
|
|
|
|
|
|
|
|
|
459 |
}
|
460 |
|
461 |
+
/**
|
462 |
+
* @internal
|
463 |
+
*/
|
464 |
+
private function convert_array( $array = array() ) {
|
465 |
+
if ( ! is_array( $array ) || empty( $array ) ) {
|
466 |
+
return array();
|
467 |
+
}
|
468 |
+
|
469 |
+
$return = array();
|
470 |
+
foreach ( $array as $key => $item ) {
|
471 |
+
$return[] = array(
|
472 |
+
'val' => $key,
|
473 |
+
'title' => $item,
|
474 |
+
);
|
475 |
+
}
|
476 |
+
|
477 |
+
return $return;
|
478 |
}
|
479 |
|
480 |
+
/**
|
481 |
+
* @internal
|
482 |
+
*/
|
483 |
+
protected function _get_value_from_input( $option, $input_value ) {
|
484 |
+
if ( is_null( $input_value ) ) {
|
485 |
+
return $option['value'];
|
486 |
+
}
|
487 |
|
488 |
+
$value = explode( '/*/', $input_value );
|
|
|
|
|
|
|
|
|
489 |
|
490 |
+
return empty( $input_value ) ? array() : $value;
|
491 |
+
}
|
492 |
}
|
|
|
493 |
|
494 |
+
FW_Option_Type::register( 'FW_Option_Type_Multi_Select' );
|
495 |
|
496 |
+
add_action( 'wp_ajax_admin_action_get_ajax_response',
|
497 |
+
array( "FW_Option_Type_Multi_Select", '_admin_action_get_ajax_response' ) );
|
498 |
|
499 |
endif;
|
framework/includes/option-types/multi-upload/views/images-only.php
CHANGED
@@ -30,15 +30,15 @@
|
|
30 |
<?php endif; ?>
|
31 |
</div>
|
32 |
<p><a href="#"><?php echo $is_empty ? $l10n['button_add'] : $l10n['button_edit']; ?></a></p>
|
33 |
-
<br class="thumb-template-empty fw-hidden" data-template="<?php
|
34 |
-
<div class="thumb no-image">
|
35 |
-
<img src="
|
36 |
-
</div>
|
37 |
-
|
38 |
-
<br class="thumb-template-not-empty fw-hidden" data-template="<?php
|
39 |
-
<div class="thumb" data-attid="<%= data.id %>" data-origsrc="
|
40 |
-
<img src="
|
41 |
-
<a href="#" class="dashicons fw-x clear-uploads-thumb"></a>
|
42 |
-
</div>
|
43 |
-
|
44 |
</div>
|
30 |
<?php endif; ?>
|
31 |
</div>
|
32 |
<p><a href="#"><?php echo $is_empty ? $l10n['button_add'] : $l10n['button_edit']; ?></a></p>
|
33 |
+
<br class="thumb-template-empty fw-hidden" data-template="<?php echo fw_htmlspecialchars(
|
34 |
+
'<div class="thumb no-image">'.
|
35 |
+
'<img src="'. fw_get_framework_directory_uri('/static/img/no-image.png') .'" class="no-image-img" alt="'. esc_attr__('No image', 'fw') .'"/>'.
|
36 |
+
'</div>'
|
37 |
+
); ?>">
|
38 |
+
<br class="thumb-template-not-empty fw-hidden" data-template="<?php echo fw_htmlspecialchars(
|
39 |
+
'<div class="thumb" data-attid="<%= data.id %>" data-origsrc="<%- data.originalSrc %>">'.
|
40 |
+
'<img src="<%- data.src %>" alt="<%- data.alt %>"/>'.
|
41 |
+
'<a href="#" class="dashicons fw-x clear-uploads-thumb"></a>'.
|
42 |
+
'</div>'
|
43 |
+
); ?>">
|
44 |
</div>
|
framework/includes/option-types/popup/class-fw-option-type-popup.php
CHANGED
@@ -117,10 +117,7 @@ class FW_Option_Type_Popup extends FW_Option_Type {
|
|
117 |
return array();
|
118 |
}
|
119 |
|
120 |
-
|
121 |
-
$values[ $key ] = isset( $op['value'] ) ? $op['value'] : null;
|
122 |
-
}
|
123 |
-
|
124 |
} else {
|
125 |
$values = json_decode( $input_value, true );
|
126 |
}
|
@@ -156,6 +153,12 @@ class FW_Option_Type_Popup extends FW_Option_Type {
|
|
156 |
* Array of options that you need to add in the popup
|
157 |
*/
|
158 |
'popup-options' => array(),
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
/*
|
160 |
* Array of default values for the popup options
|
161 |
*/
|
117 |
return array();
|
118 |
}
|
119 |
|
120 |
+
$values = fw_get_options_values_from_input($option['popup-options'], array());
|
|
|
|
|
|
|
121 |
} else {
|
122 |
$values = json_decode( $input_value, true );
|
123 |
}
|
153 |
* Array of options that you need to add in the popup
|
154 |
*/
|
155 |
'popup-options' => array(),
|
156 |
+
|
157 |
+
/*
|
158 |
+
* Popup size
|
159 |
+
*/
|
160 |
+
'size' => 'medium',
|
161 |
+
|
162 |
/*
|
163 |
* Array of default values for the popup options
|
164 |
*/
|
framework/includes/option-types/radio-text/class-fw-option-type-radio-text.php
CHANGED
@@ -85,6 +85,10 @@ class FW_Option_Type_Radio_Text extends FW_Option_Type
|
|
85 |
*/
|
86 |
protected function _get_value_from_input($option, $input_value)
|
87 |
{
|
|
|
|
|
|
|
|
|
88 |
$option['choices'][ $this->custom_choice_key ] = '';
|
89 |
|
90 |
$selected = fw()->backend->option_type( 'radio' )->get_value_from_input( array(
|
85 |
*/
|
86 |
protected function _get_value_from_input($option, $input_value)
|
87 |
{
|
88 |
+
if (is_null($input_value)) {
|
89 |
+
return $option['value'];
|
90 |
+
}
|
91 |
+
|
92 |
$option['choices'][ $this->custom_choice_key ] = '';
|
93 |
|
94 |
$selected = fw()->backend->option_type( 'radio' )->get_value_from_input( array(
|
framework/includes/option-types/rgba-color-picker/class-fw-option-type-rgba-color-picker.php
CHANGED
@@ -51,16 +51,18 @@ class FW_Option_Type_Rgba_Color_Picker extends FW_Option_Type {
|
|
51 |
* @internal
|
52 |
*/
|
53 |
protected function _get_value_from_input( $option, $input_value ) {
|
54 |
-
if (
|
|
|
|
|
55 |
$input_value = trim($input_value);
|
56 |
$input_value = (
|
57 |
preg_match( '/^#[a-f0-9]{3}([a-f0-9]{3})?$/i', $input_value )
|
58 |
||
|
59 |
preg_match( '/^rgba\( *([01]?\d\d?|2[0-4]\d|25[0-5]) *\, *([01]?\d\d?|2[0-4]\d|25[0-5]) *\, *([01]?\d\d?|2[0-4]\d|25[0-5]) *\, *(1|0|0?.\d+) *\)$/', $input_value )
|
60 |
) ? $input_value : $option['value'];
|
61 |
-
}
|
62 |
|
63 |
-
|
|
|
64 |
}
|
65 |
|
66 |
/**
|
51 |
* @internal
|
52 |
*/
|
53 |
protected function _get_value_from_input( $option, $input_value ) {
|
54 |
+
if (is_null($input_value)) {
|
55 |
+
return $option['value'];
|
56 |
+
} else {
|
57 |
$input_value = trim($input_value);
|
58 |
$input_value = (
|
59 |
preg_match( '/^#[a-f0-9]{3}([a-f0-9]{3})?$/i', $input_value )
|
60 |
||
|
61 |
preg_match( '/^rgba\( *([01]?\d\d?|2[0-4]\d|25[0-5]) *\, *([01]?\d\d?|2[0-4]\d|25[0-5]) *\, *([01]?\d\d?|2[0-4]\d|25[0-5]) *\, *(1|0|0?.\d+) *\)$/', $input_value )
|
62 |
) ? $input_value : $option['value'];
|
|
|
63 |
|
64 |
+
return (string) $input_value;
|
65 |
+
}
|
66 |
}
|
67 |
|
68 |
/**
|
framework/includes/option-types/rgba-color-picker/static/js/scripts.js
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
(function ($) {
|
2 |
$(document.body).click(function (e) {
|
3 |
if (!$(e.target).is('.fw-option-type-rgba-color-picker, .iris-picker, .iris-picker-inner, .iris-palette, .fw-alpha-container')) {
|
@@ -33,110 +34,145 @@
|
|
33 |
return '#' + hex;
|
34 |
};
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
$input
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
|
71 |
$('<div class="fw-alpha-container"><div class="slider-alpha"></div><div class="transparency"></div></div>').appendTo($input.next('.iris-picker'));
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
$input.iris('hide');
|
122 |
-
|
123 |
-
if (!Color($input.val()).error) {
|
124 |
-
$input.iris('color', $input.val());
|
125 |
}
|
|
|
126 |
|
127 |
-
|
128 |
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
|
131 |
-
|
132 |
-
$('.fw-option-type-rgba-color-picker.initialized').iris('hide');
|
133 |
|
134 |
-
|
135 |
|
136 |
-
|
137 |
-
});
|
138 |
});
|
139 |
});
|
140 |
|
141 |
})(jQuery);
|
142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* globals jQuery */
|
2 |
(function ($) {
|
3 |
$(document.body).click(function (e) {
|
4 |
if (!$(e.target).is('.fw-option-type-rgba-color-picker, .iris-picker, .iris-picker-inner, .iris-palette, .fw-alpha-container')) {
|
34 |
return '#' + hex;
|
35 |
};
|
36 |
|
37 |
+
function activateIris(input) {
|
38 |
+
|
39 |
+
var $input = input;
|
40 |
+
|
41 |
+
$input.iris({
|
42 |
+
palettes: true,
|
43 |
+
defaultColor: false,
|
44 |
+
change: function (event, ui) {
|
45 |
+
var $transparency = $input.next('.iris-picker').find('.transparency');
|
46 |
+
$transparency.css('backgroundColor', ui.color.toString('no-alpha'));
|
47 |
+
|
48 |
+
$alpha_slider.slider("option", "value", ui.color._alpha * 100);
|
49 |
+
|
50 |
+
$input.css('background-color', ui.color.toCSS());
|
51 |
+
$input.css('color', ($alpha_slider.slider("value") > 40) ? ui.color.getMaxContrastColor().toCSS() : '#000000');
|
52 |
+
|
53 |
+
$input.trigger('fw:rgba:color:picker:changed', {
|
54 |
+
$element: $input,
|
55 |
+
iris: $input.data('a8cIris'),
|
56 |
+
alphaSlider: $alpha_slider.data('uiSlider')
|
57 |
+
});
|
58 |
+
}
|
59 |
+
});
|
60 |
+
|
61 |
+
$input.on('change keyup blur', function () {
|
62 |
+
|
63 |
+
// * iris::change is not triggered when the input is empty or color is wrong
|
64 |
+
if (Color($input.val()).error) {
|
65 |
+
$input.css('background-color', '');
|
66 |
+
$input.css('color', '');
|
67 |
+
}
|
68 |
+
});
|
69 |
+
|
70 |
+
if (!$input.hasClass('initialized')) {
|
71 |
|
72 |
$('<div class="fw-alpha-container"><div class="slider-alpha"></div><div class="transparency"></div></div>').appendTo($input.next('.iris-picker'));
|
73 |
|
74 |
+
}
|
75 |
+
|
76 |
+
var $alpha_slider = $input.next('.iris-picker:first').find('.slider-alpha');
|
77 |
+
|
78 |
+
$alpha_slider.slider({
|
79 |
+
value: Color($input.val())._alpha * 100,
|
80 |
+
range: "max",
|
81 |
+
step: 1,
|
82 |
+
min: 0,
|
83 |
+
max: 100,
|
84 |
+
slide: function (event, ui) {
|
85 |
+
$(this).find('.ui-slider-handle').text(ui.value);
|
86 |
+
|
87 |
+
var color = $input.iris('color', true);
|
88 |
+
var cssColor = (ui.value < 100) ? color.toCSS('rgba', ui.value / 100) : color.toHex();
|
89 |
+
|
90 |
+
$input.css('background-color', cssColor).val(cssColor);
|
91 |
+
$input.css('color', (ui.value > 40) ? color.getMaxContrastColor().toCSS() : '#000000');
|
92 |
+
|
93 |
+
var new_alpha_val = parseFloat(ui.value),
|
94 |
+
iris = $input.data('a8cIris');
|
95 |
+
iris._color._alpha = new_alpha_val / 100.0;
|
96 |
+
},
|
97 |
+
create: function (event, ui) {
|
98 |
+
var v = $(this).slider('value');
|
99 |
+
$(this).find('.ui-slider-handle').text(v);
|
100 |
+
var $transparency = $input.next('.iris-picker:first').find('.transparency');
|
101 |
+
$transparency.css('backgroundColor', Color($input.val()).toCSS('rgb', 1));
|
102 |
+
},
|
103 |
+
change: function (event, ui) {
|
104 |
+
$(this).find('.ui-slider-handle').text(ui.value);
|
105 |
+
|
106 |
+
var color = $input.iris('color', true);
|
107 |
+
var cssColor = (ui.value < 100) ? color.toCSS('rgba', ui.value / 100) : color.toHex();
|
108 |
+
|
109 |
+
$input.css('background-color', cssColor).val(cssColor);
|
110 |
+
$input.css('color', (ui.value > 40) ? color.getMaxContrastColor().toCSS() : '#000000');
|
111 |
+
|
112 |
+
var new_alpha_val = parseFloat(ui.value),
|
113 |
+
iris = $input.data('a8cIris');
|
114 |
+
iris._color._alpha = new_alpha_val / 100.0;
|
115 |
+
|
116 |
+
$input.trigger('fw:rgba:color:picker:changed', {
|
117 |
+
$element: $input,
|
118 |
+
iris: $input.data('a8cIris'),
|
119 |
+
alphaSlider: $alpha_slider.data('uiSlider')
|
120 |
+
});
|
|
|
|
|
|
|
|
|
|
|
121 |
}
|
122 |
+
});
|
123 |
|
124 |
+
$input.iris('show');
|
125 |
|
126 |
+
if (!Color($input.val()).error) {
|
127 |
+
$input.iris('color', $input.val());
|
128 |
+
}
|
129 |
+
|
130 |
+
$input.addClass('initialized');
|
131 |
+
|
132 |
+
}
|
133 |
+
|
134 |
+
fwEvents.on('fw:options:init', function (data) {
|
135 |
+
|
136 |
+
data.$elements.find('input.fw-option-type-rgba-color-picker').each(function () {
|
137 |
+
|
138 |
+
var $this = $(this);
|
139 |
+
|
140 |
+
if ($this.val() != '') {
|
141 |
+
$this.css('background-color', $(this).val());
|
142 |
+
$this.contrastColor();
|
143 |
+
}
|
144 |
+
|
145 |
+
});
|
146 |
|
147 |
+
$('.fw-inner').on('click', '.fw-option-type-rgba-color-picker', function () {
|
|
|
148 |
|
149 |
+
activateIris($(this));
|
150 |
|
151 |
+
return false;
|
|
|
152 |
});
|
153 |
});
|
154 |
|
155 |
})(jQuery);
|
156 |
|
157 |
+
(function ($) {
|
158 |
+
$.fn.contrastColor = function () {
|
159 |
+
return this.each(function () {
|
160 |
+
var bg = $(this).css('background-color');
|
161 |
+
//use first opaque parent bg if element is transparent
|
162 |
+
if (bg == 'transparent' || bg == 'rgba(0, 0, 0, 0)') {
|
163 |
+
$(this).parents().each(function () {
|
164 |
+
bg = $(this).css('background-color');
|
165 |
+
if (bg != 'transparent' && bg != 'rgba(0, 0, 0, 0)') return false;
|
166 |
+
});
|
167 |
+
//exit if all parents are transparent
|
168 |
+
if (bg == 'transparent' || bg == 'rgba(0, 0, 0, 0)') return false;
|
169 |
+
}
|
170 |
+
//get r,g,b and decide
|
171 |
+
var rgb = bg.replace(/^(rgb|rgba)\(/, '').replace(/\)$/, '').replace(/\s/g, '').split(',');
|
172 |
+
var yiq = ((rgb[0] * 299) + (rgb[1] * 587) + (rgb[2] * 114)) / 1000;
|
173 |
+
if (yiq >= 150) $(this).css('color', '#000000');
|
174 |
+
else $(this).css('color', '#ffffff');
|
175 |
+
});
|
176 |
+
};
|
177 |
+
|
178 |
+
})(jQuery);
|
framework/includes/option-types/switch/class-fw-option-type-switch.php
CHANGED
@@ -103,7 +103,6 @@ class FW_Option_Type_Switch extends FW_Option_Type
|
|
103 |
protected function _get_value_from_input($option, $input_value)
|
104 |
{
|
105 |
if (is_null($input_value)) {
|
106 |
-
// input value is not present
|
107 |
return $option['value'];
|
108 |
} else {
|
109 |
if ($input_value) {
|
103 |
protected function _get_value_from_input($option, $input_value)
|
104 |
{
|
105 |
if (is_null($input_value)) {
|
|
|
106 |
return $option['value'];
|
107 |
} else {
|
108 |
if ($input_value) {
|
framework/includes/option-types/upload/class-fw-option-type-upload.php
CHANGED
@@ -183,8 +183,7 @@ class FW_Option_Type_Upload extends FW_Option_Type
|
|
183 |
protected function _get_value_from_input($option, $input_value)
|
184 |
{
|
185 |
if (empty($input_value)) {
|
186 |
-
|
187 |
-
return $defaults['value'];
|
188 |
} else {
|
189 |
return $this->get_attachment_info($input_value);
|
190 |
}
|
183 |
protected function _get_value_from_input($option, $input_value)
|
184 |
{
|
185 |
if (empty($input_value)) {
|
186 |
+
return $option['value'];
|
|
|
187 |
} else {
|
188 |
return $this->get_attachment_info($input_value);
|
189 |
}
|
framework/includes/option-types/upload/views/images-only.php
CHANGED
@@ -25,11 +25,12 @@
|
|
25 |
</div>
|
26 |
<?php endif; ?>
|
27 |
<p><a href="#"><?php echo $is_empty ? $l10n['button_add'] : $l10n['button_edit']; ?></a></p>
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
<
|
34 |
-
|
|
|
35 |
</div>
|
25 |
</div>
|
26 |
<?php endif; ?>
|
27 |
<p><a href="#"><?php echo $is_empty ? $l10n['button_add'] : $l10n['button_edit']; ?></a></p>
|
28 |
+
|
29 |
+
<br class="thumb-template-empty fw-hidden" data-template="<?php echo fw_htmlspecialchars(
|
30 |
+
'<img src="'. fw_get_framework_directory_uri('/static/img/no-image.png') .'" class="no-image-img" alt="'. esc_attr__('No image', 'fw') .'"/>'
|
31 |
+
); ?>">
|
32 |
+
<br class="thumb-template-not-empty fw-hidden" data-template="<?php echo fw_htmlspecialchars(
|
33 |
+
'<img src="<%- data.src %>" alt="<%- data.alt %>"/>'.
|
34 |
+
'<a href="#" class="dashicons fw-x clear-uploads-thumb"></a>'
|
35 |
+
); ?>">
|
36 |
</div>
|
framework/manifest.php
CHANGED
@@ -4,4 +4,4 @@ $manifest = array();
|
|
4 |
|
5 |
$manifest['name'] = __('Unyson', 'fw');
|
6 |
|
7 |
-
$manifest['version'] = '2.2.
|
4 |
|
5 |
$manifest['name'] = __('Unyson', 'fw');
|
6 |
|
7 |
+
$manifest['version'] = '2.2.8';
|
framework/static/css/fw.css
CHANGED
@@ -2894,6 +2894,7 @@ a.fw-wp-link:hover {
|
|
2894 |
-webkit-box-sizing: border-box;
|
2895 |
-moz-box-sizing: border-box;
|
2896 |
box-sizing: border-box;
|
|
|
2897 |
}
|
2898 |
|
2899 |
.fw-options-modal.fw-options-modal-small > .media-modal {
|
2894 |
-webkit-box-sizing: border-box;
|
2895 |
-moz-box-sizing: border-box;
|
2896 |
box-sizing: border-box;
|
2897 |
+
width: 100%;
|
2898 |
}
|
2899 |
|
2900 |
.fw-options-modal.fw-options-modal-small > .media-modal {
|
framework/static/js/backend-options.js
CHANGED
@@ -105,7 +105,7 @@ jQuery(document).ready(function($){
|
|
105 |
/**
|
106 |
* leave open only first boxes
|
107 |
*/
|
108 |
-
$boxes.filter('.fw-backend-postboxes > .fw-postbox:not(:first-child)').addClass('closed');
|
109 |
|
110 |
$boxes.addClass('fw-postbox-initialized');
|
111 |
|
105 |
/**
|
106 |
* leave open only first boxes
|
107 |
*/
|
108 |
+
$boxes.filter('.fw-backend-postboxes > .fw-postbox:not(:first-child):not(.prevent-auto-close)').addClass('closed');
|
109 |
|
110 |
$boxes.addClass('fw-postbox-initialized');
|
111 |
|
readme.txt
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
Contributors: unyson, themefusecom
|
3 |
Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio, framework
|
4 |
Requires at least: 4.0.0
|
5 |
-
Tested up to: 4.
|
6 |
-
Stable tag: 2.2.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -86,6 +86,19 @@ Yes; Unyson will work with any theme.
|
|
86 |
|
87 |
== Changelog ==
|
88 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
= 2.2.7 =
|
90 |
* Option type `popup` fixes
|
91 |
* Added "Show/Hide other extensions" button [#307](https://github.com/ThemeFuse/Unyson/issues/307)
|
2 |
Contributors: unyson, themefusecom
|
3 |
Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio, framework
|
4 |
Requires at least: 4.0.0
|
5 |
+
Tested up to: 4.2
|
6 |
+
Stable tag: 2.2.8
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
86 |
|
87 |
== Changelog ==
|
88 |
|
89 |
+
= 2.2.8 =
|
90 |
+
* Fixed [#453](https://github.com/ThemeFuse/Unyson/issues/453)
|
91 |
+
* Improved option type `multi-picker` html render [#442](https://github.com/ThemeFuse/Unyson/issues/442)
|
92 |
+
* Option type `rgba-color-picker` optimizations [#442](https://github.com/ThemeFuse/Unyson/issues/442)
|
93 |
+
* `fw_resize()` improvements [#447](https://github.com/ThemeFuse/Unyson/issues/447)
|
94 |
+
* Fixed [#445](https://github.com/ThemeFuse/Unyson/issues/445), [#161](https://github.com/ThemeFuse/Unyson/issues/161), [#484](https://github.com/ThemeFuse/Unyson/issues/484), [#456](https://github.com/ThemeFuse/Unyson/issues/456)
|
95 |
+
* Added the possibility to prevent box auto-close [#466](https://github.com/ThemeFuse/Unyson/issues/466)
|
96 |
+
* Fixed the `_get_value_from_input()` method in some option types [#275](https://github.com/ThemeFuse/Unyson/issues/275#issuecomment-94084590)
|
97 |
+
* Added the `limit` parameter for option type `addable-popup` [#478](https://github.com/ThemeFuse/Unyson/issues/478)
|
98 |
+
* Fixed popup position in IE [#483](https://github.com/ThemeFuse/Unyson/issues/483)
|
99 |
+
* Created `fw_post_options_update` action
|
100 |
+
* Improved post save: Options are saved in revision and autosave. Restore from revision works.
|
101 |
+
|
102 |
= 2.2.7 =
|
103 |
* Option type `popup` fixes
|
104 |
* Added "Show/Hide other extensions" button [#307](https://github.com/ThemeFuse/Unyson/issues/307)
|
unyson.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Unyson
|
4 |
* Plugin URI: http://unyson.themefuse.com/
|
5 |
* Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
|
6 |
-
* Version: 2.2.
|
7 |
* Author: ThemeFuse
|
8 |
* Author URI: http://themefuse.com
|
9 |
* License: GPL2+
|
3 |
* Plugin Name: Unyson
|
4 |
* Plugin URI: http://unyson.themefuse.com/
|
5 |
* Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
|
6 |
+
* Version: 2.2.8
|
7 |
* Author: ThemeFuse
|
8 |
* Author URI: http://themefuse.com
|
9 |
* License: GPL2+
|